def assignment(self) -> Expr.Expr: ''' Suck up what might be an assignment target, or might be an expression. ''' possible_lhs = self.logic_or() ''' If the next token is not "=", we are done, with an expression. ''' if not self.match(EQUAL): return possible_lhs ''' We have "something =" so note the location of the "=" for a possible later error message; then collect the r-value. Note the recursion; We take a = b = c as a = (b = c). ''' error_pos = self.previous() rhs = self.assignment() ''' Now ask, We have something =, but is it variable = or property? ''' if isinstance(possible_lhs, Expr.Variable): return Expr.Assign(possible_lhs.name, rhs) if isinstance(possible_lhs, Expr.Get): return Expr.Set(possible_lhs.object, possible_lhs.name, rhs) ''' Neither, flag an error at the "=" token noted earlier. ''' self.error(error_pos, "Invalid target for assignment")
def assignment(self) -> Expr.Expr: """ Parses an assignment expression """ expr = self.logic_or() if self.match(TokenType.EQUAL): equals = self.previous() value = self.assignment() if isinstance(expr, Expr.Variable): return Expr.Assign(expr.name, value) else: self.error(equals, "Invalid assignment target") else: return expr
def assignment(self) -> Expr.Expr: expression = self._or() if self.match(Token.TokenType.EQUAL): equals = self.previous() value = self.assignment() if type(expression) == Expr.Variable: name = expression.name return Expr.Assign(name, value) elif type(expression) == Expr.Get: get = expression return Expr.Set(get._object, get.name, value) else: self.error(equals, "Invalid assignment target") return expression
def assignment(self): ''' slight difference from other recursions because we don't want to have a chain of "=" operator/operands in the left-hand side. E.g. Can't have expressions like "a = b + c = d" The "Control Flow" chapter also includes the starting point for Logical Operators with "or_op()" The "Classes" chapter introduces setters which only activate when the Left-Hand side is a getter that we want to update ''' expr = self.or_op() if self.match(TokenType.EQUAL): equals = self.previous() value = self.assignment() if isinstance(expr, Expr.Variable): # aka non-reserved IDENTIFIERS name = expr.name return Expr.Assign(name, value) elif isinstance(expr, Expr.Get): get = expr return Expr.Set(get.object, get.name, value) Lox.Lox.error(equals, "Invalid assignment target.") return expr