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
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))
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
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))
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()
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))
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))
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])
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))