Made the type checker a tad more robust

This commit is contained in:
Sasha Koshka 2023-12-15 13:23:37 -05:00
parent b220235a43
commit 6bcbd6aff9
5 changed files with 28 additions and 11 deletions

View File

@ -129,14 +129,14 @@ func (this *Tree) canAssign (
*entity.TypeFloat,
*entity.TypeWord:
if !destination.Equals(source) {
return fail()
if destination.Equals(source) {
return nil
}
default: panic(fmt.Sprint("BUG: analyzer doesnt know about type", destination))
}
return nil
return fail()
}
func (this *Tree) canAssignCoerce (
@ -181,7 +181,7 @@ func (this *Tree) canAssignCoerce (
return fail()
}
default:
if !destination.Equals(source) {
if !this.areStructurallyEquivalent(destination, source) {
return fail()
}
}
@ -189,7 +189,7 @@ func (this *Tree) canAssignCoerce (
case *entity.TypeSlice,
*entity.TypeArray,
*entity.TypeStruct:
if !destination.Equals(source) {
if !this.areStructurallyEquivalent(destination, source) {
return fail()
}

View File

@ -224,9 +224,9 @@ func TestAssignmentInterfaceErrBadLayer (test *testing.T) {
testStringErr (test,
"no method named fly defined on this type", 7, 11,
`
Bird: ([fly distance:F64] [land])
Bird: ([fly distance:F64])
BlueJay: Int
BlueJay.[land] = { }
BlueJay.[fly distance:F64] = { }
BlueJayRef: *BlueJay
[main] = {
b:Bird = a:BlueJayRef
@ -249,6 +249,17 @@ BlueJay.[land] = { }
`)
}
func TestAssignmentErrByteSliceString (test *testing.T) {
testStringErr (test,
"expected *:Byte", 4, 13,
`
[main] = {
a:String = 'hello'
b:*:Byte = a
}
`)
}
// TODO: complete and test error cases
func TestAssignmentPropagateRules (test *testing.T) {
testString (test,

View File

@ -84,6 +84,8 @@ IntDerived: Int
d:(x:Int y:Int) = (x: 1 y: 2)
e:(z:Int a:Int) = [~~ (z:Int a:Int) d]
f:Bird = [~~ BlueJay 0]
g:String = 'hello'
h:*:Byte = [~ *:Byte g]
}
`)
}

View File

@ -31,7 +31,7 @@ func testReaderErr (
for index, stream := range inputs {
err := ast.Parse(fmt.Sprintf("stream%d.fspl", index), stream)
if err != nil {
test.Error("parser returned error: ", err)
test.Error("parser returned error:", err)
return
}
}
@ -68,7 +68,7 @@ func testReader (test *testing.T, inputs ...io.Reader) {
for index, stream := range inputs {
err := ast.Parse(fmt.Sprintf("stream%d.fspl", index), stream)
if err != nil {
test.Error("parser returned error: ", err)
test.Error("parser returned error:", err)
return
}
}
@ -76,7 +76,7 @@ func testReader (test *testing.T, inputs ...io.Reader) {
tree := Tree { }
err := tree.Analyze(ast)
if err != nil {
test.Error("analyzer returned error: ", err)
test.Error("analyzer returned error:", err)
return
}
}

View File

@ -151,7 +151,11 @@ type TypeInt struct {
}
func (*TypeInt) ty(){}
func (this *TypeInt) String () string {
return fmt.Sprint("I", this.Width)
if this.Signed {
return fmt.Sprint("I", this.Width)
} else {
return fmt.Sprint("U", this.Width)
}
}
func (this *TypeInt) Equals (ty Type) bool {
real, ok := ty.(*TypeInt)