From 8c250005bcb7184e02c0e9c68a8685667f724d7f Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Tue, 19 Mar 2024 10:54:21 +0100 Subject: [PATCH] More compiler stuff --- .gitignore | 1 + backend_wat.go | 52 +++++++++++++++++++++++++++++++++++++++++------- example/add.lang | 1 - validator.go | 4 ++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0c47708..87da47a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ compiler out.wat +build \ No newline at end of file diff --git a/backend_wat.go b/backend_wat.go index 00cc31c..6baecd8 100644 --- a/backend_wat.go +++ b/backend_wat.go @@ -2,6 +2,7 @@ package main import ( "errors" + "log" "strconv" ) @@ -118,7 +119,9 @@ func upcastTypeWAT(from PrimitiveType, to PrimitiveType) (string, error) { } if getPrimitiveWATType(from) == getPrimitiveWATType(to) { - // TODO: cast if to is smaller than from + if getBits(to) < getBits(from) { + return getTypeCast(to), nil + } } if getBits(from) < 64 && getBits(to) == 64 { @@ -132,9 +135,7 @@ func upcastTypeWAT(from PrimitiveType, to PrimitiveType) (string, error) { return "i64.extend_i32_" + suffix + "\n", nil } - // TODO: cast down from 64 to 32 - - return "", nil + return "i32.wrap_i64\n" + getTypeCast(to), nil } func compileExpressionWAT(expr Expression, block Block) (string, error) { @@ -161,20 +162,54 @@ func compileExpressionWAT(expr Expression, block Block) (string, error) { case Expression_Arithmetic: arith := expr.Value.(ArithmeticExpression) + // TODO: currently fine, only allowed for primitive types, but should be expanded to allow e.g. strings + exprType := expr.ValueType.Value.(PrimitiveType) + watLeft, err := compileExpressionWAT(arith.Left, block) if err != nil { return "", err } + log.Printf("%+#v", arith) + + castLeft, err := upcastTypeWAT(arith.Left.ValueType.Value.(PrimitiveType), exprType) + if err != nil { + return "", err + } + watRight, err := compileExpressionWAT(arith.Right, block) if err != nil { return "", err } - //TODO: upcast expressions and perform operation + castRight, err := upcastTypeWAT(arith.Left.ValueType.Value.(PrimitiveType), exprType) + if err != nil { + return "", err + } - // TODO: cast result - return watLeft + watRight, nil + op := "" + + suffix := "" + if isUnsignedInt(exprType) { + suffix = "u" + } else { + suffix = "s" + } + + switch arith.Operation { + case Arithmetic_Add: + op = getPrimitiveWATType(exprType) + ".add\n" + case Arithmetic_Sub: + op = getPrimitiveWATType(exprType) + ".sub\n" + case Arithmetic_Mul: + op = getPrimitiveWATType(exprType) + ".mul\n" + case Arithmetic_Div: + op = getPrimitiveWATType(exprType) + ".div:" + suffix + "\n" + case Arithmetic_Mod: + op = getPrimitiveWATType(exprType) + ".rem" + suffix + "\n" + } + + return watLeft + castLeft + watRight + castRight + op + getTypeCast(expr.ValueType.Value.(PrimitiveType)), nil case Expression_Tuple: } @@ -252,6 +287,9 @@ func compileFunctionWAT(function ParsedFunction) (string, error) { funcWAT += "\t(" + pfx + " $" + strconv.Itoa(local.Index) + " " + getWATType(local.Type) + ")\n" } + // TODO: tuples + funcWAT += "\t(result " + getWATType(function.ReturnType) + ")\n" + wat, err := compileBlockWAT(function.Body) if err != nil { return "", err diff --git a/example/add.lang b/example/add.lang index 49d67c9..454736f 100644 --- a/example/add.lang +++ b/example/add.lang @@ -1,4 +1,3 @@ u8 add(u8 a, u8 b) { - u8 c = b; return a + b; } diff --git a/validator.go b/validator.go index c39a366..d45a8b6 100644 --- a/validator.go +++ b/validator.go @@ -88,6 +88,7 @@ func validateExpression(expr *Expression, block *Block) []error { // TODO: check if assignment is valid expr.ValueType = local.Type + expr.Value = assignment case Expression_Literal: literal := expr.Value.(LiteralExpression) @@ -108,6 +109,7 @@ func validateExpression(expr *Expression, block *Block) []error { } expr.ValueType = local.Type + expr.Value = reference case Expression_Arithmetic: arithmethic := expr.Value.(ArithmeticExpression) @@ -133,6 +135,7 @@ func validateExpression(expr *Expression, block *Block) []error { } expr.ValueType = Type{Type: Type_Primitive, Value: result} + expr.Value = arithmethic case Expression_Tuple: tuple := expr.Value.(TupleExpression) @@ -154,6 +157,7 @@ func validateExpression(expr *Expression, block *Block) []error { } expr.ValueType = Type{Type: Type_Tuple, Value: TupleType{Types: types}} + expr.Value = tuple } return errors