def visit(self, node: ast.Ctes, dest):
     # print("------------visit node: Ctes")
     if node.type == "String":
         msg = self.register_data(node.value)
         var = self.define_internal_local()
         self.register_instruction(cil.CILLoadNode(var, msg))
         self.register_instruction(cil.CILAssignNode(dest, var))
     elif node.type == "Bool":
         var = 1 if node.value else 0
         self.register_instruction(cil.CILAssignNode(dest, var))
     else:
         self.register_instruction(cil.CILAssignNode(dest, node.value))
 def visit(self, node: ast.Variable, dest):
     # print("------------visit node: Variable")
     if node.name == 'self':
         v_self = self._find('self')
         self.register_instruction(cil.CILAssignNode(dest, v_self))
     elif not node.vinfo in [
             a.vinfo for a in self.localvars
     ] and not node.vinfo in [a.vinfo for a in self.arguments]:
         v_self = self._find('self')
         num = self.dottypes[self.current_class.cinfo.name].attrs[
             node.name].vmholder
         self.register_instruction(cil.CILGetAttribNode(dest, v_self, num))
     else:
         self.register_instruction(cil.CILAssignNode(dest, node.vinfo))
    def visit(self, node: ast.IsVoid, dest):
        # print("------------visit node: IsVoid")
        vlocal = self.define_internal_local()
        self.visit(node.expr, vlocal)
        v_box = self._ifboxing(vlocal, node.expr.computedType)
        # self.register_instruction(cil.CILMinusNode(dest, self.void, v_box))

        rest = self.define_internal_local()
        self.register_instruction(cil.CILMinusNode(rest, self.void, v_box))
        label_1 = self.build_label()
        label_2 = self.build_label()
        self.register_instruction(cil.CILGotoIfNode(rest, label_1))
        self.register_instruction(cil.CILAssignNode(dest, 1))
        self.register_instruction(cil.CILGotoNode(label_2))
        self.register_instruction(label_1)
        self.register_instruction(cil.CILAssignNode(dest, 0))
        self.register_instruction(label_2)
 def visit(self, node: ast.Block, dest):
     # print("------------visit node: Block")
     last = None
     for expr in node.exprlist:
         vlocal = self.define_internal_local()
         last = vlocal
         self.visit(expr, vlocal)
     self.register_instruction(cil.CILAssignNode(dest, last))
 def visit(self, node: ast.Declaration):
     # print("------------visit node: Declaration")
     vlocal = self.register_local(node.vinfo)
     ret_var = self.define_internal_local()
     self.visit(node.expr, ret_var)
     vbox = self._ifobjectboxing(ret_var, node.expr.computedType,
                                 node.vinfo.ctype)
     self.register_instruction(cil.CILAssignNode(vlocal, vbox))
     return vlocal
    def visit(self, node: ast.Assignment, dest):
        # print("------------visit node: Assignment")
        v_temp = self.define_internal_local()

        self.visit(node.expr, v_temp)
        # print("................. node.id.vinfo",node.id.computedType)
        v_box = self._ifobjectboxing(v_temp, node.expr.computedType,
                                     node.id.computedType)

        if not node.id.vinfo in [
                a.vinfo for a in self.localvars
        ] and not node.id.vinfo in [a.vinfo for a in self.arguments]:
            v_self = self._find('self')
            num = self.dottypes[self.current_class.cinfo.name].attrs[
                node.id.name].vmholder
            self.register_instruction(cil.CILSetAttribNode(v_self, num, v_box))
            self.register_instruction(cil.CILGetAttribNode(dest, v_self, num))
        else:
            self.register_instruction(cil.CILAssignNode(node.id.vinfo, v_box))
            self.register_instruction(cil.CILAssignNode(dest, node.id.vinfo))
    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.Loop, dest):
        # print("------------visit node: Loop")

        cond_eval = self.define_internal_local()

        label_entry = self.build_label()
        self.register_instruction(label_entry)

        self.visit(node.whileexpr, cond_eval)

        label_end = self.build_label()
        label_loop = self.build_label()
        self.register_instruction(cil.CILGotoIfNode(cond_eval, label_loop))
        self.register_instruction(cil.CILGotoNode(label_end))

        self.register_instruction(label_loop)

        vbody = self.define_internal_local()
        self.visit(node.loopexpr, vbody)

        self.register_instruction(cil.CILGotoNode(label_entry))
        self.register_instruction(label_end)

        self.register_instruction(cil.CILAssignNode(dest, self.void))
 def visit(self, node: ast.Void, dest):
     # print("------------visit node: Void")
     self.register_instruction(cil.CILAssignNode(dest, self.void))
    def visit(self, node: ast.Equal, dest):
        # print("------------visit node: Equal")
        vleft = self.define_internal_local()
        vright = self.define_internal_local()
        self.visit(node.left, vleft)
        self.visit(node.right, vright)

        if node.left.computedType == 'String':

            vlength_r = self.define_internal_local()
            self.register_instruction(cil.CILLengthNode(vlength_r, vright))
            vlength_l = self.define_internal_local()
            self.register_instruction(cil.CILLengthNode(vlength_l, vleft))

            self.register_instruction(
                cil.CILMinusNode(dest, vlength_l, vlength_r))

            label_loop = self.build_label()
            label_loopbody = self.build_label()
            label_equal = self.build_label()
            label_notequal = self.build_label()
            label_end = self.build_label()

            self.register_instruction(cil.CILGotoIfNode(dest, label_notequal))

            pos = self.define_internal_local()
            self.register_instruction(cil.CILAssignNode(pos, 0))

            self.register_instruction(label_loop)
            self.register_instruction(
                cil.CILGotoIfNode(vlength_r, label_loopbody))

            self.register_instruction(cil.CILGotoNode(label_equal))

            self.register_instruction(label_loopbody)
            cleft = self.define_internal_local()
            cright = self.define_internal_local()
            self.register_instruction(cil.CILGetIndexNode(cleft, vleft, pos))
            self.register_instruction(cil.CILGetIndexNode(cright, vright, pos))
            self.register_instruction(cil.CILMinusNode(vlength_r, vlength_r,
                                                       1))
            self.register_instruction(cil.CILPlusNode(pos, pos, 1))

            vrest = self.define_internal_local()
            self.register_instruction(cil.CILMinusNode(vrest, cleft, cright))
            self.register_instruction(cil.CILGotoIfNode(vrest, label_notequal))

            self.register_instruction(cil.CILGotoNode(label_loop))

            self.register_instruction(label_equal)
            self.register_instruction(cil.CILAssignNode(dest, 1))
            self.register_instruction(cil.CILGotoNode(label_end))

            self.register_instruction(label_notequal)
            self.register_instruction(cil.CILAssignNode(dest, 0))
            self.register_instruction(label_end)

        else:
            rest = self.define_internal_local()
            self.register_instruction(cil.CILMinusNode(rest, vleft, vright))
            label_1 = self.build_label()
            label_2 = self.build_label()
            self.register_instruction(cil.CILGotoIfNode(rest, label_1))
            self.register_instruction(cil.CILAssignNode(dest, 1))
            self.register_instruction(cil.CILGotoNode(label_2))
            self.register_instruction(label_1)
            self.register_instruction(cil.CILAssignNode(dest, 0))
            self.register_instruction(label_2)
        label_init = self.build_label()
        self.register_instruction(label_init)

        label_error = self.build_label()

        for tlocal, label_expr, _, _ in expr_list:
            vinternal = self.define_internal_local()
            # self.register_instruction(cil.CILMinusNode(vinternal, tlocal, texpr))

            rest = self.define_internal_local()
            self.register_instruction(cil.CILMinusNode(rest, tlocal, texpr))
            label_1 = self.build_label()
            label_2 = self.build_label()
            self.register_instruction(cil.CILGotoIfNode(rest, label_1))
            self.register_instruction(cil.CILAssignNode(vinternal, 1))
            self.register_instruction(cil.CILGotoNode(label_2))
            self.register_instruction(label_1)
            self.register_instruction(cil.CILAssignNode(vinternal, 0))
            self.register_instruction(label_2)

            # self.register_instruction(cil.CILMinusNode(vinternal, 1, vinternal))
            self.register_instruction(cil.CILGotoIfNode(vinternal, label_expr))

        vobject = self.define_internal_local()
        self.register_instruction(
            cil.CILAllocateNode(vobject, self.dottypes['Object'].cinfo))
        self.register_instruction(cil.CILTypeOfNode(vobject, vobject))
        vo_comp = self.define_internal_local()
        # self.register_instruction(cil.CILMinusNode(vo_comp, vobject, texpr))
    def string_bi(self, object_type):
        attrs = {'value': VariableInfo('value', vmholder=1)}
        methods = copy(object_type.methods)

        self.change_current_function()
        self.arguments = [
            cil.CILArgNode(VariableInfo('self', vmholder=1)),
            cil.CILArgNode(VariableInfo('string2', vmholder=2))
        ]

        vlocal1 = self.define_internal_local()
        self.register_instruction(
            cil.CILGetAttribNode(vlocal1, self.arguments[0].vinfo,
                                 attrs['value'].vmholder))

        vlocal2 = self.define_internal_local()
        self.register_instruction(
            cil.CILConcatNode(vlocal2, vlocal1, self.arguments[1].vinfo))

        # self.register_instruction(cil.CILSetAttribNode(self.arguments[0].vinfo, 'value', vlocal2))
        self.register_instruction(cil.CILReturnNode(vlocal2))

        concat_func = cil.CILFunctionNode(
            MethodInfo(self.build_funcname('concat'),
                       paramsType=['String'],
                       returnType='String'), self.arguments, self.localvars,
            self.instructions)
        self.register_function(concat_func)

        self.change_current_function()
        self.arguments = [cil.CILArgNode(VariableInfo('self', vmholder=1))]

        v_local3 = self.define_internal_local()
        self.register_instruction(
            cil.CILGetAttribNode(v_local3, self.arguments[0].vinfo,
                                 attrs['value'].vmholder))

        v_local4 = self.define_internal_local()
        self.register_instruction(cil.CILLengthNode(v_local4, v_local3))

        self.register_instruction(cil.CILReturnNode(v_local4))

        length_func = cil.CILFunctionNode(
            MethodInfo(self.build_funcname('length'), returnType='Int'),
            self.arguments, self.localvars, self.instructions)
        self.register_function(length_func)

        # Substring
        self.change_current_function()
        self.arguments = [
            cil.CILArgNode(VariableInfo('self', vmholder=1)),
            cil.CILArgNode(VariableInfo('i', vmholder=2)),
            cil.CILArgNode(VariableInfo('l', vmholder=3))
        ]

        label_val = self.build_label()
        label_nval = self.build_label()
        label_fin = self.build_label()

        label_nval1 = self.build_label()
        label_fin1 = self.build_label()

        label_nval2 = self.build_label()
        label_fin2 = self.build_label()

        vvar2 = self.define_internal_local()
        self.register_instruction(cil.CILAssignNode(vvar2, 0))

        vvar1 = self.define_internal_local()
        self.register_instruction(
            cil.CILLessThan(vvar1, self.arguments[1].vinfo, vvar2))
        self.register_instruction(cil.CILGotoIfNode(vvar1, label_nval1))

        self.register_instruction(
            cil.CILLessThan(vvar1, self.arguments[2].vinfo, vvar2))
        self.register_instruction(cil.CILGotoIfNode(vvar1, label_nval2))

        self.register_instruction(
            cil.CILGotoIfNode(self.arguments[2].vinfo, label_val))

        self.register_instruction(cil.CILGotoNode(label_nval))

        self.register_instruction(label_val)
        v_local5 = self.define_internal_local()
        self.register_instruction(
            cil.CILGetAttribNode(v_local5, self.arguments[0].vinfo,
                                 attrs['value'].vmholder))

        vhalt = self.define_internal_local()
        vlength = self.define_internal_local()
        self.register_instruction(cil.CILLengthNode(vlength, v_local5))

        vsum = self.define_internal_local()
        self.register_instruction(
            cil.CILPlusNode(vsum, self.arguments[1].vinfo,
                            self.arguments[2].vinfo))
        self.register_instruction(cil.CILMinusNode(vsum, vsum, 1))
        self.register_instruction(cil.CILLessThan(vhalt, vsum, vlength))

        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_local6 = self.define_internal_local()
        self.register_instruction(
            cil.CILSubstringNode(v_local6, v_local5, self.arguments[1].vinfo,
                                 self.arguments[2].vinfo))
        self.register_instruction(cil.CILReturnNode(v_local6))

        self.register_instruction(cil.CILGotoNode(labelend))

        self.register_instruction(labelerror)
        var1 = self.define_internal_local()
        self.register_instruction(
            cil.CILLoadNode(var1, self.dotdata['exception_5']))
        self.register_instruction(cil.CILPrintStrNode(var1))
        self.register_instruction(cil.CILErrorNode())

        self.register_instruction(labelend)
        self.register_instruction(cil.CILGotoNode(label_fin))

        self.register_instruction(label_nval)
        msg = self.register_data("")
        var = self.define_internal_local()
        self.register_instruction(cil.CILLoadNode(var, msg))
        self.register_instruction(cil.CILReturnNode(var))

        self.register_instruction(label_fin)
        self.register_instruction(cil.CILGotoNode(label_fin2))

        self.register_instruction(label_nval2)
        var1 = self.define_internal_local()
        self.register_instruction(
            cil.CILLoadNode(var1, self.dotdata['exception_5']))
        self.register_instruction(cil.CILPrintStrNode(var1))
        self.register_instruction(cil.CILErrorNode())

        self.register_instruction(label_fin2)
        self.register_instruction(cil.CILGotoNode(label_fin1))

        self.register_instruction(label_nval1)
        var1 = self.define_internal_local()
        self.register_instruction(
            cil.CILLoadNode(var1, self.dotdata['exception_5']))
        self.register_instruction(cil.CILPrintStrNode(var1))
        self.register_instruction(cil.CILErrorNode())

        self.register_instruction(label_fin1)

        substr_func = cil.CILFunctionNode(
            MethodInfo(self.build_funcname('substr'),
                       paramsType=['Int', 'Int'],
                       returnType='String'), self.arguments, self.localvars,
            self.instructions)
        self.register_function(substr_func)

        length_func.finfo.vmholder = len(methods.keys()) + 2
        methods['length'] = length_func
        concat_func.finfo.vmholder = len(methods.keys()) + 2
        methods['concat'] = concat_func
        substr_func.finfo.vmholder = len(methods.keys()) + 2
        methods['substr'] = substr_func

        cinfo = ClassInfo('String', 4 * len(attrs.keys()),
                          4 * len(methods.keys()), object_type)
        return cil.CILTypeNode(cinfo, attrs, methods)