From adc91a1d6b765f0d15cc2b2fd57775f51afb3125 Mon Sep 17 00:00:00 2001 From: Flipez Date: Thu, 3 Feb 2022 21:26:04 +0100 Subject: [PATCH] add modulo Signed-off-by: Flipez --- evaluator/evaluator_test.go | 2 ++ evaluator/infix.go | 5 +++++ lexer/lexer.go | 3 +++ lexer/lexer_test.go | 5 +++++ parser/parser.go | 3 +++ token/token.go | 1 + 6 files changed, 19 insertions(+) diff --git a/evaluator/evaluator_test.go b/evaluator/evaluator_test.go index d098522..6708f8d 100644 --- a/evaluator/evaluator_test.go +++ b/evaluator/evaluator_test.go @@ -30,6 +30,8 @@ func TestEvalIntegerExpression(t *testing.T) { {"3 * (3 * 3) + 10", 37}, {"(5 + 10 * 2 + 15 / 3) * 2 + -10", 50}, {"5 ➕ 5 ➕ 5 ➕ 5 - 10", 10}, + {"5 % 5", 0}, + {"5 % 4", 1}, } for _, tt := range tests { diff --git a/evaluator/infix.go b/evaluator/infix.go index 04bfbd5..f1f1f11 100644 --- a/evaluator/infix.go +++ b/evaluator/infix.go @@ -22,6 +22,11 @@ func evalIntegerInfix(operator string, left, right object.Object) object.Object return object.NewErrorFormat("devision by zero not allowed") } return object.NewInteger(leftVal / rightVal) + case "%": + if rightVal == 0 { + return object.NewErrorFormat("devision by zero not allowed") + } + return object.NewInteger(leftVal % rightVal) case "<": return nativeBoolToBooleanObject(leftVal < rightVal) case "<=": diff --git a/lexer/lexer.go b/lexer/lexer.go index deb39ac..a25bb3b 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -78,6 +78,9 @@ func (l *Lexer) NextToken() token.Token { case '*': tok.Type = token.ASTERISK tok.Literal = string(l.ch) + case '%': + tok.Type = token.PERCENT + tok.Literal = string(l.ch) case '<': if l.peekChar() == '=' { ch := l.ch diff --git a/lexer/lexer_test.go b/lexer/lexer_test.go index d9d10cf..f52eb32 100644 --- a/lexer/lexer_test.go +++ b/lexer/lexer_test.go @@ -32,6 +32,7 @@ func TestNextToken(t *testing.T) { {"foo": "bar"} 5 <= 10 >= 5; + 4 % 3; ` tests := []struct { @@ -126,6 +127,10 @@ func TestNextToken(t *testing.T) { {token.GT_EQ, ">="}, {token.INT, "5"}, {token.SEMICOLON, ";"}, + {token.INT, "4"}, + {token.PERCENT, "%"}, + {token.INT, "3"}, + {token.SEMICOLON, ";"}, {token.EOF, ""}, } diff --git a/parser/parser.go b/parser/parser.go index f0a7383..bb0c0fa 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -16,6 +16,7 @@ const ( LESSGREATER // > or < SUM // + PRODUCT // * + MODULO // % PREFIX // -X or !X CALL // myFcuntion(X) INDEX // array[index] @@ -33,6 +34,7 @@ var precedences = map[token.TokenType]int{ token.MINUS: SUM, token.SLASH: PRODUCT, token.ASTERISK: PRODUCT, + token.PERCENT: MODULO, token.LPAREN: CALL, token.PERIOD: CALL, token.LBRACKET: INDEX, @@ -87,6 +89,7 @@ func New(l *lexer.Lexer, imports map[string]struct{}) *Parser { p.registerInfix(token.MINUS, p.parseInfix) p.registerInfix(token.SLASH, p.parseInfix) p.registerInfix(token.ASTERISK, p.parseInfix) + p.registerInfix(token.PERCENT, p.parseInfix) p.registerInfix(token.EQ, p.parseInfix) p.registerInfix(token.NOT_EQ, p.parseInfix) p.registerInfix(token.PERIOD, p.parseMethodCall) diff --git a/token/token.go b/token/token.go index 63f5e42..f7ec54d 100644 --- a/token/token.go +++ b/token/token.go @@ -28,6 +28,7 @@ const ( BANG = "!" ASTERISK = "*" SLASH = "/" + PERCENT = "%" LT = "<" LT_EQ = "<="