def visit(self, node: ast.ProgramNode): object_class = self.object_bi() self.dottypes['Object'] = object_class self.dottypes['Int'] = self.int_bi(object_class) self.dottypes['Bool'] = self.bool_bi(object_class) self.dottypes['String'] = self.string_bi(object_class) self.dottypes['IO'] = self.io_bi(object_class) for child in node.classList: self.dottypes[child.name] = self.visit(child) self.change_current_function('entry') vlocal = self.define_internal_local() cclass = self.dottypes['Main'] self.register_instruction(cil.CILAllocateNode(vlocal, cclass.cinfo)) self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(vlocal)) vlocal2 = self.define_internal_local() nctor = cclass.methods['ctor'].finfo.name self.register_instruction(cil.CILStaticCallNode(vlocal2, nctor)) mname = cclass.methods['main'].finfo.name self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(vlocal)) self.register_instruction(cil.CILStaticCallNode(vlocal2, mname)) self.register_instruction(cil.CILReturnFinal()) entry_m = cil.CILFunctionNode(MethodInfo(self.current_function_name), self.arguments, self.localvars, self.instructions) self.register_function(entry_m) return cil.CILProgramNode(self.dottypes, self.dotdata, self.dotcode)
def visit(self, node: ast.DispatchDot, dest): # print("------------visit node: DispatchDot") params = [] ctype_ = node.expr0.computedType method_ = self.dottypes[ctype_].methods[node.methodName].finfo for i, expr in enumerate(node.paramsList): vlocal = self.define_internal_local() self.visit(expr, vlocal) p = method_.paramsType[i] v_box = self._ifobjectboxing(vlocal, expr.computedType, p) params.append(v_box) v_eval = self.define_internal_local() self.visit(node.expr0, v_eval) v_box_eval = self._ifboxing(v_eval, node.expr0.computedType) vhalt = self.define_internal_local() self.register_instruction( cil.CILMinusNode(vhalt, self.void, v_box_eval)) label1 = self.build_label() labelerror = self.build_label() labelend = self.build_label() self.register_instruction(cil.CILGotoIfNode(vhalt, label1)) self.register_instruction(cil.CILGotoNode(labelerror)) self.register_instruction(label1) v_type = self.define_internal_local() self.register_instruction(cil.CILTypeOfNode(v_type, v_box_eval)) self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(v_box_eval)) for p in params: self.register_instruction(cil.CILParamNode(p)) self.register_instruction( cil.CILDynamicCallNode(dest, v_type, method_.vmholder)) self.register_instruction(cil.CILGotoNode(labelend)) self.register_instruction(labelerror) var1 = self.define_internal_local() self.register_instruction( cil.CILLoadNode(var1, self.dotdata['exception_1'])) self.register_instruction(cil.CILPrintStrNode(var1)) self.register_instruction(cil.CILErrorNode()) self.register_instruction(labelend)
def _boxing(self, vinfo, ctype): vlocal = self.define_internal_local() self.register_instruction( cil.CILAllocateNode(vlocal, self.dottypes[ctype].cinfo)) # t_local = self.define_internal_local() # self.register_instruction(cil.CILTypeOfNode(t_local, vlocal)) self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(vlocal)) useless = self.define_internal_local() fname = self.dottypes[ctype].methods['ctor'].finfo.name self.register_instruction(cil.CILStaticCallNode(useless, fname)) num2 = self.dottypes[ctype].attrs['value'].vmholder self.register_instruction(cil.CILSetAttribNode(vlocal, num2, vinfo)) return vlocal
def visit(self, node: ast.DispatchSelf, dest): # print("------------visit node: DispatchSelf") params = [] method_ = self.dottypes[self.current_class.cinfo.name].methods[ node.methodName].finfo vself = self._find('self') vhalt = self.define_internal_local() self.register_instruction(cil.CILMinusNode(vhalt, self.void, vself)) label1 = self.build_label() labelerror = self.build_label() labelend = self.build_label() self.register_instruction(cil.CILGotoIfNode(vhalt, label1)) self.register_instruction(cil.CILGotoNode(labelerror)) self.register_instruction(label1) for i, expr in enumerate(node.paramsList): vlocal = self.define_internal_local() self.visit(expr, vlocal) p = method_.paramsType[i] v_box = self._ifobjectboxing(vlocal, expr.computedType, p) params.append(v_box) self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(vself)) for p in params: self.register_instruction(cil.CILParamNode(p)) self.register_instruction(cil.CILStaticCallNode(dest, method_.name)) self.register_instruction(cil.CILGotoNode(labelend)) self.register_instruction(labelerror) var1 = self.define_internal_local() self.register_instruction( cil.CILLoadNode(var1, self.dotdata['exception_1'])) self.register_instruction(cil.CILPrintStrNode(var1)) self.register_instruction(cil.CILErrorNode()) self.register_instruction(labelend)
def visit(self, node: ast.New, dest): # print("------------visit node: New") if node.newType == 'Int' or node.newType == 'Bool': self.register_instruction(cil.CILAssignNode(dest, 0)) elif node.newType == 'String': msg = self.register_data("") var = self.define_internal_local() self.register_instruction(cil.CILLoadNode(var, msg)) self.register_instruction(cil.CILAssignNode(dest, var)) else: self.register_instruction( cil.CILAllocateNode(dest, self.dottypes[node.newType].cinfo)) self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(dest)) useless = self.define_internal_local() # v_type = self.define_internal_local() # self.register_instruction(cil.CILTypeOfNode(v_type, dest)) fname = self.dottypes[node.newType].methods['ctor'].finfo.name self.register_instruction(cil.CILStaticCallNode(useless, fname))
def visit(self, node: ast.CoolClass): # print("------------visit node: CoolClass") self.current_class = self.dottypes[node.name] parent_class = self.current_class.cinfo.parent self.change_current_function(self.current_class.methods['ctor']) self.register_argument(VariableInfo('self')) useless = self.define_internal_local() self.register_instruction(cil.CILSaveState()) self.register_instruction(cil.CILParamNode(self.arguments[0].vinfo)) name = parent_class.methods['ctor'].finfo.name self.register_instruction(cil.CILStaticCallNode(useless, name)) for attr in node.attrs: self.visit(attr) self.register_instruction(cil.CILReturnNode()) for func in node.methods: self.visit(func)