Better compiler errors
This commit is contained in:
parent
c7fc2fdae0
commit
aef95b74cc
37
types.go
37
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:
|
||||
|
18
validator.go
18
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user