Added untested object member analysis

This commit is contained in:
Sasha Koshka 2022-10-12 23:25:21 -04:00
parent aaf268d0d1
commit f817894b49
3 changed files with 106 additions and 8 deletions

View File

@ -19,6 +19,7 @@ type TypeSection struct {
// ObjectMember is a member of an object type.
type ObjectMember struct {
locatable
name string
// even if there is a private permission in another module, we still
@ -27,6 +28,7 @@ type ObjectMember struct {
permission types.Permission
what Type
argument Argument
}
func (member ObjectMember) ToString (indent int) (output string) {
@ -98,12 +100,13 @@ func (analyzer analysisOperation) analyzeTypeSection () (
inputSection := analyzer.currentSection.(parser.TypeSection)
outputSection.location = analyzer.currentSection.Location()
if inputSection.Permission() == types.PermissionReadWrite {
err = inputSection.NewError (
"read-write (rw) permission not understood in this " +
"context, try read-only (ro)",
infoerr.ErrorKindError)
return
}
outputSection.permission = inputSection.Permission()
@ -126,12 +129,10 @@ func (analyzer analysisOperation) analyzeTypeSection () (
// analyze members
isObj := outputSection.what.underlyingPrimitive() == &PrimitiveObj
if isObj {
// use the Member method on the inherited type to type check and
// permission check default value overrides.
for index := 0; index < inputSection.MembersLength(); index ++ {
// inputMember := inputSection.Member(index)
// TODO
}
err = analyzer.analyzeObjectMembers (
&outputSection,
inputSection)
if err != nil { return }
} else if inputSection.MembersLength() > 0 {
// if there are members, and the inherited type does not have
@ -140,8 +141,95 @@ func (analyzer analysisOperation) analyzeTypeSection () (
"members can only be defined on types descending " +
"from Obj",
infoerr.ErrorKindError)
if err != nil { return }
}
outputSection.complete = true
return
}
func (analyzer *analysisOperation) analyzeObjectMembers (
into *TypeSection,
from parser.TypeSection,
) (
err error,
) {
inheritedSection := into.what.actual
for index := 0; index < from.MembersLength(); index ++ {
inputMember := from.Member(index)
outputMember := ObjectMember { }
outputMember.location = inputMember.Location()
outputMember.name = inputMember.Name()
outputMember.permission = inputMember.Permission()
inheritedMember, exists :=
inheritedSection.Member(inputMember.Name())
if exists {
// modifying default value/permissions of an
// inherited member
outputMember.what = inheritedMember.what
if !inputMember.Type().Nil() {
err = inputMember.NewError (
"cannot override type of " +
"inherited member",
infoerr.ErrorKindError)
return
}
if outputMember.permission > inheritedMember.permission {
err = inputMember.NewError (
"cannot relax permission of " +
"inherited member",
infoerr.ErrorKindError)
return
}
// apply default value
if inputMember.Argument().Nil() {
// if it is unspecified, inherit it
outputMember.argument = inheritedMember.argument
} else {
outputMember.argument,
err = analyzer.analyzeArgument(inputMember.Argument())
if err != nil { return }
// type check default value
err = analyzer.typeCheck (
outputMember.argument,
outputMember.what)
if err != nil { return }
}
} else {
// defining a new member
if inputMember.Type().Nil() {
err = inputMember.NewError (
"new members must be given a " +
"type",
infoerr.ErrorKindError)
return
}
// apply default value
if !inputMember.Argument().Nil() {
outputMember.argument,
err = analyzer.analyzeArgument(inputMember.Argument())
if err != nil { return }
// type check default value
err = analyzer.typeCheck (
outputMember.argument,
outputMember.what)
if err != nil { return }
}
}
into.members = append (
into.members,
outputMember)
}
return
}

View File

@ -4,7 +4,9 @@ import "testing"
func TestTypeSection (test *testing.T) {
checkTree ("../tests/analyzer/typeSection", false,
`typeSection ro ../tests/analyzer/typeSection.aBasicInt
`typeSection ro ../tests/analyzer/typeSection/something.Thing
type 1 basic Int
typeSection ro ../tests/analyzer/typeSection.aBasicInt
type 1 basic Int
arg uint 5
typeSection ro ../tests/analyzer/typeSection.bOnBasicInt
@ -15,5 +17,7 @@ typeSection ro ../tests/analyzer/typeSection.cBasicObject
type 1 basic Int
member ro this
type 1 basic Int
typeSection ro ../tests/analyzer/typeSection.dInheritedFromOther
type 1 basic Thing
`, test)
}

View File

@ -55,6 +55,12 @@ func (what Type) Kind () (kind TypeKind) {
return
}
// Nil returns true if the type is nil, and false if it isn't.
func (what Type) Nil () (isNil bool) {
isNil = what.kind == TypeKindNil
return
}
// Mutable returns whether or not the type's data is mutable.
func (what Type) Mutable () (mutable bool) {
mutable = what.mutable