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
|
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:
|
||||||
|
18
validator.go
18
validator.go
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user