예제 #1
0
 def get_var_number(self, var_id):
     try:
         var_number = self.scope.vars.index(var_id)
     except ValueError:
         raise error_processor.UnsupportedOperation(
             self.get_rule_position(), 'Undefined ID "%s".' % var_id)
     return RESERVED_LOCALS + var_number
예제 #2
0
 def additive_expr(self, operator, type1, type2):
     self.code_maker.command_comment('additive_expr %s %s %s' %
                                     (type1, operator, type2))
     if operator == '+':
         if type1 == type2 == ELEMENT:
             self.code_maker.command_iadd()
             return ELEMENT
         elif type1 == type2 == LIST:
             self.code_maker.list.concat()
             return LIST
         elif type1 == ELEMENT and type2 == LIST:
             self.code_maker.command_dup()
             self.code_maker.command_store(INTEGER_LIST_JTYPE, 0)
             self.code_maker.command_swap()
             self.code_maker.list.addFirst()
             self.code_maker.command_load(INTEGER_LIST_JTYPE, 0)
             return LIST
         elif type1 == LIST and type2 == ELEMENT:
             self.code_maker.command_swap()
             self.code_maker.command_dup()
             self.code_maker.command_store(INTEGER_LIST_JTYPE, 0)
             self.code_maker.command_swap()
             self.code_maker.list.addLast()
             self.code_maker.command_load(INTEGER_LIST_JTYPE, 0)
             return LIST
     elif operator == '-':
         if type1 == type2 == ELEMENT:
             self.code_maker.command_isub()
             return ELEMENT
         else:
             raise error_processor.UnsupportedOperation(
                 self.get_rule_position(),
                 'Additive expression (%s %s %s) is unsupported.' %
                 (type1, operator, type2))
예제 #3
0
    def relational_expr(self, operator, type1, type2):
        self.code_maker.command_comment('relational_expr %s %s %s' %
                                        (type1, operator, type2))
        if type1 == LIST or type2 == LIST:
            raise error_processor.UnsupportedOperation(
                self.get_rule_position(),
                'Relational operation (%s) for lists is unsupported.' %
                operator)

        rel_true_label = self.code_maker.make_label(self.scope.scope_number,
                                                    'REL_TRUE')
        rel_end_label = self.code_maker.make_label(self.scope.scope_number,
                                                   'REL_END')

        if operator == '<': self.code_maker.command_if_icmplt(rel_true_label)
        elif operator == '<=':
            self.code_maker.command_if_icmple(rel_true_label)
        elif operator == '>':
            self.code_maker.command_if_icmpgt(rel_true_label)
        elif operator == '>=':
            self.code_maker.command_if_icmpge(rel_true_label)

        self.code_maker.command_ldc(0)
        self.code_maker.command_goto(rel_end_label)
        self.code_maker.command_label(rel_true_label)
        self.code_maker.command_ldc(1)
        self.code_maker.command_label(rel_end_label)

        self.code_maker.stack_size -= 1

        return ELEMENT
예제 #4
0
 def post_decr_expr(self, value_type):
     self.code_maker.command_comment('post_decr_expr %s--' % value_type)
     if value_type == LIST:
         self.code_maker.command_dup()
         self.code_maker.list.removeLast()
         return LIST
     raise error_processor.UnsupportedOperation(
         self.get_rule_position(),
         'Postfix decrement operation for type "%s" is unsupported.' %
         (value_type))
예제 #5
0
    def list_maker_arg(self, arg_type):
        """ Calls for every arg """
        self.code_maker.command_comment('list_maker_arg')

        if arg_type != ELEMENT:
            raise error_processor.UnsupportedOperation(
                self.get_rule_position(),
                'Making list of lists is unsupported.')

        self.code_maker.list.addLast()
        self.code_maker.command_dup()
예제 #6
0
 def pre_incr_expr(self, value_type):
     self.code_maker.command_comment('pre_incr_expr ++%s' % value_type)
     if value_type == LIST:
         self.code_maker.command_dup()
         self.code_maker.command_ldc(0)
         self.code_maker.list.addFirst()
         return LIST
     else:
         raise error_processor.UnsupportedOperation(
             self.get_rule_position(),
             'Prefix increment operation for type "%s" is unsupported.' %
             (value_type))
