Ejemplo n.º 1
0
    def visit(self, node, context):
        localvars = []
        code = []

        self.num_labels += 1
        cil_while_label = ast_cil.CILLabel('WHILE' + str(self.num_labels))
        self.num_labels += 1
        cil_loop_label = ast_cil.CILLabel('LOOP' + str(self.num_labels))
        self.num_labels += 1
        cil_pool_label = ast_cil.CILLabel('POOL' + str(self.num_labels))

        local_while_value = context.define_local()
        localvars.append(local_while_value)

        code.append(cil_while_label)  # WHILE

        self.visit(node.while_expression, context)
        localvars += node.while_expression.locals
        code += node.while_expression.code

        cil_getattr = ast_cil.CILGetAttr(node.while_expression.value, 0)
        cil_assign = ast_cil.CILAssignment(local_while_value, cil_getattr)
        code.append(cil_assign)

        cil_condition = ast_cil.CILCondition(local_while_value,
                                             cil_loop_label.label)
        code.append(cil_condition)

        cil_goto1 = ast_cil.CILGoTo(cil_pool_label.label)
        code.append(cil_goto1)

        code.append(cil_loop_label)  # LOOP
        self.visit(node.loop_expression, context)
        localvars += node.loop_expression.locals
        code += node.loop_expression.code

        cil_goto2 = ast_cil.CILGoTo(cil_while_label.label)
        code.append(cil_goto2)

        code.append(cil_pool_label)  # POOL
        # return void
        local_value = context.define_local()
        localvars.append(local_value)

        node.value = local_value
        node.locals = localvars
        node.code = code
Ejemplo n.º 2
0
    def visit(self, node, context):
        self.visit(node.left_expression, context)
        code = node.left_expression.code
        localvars = node.left_expression.locals

        self.visit(node.right_expression, context)
        code += node.right_expression.code
        localvars += node.right_expression.locals

        local_int_left = context.define_local()
        localvars.append(local_int_left)
        cil_getattr1 = ast_cil.CILGetAttr(node.left_expression.value, 0)
        cil_assign1 = ast_cil.CILAssignment(local_int_left, cil_getattr1)
        code.append(cil_assign1)

        local_int_right = context.define_local()
        localvars.append(local_int_right)
        cil_getattr2 = ast_cil.CILGetAttr(node.right_expression.value, 0)
        cil_assign2 = ast_cil.CILAssignment(local_int_right, cil_getattr2)
        code.append(cil_assign2)

        self.num_labels += 1
        cil_notnone_label = ast_cil.CILLabel('NOT_NONE' + str(self.num_labels))
        self.num_labels += 1
        cil_divisionby0_label = ast_cil.CILLabel('DIVISION_BY_0' +
                                                 str(self.num_labels))

        cil_condition = ast_cil.CILCondition(local_int_right,
                                             cil_notnone_label.label)
        code.append(cil_condition)

        code.append(cil_divisionby0_label)  # DIVISION_BY_0
        cil_goto = ast_cil.CILGoTo('_divide_by_0')
        code.append(cil_goto)

        code.append(cil_notnone_label)  # NOT_NONE

        local_int_content = context.define_local()
        localvars.append(local_int_content)

        cil_div = ast_cil.CILDiv(local_int_left, local_int_right)
        cil_assign3 = ast_cil.CILAssignment(local_int_content, cil_div)
        code.append(cil_assign3)

        local_value = context.define_local()
        localvars.append(local_value)
        local_int_tag = context.define_local(self.types_dict['Int'])
        localvars.append(local_int_tag)

        cil_allocate = ast_cil.CILAllocate(local_int_tag)
        cil_assign4 = ast_cil.CILAssignment(local_value, cil_allocate)
        cil_setattr = ast_cil.CILSetAttr(local_value, 0, local_int_content)
        code += [cil_assign4, cil_setattr]

        node.value = local_value
        node.locals = localvars
        node.code = code
