def visit(self, node, scope): result_local = self.define_internal_local(scope=scope, name="result") op_local = self.define_internal_local(scope=scope, name="op") left_local = self.define_internal_local(scope=scope, name="left") right_local = self.define_internal_local(scope=scope, name="right") left_value = self.visit(node.lvalue, scope) right_value = self.visit(node.rvalue, scope) if node.lvalue.computed_type.name == 'String': self.register_instruction( cil.CallNode( op_local, 'String_equals', [cil.ArgNode(right_value), cil.ArgNode(left_value)], 'String')) # Allocate Bool result self.register_instruction( cil.AllocateNode('Bool', self.context.get_type('Bool').tag, result_local)) result_init = self.define_internal_local(scope=scope, name="result_init") self.register_instruction( cil.CallNode( result_init, 'Bool_init', [cil.ArgNode(op_local), cil.ArgNode(result_local)], "Bool")) return result_local elif node.lvalue.computed_type.name in ['Int', 'Bool']: self.register_instruction( cil.GetAttrNode(left_local, left_value, "value", node.lvalue.computed_type.name)) self.register_instruction( cil.GetAttrNode(right_local, right_value, "value", node.rvalue.computed_type.name)) else: self.register_instruction(cil.AssignNode(left_local, left_value)) self.register_instruction(cil.AssignNode(right_local, right_value)) self.register_instruction( cil.BinaryOperationNode(op_local, left_local, right_local, "=")) # Allocate Bool result self.register_instruction( cil.AllocateNode('Bool', self.context.get_type('Bool').tag, result_local)) result_init = self.define_internal_local(scope=scope, name="result_init") self.register_instruction( cil.CallNode(result_init, 'Bool_init', [cil.ArgNode(op_local), cil.ArgNode(result_local)], "Bool")) return result_local
def visit(self, node, scope): if not node.expr is None: expr_value = self.visit(node.expr, scope) let_var = self.define_internal_local(scope=scope, name=node.id, cool_var=node.id) self.register_instruction(cil.AssignNode(let_var, expr_value)) else: instance = None if node.type in ['Int', 'Bool']: instance = self.define_internal_local(scope=scope, name="instance") self.register_instruction( cil.AllocateNode(node.type, self.context.get_type(node.type).tag, instance)) value = self.define_internal_local(scope=scope, name="value") self.register_instruction(cil.LoadIntNode(0, value)) result_init = self.define_internal_local(scope=scope, name="result_init") self.register_instruction( cil.CallNode(result_init, f'{node.type}_init', [cil.ArgNode(value), cil.ArgNode(instance)], node.type)) elif node.type == 'String': instance = self.define_internal_local(scope=scope, name="instance") self.register_instruction( cil.AllocateNode(node.type, self.context.get_type(node.type).tag, instance)) value = self.define_internal_local(scope=scope, name="value") self.register_instruction( cil.LoadStringNode('empty_str', value)) result_init = self.define_internal_local(scope=scope, name="result_init") self.register_instruction( cil.CallNode(result_init, f'{node.type}_init', [cil.ArgNode(value), cil.ArgNode(instance)], node.type)) let_var = self.define_internal_local(scope=scope, name=node.id, cool_var=node.id) self.register_instruction(cil.AssignNode(let_var, instance)) return let_var
def visit(self, node, scope): expr_local = self.visit(node.expr, scope) result_local = self.define_internal_local(scope=scope, name="result") cil_node_name = scope.find_cil_local(node.id) if self.is_defined_param(node.id): self.register_instruction(cil.AssignNode(node.id, expr_local)) elif self.current_type.has_attr(node.id): cil_type_name = 'self' self.register_instruction( cil.SetAttrNode(cil_type_name, node.id, expr_local, self.current_type.name)) else: self.register_instruction(cil.AssignNode(cil_node_name, expr_local)) return expr_local
def visit(self, node, scope): let_scope = scope.create_child() for var in node.letBody: self.visit(var, let_scope) body_value = self.visit(node.inBody, let_scope) result_local = self.define_internal_local(scope=scope, name="let_result") self.register_instruction(cil.AssignNode(result_local, body_value)) return result_local
def visit(self, node, scope): result_local = self.define_internal_local(scope=scope, name="result") case_expr = self.visit(node.expr, scope) exit_label = self.get_label() label = self.get_label() self.register_instruction(cil.CaseNode(case_expr, label)) tag_lst = [] option_dict = {} for option in node.optionList: tag = self.context.get_type(option.type).tag tag_lst.append(tag) option_dict[tag] = option tag_lst.sort() for t in reversed(tag_lst): option = option_dict[t] self.register_instruction(cil.LabelNode(label)) label = self.get_label() option_type = self.context.get_type(option.type) self.register_instruction( cil.CaseOptionNode(case_expr, option_type.tag, option_type.max_tag, label)) option_scope = scope.create_child() option_id = self.define_internal_local(scope=option_scope, name=option.id, cool_var=option.id) self.register_instruction(cil.AssignNode(option_id, case_expr)) expr_result = self.visit(option.expr, option_scope) self.register_instruction(cil.AssignNode(result_local, expr_result)) self.register_instruction(cil.GoToNode(exit_label)) self.register_instruction(cil.LabelNode(label)) self.register_instruction(cil.GoToNode('case_no_match_error')) self.register_instruction(cil.LabelNode(exit_label)) return result_local
def visit(self, node, scope): result_local = self.define_internal_local(scope=scope, name="result") cond_value = self.visit(node.condition, scope) if_then_label = self.get_label() self.register_instruction(cil.IfGoToNode(cond_value, if_then_label)) else_value = self.visit(node.elseBody, scope) self.register_instruction(cil.AssignNode(result_local, else_value)) end_if_label = self.get_label() self.register_instruction(cil.GoToNode(end_if_label)) self.register_instruction(cil.LabelNode(if_then_label)) then_value = self.visit(node.ifBody, scope) self.register_instruction(cil.AssignNode(result_local, then_value)) self.register_instruction(cil.LabelNode(end_if_label)) return result_local