diff --git a/nolang/lexer.py b/nolang/lexer.py index d6cb4ae..5378560 100644 --- a/nolang/lexer.py +++ b/nolang/lexer.py @@ -4,8 +4,10 @@ from rply import LexerGenerator RULES = [ ('INTEGER', r'\d+'), ('PLUS', r'\+'), + ('MINUS', r'\-'), ('LT', r'\<'), - ('EQUALS', r'='), + ('EQ', r'=='), + ('ASSIGN', r'='), ('FUNCTION', r'function'), ('RETURN', r'return'), ('VAR', r'var'), diff --git a/nolang/parser.py b/nolang/parser.py index ac2f8f3..d075e6f 100644 --- a/nolang/parser.py +++ b/nolang/parser.py @@ -80,8 +80,8 @@ def get_parser(): def var_decl_identifier(state, p): return ast.VarDeclPartial([p[1].getstr()] + p[2].get_names()) - @pg.production('statement : IDENTIFIER EQUALS expression SEMICOLON') - def statement_identifier_equals_expr(state, p): + @pg.production('statement : IDENTIFIER ASSIGN expression SEMICOLON') + def statement_identifier_assign_expr(state, p): return ast.Assignment(p[0].getstr(), p[2]) @pg.production('statement : RETURN expression SEMICOLON') @@ -140,12 +140,14 @@ def get_parser(): return p[1] @pg.production('expression : expression PLUS expression') + @pg.production('expression : expression MINUS expression') def expression_plus_expression(state, p): - return ast.BinOp('+', p[0], p[2]) + return ast.BinOp(p[1].getstr(), p[0], p[2]) @pg.production('expression : expression LT expression') + @pg.production('expression : expression EQ expression') def expression_lt_expression(state, p): - return ast.BinOp('<', p[0], p[2]) + return ast.BinOp(p[1].getstr(), p[0], p[2]) @pg.production('expression_list : ') def expression_list_empty(state, p): diff --git a/tests/test_interpreter.py b/tests/test_interpreter.py index aeb81b7..162589b 100644 --- a/tests/test_interpreter.py +++ b/tests/test_interpreter.py @@ -123,8 +123,16 @@ class TestInterpreter(BaseTest): ''') assert self.space.int_w(w_res) == 4 - # def test_recursive_call(self): - # w_res = self.interpret(''' - # function fib(n) { - # if n == 0 or n == 1 - # } \ No newline at end of file + def test_recursive_call(self): + w_res = self.interpret(''' + function fib(n) { + if n == 0 or n == 1 { + return 1; + } + return fib(n - 1) + fib(n - 2); + } + function main() { + return fib(5); + } + ''') + assert self.space.int_w(w_res) == 8