def eval(self): with logger.context("IF-STMT") as log: log(f"if {self.condition}") if self.condition.eval().val: self.if_code.eval() return with logger.context("ELSE-STMT") as log: log(f"else") self.else_code.eval()
def eval(self): vals = self.vals[::-1] ops = self.ops[::-1] with logger.context("BIN EXP") as log: old_state = str(self) log(old_state) left = vals.pop().eval() while vals: op = ops.pop() if op in self.SHORT_CIRCUITS and self.SHORT_CIRCUITS[op](left): return left right = vals.pop().eval() comp = self.COMPUTATIONS[op] left = comp(left, right) new_state = self._format(ops[::-1], [str(left)] + [str(val) for val in vals[::-1]]) log(f"{old_state} => {logger.emphasize(new_state)}") old_state = new_state return left
def _compare(left, right, accepted_types, log_msg, symbol, operation): with logger.context(log_msg) as log: if not any(isinstance(right, t) for t in accepted_types): raise UnsupportedOperationError( f"Cannot compare: {left} {symbol} {right}") result = factory().types.Bool(str(operation())) log(f"{left} {symbol} {right} => {logger.emphasize(result)}") return result
def eq(self, other): with logger.context("EQ STRING") as log: if not isinstance(other, String): raise UnsupportedOperationError( f"Cannot compare (==) {self} and {other}") result = factory().types.Bool(str(self.text == other.text)) log(f"{self} == {other} => {logger.emphasize(result)}") return result
def and_(self, other): with logger.context("AND BOOL") as log: if not isinstance(other, Bool): raise UnsupportedOperationError( f"Cannot compare (&&) {self} and {other}") result = factory().types.Bool(str(other.val and self.val)) log(f"{self} && {other} => {logger.emphasize(result)}") return result
def eval(self): with logger.context("INDEX") as log: log(str(self)) iterable = self.iterable.eval() self._cached_iterable = iterable index = self.index.eval() self._cached_index = index result = iterable.index(index) log(f"{iterable}[{index}] => {logger.emphasize(result)}") return result
def eval(self): with logger.context("WHILE-LOOP") as log: while True: log(f"while {logger.highlight(self.condition)}") if not self.condition.eval().val: break try: self.code.eval() except BreakSignal: break except ContinueSignal: pass
def eval(self): with logger.context("FOR-LOOP") as log: log(f"for ({logger.highlight(self.initialize)}; {self.condition}; {self.update})") self.initialize.eval() while True: log(f"for ({self.initialize}; {logger.highlight(self.condition)}; {self.update})") if not self.condition.eval().val: break try: self.code.eval() except BreakSignal: break except ContinueSignal: pass log(f"for ({self.initialize}; {self.condition}; {logger.highlight(self.update)})") self.update.eval()
def eval(self): with logger.context("FUNC CALL") as log: log(str(self)) # Grab the function function = self.atom.eval() # Assert arg count if len(function.variables) != len(self.arguments): start = "Too few" if len(function.variables) > len( self.arguments) else "Too many" raise FunctionError( f"{start} arguments passed for function {self.atom}, " f"expected {len(function.variables)}, but got {len(self.arguments)}" ) # Eval all args args = [arg.eval() for arg in self.arguments] # Create a new BlockingFrame for this function call STACK.push(BlockingFrame()) try: # Create all new variables on that frame for var, arg in zip(function.variables, args): var.assign(arg) # Execute the function try: function.code.eval() except ReturnSignal as r: result = r.payload else: result = factory().types.Null() log(f"{self._format(function.name, args)} => {logger.emphasize(result)}" ) return result finally: STACK.pop()
def eval(self): with logger.context("IF-STMT") as log: log(f"if {self.condition}") if self.condition.eval().val: self.code.eval()
def not_(self): with logger.context("NOT BOOL") as log: result = factory().types.Bool(str(not self.val)) log(f"!{self} => {logger.emphasize(result)}") return result
def eval(self): with logger.context("BREAK") as log: log(str(self)) raise BreakSignal()
def eval(self): with logger.context("CONTINUE") as log: log(str(self)) raise ContinueSignal()
def eval(self): with logger.context("PRE INCREMENT") as log: log(str(self)) val = self.assignable.eval().add(factory().types.Int(1)) self.assignable.assign(val) return val
def sub_int(self, left): with logger.context("SUB INT") as log: res = factory().types.Int(left.val - self.val) log(f"{left} - {self} => {logger.emphasize(res)}") return res
def div_int(self, left): with logger.context("DIV INT") as log: res = factory().types.Int(left.val // self.val) log(f"{left} / {self} => {logger.emphasize(res)}") return res
def mod_float(self, left): with logger.context("CONV FLOAT") as log: self_float = factory().types.Float(self.val) log(f"{left} % {self} => {left} % {logger.emphasize(self_float)}") return self_float.mod_float(left)
def eval(self): with logger.context("RETURN") as log: log(str(self)) raise ReturnSignal(self.code.eval())
def eval(self): with logger.context("VAR EXP") as log: result = STACK[str(self.variable)] log(f"{str(self.variable)} => {logger.emphasize(str(result))}") return result
def mul_float(self, left): with logger.context("MUL FLOAT") as log: res = factory().types.Float(left.val * self.val) log(f"{left} * {self} => {logger.emphasize(res)}") return res
def eval(self): with logger.context("FUNC DEF") as log: log(str(self)) STACK[str(self.name)] = self
def eval(self): with logger.context("POST DECREMENT") as log: log(str(self)) val = self.assignable.eval() self.assignable.assign(val.sub(factory().types.Int(1))) return val
def div_int(self, left): with logger.context("CONV FLOAT") as log: left_float = factory().types.Float(left.val) log(f"{left} / {self} => {logger.emphasize(left_float)} / {self}") return self.div_float(left_float)
def eval(self): with logger.context("ASSIGNMENT") as log: log(str(self)) result = self.val.eval() self.assignable.assign(result) log(logger.emphasize(f"{self.assignable} = {result}"))
def add_float(self, left): with logger.context("ADD FLOAT") as log: res = factory().types.Float(left.val + self.val) log(f"{left} + {self} => {logger.emphasize(res)}") return res
def mod_int(self, left): with logger.context("MOD INT") as log: res = factory().types.Int(left.val % self.val) log(f"{left} % {self} => {logger.emphasize(res)}") return res