From aef95b74cc2e9a7ca544df0b2a5d3880ab772e6c Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Thu, 28 Mar 2024 15:48:50 +0100 Subject: [PATCH] Better compiler errors --- types.go | 37 +++++++++++++++++++++++++++++++++++++ validator.go | 18 +++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/types.go b/types.go index 05c8e94..c83d5f8 100644 --- a/types.go +++ b/types.go @@ -102,6 +102,43 @@ func getPrimitiveTypeByName(name string) (PrimitiveType, error) { return PrimitiveType(idx), nil } +func getPrimitiveTypeName(primitiveType PrimitiveType) string { + return PRIMITIVE_TYPE_NAMES[primitiveType] +} + +func getTypeName(theType Type) string { + switch theType.Type { + case Type_Primitive: + return getPrimitiveTypeName(theType.Value.(PrimitiveType)) + case Type_Named: + return theType.Value.(NamedType).TypeName + case Type_Array: + return getTypeName(theType.Value.(ArrayType).ElementType) + "[]" + case Type_Tuple: + name := "(" + + for idx, member := range theType.Value.(TupleType).Types { + name += getTypeName(member) + if idx != len(theType.Value.(TupleType).Types)-1 { + name += ", " + } + } + + name += ")" + return name + default: + panic("type name not implemented") + } +} + +func (t Type) String() string { + return getTypeName(t) +} + +func (t PrimitiveType) String() string { + return getPrimitiveTypeName(t) +} + func isAssigmentOperator(operator Operator) bool { switch operator { case Operator_Equals, Operator_PlusEquals, Operator_MinusEquals, Operator_MultiplyEquals, Operator_DivideEquals, Operator_ModuloEquals: diff --git a/validator.go b/validator.go index 3e40c5e..2747b10 100644 --- a/validator.go +++ b/validator.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "strconv" ) @@ -74,12 +75,11 @@ func isPrimitiveTypeExpandableTo(from PrimitiveType, to PrimitiveType) bool { } func (v *Validator) createError(message string, position uint64) error { - // TODO: pass token and get actual token position return CompilerError{Position: position, Message: message} } func (v *Validator) validateImport(imp *Import) []error { - // TODO + // TODO imports return nil } @@ -96,9 +96,7 @@ func (v *Validator) getArithmeticResultType(expr *Expression, left PrimitiveType return left, nil } - // TODO: boolean expressions etc. - - return InvalidValue, v.createError("cannot use these types in an arithmetic expression without an explicit cast", expr.Position) // TODO: include type names in error + return InvalidValue, v.createError(fmt.Sprintf("cannot use the types [%s, %s] in an arithmetic expression without an explicit cast", left, right), expr.Position) // TODO: include type names in error } func getLocal(block *Block, variable string) *Local { @@ -132,7 +130,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error } if !isTypeExpandableTo(*assignment.Value.ValueType, local.Type) { - errors = append(errors, v.createError("cannot assign expression to variable type", expr.Position)) + errors = append(errors, v.createError(fmt.Sprintf("cannot assign expression of type %s to variable of type %s", *assignment.Value.ValueType, local.Type), expr.Position)) } expr.ValueType = &local.Type @@ -184,7 +182,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error } if result == InvalidValue { - errors = append(errors, v.createError("cannot compare these types without explicit cast", expr.Position)) + errors = append(errors, v.createError(fmt.Sprintf("cannot compare the types %s and %s without an explicit cast", leftType, rightType), expr.Position)) return errors } @@ -194,7 +192,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error if isArithmeticOperation(binary.Operation) { if binary.Left.ValueType.Type != Type_Primitive || binary.Right.ValueType.Type != Type_Primitive { - errors = append(errors, v.createError("both sides of an arithmetic expression must be a primitive type", expr.Position)) + errors = append(errors, v.createError("both sides of an arithmetic expression must evaluate to a primitive type", expr.Position)) return errors } @@ -315,8 +313,6 @@ func (v *Validator) validateExpression(expr *Expression) []error { func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local) []error { var errors []error - // TODO: support references to variables in parent block - switch stmt.Type { case Statement_Expression: expression := stmt.Value.(ExpressionStatement) @@ -357,7 +353,7 @@ func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local) } if !isTypeExpandableTo(*dlv.Initializer.ValueType, dlv.VariableType) { - errors = append(errors, v.createError("cannot assign expression to variable type", stmt.Position)) + errors = append(errors, v.createError(fmt.Sprintf("cannot assign expression of type %s to variable of type %s", *dlv.Initializer.ValueType, dlv.VariableType), stmt.Position)) } }