def primary(self) -> e.Expr: if self.match(TokenType.FALSE): return e.Literal(False) if self.match(TokenType.TRUE): return e.Literal(True) if self.match(TokenType.NIL): return e.Literal(None) if self.match(TokenType.NUMBER, TokenType.STRING): return e.Literal(self.previous().literal) if self.match(TokenType.SUPER): keyword: Token = self.previous() self.consume(TokenType.DOT, "Expect '.' after 'super'.") method: Token = self.consume(TokenType.IDENTIFIER, "Expect superclass method name.") return e.Super(keyword, method) if self.match(TokenType.THIS): return e.This(self.previous()) if self.match(TokenType.IDENTIFIER): return e.Variable(self.previous()) if self.match(TokenType.LEFT_PAREN): expr: e.Expr = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.") return e.Grouping(expr) raise self.error(self.peek(), "Expect expression.")
def _primary(self) -> ex.Expr: if self._match(TokenType.FALSE): return ex.Literal(False) if self._match(TokenType.TRUE): return ex.Literal(True) if self._match(TokenType.NIL): return ex.Literal(None) if self._match(TokenType.NUMBER, TokenType.STRING): return ex.Literal(self._previous.literal) if self._match(TokenType.SUPER): keyword = self._previous self._consume(TokenType.DOT, "Expect a '.' after 'super'.") method = self._consume(TokenType.IDENTIFIER, 'Expect superclass method name.') return ex.Super(keyword, method) if self._match(TokenType.THIS): return ex.This(self._previous) if self._match(TokenType.IDENTIFIER): return ex.Variable(self._previous) if self._match(TokenType.LEFT_PAREN): expr = self._expression() self._consume(TokenType.RIGHT_PAREN, "Expect ')' after expression.") return ex.Grouping(expr) raise self._error(self._peek(), 'Expect expression.')
def _for_statement(self) -> st.While: self._consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'.") initializer = None if self._match(TokenType.SEMICOLON): pass elif self._match(TokenType.VAR): initializer = self._variable_declaration() else: initializer = self._expression_statement() condition = ex.Literal(True) if self._check( TokenType.SEMICOLON) else self._expression() self._consume(TokenType.SEMICOLON, "Expect ';' after loop condition.") increment = None if self._check( TokenType.RIGHT_PAREN) else self._expression() self._consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.") body = self._statement() if increment is not None: body = st.Block([body, st.Expression(increment)]) body = st.While(condition, body) if initializer is not None: body = st.Block([initializer, body]) return body
def for_statement(self): self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'.") if self.match(TokenType.SEMICOLON): initializer = None elif self.match(TokenType.VAR): initializer = self.var_declaration() else: initializer = self.expression_statement() condition = None if not self.check(TokenType.SEMICOLON): condition = self.expression() self.consume(TokenType.SEMICOLON, "Expect ';' after loop condition.") increment = None if not self.check(TokenType.RIGHT_PAREN): increment = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.") body = self.statement() if increment is not None: body = Stmt.Block(list(body), Stmt.Expression(increment)) if condition is None: condition = Expr.Literal(True) body = Stmt.While(condition, body) if initializer is not None: body = Stmt.Block(list(initializer), body) return body
def primary(self): if self.match(TokenType.FALSE): return Expr.Literal(False) if self.match(TokenType.TRUE): return Expr.Literal(True) if self.match(TokenType.NIL): return Expr.Literal(None) if self.match(TokenType.NUMBER, TokenType.STRING): return Expr.Literal(self.peek(-1).literal) if self.match(TokenType.LEFT_PAREN): expr = self.expression() self.consume(TokenType.RIGHT_PAREN, "Missing ')' after expression") return Expr.Grouping(expr) if self.match(TokenType.IDENTIFIER): return Expr.Variable(self.peek(-1)) raise self.error(self.peek(), "Requires an expression")
def breakStatement(self, type="break"): locTok = self.peek(-1) try: l = self.expression() except ParseError: l = Expr.Literal(1) if type == "continue": return Stmt.Continue(locTok, l) elif type == "break": return Stmt.Break(locTok, l)
def crement(self): isAdding = False if self.peek(-1).type == TokenType.PLUS_PLUS: isAdding = True identifier = self.peek(-2) if isAdding: tok = TokenType.PLUS else: tok = TokenType.MINUS val = 1 return Expr.Assignment( Expr.Variable(identifier).name, Expr.Binary(Expr.Variable(identifier), Token(tok, None, None, None), Expr.Literal(val)))
def forStatement(self) -> s.Stmt: self.consume(TokenType.LEFT_PAREN, "Expect '(' after 'for'.") if self.match(TokenType.SEMICOLON): initializer = None elif self.match(TokenType.VAR): initializer = self.varDeclaration() else: initializer = self.expressionStatement() condition = None if not self.check(TokenType.SEMICOLON): condition = self.expression() self.consume(TokenType.SEMICOLON, "Expect ';' after loop condition.") increment = None if not self.check(TokenType.RIGHT_PAREN): increment = self.expression() self.consume(TokenType.RIGHT_PAREN, "Expect ')' after for clauses.") body: s.Stmt = self.statement() # not null if increment: body = s.Block([body, s.Expression(increment)]) # is null if condition is None: condition = e.Literal(True) body = s.While(condition, body) # not null if initializer: body = s.Block([initializer, body]) return body
def forStatement(self): init = None cond = None incr = None if self.match(TokenType.LEFT_BRACE): # infinite loop return Stmt.Block( [Stmt.For(init, cond, incr, self.blockStatement())]) elif self.match(TokenType.COMMA): first = None elif self.match(TokenType.VAR, TokenType.CONST): first = self.varDeclaration(self.peek(-1)) else: first = self.expressionStatement() if self.match(TokenType.LEFT_BRACE): # while loop return Stmt.Block( [Stmt.For(None, first, None, self.blockStatement())]) init = first self.consume(TokenType.COMMA, "requires comma between initilizer and condition") if not self.match(TokenType.COMMA): cond = self.expression() else: cond = Expr.Literal(True) self.consume(TokenType.COMMA, "requires comma between condition and increment") if not self.check(TokenType.RIGHT_BRACE): incr = self.expression() self.consume(TokenType.LEFT_BRACE, "requires block after for loop") return Stmt.Block([Stmt.For(init, cond, incr, self.blockStatement())])
def visit_char(self, node, ch): c, _ = getchar(node.value[1:-1]) c = gdb.Value(ord(c)).cast(gdb.lookup_type('char')) return expr.Literal(node.value, c)
def visit_string(self, node, ch): s, tail = '', node.value[1:-1] while tail: head, tail = getchar(tail) s += head return expr.Literal(node.value, gdb.Value(s))
def visit_hexadecimal(self, node, ch): return expr.Literal(node.value, gdb.Value(int(node.value, 16)))
def visit_octal(self, node, ch): return expr.Literal(node.value, gdb.Value(int(node.value, 8)))
def visit_real(self, node, ch): return expr.Literal(node.value, gdb.Value(float(node.value)))