Ejemplo n.º 3
0
    def visit(self, node, context):
        localvars = []
        code = []

        params = []
        for arg_expr in node.arguments:
            self.visit(arg_expr, context)
            localvars += arg_expr.locals
            code += arg_expr.code
            params.append(ast_cil.CILParam(arg_expr.value))

        self.visit(node.instance, context)
        localvars += node.instance.locals
        code += node.instance.code

        self.num_labels += 1
        cil_dispatchnotvoid_label = ast_cil.CILLabel('DISPATCH_NOT_VOID' +
                                                     str(self.num_labels))

        cil_cond = ast_cil.CILCondition(node.instance.value,
                                        cil_dispatchnotvoid_label.label)
        code.append(cil_cond)

        cil_goto1 = ast_cil.CILGoTo('_dispatch_abort')  # DISPATCH_ON_VOID
        code.append(cil_goto1)

        code.append(cil_dispatchnotvoid_label)  # DISPATCH_NOT_VOID

        param_instance = ast_cil.CILParam(node.instance.value)

        # take the method offset
        type_name = node.instance.computed_type.name
        if type_name == 'SELF_TYPE':
            type_name = node.instance.computed_type.parent
        meth_offset = self.cilProgram.dotTYPES.types[type_name].methods.get(
            node.method).offset

        # check order of parameters
        code.append(param_instance)
        for _param in params:
            code.append(_param)

        local_value = context.define_local()
        localvars.append(local_value)

        cil_dcall = ast_cil.CILDinamicCall(node.instance.value, meth_offset)
        cil_assign = ast_cil.CILAssignment(local_value, cil_dcall)
        code.append(cil_assign)

        node.value = local_value
        node.locals = localvars
        node.code = code
Ejemplo n.º 4
0
    def visit(self, node, context):
        self.visit(node.if_expression, context)
        localvars = node.if_expression.locals
        code = node.if_expression.code

        local_value = context.define_local()
        localvars.append(local_value)

        self.num_labels += 1
        cil_then_label = ast_cil.CILLabel('THEN' + str(self.num_labels))
        self.num_labels += 1
        cil_end_label = ast_cil.CILLabel('END' + str(self.num_labels))

        local_if_value = context.define_local()
        localvars.append(local_if_value)

        cil_getattr = ast_cil.CILGetAttr(node.if_expression.value, 0)
        cil_assign1 = ast_cil.CILAssignment(local_if_value, cil_getattr)
        code.append(cil_assign1)

        cil_condition = ast_cil.CILCondition(local_if_value,
                                             cil_then_label.label)
        code.append(cil_condition)

        self.visit(node.else_expression, context)
        localvars += node.else_expression.locals
        code += node.else_expression.code
        cil_assign2 = ast_cil.CILAssignment(
            local_value, ast_cil.CILVar(node.else_expression.value))
        code.append(cil_assign2)

        cil_goto = ast_cil.CILGoTo(cil_end_label.label)
        code.append(cil_goto)

        code.append(cil_then_label)  # THEN
        self.visit(node.then_expression, context)
        localvars += node.then_expression.locals
        code += node.then_expression.code
        cil_assign3 = ast_cil.CILAssignment(
            local_value, ast_cil.CILVar(node.then_expression.value))
        code.append(cil_assign3)

        code.append(cil_end_label)  # END

        node.value = local_value
        node.locals = localvars
        node.code = code
Ejemplo n.º 5
0
    def visit(self, node, context):
        self.visit(node.expression, context)
        code = node.expression.code
        localvars = node.expression.locals

        self.num_labels += 1
        cil_false_label = ast_cil.CILLabel('FALSE' + str(self.num_labels))
        self.num_labels += 1
        cil_end_label = ast_cil.CILLabel('END' + str(self.num_labels))

        local_value = context.define_local()
        localvars.append(local_value)
        local_bool_tag = context.define_local(self.types_dict['Bool'])
        localvars.append(local_bool_tag)
        cil_allocate = ast_cil.CILAllocate(local_bool_tag)
        cil_assign = ast_cil.CILAssignment(local_value, cil_allocate)
        code.append(cil_assign)

        cil_condition = ast_cil.CILCondition(node.expression.value,
                                             cil_false_label.label)
        code.append(cil_condition)

        # TRUE
        local_true_content = context.define_local(1)
        localvars.append(local_true_content)
        cil_setattr_true = ast_cil.CILSetAttr(local_value, 0,
                                              local_true_content)
        code.append(cil_setattr_true)

        cil_goto = ast_cil.CILGoTo(cil_end_label.label)
        code.append(cil_goto)

        code.append(cil_false_label)  # FALSE
        local_false_content = context.define_local(0)
        localvars.append(local_false_content)
        cil_setattr_false = ast_cil.CILSetAttr(local_value, 0,
                                               local_false_content)
        code.append(cil_setattr_false)

        code.append(cil_end_label)  #END

        node.value = local_value
        node.locals = localvars
        node.code = code
