def mult(self): expr = self.unary() while (self.match_val('/', '*', '%')): op = self.pop().val rhs = self.unary() expr = ast.Binary(expr, op, rhs) return expr
def add(self): expr = self.mult() while (self.match_val('+', '-')): op = self.pop().val rhs = self.mult() expr = ast.Binary(expr, op, rhs) return expr
def compare(self): expr = self.add() while (self.match_val('>', '<', '<=', '>=')): op = self.pop().val rhs = self.add() expr = ast.Binary(expr, op, rhs) return expr
def expr(self): expr = self.compare() while (self.match_val('==', '!=')): op = self.pop().val rhs = self.compare() expr = ast.Binary(expr, op, rhs) return expr
def _parse_array_offset(self, expr, env): """ Parses the array offset. """ self._match('[') num = self._parse_logical_expression(env) self._match(']') of_type = expr.get_type().get_of_type() width = ast.Constant(lexer.Num(of_type.get_width()), ty.Type.Int) expr_id = expr offset = ast.Binary(lexer.Token('*'), num, width) if type(expr) is ast.Access: expr_id = expr.get_access_id() offset = ast.Binary(lexer.Token('+'), expr.get_offset(), offset) return ast.Access(lexer.Word('[]', lexer.Tag.INDEX), of_type, expr_id, offset)
def _parse_and_expression(self, env): """ <and_expression> Parses the <and_expression> language structure. and_expression -> and_expression '&' equality_expression | equality_expression """ eqexp = self._parse_equality_expression(env) while self._look.tag == '&': tok = self._look.tag self._match('&') eqexp = ast.Binary(tok, eqexp, self._parse_and_expression(env)) return eqexp
def _parse_exclusive_or_expression(self, env): """ <exclusive_or_expression> Parses the <exclusive_or_expression> language structure. exclusive_or_expression -> exclusive_or_expression '^' and_expression | and_expression """ andexp = self._parse_and_expression(env) while self._look.tag == '^': tok = self._look self._match('^') andexp = ast.Binary(tok, andexp, self._parse_exclusive_or_expression(env)) return andexp
def _parse_inclusive_or_expression(self, env): """ <inclusive_or_expression> Parses the <inclusive_or_expression> language structure. inclusive_or_expression -> inclusive_or_expression '|' exclusive_or_expression | exclusive_or_expression """ exclor = self._parse_exclusive_or_expression(env) while self._look.tag == '|': tok = self._look self._match('|') exclor = ast.Binary(tok, exclor, self._parse_inclusive_or_expression(env)) return exclor
def _parse_shift_expression(self, env): """ <shift_expression> Parses the <shift_expression> language structure. shift_expression -> shift_expression '<<' additive_expression | shift_expression '>>' additive_expression | additive_expression """ addexp = self._parse_additive_expression(env) while self._look.tag == lexer.Tag.LS or self._look.tag == lexer.Tag.RS: tok = self._look if self._look.tag == lexer.Tag.LS: self._match(lexer.Tag.LS) else: self._match(lexer.Tag.RS) addexp = ast.Binary(tok, addexp, self._parse_shift_expression(env)) return addexp
def _parse_multiplicative_expression(self, env): """ <multiplicative_expression> Parses the <multiplicative_expression> language structure. multiplicative_expression -> multiplicative_expression '*' cast_expression | multiplicative_expression '/' cast_expression | cast_expression """ castexp = self._parse_cast_expression(env) while self._look.tag == '*' or self._look.tag == '/': tok = self._look if self._look.tag == '*': self._match('*') else: self._match('/') castexp = ast.Binary(tok, castexp, self._parse_multiplicative_expression(env)) return castexp
def _parse_additive_expression(self, env): """ <additive_expression> Parses the <additive_expression> language structure. additive_expression -> additive_expression '+' multiplicative_expression | additive_expression '-' multiplicative_expression | multiplicative_expression """ mulexp = self._parse_multiplicative_expression(env) while self._look.tag == '+' or self._look.tag == '-': tok = self._look if self._look.tag == '+': self._match('+') else: self._match('-') mulexp = ast.Binary(tok, mulexp, self._parse_additive_expression(env)) return mulexp
def statement(self): if self.match("let"): line = self.pop().line ty = self.type() if self.match_val("="): name = ty[1] ty = None #this is where more complete type parsing would happen #for the time being, just error out elif self.match("ident"): name = self.pop().val else: raise ValueError( f"expected type in var declaration on line {line}, saw {self.tl[0].val}" ) self.consume( "=", f"expected '=' in let declaration on line {line}, saw {self.tl[0].val}" ) ex = self.expr() if ty != None: return ast.Let(name, (ty, None), ex) else: return ast.Let(name, None, ex) elif self.match("var"): line = self.pop().line ty = self.type() if self.match_val("="): name = ty[0] ty = None #this is where more complete type parsing would happen #for the time being, just error out elif self.match("ident"): name = self.pop().val else: raise ValueError( f"expected type in var declaration on line {line}, saw {self.tl[0].val}" ) self.consume( "=", f"expected '=' in var declaration on line {line}, saw {self.tl[0].val}" ) ex = self.expr() return ast.Var(name, ty, ex) elif self.match("if"): line = self.pop().line ex = self.expr() thenstmnts = self.statementlist("if statement", line) if not self.match("else"): elsestmnts = None else: line = self.pop().line elsestmnts = self.statementlist("else statement", line) return ast.If(ex, thenstmnts, elsestmnts) elif self.match('return'): self.pop() returning = self.expr() return ast.Return(returning) elif self.match('while'): line = self.pop().line condition = self.expr() body = self.statementlist("while body", line) return ast.While(condition, body) else: lhs = self.expr() if self.match_val('=') or self.match_val('+=') or self.match_val( '-=') or self.match_val('*=') or self.match_val( '/=') or self.match_val('%='): op = self.pop().val rhs = self.expr() if (op[0] != '='): rhs = ast.Binary(lhs, op[0], rhs) return ast.Assign(lhs, rhs) else: return lhs