def visit_ForNode(self, node, context): res = p.RTResult() elements = [] start_value = res.register(self.visit(node.start_value_node, context)) if res.error: return res end_value = res.register(self.visit(node.end_value_node, context)) if res.error: return res if node.step_value_node: step_value = res.register(self.visit(node.step_value_node, context)) if res.error: return res else: step_value = Number(1) i = start_value.value if step_value.value >= 0: condition = lambda: i < end_value.value else: condition = lambda: i > end_value.value while condition(): context.symbol_table.set(node.var_name_tok.value, Number(i)) i += step_value.value elements.append(res.register(self.visit(node.body_node, context))) if res.error: return res return res.success( List(elements).set_context(context).set_pos( node.pos_start, node.pos_end))
def visit_VarAssignNode(self, node, context): res = p.RTResult() var_name = node.var_name_tok.value value = res.register(self.visit(node.value_node, context)) if res.error: return res context.symbol_table.set(var_name, value) return res.success(value)
def visit_ListNode(self, node, context): res = p.RTResult() elements = [] for element_node in node.element_nodes: elements.append(res.register(self.visit(element_node, context))) if res.error: return res return res.success( List(elements).set_context(context).set_pos( node.pos_start, node.pos_end))
def visit_VarAccessNode(self, node, context): res = p.RTResult() var_name = node.var_name_tok.value value = context.symbol_table.get(var_name) if not value: return res.failure( errors.RTError(node.pos_start, node.pos_end, f"'{var_name}' is not defined", context)) value = value.copy().set_pos(node.pos_start, node.pos_end) return res.success(value)
def visit_FuncDefNode(self, node, context): res = p.RTResult() func_name = node.var_name_tok.value if node.var_name_tok else None body_node = node.body_node arg_names = [arg_name.value for arg_name in node.arg_name_toks] func_value = Function(func_name, body_node, arg_names).set_context(context).set_pos( node.pos_start, node.pos_end) if node.var_name_tok: context.symbol_table.set(func_name, func_value) return res.success(func_value)
def visit_CallNode(self, node, context): res = p.RTResult() args = [] value_to_call = res.register(self.visit(node.node_to_call, context)) if res.error: return res value_to_call = value_to_call.copy().set_pos(node.pos_start, node.pos_end) for arg_node in node.arg_nodes: args.append(res.register(self.visit(arg_node, context))) if res.error: return res return_value = res.register(value_to_call.execute(args)) if res.error: return res return res.success(return_value)
def visit_WhileNode(self, node, context): res = p.RTResult() elements = [] while True: condition = res.register(self.visit(node.condition_node, context)) if res.error: return res if not condition.is_true(): break elements.append(res.register(self.visit(node.body_node, context))) if res.error: return res return res.success( List(elements).set_context(context).set_pos( node.pos_start, node.pos_end))
def visit_UnaryOpNode(self, node, context): res = p.RTResult() number = res.register(self.visit(node.node, context)) if res.error: return res error = None if node.op_tok.type == t.TT_MINUS: number, error = number.multed_by(Number(-1)) elif node.op_tok.matches(t.TT_KEYWORD, 'NOT'): number, error = number.notted() if error: return res.failure(error) else: return res.success(number.set_pos(node.pos_start, node.pos_end))
def visit_IfNode(self, node, context): res = p.RTResult() for condition, expr in node.cases: condition_value = res.register(self.visit(condition, context)) if res.error: return res if condition_value.is_true(): expr_value = res.register(self.visit(expr, context)) if res.error: return res return res.success(expr_value) if node.else_case: else_value = res.register(self.visit(node.else_case, context)) if res.error: return res return res.success(else_value) return res.success(None)
def visit_BinOpNode(self, node, context): res = p.RTResult() left = res.register(self.visit(node.left_node, context)) if res.error: return res right = res.register(self.visit(node.right_node, context)) if res.error: return res if node.op_tok.type == t.TT_PLUS: result, error = left.added_to(right) elif node.op_tok.type == t.TT_MINUS: result, error = left.subbed_by(right) elif node.op_tok.type == t.TT_MUL: result, error = left.multed_by(right) elif node.op_tok.type == t.TT_DIV: result, error = left.dived_by(right) elif node.op_tok.type == t.TT_POW: result, error = left.powed_by(right) elif node.op_tok.type == t.TT_EE: result, error = left.get_comparison_eq(right) elif node.op_tok.type == t.TT_NE: result, error = left.get_comparison_ne(right) elif node.op_tok.type == t.TT_LT: result, error = left.get_comparison_lt(right) elif node.op_tok.type == t.TT_GT: result, error = left.get_comparison_gt(right) elif node.op_tok.type == t.TT_LTE: result, error = left.get_comparison_lte(right) elif node.op_tok.type == t.TT_GTE: result, error = left.get_comparison_gte(right) elif node.op_tok.matches(t.TT_KEYWORD, 'AND'): result, error = left.anded_by(right) elif node.op_tok.matches(t.TT_KEYWORD, 'OR'): result, error = left.ored_by(right) if error: return res.failure(error) else: return res.success(result.set_pos(node.pos_start, node.pos_end))
def execute(self, args): return p.RTResult().failure(self.illegal_operation())
def visit_StringNode(self, node, context): return p.RTResult().success( String(node.tok.value).set_context(context).set_pos( node.pos_start, node.pos_end))