rename some things
This commit is contained in:
parent
193bd5c2d5
commit
c0b9ee086a
@ -218,15 +218,15 @@ func compileExpressionWAT(expr Expression, block Block) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch arith.Operation {
|
switch arith.Operation {
|
||||||
case Arithmetic_Add:
|
case Operation_Add:
|
||||||
op = getPrimitiveWATType(exprType) + ".add\n"
|
op = getPrimitiveWATType(exprType) + ".add\n"
|
||||||
case Arithmetic_Sub:
|
case Operation_Sub:
|
||||||
op = getPrimitiveWATType(exprType) + ".sub\n"
|
op = getPrimitiveWATType(exprType) + ".sub\n"
|
||||||
case Arithmetic_Mul:
|
case Operation_Mul:
|
||||||
op = getPrimitiveWATType(exprType) + ".mul\n"
|
op = getPrimitiveWATType(exprType) + ".mul\n"
|
||||||
case Arithmetic_Div:
|
case Operation_Div:
|
||||||
op = getPrimitiveWATType(exprType) + ".div_" + suffix + "\n"
|
op = getPrimitiveWATType(exprType) + ".div_" + suffix + "\n"
|
||||||
case Arithmetic_Mod:
|
case Operation_Mod:
|
||||||
op = getPrimitiveWATType(exprType) + ".rem_" + suffix + "\n"
|
op = getPrimitiveWATType(exprType) + ".rem_" + suffix + "\n"
|
||||||
default:
|
default:
|
||||||
panic("operation not implemented")
|
panic("operation not implemented")
|
||||||
|
31
parser.go
31
parser.go
@ -104,27 +104,28 @@ type VariableReferenceExpression struct {
|
|||||||
Variable string
|
Variable string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArithmeticOperation uint32
|
type Operation uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Arithmetic_Add ArithmeticOperation = iota
|
Operation_Add Operation = iota
|
||||||
Arithmetic_Sub
|
Operation_Sub
|
||||||
Arithmetic_Mul
|
Operation_Mul
|
||||||
Arithmetic_Div
|
Operation_Div
|
||||||
Arithmetic_Mod
|
Operation_Mod
|
||||||
Arithmetic_Greater
|
Operation_Greater
|
||||||
Arithmetic_Less
|
Operation_Less
|
||||||
Arithmetic_GreaterEquals
|
Operation_GreaterEquals
|
||||||
Arithmetic_LessEquals
|
Operation_LessEquals
|
||||||
Arithmetic_LogicalNot
|
Operation_LogicalNot
|
||||||
Arithmetic_NotEquals
|
Operation_NotEquals
|
||||||
Arithmetic_Equals
|
Operation_Equals
|
||||||
)
|
)
|
||||||
|
|
||||||
type BinaryExpression struct {
|
type BinaryExpression struct {
|
||||||
Operation ArithmeticOperation
|
Operation Operation
|
||||||
Left Expression
|
Left Expression
|
||||||
Right Expression
|
Right Expression
|
||||||
|
ResultType *Type
|
||||||
}
|
}
|
||||||
|
|
||||||
type TupleExpression struct {
|
type TupleExpression struct {
|
||||||
@ -516,7 +517,7 @@ func (p *Parser) tryBinaryExpression0(opFunc func() (*Expression, error), operat
|
|||||||
return nil, p.error("expected expression")
|
return nil, p.error("expected expression")
|
||||||
}
|
}
|
||||||
|
|
||||||
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getArithmeticOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
types.go
39
types.go
@ -111,33 +111,46 @@ func isAssigmentOperator(operator Operator) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArithmeticOperation(operator Operator) ArithmeticOperation {
|
func getOperation(operator Operator) Operation {
|
||||||
switch operator {
|
switch operator {
|
||||||
case Operator_Greater:
|
case Operator_Greater:
|
||||||
return Arithmetic_Greater
|
return Operation_Greater
|
||||||
case Operator_Less:
|
case Operator_Less:
|
||||||
return Arithmetic_Less
|
return Operation_Less
|
||||||
case Operator_Not:
|
case Operator_Not:
|
||||||
return Arithmetic_LogicalNot
|
return Operation_LogicalNot
|
||||||
case Operator_Plus, Operator_PlusEquals:
|
case Operator_Plus, Operator_PlusEquals:
|
||||||
return Arithmetic_Add
|
return Operation_Add
|
||||||
case Operator_Minus, Operator_MinusEquals:
|
case Operator_Minus, Operator_MinusEquals:
|
||||||
return Arithmetic_Sub
|
return Operation_Sub
|
||||||
case Operator_Multiply, Operator_MultiplyEquals:
|
case Operator_Multiply, Operator_MultiplyEquals:
|
||||||
return Arithmetic_Mul
|
return Operation_Mul
|
||||||
case Operator_Divide, Operator_DivideEquals:
|
case Operator_Divide, Operator_DivideEquals:
|
||||||
return Arithmetic_Div
|
return Operation_Div
|
||||||
case Operator_Modulo, Operator_ModuloEquals:
|
case Operator_Modulo, Operator_ModuloEquals:
|
||||||
return Arithmetic_Mod
|
return Operation_Mod
|
||||||
case Operator_EqualsEquals:
|
case Operator_EqualsEquals:
|
||||||
return Arithmetic_Equals
|
return Operation_Equals
|
||||||
case Operator_GreaterEquals:
|
case Operator_GreaterEquals:
|
||||||
return Arithmetic_GreaterEquals
|
return Operation_GreaterEquals
|
||||||
case Operator_LessEquals:
|
case Operator_LessEquals:
|
||||||
return Arithmetic_LessEquals
|
return Operation_LessEquals
|
||||||
case Operator_NotEquals:
|
case Operator_NotEquals:
|
||||||
return Arithmetic_NotEquals
|
return Operation_NotEquals
|
||||||
default:
|
default:
|
||||||
return InvalidValue
|
return InvalidValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isBooleanOperation(operation Operation) bool {
|
||||||
|
switch operation {
|
||||||
|
case Operation_Greater, Operation_Less, Operation_LogicalNot, Operation_Equals, Operation_GreaterEquals, Operation_LessEquals, Operation_NotEquals:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isArithmeticOperation(operation Operation) bool {
|
||||||
|
return !isBooleanOperation(operation)
|
||||||
|
}
|
||||||
|
73
validator.go
73
validator.go
@ -58,7 +58,7 @@ func (v *Validator) validateImport(imp *Import) []error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Validator) getArithmeticResultType(expr *Expression, left PrimitiveType, right PrimitiveType, operation ArithmeticOperation) (PrimitiveType, error) {
|
func (v *Validator) getArithmeticResultType(expr *Expression, left PrimitiveType, right PrimitiveType, operation Operation) (PrimitiveType, error) {
|
||||||
if left == Primitive_Bool || right == Primitive_Bool {
|
if left == Primitive_Bool || right == Primitive_Bool {
|
||||||
return InvalidValue, v.createError("bool type cannot be used in arithmetic expressions", expr.Position)
|
return InvalidValue, v.createError("bool type cannot be used in arithmetic expressions", expr.Position)
|
||||||
}
|
}
|
||||||
@ -118,30 +118,61 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
|||||||
|
|
||||||
expr.ValueType = &local.Type
|
expr.ValueType = &local.Type
|
||||||
case Expression_Binary:
|
case Expression_Binary:
|
||||||
arithmethic := expr.Value.(BinaryExpression)
|
binary := expr.Value.(BinaryExpression)
|
||||||
|
|
||||||
errors = append(errors, v.validateExpression(&arithmethic.Left, block)...)
|
errors = append(errors, v.validateExpression(&binary.Left, block)...)
|
||||||
errors = append(errors, v.validateExpression(&arithmethic.Right, block)...)
|
errors = append(errors, v.validateExpression(&binary.Right, block)...)
|
||||||
|
|
||||||
if len(errors) != 0 {
|
if len(errors) != 0 {
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
if arithmethic.Left.ValueType.Type != Type_Primitive || arithmethic.Right.ValueType.Type != Type_Primitive {
|
if isBooleanOperation(binary.Operation) {
|
||||||
|
if binary.Left.ValueType.Type != Type_Primitive || binary.Right.ValueType.Type != Type_Primitive {
|
||||||
|
errors = append(errors, v.createError("cannot compare non-primitive types", expr.Position))
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
leftType := binary.Left.ValueType.Value.(PrimitiveType)
|
||||||
|
rightType := binary.Right.ValueType.Value.(PrimitiveType)
|
||||||
|
|
||||||
|
var result PrimitiveType = InvalidValue
|
||||||
|
if isPrimitiveTypeExpandableTo(leftType, rightType) {
|
||||||
|
result = leftType
|
||||||
|
}
|
||||||
|
|
||||||
|
if isPrimitiveTypeExpandableTo(rightType, leftType) {
|
||||||
|
result = leftType
|
||||||
|
}
|
||||||
|
|
||||||
|
if result == InvalidValue {
|
||||||
|
errors = append(errors, v.createError("cannot compare these types without explicit cast", expr.Position))
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
binary.ResultType = &Type{Type: Type_Primitive, Value: result}
|
||||||
|
expr.ValueType = &Type{Type: Type_Primitive, Value: Primitive_Bool}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 be a primitive type", expr.Position))
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
leftType := arithmethic.Left.ValueType.Value.(PrimitiveType)
|
leftType := binary.Left.ValueType.Value.(PrimitiveType)
|
||||||
rightType := arithmethic.Right.ValueType.Value.(PrimitiveType)
|
rightType := binary.Right.ValueType.Value.(PrimitiveType)
|
||||||
result, err := v.getArithmeticResultType(expr, leftType, rightType, arithmethic.Operation)
|
result, err := v.getArithmeticResultType(expr, leftType, rightType, binary.Operation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binary.ResultType = &Type{Type: Type_Primitive, Value: result}
|
||||||
expr.ValueType = &Type{Type: Type_Primitive, Value: result}
|
expr.ValueType = &Type{Type: Type_Primitive, Value: result}
|
||||||
expr.Value = arithmethic
|
}
|
||||||
|
|
||||||
|
expr.Value = binary
|
||||||
case Expression_Tuple:
|
case Expression_Tuple:
|
||||||
tuple := expr.Value.(TupleExpression)
|
tuple := expr.Value.(TupleExpression)
|
||||||
|
|
||||||
@ -223,6 +254,8 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
|||||||
|
|
||||||
expr.ValueType = neg.Value.ValueType
|
expr.ValueType = neg.Value.ValueType
|
||||||
expr.Value = neg
|
expr.Value = neg
|
||||||
|
default:
|
||||||
|
panic("expr not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
@ -275,6 +308,28 @@ func (v *Validator) validateStatement(stmt *Statement, block *Block, functionLoc
|
|||||||
*functionLocals = append(*functionLocals, local)
|
*functionLocals = append(*functionLocals, local)
|
||||||
|
|
||||||
// TODO: check if assignment of initializer is correct
|
// TODO: check if assignment of initializer is correct
|
||||||
|
stmt.Value = dlv
|
||||||
|
case Statement_If:
|
||||||
|
ifS := stmt.Value.(IfStatement)
|
||||||
|
|
||||||
|
errors = append(errors, v.validateExpression(&ifS.Condition, block)...)
|
||||||
|
errors = append(errors, v.validateBlock(&ifS.ConditionalBlock, functionLocals)...)
|
||||||
|
|
||||||
|
if ifS.ElseBlock != nil {
|
||||||
|
errors = append(errors, v.validateBlock(ifS.ElseBlock, functionLocals)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errors) != 0 {
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
if ifS.Condition.ValueType.Type != Type_Primitive || ifS.Condition.ValueType.Value.(PrimitiveType) != Primitive_Bool {
|
||||||
|
errors = append(errors, v.createError("condition must evaluate to boolean", ifS.Condition.Position))
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.Value = ifS
|
||||||
|
default:
|
||||||
|
panic("stmt not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
Loading…
Reference in New Issue
Block a user