def LeftAssign(p, w, left, rbp): """ Normal binary operator like 1+2 or 2*3, etc. """ # x += 1, or a[i] += 1 lhs = ToLValue(left) if lhs is None: p_die("Can't assign to %r", lhs, word=w) return arith_expr.BinaryAssign(word.ArithId(w), lhs, p.ParseUntil(rbp))
def LeftIndex(p, w, left, unused_bp): # type: (TdopParser, word_t, arith_expr_t, int) -> arith_expr_t """Array indexing, in both LValue and RValue context. LValue: f[0] = 1 f[x+1] = 2 RValue: a = f[0] b = f[x+1] On RHS, you can have: 1. a = f[0] 2. a = f(x, y)[0] 3. a = f[0][0] # in theory, if we want character indexing? NOTE: a = f[0].charAt() is probably better On LHS, you can only have: 1. a[0] = 1 Nothing else is valid: 2. function calls return COPIES. They need a name, at least in osh. 3. strings don't have mutable characters. """ if not tdop.IsIndexable(left): p_die("%s can't be indexed", left, word=w) index = p.ParseUntil(0) p.Eat(Id.Arith_RBracket) return arith_expr.ArithBinary(word.ArithId(w), left, index)
def Next(self): # type: () -> bool """Preferred over Eat()? """ self.cur_word = self.w_parser.ReadWord(lex_mode_e.Arith) assert self.cur_word is not None self.op_id = word.ArithId(self.cur_word) return True
def NullIncDec(p, w, bp): """ ++x or ++x[1] """ right = p.ParseUntil(bp) child = tdop.ToLValue(right) if child is None: p_die("This value can't be assigned to", word=w) return arith_expr.UnaryAssign(word.ArithId(w), child)
def NullPrefixOp(p, w, bp): """Prefix operator. Low precedence: return, raise, etc. return x+y is return (x+y), not (return x) + y High precedence: logical negation, bitwise complement, etc. !x && y is (!x) && y, not !(x && y) """ right = p.ParseUntil(bp) return arith_expr.ArithUnary(word.ArithId(w), right)
def LeftBinaryOp(p, w, left, rbp): """ Normal binary operator like 1+2 or 2*3, etc. """ # TODO: w shoudl be a TokenWord, and we should extract the token from it. return arith_expr.ArithBinary(word.ArithId(w), left, p.ParseUntil(rbp))
def Next(self): # type: () -> bool self.cur_word = self.w_parser.ReadWord(lex_mode_e.Arith) self.op_id = word.ArithId(self.cur_word) return True