예제 #7
0
    def slice_expr(self, list_type, value_type1, value_type2):
        if list_type == LIST:
            self.code_maker.command_comment('slice_expr [%s:%s]' %
                                            (value_type1, value_type2))
            if value_type1 == ELEMENT and not value_type2:
                self.code_maker.list.get()
                return ELEMENT
            elif value_type1 == ELEMENT and value_type2 == ELEMENT:
                self.code_maker.list.slice()
                return LIST

        raise error_processor.UnsupportedOperation(
            self.get_rule_position(),
            'Slice expression %s[%s:%s] is unsupported.' %
            (list_type, value_type1, value_type2))
예제 #8
0
    def for_operation_begin(self, iter_id, value_type):  # stack: 1
        if value_type != LIST:
            raise error_processor.UnsupportedOperation(
                self.get_rule_position(),
                '"for" operation with "in" type %s is unsupported' %
                value_type)

        for_begin_label = self.code_maker.make_label(self.scope.scope_number,
                                                     'FOR_BEGIN')
        for_end_label = self.code_maker.make_label(self.scope.scope_number,
                                                   'FOR_END')

        self.code_maker.command_comment('for_operation_begin')

        self.code_maker.command_ldc(0)  # iterator
        # stack: 2 (list, iter)
        self.code_maker.command_label(for_begin_label)
        self.code_maker.command_store(INTEGER_JTYPE,
                                      TEMPORARY_STORE_VAR_1)  # save iterator
        self.code_maker.command_dup()  # duplicate list
        self.code_maker.list.len()
        self.code_maker.command_load(INTEGER_JTYPE, TEMPORARY_STORE_VAR_1)
        # stack: 3 (list, list_len, iter)
        self.code_maker.command_if_icmple(for_end_label)
        # stack: 1 (list)
        self.code_maker.command_dup()  # duplicate list
        self.code_maker.command_load(INTEGER_JTYPE, TEMPORARY_STORE_VAR_1)
        self.code_maker.list.get()
        # stack: 2 (list, element)
        self.code_maker.command_load(INTEGER_JTYPE, TEMPORARY_STORE_VAR_1)
        self.code_maker.command_swap()
        # stack: 3 (list, iter, element)
        self.assignment_expr(iter_id, ELEMENT)
        # stack: 2 (list, iter)

        cleaner = jcodemaker.StackCleaner(self.code_maker)
        self.for_stack.append([for_begin_label, for_end_label, cleaner])
예제 #9
0
    def multiplicative_expr(self, operator, type1, type2):
        self.code_maker.command_comment('multiplicative_expr %s %s %s' %
                                        (type1, operator, type2))
        if operator == '*':
            if type1 == type2 == ELEMENT:
                self.code_maker.command_imul()
                return ELEMENT
            elif type1 == LIST and type2 == ELEMENT:
                self.code_maker.list.multiply()
                return LIST

        elif operator == '/':
            if type1 == type2 == ELEMENT:
                self.code_maker.command_idiv()
                return ELEMENT
            elif type1 == LIST and type2 == ELEMENT:
                self.code_maker.list.removeEvery()
                return LIST

        elif operator == '%':
            if type1 == type2 == ELEMENT:
                self.code_maker.command_irem()
                return ELEMENT
            elif type1 == LIST and type2 == ELEMENT:
                self.code_maker.command_swap()
                self.code_maker.command_dup()
                self.code_maker.command_store(INTEGER_LIST_JTYPE, 0)
                self.code_maker.command_swap()
                self.code_maker.list.delete()
                self.code_maker.command_load(INTEGER_LIST_JTYPE, 0)
                return LIST

        raise error_processor.UnsupportedOperation(
            self.get_rule_position(),
            'Multiplicative expression (%s %s %s) is unsupported.' %
            (type1, operator, type2))