Ejemplo n.º 6
0
    def visit(self, node, context):
        self.visit(node.case_expression, context)
        localvars = node.case_expression.locals
        code = node.case_expression.code

        self.num_labels += 1
        cil_caseonvoid_label = ast_cil.CILLabel('CASE_ON_VOID' +
                                                str(self.num_labels))
        self.num_labels += 1
        cil_taketag_label = ast_cil.CILLabel('TAKE_TAG' + str(self.num_labels))
        self.num_labels += 1
        cil_while_label = ast_cil.CILLabel('WHILE' + str(self.num_labels))
        self.num_labels += 1
        cil_casenobranch_label = ast_cil.CILLabel('CASE_NO_BRANCH' +
                                                  str(self.num_labels))
        self.num_labels += 1
        cil_takeparenttag_label = ast_cil.CILLabel('TAKE_PARENT_TAG' +
                                                   str(self.num_labels))
        self.num_labels += 1
        cil_end_label = ast_cil.CILLabel('END' + str(self.num_labels))

        cil_condition1 = ast_cil.CILCondition(node.case_expression.value,
                                              cil_taketag_label.label)
        code.append(cil_condition1)

        code.append(cil_caseonvoid_label)  # CASE_ON_VOID _case_abort2
        cil_goto1 = ast_cil.CILGoTo('_case_abort2')
        code.append(cil_goto1)

        # cil_goto1 = ast_cil.CILGoTo(cil_end_label.label)
        # code.append(cil_goto1)

        code.append(cil_taketag_label)  # TAKE_TAG
        local_instance_tag = context.define_local()
        localvars.append(local_instance_tag)

        cil_typeof = ast_cil.CILTypeOf(node.case_expression.value)
        cil_assign1 = ast_cil.CILAssignment(local_instance_tag, cil_typeof)
        code.append(cil_assign1)

        local_value = context.define_local()
        localvars.append(local_value)

        code.append(cil_while_label)  # WHILE

        for _branch in node.branch_list:
            local_branch_tag = context.define_local(
                self.types_dict[_branch.type_branch])
            localvars.append(local_branch_tag)
            local_diff = context.define_local()
            localvars.append(local_diff)

            cil_minus = ast_cil.CILMinus(local_instance_tag, local_branch_tag)
            cil_assign2 = ast_cil.CILAssignment(local_diff, cil_minus)
            code.append(cil_assign2)

            self.num_labels += 1
            cil_typenotmatch_label = ast_cil.CILLabel('TYPE_NOT_MATCH' +
                                                      str(self.num_labels))

            cil_condition = ast_cil.CILCondition(local_diff,
                                                 cil_typenotmatch_label.label)
            code.append(cil_condition)

            child_context = context.create_child()
            child_context.define_variable(_branch.name, _branch.type_branch,
                                          node.case_expression.value)

            self.visit(_branch.expression, child_context)
            localvars += _branch.expression.locals
            code += _branch.expression.code

            cil_assign3 = ast_cil.CILAssignment(
                local_value, ast_cil.CILVar(_branch.expression.value))
            code.append(cil_assign3)

            cil_goto = ast_cil.CILGoTo(cil_end_label.label)
            code.append(cil_goto)

            code.append(cil_typenotmatch_label)  # TYPE_NOT_MATCH

        cil_condition2 = ast_cil.CILCondition(local_instance_tag,
                                              cil_takeparenttag_label.label)
        code.append(cil_condition2)

        code.append(cil_casenobranch_label)  # CASE_NO_BRANCH _case_abort
        cil_goto2 = ast_cil.CILGoTo('_case_abort')
        code.append(cil_goto2)

        # cil_goto2 = ast_cil.CILGoTo(cil_end_label.label)
        # code.append(cil_goto2)

        code.append(cil_takeparenttag_label)  # TAKE_PARENT_TAG

        cil_parent = ast_cil.CILGetIndex(local_instance_tag)
        cil_assign4 = ast_cil.CILAssignment(local_instance_tag, cil_parent)
        code.append(cil_assign4)

        cil_goto3 = ast_cil.CILGoTo(cil_while_label.label)
        code.append(cil_goto3)

        code.append(cil_end_label)  # END

        node.value = local_value
        node.locals = localvars
        node.code = code