From e9074e1632a15c11ffc4357c6e9d601e11c1c262 Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Thu, 11 Apr 2024 13:40:04 +0200 Subject: [PATCH] Add pre/postfix expressions --- backend_wat.go | 3 ++- example/test.ely | 2 +- parser.go | 42 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/backend_wat.go b/backend_wat.go index 0d6eaf6..2204128 100644 --- a/backend_wat.go +++ b/backend_wat.go @@ -350,8 +350,9 @@ func (c *Compiler) compileExpressionWAT(expr Expression) (string, error) { } case UnaryOperation_LogicalNot: return wat + "i32.eqz\n", nil + case UnaryOperation_PreIncrement, UnaryOperation_PreDecrement, UnaryOperation_PostIncrement, UnaryOperation_PostDecrement: + // TODO: implement } - case Expression_Cast: cast := expr.Value.(CastExpression) diff --git a/example/test.ely b/example/test.ely index 9ff23c4..14635b7 100644 --- a/example/test.ely +++ b/example/test.ely @@ -12,7 +12,7 @@ u64 fib(u64 i) { u64 fibA = 0u64; u64 fibB = 1u64; - while((i -= 1u64) > 0u64) { + while(--i > 0u64) { u64 tmp = fibB; fibB = fibA + fibB; fibA = tmp; diff --git a/parser.go b/parser.go index 5b13e31..a3166b3 100644 --- a/parser.go +++ b/parser.go @@ -136,6 +136,10 @@ const ( UnaryOperation_Nop UnaryOperation_BitwiseNot UnaryOperation_LogicalNot + UnaryOperation_PreIncrement + UnaryOperation_PreDecrement + UnaryOperation_PostIncrement + UnaryOperation_PostDecrement ) type BinaryExpression struct { @@ -603,7 +607,7 @@ func (p *Parser) tryUnaryExpression() (*Expression, error) { return nil, nil } - op, err := pCopy.tryOperator(Operator_Minus, Operator_Plus, Operator_BitwiseNot, Operator_Not) + op, err := pCopy.tryOperator(Operator_Minus, Operator_Plus, Operator_BitwiseNot, Operator_Not, Operator_PlusPlus, Operator_MinusMinus) if err != nil { return nil, err } @@ -619,12 +623,44 @@ func (p *Parser) tryUnaryExpression() (*Expression, error) { } *p = pCopy + switch *op { + case Operator_PlusPlus: + return &Expression{Type: Expression_Unary, Value: UnaryExpression{Operation: UnaryOperation_PreIncrement, Value: *expr}, Position: token.Position}, nil + case Operator_MinusMinus: + return &Expression{Type: Expression_Unary, Value: UnaryExpression{Operation: UnaryOperation_PreDecrement, Value: *expr}, Position: token.Position}, nil + } + return &Expression{Type: Expression_Unary, Value: UnaryExpression{Operation: getUnaryOperation(*op), Value: *expr}, Position: token.Position}, nil } - // TODO: pre-/postfix in-/decrement expr + expr, err := pCopy.tryPrimaryExpression() + if err != nil { + return nil, err + } - return p.tryPrimaryExpression() + if expr == nil { + return nil, nil + } + + op, err = pCopy.tryOperator(Operator_PlusPlus, Operator_MinusMinus) + if err != nil { + return nil, err + } + + if op == nil { + *p = pCopy + return expr, nil + } + + *p = pCopy + switch *op { + case Operator_PlusPlus: + return &Expression{Type: Expression_Unary, Value: UnaryExpression{Operation: UnaryOperation_PostIncrement, Value: *expr}, Position: token.Position}, nil + case Operator_MinusMinus: + return &Expression{Type: Expression_Unary, Value: UnaryExpression{Operation: UnaryOperation_PostDecrement, Value: *expr}, Position: token.Position}, nil + } + + panic("Operator not implemented") } func (p *Parser) tryBinaryExpression0(opFunc func() (*Expression, error), operators ...Operator) (*Expression, error) {