From 605fd24228fd3de45aa90db88e007278e24c3bda Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 4 Nov 2023 17:59:04 -0400 Subject: [PATCH] Pass all analyzer tests --- analyzer/assignment.go | 23 +++++++++---------- analyzer/expression.go | 14 ++++++++---- analyzer/operation_test.go | 46 ++++++++++++++++++++------------------ analyzer/type.go | 4 ++-- entity/type.go | 11 --------- 5 files changed, 47 insertions(+), 51 deletions(-) diff --git a/analyzer/assignment.go b/analyzer/assignment.go index 2e9069c..d79049c 100644 --- a/analyzer/assignment.go +++ b/analyzer/assignment.go @@ -103,8 +103,7 @@ func (this *Tree) canAssign ( *entity.TypeStruct, *entity.TypeInt, *entity.TypeFloat, - *entity.TypeWord, - *entity.TypeBool: + *entity.TypeWord: if !destination.Equals(source) { return fail() @@ -138,14 +137,14 @@ func (this *Tree) canAssignCoerce ( // base type case *entity.TypeInt, *entity.TypeFloat, - *entity.TypeWord, - *entity.TypeBool: + *entity.TypeWord: switch source.(type) { case *entity.TypeInt, *entity.TypeFloat, - *entity.TypeWord, - *entity.TypeBool: return nil - default: return fail() + *entity.TypeWord: + return nil + default: + return fail() } case *entity.TypePointer, @@ -271,8 +270,7 @@ func (this *Tree) areStructurallyEquivalent (left, right entity.Type) bool { // terminals case *entity.TypeInt, *entity.TypeFloat, - *entity.TypeWord, - *entity.TypeBool: + *entity.TypeWord: return left.Equals(right) default: panic(fmt.Sprint("BUG: analyzer doesnt know about type ", left)) @@ -390,9 +388,10 @@ func (this *Tree) isOrdered (ty entity.Type) bool { // isBoolean returns whether or not the specified type is a boolean. func (this *Tree) isBoolean (ty entity.Type) bool { - switch this.reduceToBase(ty).(type) { - case *entity.TypeBool: return true - default: return false + for { + named, ok := ty.(*entity.TypeNamed) + if !ok { return false } + if named.Name == "Bool" { return true } } } diff --git a/analyzer/expression.go b/analyzer/expression.go index 2c967c1..ba12c4a 100644 --- a/analyzer/expression.go +++ b/analyzer/expression.go @@ -354,7 +354,10 @@ func (this *Tree) analyzeOperation ( comparison := func (argConstraint func (entity.Type) bool) (entity.Expression, error) { if len(operation.Arguments) < 2 { return wrongArgCount() } if !this.isBoolean(into) { return wrongInto() } - operation.Ty = &entity.TypeBool { } + operation.Ty = &entity.TypeNamed { + Name: "Bool", + Type: this.Types["Bool"].Type, + } // find the first argument that has explicit type information. // TODO: possibly make a method of expressions to check this @@ -413,14 +416,14 @@ func (this *Tree) analyzeOperation ( case entity.OperatorLogicalOr, entity.OperatorLogicalAnd, entity.OperatorLogicalXor: - return nSameType(2, this.isBoolean) + return nSameType(-1, this.isBoolean) // bit manipulation case entity.OperatorNot: return nSameType(1, this.isInteger) case entity.OperatorOr, entity.OperatorAnd, entity.OperatorXor: - return nSameType(2, this.isInteger) + return nSameType(-1, this.isInteger) case entity.OperatorLeftShift, entity.OperatorRightShift: if len(operation.Arguments) != 2 { return wrongArgCount() } @@ -535,7 +538,10 @@ func (this *Tree) analyzeIfElse ( error, ) { condition, err := this.analyzeExpression ( - &entity.TypeBool { }, + &entity.TypeNamed { + Name: "Bool", + Type: this.Types["Bool"].Type, + }, weak, ifelse.Condition) if err != nil { return nil, err } ifelse.Condition = condition diff --git a/analyzer/operation_test.go b/analyzer/operation_test.go index 45b520b..e448a42 100644 --- a/analyzer/operation_test.go +++ b/analyzer/operation_test.go @@ -54,28 +54,30 @@ func TestOperationArgCount (test *testing.T) { testString (test, ` [main] = { - [+ 1 2 3 4] - [++ 1] - [- 1 2 3 4] - [-- 1] - [* 5 6] - [/ 32 16] - [% 5 6] - [!! true] - [|| false] - [&& true true false true] - [^^ true true false true] - [! 1] - [| 1 2] - [& 3 1] - [^ 1 2 3 4] - [<< 1 8] - [>> 8 1] - [< 1 2 3 4] - [> 1 2 3 4] - [<= 10 5 3] - [>= 1 2 3 3 4] - [= 2 2 2 3 9] + x:Int + b:Bool + x = [+ 1 2 3 4] + x = [++ 1] + x = [- 1 2 3 4] + x = [-- 1] + x = [* 5 6] + x = [/ 32 16] + x = [% 5 6] + x = [!! 1] + x = [|| 1 2] + x = [&& 3 1 5] + x = [^^ 1 2 3 4] + b = [! true] + b = [| true false] + b = [& true true] + b = [^ true true false true] + x = [<< 1 8] + x = [>> 8 1] + b = [< x 2 3 4] + b = [> x 2 3 4] + b = [<= x 5 3] + b = [>= x 2 3 3 4] + b = [= x 2 2 3 9] } `) } diff --git a/analyzer/type.go b/analyzer/type.go index 25b607a..2543271 100644 --- a/analyzer/type.go +++ b/analyzer/type.go @@ -149,8 +149,8 @@ func (this *Tree) analyzeTypeInternal ( } return ty, nil - // floating point, word, and boolean types - case *entity.TypeFloat, *entity.TypeWord, *entity.TypeBool: + // floating point and word types + case *entity.TypeFloat, *entity.TypeWord: return ty, nil default: panic(fmt.Sprint("BUG: analyzer doesnt know about type ", ty)) diff --git a/entity/type.go b/entity/type.go index 6f17a17..c844b59 100644 --- a/entity/type.go +++ b/entity/type.go @@ -190,17 +190,6 @@ func (this *TypeWord) Equals (ty Type) bool { return ok && real.Signed == this.Signed } -// TypeBool represents a boolean type. -type TypeBool struct { - Pos lexer.Position -} -func (*TypeBool) ty(){} -func (this *TypeBool) String () string { return "Bool" } -func (this *TypeBool) Equals (ty Type) bool { - _, ok := ty.(*TypeBool) - return ok -} - // TypesEqual checks if two types are equal to eachother, even if one or both // are nil. func TypesEqual (left, right Type) bool {