diff options
-rw-r--r-- | doc/mylang.ebnf | 19 | ||||
-rw-r--r-- | src/front/ast.py | 3 | ||||
-rw-r--r-- | src/front/parser.py | 27 |
3 files changed, 23 insertions, 26 deletions
diff --git a/doc/mylang.ebnf b/doc/mylang.ebnf index f84869f..04db743 100644 --- a/doc/mylang.ebnf +++ b/doc/mylang.ebnf @@ -10,25 +10,24 @@ integer = digit { digit }. boolean = join { "||" join }. join = relation { "&&" relation }. -relation = expression { ( "==" | "!=" | "<" | "<=" | ">=" | ">" ) expression }. -expression = term { ( "+" | "-" ) term }. -term = unary { ( "*" | "/" | "%" ) unary }. +relation = expression [ ( "==" | "!=" | "<" | "<=" | ">=" | ">" ) expression ]. +expression = term [ ( "+" | "-" ) term ]. +term = unary [ ( "*" | "/" | "%" ) unary ]. unary = "!" unary | "-" unary | factor. factor = "(" boolean ")" | ident | integer | "true" | "false" | function_call. -function_call = "call" ident "[" [ expression_list ] "]". - ident_list = ident { "," ident }. expression_list = boolean { "," boolean }. function_list = function { function }. statement_list = statement { statement }. function = "fun" ident "[" [ ident_list ] "]" nl statement_list "end" nl. -statement = ( if_statement | while_statement | assign_statement | return_statement | function_call ). +statement = ( if_statement | while_statement | assign_statement | return_statement | function_call ) nl. -if_statement = "if" boolean nl statement_list [ "else" nl statement_list ] "end" nl. -while_statement = "while" boolean nl statement_list "end" nl. -return_statement = "@" boolean nl. -assign_statement = ident "=" boolean nl. +if_statement = "if" boolean nl statement_list [ "else" nl statement_list ] "end". +while_statement = "while" boolean nl statement_list "end". +return_statement = "@" boolean. +assign_statement = ident "=" boolean. +function_call = "call" ident "[" [ expression_list ] "]". program = function_list. diff --git a/src/front/ast.py b/src/front/ast.py index 875bdf0..77aab95 100644 --- a/src/front/ast.py +++ b/src/front/ast.py @@ -178,8 +178,7 @@ class FunctionCall(Statement, Expression): for argument in self.arguments: self.emit(Op.POP, 0) - # XXX: wrong signature? - def generate(self): + def generate(self, before, after, last): self.debug("FunctionCall.generate(): %s" % (repr(self))) self.push_params() self.emit(Op.CALL, self.ident, 0) diff --git a/src/front/parser.py b/src/front/parser.py index 8eca7a2..72e0051 100644 --- a/src/front/parser.py +++ b/src/front/parser.py @@ -17,7 +17,6 @@ class Parser: def move(self): self.token = self.lexer.scan() - #print "move(): %s" % self.token def error(self, msg): raise ParseError(msg) @@ -50,21 +49,21 @@ class Parser: res = BinaryExpression(res, self.match(Tag.OPERATOR), self.relation(), self.lexer.line) return res - # relation = expression { ( "==" | "!=" | "<" | "<=" | ">=" | ">" ) expression }. + # relation = expression [ ( "==" | "!=" | "<" | "<=" | ">=" | ">" ) expression ]. def relation(self): res = self.expression() while self.token.tag == Tag.OPERATOR and self.token.value in ["==", "!=", "<", "<=", ">=", ">"]: res = BinaryExpression(res, self.match(Tag.OPERATOR), self.expression(), self.lexer.line) return res - # expression = term { ( "+" | "-" ) term }. + # expression = term [ ( "+" | "-" ) term ]. def expression(self): res = self.term() while self.token.tag == Tag.OPERATOR and self.token.value in ["+", "-"]: res = BinaryExpression(res, self.match(Tag.OPERATOR), self.term(), self.lexer.line) return res - # term = unary { ( "*" | "/" | "%" ) unary }. + # term = unary [ ( "*" | "/" | "%" ) unary ]. def term(self): res = self.unary() while self.token.tag == Tag.OPERATOR and self.token.value in ["*", "/", "%"]: @@ -150,16 +149,18 @@ class Parser: self.match(Tag.END, Tag.NEWLINE) return Function(name, args, block, line) - # statement = [ if_statement | while_statement | assign_statement | return_statement | function_call ]. + # statement = ( if_statement | while_statement | assign_statement | return_statement | function_call ) nl. def statement(self): - return {Tag.IF: self.if_statement, + res = {Tag.IF: self.if_statement, Tag.WHILE: self.while_statement, Tag.IDENT: self.assignment, Tag.RETURN: self.return_statement, Tag.CALL: self.function_call, }[self.token.tag]() + self.match(Tag.NEWLINE) + return res - # if_statement = "if" boolean nl statement_list [ "else" nl statement_list ] "end" nl. + # if_statement = "if" boolean nl statement_list [ "else" nl statement_list ] "end". def if_statement(self): line = self.lexer.line self.match(Tag.IF) @@ -171,34 +172,32 @@ class Parser: self.move() self.match(Tag.NEWLINE) else_case = self.statement_list() - self.match(Tag.END, Tag.NEWLINE) + self.match(Tag.END) return IfStatement(condition, true_case, else_case, line) - # while_statement = "while" boolean nl statement_list "end" nl. + # while_statement = "while" boolean nl statement_list "end". def while_statement(self): line = self.lexer.line self.match(Tag.WHILE) condition = self.boolean() self.match(Tag.NEWLINE) body = self.statement_list() - self.match(Tag.END, Tag.NEWLINE) + self.match(Tag.END) return WhileStatement(condition, body, line) - # return_statement = "@" boolean nl. + # return_statement = "@" boolean. def return_statement(self): line = self.lexer.line self.match(Tag.RETURN) exp = self.boolean() - self.match(Tag.NEWLINE) return ReturnStatement(exp, line) - # assignment = ident "=" boolean nl. + # assignment = ident "=" boolean. def assignment(self): line = self.lexer.line name = self.match(Tag.IDENT) self.match(Tag.ASSIGNMENT) exp = self.boolean() - self.match(Tag.NEWLINE) self.scope.add_locals(name) return AssignStatement(name, exp, line) |