Better compiler errors

This commit is contained in:
MrLetsplay 2024-03-28 15:48:50 +01:00
parent c7fc2fdae0
commit aef95b74cc
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
2 changed files with 44 additions and 11 deletions

View File

@ -102,6 +102,43 @@ func getPrimitiveTypeByName(name string) (PrimitiveType, error) {
return PrimitiveType(idx), nil 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 { func isAssigmentOperator(operator Operator) bool {
switch operator { switch operator {
case Operator_Equals, Operator_PlusEquals, Operator_MinusEquals, Operator_MultiplyEquals, Operator_DivideEquals, Operator_ModuloEquals: case Operator_Equals, Operator_PlusEquals, Operator_MinusEquals, Operator_MultiplyEquals, Operator_DivideEquals, Operator_ModuloEquals:

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"strconv" "strconv"
) )
@ -74,12 +75,11 @@ func isPrimitiveTypeExpandableTo(from PrimitiveType, to PrimitiveType) bool {
} }
func (v *Validator) createError(message string, position uint64) error { func (v *Validator) createError(message string, position uint64) error {
// TODO: pass token and get actual token position
return CompilerError{Position: position, Message: message} return CompilerError{Position: position, Message: message}
} }
func (v *Validator) validateImport(imp *Import) []error { func (v *Validator) validateImport(imp *Import) []error {
// TODO // TODO imports
return nil return nil
} }
@ -96,9 +96,7 @@ func (v *Validator) getArithmeticResultType(expr *Expression, left PrimitiveType
return left, nil return left, nil
} }
// TODO: boolean expressions etc. 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
return InvalidValue, v.createError("cannot use these types in an arithmetic expression without an explicit cast", expr.Position) // TODO: include type names in error
} }
func getLocal(block *Block, variable string) *Local { 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) { 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 expr.ValueType = &local.Type
@ -184,7 +182,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error
} }
if result == InvalidValue { 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 return errors
} }
@ -194,7 +192,7 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression) []error
if isArithmeticOperation(binary.Operation) { if isArithmeticOperation(binary.Operation) {
if binary.Left.ValueType.Type != Type_Primitive || binary.Right.ValueType.Type != Type_Primitive { 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 return errors
} }
@ -315,8 +313,6 @@ func (v *Validator) validateExpression(expr *Expression) []error {
func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local) []error { func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local) []error {
var errors []error var errors []error
// TODO: support references to variables in parent block
switch stmt.Type { switch stmt.Type {
case Statement_Expression: case Statement_Expression:
expression := stmt.Value.(ExpressionStatement) expression := stmt.Value.(ExpressionStatement)
@ -357,7 +353,7 @@ func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local)
} }
if !isTypeExpandableTo(*dlv.Initializer.ValueType, dlv.VariableType) { 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))
} }
} }