More compiler stuff

This commit is contained in:
MrLetsplay 2024-03-19 10:54:21 +01:00
parent fc8e2acb71
commit 8c250005bc
Signed by: mr
SSH Key Fingerprint: SHA256:0zWNiRisbQ4dq/CCQAaMLoF3UfkF5wKPXO7DcjfFBEU
4 changed files with 50 additions and 8 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
compiler compiler
out.wat out.wat
build

View File

@ -2,6 +2,7 @@ package main
import ( import (
"errors" "errors"
"log"
"strconv" "strconv"
) )
@ -118,7 +119,9 @@ func upcastTypeWAT(from PrimitiveType, to PrimitiveType) (string, error) {
} }
if getPrimitiveWATType(from) == getPrimitiveWATType(to) { 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 { 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 return "i64.extend_i32_" + suffix + "\n", nil
} }
// TODO: cast down from 64 to 32 return "i32.wrap_i64\n" + getTypeCast(to), nil
return "", nil
} }
func compileExpressionWAT(expr Expression, block Block) (string, error) { func compileExpressionWAT(expr Expression, block Block) (string, error) {
@ -161,20 +162,54 @@ func compileExpressionWAT(expr Expression, block Block) (string, error) {
case Expression_Arithmetic: case Expression_Arithmetic:
arith := expr.Value.(ArithmeticExpression) 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) watLeft, err := compileExpressionWAT(arith.Left, block)
if err != nil { if err != nil {
return "", err 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) watRight, err := compileExpressionWAT(arith.Right, block)
if err != nil { if err != nil {
return "", err 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 op := ""
return watLeft + watRight, nil
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: case Expression_Tuple:
} }
@ -252,6 +287,9 @@ func compileFunctionWAT(function ParsedFunction) (string, error) {
funcWAT += "\t(" + pfx + " $" + strconv.Itoa(local.Index) + " " + getWATType(local.Type) + ")\n" 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) wat, err := compileBlockWAT(function.Body)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -1,4 +1,3 @@
u8 add(u8 a, u8 b) { u8 add(u8 a, u8 b) {
u8 c = b;
return a + b; return a + b;
} }

View File

@ -88,6 +88,7 @@ func validateExpression(expr *Expression, block *Block) []error {
// TODO: check if assignment is valid // TODO: check if assignment is valid
expr.ValueType = local.Type expr.ValueType = local.Type
expr.Value = assignment
case Expression_Literal: case Expression_Literal:
literal := expr.Value.(LiteralExpression) literal := expr.Value.(LiteralExpression)
@ -108,6 +109,7 @@ func validateExpression(expr *Expression, block *Block) []error {
} }
expr.ValueType = local.Type expr.ValueType = local.Type
expr.Value = reference
case Expression_Arithmetic: case Expression_Arithmetic:
arithmethic := expr.Value.(ArithmeticExpression) arithmethic := expr.Value.(ArithmeticExpression)
@ -133,6 +135,7 @@ func validateExpression(expr *Expression, block *Block) []error {
} }
expr.ValueType = Type{Type: Type_Primitive, Value: result} expr.ValueType = Type{Type: Type_Primitive, Value: result}
expr.Value = arithmethic
case Expression_Tuple: case Expression_Tuple:
tuple := expr.Value.(TupleExpression) 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.ValueType = Type{Type: Type_Tuple, Value: TupleType{Types: types}}
expr.Value = tuple
} }
return errors return errors