rename some things

This commit is contained in:
MrLetsplay 2024-03-24 14:01:23 +01:00
parent 193bd5c2d5
commit c0b9ee086a
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
4 changed files with 119 additions and 50 deletions

View File

@ -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")

View File

@ -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}
} }
} }

View File

@ -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)
}

View File

@ -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