# HG changeset patch # User Paul Boddie # Date 1254263081 -7200 # Node ID 49e650e830301095092d28176047bea9127e2107 # Parent 25c1660165dbf171b3a187204951a0af4ff2d0f8 Moved the native function library into a separate module. Added notes about narrowing type candidates when predicting accesses to attributes. diff -r 25c1660165db -r 49e650e83030 README.txt --- a/README.txt Fri Sep 25 00:35:17 2009 +0200 +++ b/README.txt Wed Sep 30 00:24:41 2009 +0200 @@ -205,3 +205,23 @@ could be costly. Another less ambitious solution might only involve the optimisation of such internal method calls if an unambiguous target can be resolved. + +Narrowing Type Candidates using Attribute Names +----------------------------------------------- + +Within functions, it might be useful to record attribute accesses on local +names and to collect the names in order to help resolve targets in the +generated code. For example: + + def f(x, y): + x.method(y) + if x.something: + ... + return x.attr + +Here, the object referenced via x should have "method", "something" and "attr" +as attributes. We could impose a test for a type providing these attributes at +the earliest opportunity and then specialise the attribute accesses, perhaps +also invocations, in the generated code. AttributeError occurrences would need +to be considered, however, potentially disqualifying certain attributes from +any optimisations, and control flow would also need to be considered. diff -r 25c1660165db -r 49e650e83030 rsvp.py --- a/rsvp.py Fri Sep 25 00:35:17 2009 +0200 +++ b/rsvp.py Wed Sep 30 00:24:41 2009 +0200 @@ -53,7 +53,7 @@ """ from micropython.program import ReplaceableContext, PlaceholderContext, FragmentObject -import operator +from rsvplib import Library class IllegalInstruction(Exception): pass @@ -791,446 +791,6 @@ else: return context, ref -class Library: - - "Native function implementations." - - def __init__(self, machine, true_constant, false_constant): - - """ - Initialise the library with the 'machine' and the addresses - 'true_constant' and 'false_constant'. - """ - - self.machine = machine - self.true_constant = true_constant - self.false_constant = false_constant - - # Native class constants. - - cls = self.machine._get_class("__builtins__", "int") - self.int_class = cls.location - self.int_instance = cls.instance_template_location - cls = self.machine._get_class("__builtins__", "list") - self.list_class = cls.location - self.list_instance = cls.instance_template_location - cls = self.machine._get_class("__builtins__", "IndexError") - self.index_error = cls.location - self.index_error_instance = cls.instance_template_location - - self.tuple_class = self.machine.tuple_class - self.type_error_instance = self.machine.type_error_instance - - self.frame_stack = self.machine.frame_stack - self.local_sp_stack = self.machine.local_sp_stack - - def builtins_int_arithmetic_op(self, op): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - right_context, right = self.frame_stack[frame + 1] - - # Test operand suitability. - # NOTE: Support other types. - - if not (self.machine._CheckInstance(left, self.int_class) and self.machine._CheckInstance(right, self.int_class)): - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) - return self.machine.RaiseException() - - # NOTE: Assume single location for data. - - left_data = left + 1 - right_data = right + 1 - - # Make a new object. - - addr = self.machine._MakeObject(2, self.int_instance) - - # Store the result. - # NOTE: The data is considered ready to use. - - self.machine.save(addr + 1, op(self.machine.load(left_data), self.machine.load(right_data))) - - # Return the new object. - # Introduce object as context for the new object. - - self.machine.result = addr, addr - - def builtins_int_bool(self): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - - # Test operand suitability. - - if not self.machine._CheckInstance(left, self.int_class): - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) - return self.machine.RaiseException() - - # NOTE: Assume single location for data. - - left_data = left + 1 - - # Test the data. - # NOTE: The data is considered ready to use. - - if self.machine.load(left_data) != 0: - self.machine.result = self.true_constant, self.true_constant - else: - self.machine.result = self.false_constant, self.false_constant - - def builtins_int_neg(self): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - - # Test operand suitability. - - if not self.machine._CheckInstance(left, self.int_class): - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) - return self.machine.RaiseException() - - # NOTE: Assume single location for data. - - left_data = left + 1 - - # Make a new object. - - addr = self.machine._MakeObject(2, self.int_instance) - - # Store the result. - # NOTE: The data is considered ready to use. - - self.machine.save(addr + 1, -self.machine.load(left_data)) - - # Return the new object. - # Introduce object as context for the new object. - - self.machine.result = addr, addr - - def builtins_int_op(self, op, true_if_incompatible): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - right_context, right = self.frame_stack[frame + 1] - - # Test operand suitability. - # NOTE: Support other types. - # NOTE: Handle comparisons of incompatible types more appropriately. - - if not (self.machine._CheckInstance(left, self.int_class) and self.machine._CheckInstance(right, self.int_class)): - if true_if_incompatible: - self.machine.result = self.true_constant, self.true_constant - else: - self.machine.result = self.false_constant, self.false_constant - return - - # NOTE: Assume single location for data. - - left_data = left + 1 - right_data = right + 1 - - # Test the data. - # NOTE: The data is considered ready to use. - - if op(self.machine.load(left_data), self.machine.load(right_data)): - self.machine.result = self.true_constant, self.true_constant - else: - self.machine.result = self.false_constant, self.false_constant - - def builtins_int_add(self): - return self.builtins_int_arithmetic_op(operator.add) - - def builtins_int_sub(self): - return self.builtins_int_arithmetic_op(operator.sub) - - def builtins_int_lt(self): - return self.builtins_int_op(operator.lt, 0) - - def builtins_int_le(self): - return self.builtins_int_op(operator.le, 0) - - def builtins_int_gt(self): - return self.builtins_int_op(operator.gt, 0) - - def builtins_int_ge(self): - return self.builtins_int_op(operator.ge, 0) - - def builtins_int_eq(self): - return self.builtins_int_op(operator.eq, 0) - - def builtins_int_ne(self): - return self.builtins_int_op(operator.ne, 1) - - def builtins_int_and(self): - return self.builtins_int_arithmetic_op(operator.and_) - - def builtins_int_or(self): - return self.builtins_int_arithmetic_op(operator.or_) - - def builtins_bool_bool(self): - frame = self.local_sp_stack[-1] - - # Get operands addresses. - - left_context, left = self.frame_stack[frame] - self.machine.result = left, left - - def builtins_list_new(self): - frame = self.local_sp_stack[-1] - - # The first parameter should be empty. - # NOTE: Specific copying of tuples/lists. - - args_context, args = self.frame_stack[frame + 1] - - # Test operand suitability. - - if self.machine._CheckInstance(args, self.list_class): - _x, sequence = self.machine.load(args + 1) - header = self.machine.load(sequence) - size = header.occupied_size - elif self.machine._CheckInstance(args, self.tuple_class): - sequence = args - header = self.machine.load(sequence) - size = header.size - else: - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) - return self.machine.RaiseException() - - # Copy the sequence contents. - - new_fragment = self.machine._MakeFragment(size) - for i in range(1, size): - self.machine.save(new_fragment + i, self.machine.load(sequence + i)) - - # Make the list instance. - - addr = self.machine._MakeObject(2, self.list_instance) - self.machine.save(addr + 1, (None, new_fragment)) - - self.machine.result = addr, addr - - def builtins_list_getitem(self): - frame = self.local_sp_stack[-1] - - # Get the operand address. - - item_context, item = self.frame_stack[frame + 1] - - # Get the list address. - - obj_context, obj = self.frame_stack[frame] - - # Get the fragment address. - # NOTE: Assume single location for header. - - _x, fragment = self.machine.load(obj + 1) - - # Get the fragment header. - - header = self.machine.load(fragment) - nelements = header.occupied_size - 1 - - # NOTE: Assume single location for data and header. - - item_pos = self.machine.load(item + 1) - - if item_pos >= 0 and item_pos < nelements: - pass - elif item_pos < 0 and item_pos >= -nelements: - item_pos = nelements + item_pos - else: - self.machine.exception = self.machine._MakeObject(2, self.index_error_instance) - return self.machine.RaiseException() - - # NOTE: Assume single location for header. - - self.machine.result = self.machine.load(fragment + 1 + item_pos) - - def builtins_list_len(self): - frame = self.local_sp_stack[-1] - - # Get the list address. - - obj_context, obj = self.frame_stack[frame] - - # Get the fragment address. - # NOTE: Assume single location for header. - - _x, fragment = self.machine.load(obj + 1) - - # Get the fragment header. - - header = self.machine.load(fragment) - nelements = header.occupied_size - 1 - - # Make a new object. - - addr = self.machine._MakeObject(2, self.int_instance) - - # Store the result. - # NOTE: The data is considered ready to use. - - self.machine.save(addr + 1, nelements) - - # Return the new object. - # Introduce object as context for the new object. - - self.machine.result = addr, addr - - def builtins_list_append(self): - frame = self.local_sp_stack[-1] - - # Get operand address. - - arg_context, arg = self.frame_stack[frame + 1] - - # Get the list address. - - obj_context, obj = self.frame_stack[frame] - - # Get the fragment address. - # NOTE: Assume single location for header. - - _x, fragment = self.machine.load(obj + 1) - - # Get the fragment header. - - header = self.machine.load(fragment) - - # Attempt to add the reference. - - if header.occupied_size < header.allocated_size: - self.machine.save(fragment + header.occupied_size, (arg_context, arg)) - header.occupied_size += 1 - else: - - # Make a new fragment, maintaining more space than currently - # occupied in order to avoid reallocation. - - new_fragment = self.machine._MakeFragment(header.allocated_size + 1) - - # Copy existing elements. - - for i in range(1, header.allocated_size): - self.machine.save(new_fragment + i, self.machine.load(fragment + i)) - - self.machine.save(new_fragment + header.allocated_size, (arg_context, arg)) - - # Set the new fragment in the object. - # NOTE: The old fragment could be deallocated. - - self.machine.save(obj + 1, (None, new_fragment)) - - def builtins_tuple_len(self): - frame = self.local_sp_stack[-1] - - # Get the tuple address. - - obj_context, obj = self.frame_stack[frame] - - # Get the header. - # NOTE: Assume single location for header. - - header = self.machine.load(obj) - nelements = header.size - 1 - - # Make a new object. - - addr = self.machine._MakeObject(2, self.int_instance) - - # Store the result. - # NOTE: The data is considered ready to use. - - self.machine.save(addr + 1, nelements) - - # Return the new object. - # Introduce object as context for the new object. - - self.machine.result = addr, addr - - def builtins_tuple_getitem(self): - frame = self.local_sp_stack[-1] - - # Get the operand address. - - item_context, item = self.frame_stack[frame + 1] - - # Get the tuple address. - - obj_context, obj = self.frame_stack[frame] - - # Get the header. - # NOTE: Assume single location for header. - - header = self.machine.load(obj) - nelements = header.size - 1 - - # NOTE: Assume single location for data and header. - - item_pos = self.machine.load(item + 1) - - if item_pos >= 0 and item_pos < nelements: - pass - elif item_pos < 0 and item_pos >= -nelements: - item_pos = nelements + item_pos - else: - self.machine.exception = self.machine._MakeObject(2, self.index_error_instance) - return self.machine.RaiseException() - - # NOTE: Assume single location for header. - - self.machine.result = self.machine.load(obj + 1 + item_pos) - - def builtins_object_init(self): - pass - - native_functions = { - - # Native method implementations: - - "__builtins__.int.__add__" : builtins_int_add, - "__builtins__.int.__radd__" : builtins_int_add, # NOTE: To be made distinct. - "__builtins__.int.__sub__" : builtins_int_sub, - "__builtins__.int.__iadd__" : builtins_int_add, - "__builtins__.int.__bool__" : builtins_int_bool, - "__builtins__.int.__neg__" : builtins_int_neg, - "__builtins__.int.__lt__" : builtins_int_lt, - "__builtins__.int.__le__" : builtins_int_le, - "__builtins__.int.__gt__" : builtins_int_gt, - "__builtins__.int.__ge__" : builtins_int_ge, - "__builtins__.int.__eq__" : builtins_int_eq, - "__builtins__.int.__ne__" : builtins_int_ne, - "__builtins__.int.__and__" : builtins_int_and, - "__builtins__.int.__rand__" : builtins_int_and, - "__builtins__.int.__or__" : builtins_int_or, - "__builtins__.int.__ror__" : builtins_int_or, - "__builtins__.bool.__bool__" : builtins_bool_bool, - "__builtins__.list.__getitem__" : builtins_list_getitem, - "__builtins__.list.__len__" : builtins_list_len, - "__builtins__.list.append" : builtins_list_append, - "__builtins__.tuple.__len__" : builtins_tuple_len, - "__builtins__.tuple.__getitem__" : builtins_tuple_getitem, - - # Native initialisers: - - "__builtins__.object.__init__" : builtins_object_init, # NOTE: A no-operation. - "__builtins__.BaseException.__init__" : builtins_object_init, # NOTE: To be made distinct, potentially in the builtins module. - - # Native instantiators: - - "__builtins__.list" : builtins_list_new, - } - # Convenience functions. def machine(program, with_builtins=0, debug=0, abort_upon_exception=0): diff -r 25c1660165db -r 49e650e83030 rsvplib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rsvplib.py Wed Sep 30 00:24:41 2009 +0200 @@ -0,0 +1,464 @@ +#!/usr/bin/env python + +""" +A native function library for a really simple virtual processor. + +Copyright (C) 2007, 2008, 2009 Paul Boddie + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +import operator + +class Library: + + "Native function implementations." + + def __init__(self, machine, true_constant, false_constant): + + """ + Initialise the library with the 'machine' and the addresses + 'true_constant' and 'false_constant'. + """ + + self.machine = machine + self.true_constant = true_constant + self.false_constant = false_constant + + # Native class constants. + + cls = self.machine._get_class("__builtins__", "int") + self.int_class = cls.location + self.int_instance = cls.instance_template_location + cls = self.machine._get_class("__builtins__", "list") + self.list_class = cls.location + self.list_instance = cls.instance_template_location + cls = self.machine._get_class("__builtins__", "IndexError") + self.index_error = cls.location + self.index_error_instance = cls.instance_template_location + + self.tuple_class = self.machine.tuple_class + self.type_error_instance = self.machine.type_error_instance + + self.frame_stack = self.machine.frame_stack + self.local_sp_stack = self.machine.local_sp_stack + + def builtins_int_arithmetic_op(self, op): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + right_context, right = self.frame_stack[frame + 1] + + # Test operand suitability. + # NOTE: Support other types. + + if not (self.machine._CheckInstance(left, self.int_class) and self.machine._CheckInstance(right, self.int_class)): + self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) + return self.machine.RaiseException() + + # NOTE: Assume single location for data. + + left_data = left + 1 + right_data = right + 1 + + # Make a new object. + + addr = self.machine._MakeObject(2, self.int_instance) + + # Store the result. + # NOTE: The data is considered ready to use. + + self.machine.save(addr + 1, op(self.machine.load(left_data), self.machine.load(right_data))) + + # Return the new object. + # Introduce object as context for the new object. + + self.machine.result = addr, addr + + def builtins_int_bool(self): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + + # Test operand suitability. + + if not self.machine._CheckInstance(left, self.int_class): + self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) + return self.machine.RaiseException() + + # NOTE: Assume single location for data. + + left_data = left + 1 + + # Test the data. + # NOTE: The data is considered ready to use. + + if self.machine.load(left_data) != 0: + self.machine.result = self.true_constant, self.true_constant + else: + self.machine.result = self.false_constant, self.false_constant + + def builtins_int_neg(self): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + + # Test operand suitability. + + if not self.machine._CheckInstance(left, self.int_class): + self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) + return self.machine.RaiseException() + + # NOTE: Assume single location for data. + + left_data = left + 1 + + # Make a new object. + + addr = self.machine._MakeObject(2, self.int_instance) + + # Store the result. + # NOTE: The data is considered ready to use. + + self.machine.save(addr + 1, -self.machine.load(left_data)) + + # Return the new object. + # Introduce object as context for the new object. + + self.machine.result = addr, addr + + def builtins_int_op(self, op, true_if_incompatible): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + right_context, right = self.frame_stack[frame + 1] + + # Test operand suitability. + # NOTE: Support other types. + # NOTE: Handle comparisons of incompatible types more appropriately. + + if not (self.machine._CheckInstance(left, self.int_class) and self.machine._CheckInstance(right, self.int_class)): + if true_if_incompatible: + self.machine.result = self.true_constant, self.true_constant + else: + self.machine.result = self.false_constant, self.false_constant + return + + # NOTE: Assume single location for data. + + left_data = left + 1 + right_data = right + 1 + + # Test the data. + # NOTE: The data is considered ready to use. + + if op(self.machine.load(left_data), self.machine.load(right_data)): + self.machine.result = self.true_constant, self.true_constant + else: + self.machine.result = self.false_constant, self.false_constant + + def builtins_int_add(self): + return self.builtins_int_arithmetic_op(operator.add) + + def builtins_int_sub(self): + return self.builtins_int_arithmetic_op(operator.sub) + + def builtins_int_lt(self): + return self.builtins_int_op(operator.lt, 0) + + def builtins_int_le(self): + return self.builtins_int_op(operator.le, 0) + + def builtins_int_gt(self): + return self.builtins_int_op(operator.gt, 0) + + def builtins_int_ge(self): + return self.builtins_int_op(operator.ge, 0) + + def builtins_int_eq(self): + return self.builtins_int_op(operator.eq, 0) + + def builtins_int_ne(self): + return self.builtins_int_op(operator.ne, 1) + + def builtins_int_and(self): + return self.builtins_int_arithmetic_op(operator.and_) + + def builtins_int_or(self): + return self.builtins_int_arithmetic_op(operator.or_) + + def builtins_bool_bool(self): + frame = self.local_sp_stack[-1] + + # Get operands addresses. + + left_context, left = self.frame_stack[frame] + self.machine.result = left, left + + def builtins_list_new(self): + frame = self.local_sp_stack[-1] + + # The first parameter should be empty. + # NOTE: Specific copying of tuples/lists. + + args_context, args = self.frame_stack[frame + 1] + + # Test operand suitability. + + if self.machine._CheckInstance(args, self.list_class): + _x, sequence = self.machine.load(args + 1) + header = self.machine.load(sequence) + size = header.occupied_size + elif self.machine._CheckInstance(args, self.tuple_class): + sequence = args + header = self.machine.load(sequence) + size = header.size + else: + self.machine.exception = self.machine._MakeObject(2, self.type_error_instance) + return self.machine.RaiseException() + + # Copy the sequence contents. + + new_fragment = self.machine._MakeFragment(size) + for i in range(1, size): + self.machine.save(new_fragment + i, self.machine.load(sequence + i)) + + # Make the list instance. + + addr = self.machine._MakeObject(2, self.list_instance) + self.machine.save(addr + 1, (None, new_fragment)) + + self.machine.result = addr, addr + + def builtins_list_getitem(self): + frame = self.local_sp_stack[-1] + + # Get the operand address. + + item_context, item = self.frame_stack[frame + 1] + + # Get the list address. + + obj_context, obj = self.frame_stack[frame] + + # Get the fragment address. + # NOTE: Assume single location for header. + + _x, fragment = self.machine.load(obj + 1) + + # Get the fragment header. + + header = self.machine.load(fragment) + nelements = header.occupied_size - 1 + + # NOTE: Assume single location for data and header. + + item_pos = self.machine.load(item + 1) + + if item_pos >= 0 and item_pos < nelements: + pass + elif item_pos < 0 and item_pos >= -nelements: + item_pos = nelements + item_pos + else: + self.machine.exception = self.machine._MakeObject(2, self.index_error_instance) + return self.machine.RaiseException() + + # NOTE: Assume single location for header. + + self.machine.result = self.machine.load(fragment + 1 + item_pos) + + def builtins_list_len(self): + frame = self.local_sp_stack[-1] + + # Get the list address. + + obj_context, obj = self.frame_stack[frame] + + # Get the fragment address. + # NOTE: Assume single location for header. + + _x, fragment = self.machine.load(obj + 1) + + # Get the fragment header. + + header = self.machine.load(fragment) + nelements = header.occupied_size - 1 + + # Make a new object. + + addr = self.machine._MakeObject(2, self.int_instance) + + # Store the result. + # NOTE: The data is considered ready to use. + + self.machine.save(addr + 1, nelements) + + # Return the new object. + # Introduce object as context for the new object. + + self.machine.result = addr, addr + + def builtins_list_append(self): + frame = self.local_sp_stack[-1] + + # Get operand address. + + arg_context, arg = self.frame_stack[frame + 1] + + # Get the list address. + + obj_context, obj = self.frame_stack[frame] + + # Get the fragment address. + # NOTE: Assume single location for header. + + _x, fragment = self.machine.load(obj + 1) + + # Get the fragment header. + + header = self.machine.load(fragment) + + # Attempt to add the reference. + + if header.occupied_size < header.allocated_size: + self.machine.save(fragment + header.occupied_size, (arg_context, arg)) + header.occupied_size += 1 + else: + + # Make a new fragment, maintaining more space than currently + # occupied in order to avoid reallocation. + + new_fragment = self.machine._MakeFragment(header.allocated_size + 1) + + # Copy existing elements. + + for i in range(1, header.allocated_size): + self.machine.save(new_fragment + i, self.machine.load(fragment + i)) + + self.machine.save(new_fragment + header.allocated_size, (arg_context, arg)) + + # Set the new fragment in the object. + # NOTE: The old fragment could be deallocated. + + self.machine.save(obj + 1, (None, new_fragment)) + + def builtins_tuple_len(self): + frame = self.local_sp_stack[-1] + + # Get the tuple address. + + obj_context, obj = self.frame_stack[frame] + + # Get the header. + # NOTE: Assume single location for header. + + header = self.machine.load(obj) + nelements = header.size - 1 + + # Make a new object. + + addr = self.machine._MakeObject(2, self.int_instance) + + # Store the result. + # NOTE: The data is considered ready to use. + + self.machine.save(addr + 1, nelements) + + # Return the new object. + # Introduce object as context for the new object. + + self.machine.result = addr, addr + + def builtins_tuple_getitem(self): + frame = self.local_sp_stack[-1] + + # Get the operand address. + + item_context, item = self.frame_stack[frame + 1] + + # Get the tuple address. + + obj_context, obj = self.frame_stack[frame] + + # Get the header. + # NOTE: Assume single location for header. + + header = self.machine.load(obj) + nelements = header.size - 1 + + # NOTE: Assume single location for data and header. + + item_pos = self.machine.load(item + 1) + + if item_pos >= 0 and item_pos < nelements: + pass + elif item_pos < 0 and item_pos >= -nelements: + item_pos = nelements + item_pos + else: + self.machine.exception = self.machine._MakeObject(2, self.index_error_instance) + return self.machine.RaiseException() + + # NOTE: Assume single location for header. + + self.machine.result = self.machine.load(obj + 1 + item_pos) + + def builtins_object_init(self): + pass + + native_functions = { + + # Native method implementations: + + "__builtins__.int.__add__" : builtins_int_add, + "__builtins__.int.__radd__" : builtins_int_add, # NOTE: To be made distinct. + "__builtins__.int.__sub__" : builtins_int_sub, + "__builtins__.int.__iadd__" : builtins_int_add, + "__builtins__.int.__bool__" : builtins_int_bool, + "__builtins__.int.__neg__" : builtins_int_neg, + "__builtins__.int.__lt__" : builtins_int_lt, + "__builtins__.int.__le__" : builtins_int_le, + "__builtins__.int.__gt__" : builtins_int_gt, + "__builtins__.int.__ge__" : builtins_int_ge, + "__builtins__.int.__eq__" : builtins_int_eq, + "__builtins__.int.__ne__" : builtins_int_ne, + "__builtins__.int.__and__" : builtins_int_and, + "__builtins__.int.__rand__" : builtins_int_and, + "__builtins__.int.__or__" : builtins_int_or, + "__builtins__.int.__ror__" : builtins_int_or, + "__builtins__.bool.__bool__" : builtins_bool_bool, + "__builtins__.list.__getitem__" : builtins_list_getitem, + "__builtins__.list.__len__" : builtins_list_len, + "__builtins__.list.append" : builtins_list_append, + "__builtins__.tuple.__len__" : builtins_tuple_len, + "__builtins__.tuple.__getitem__" : builtins_tuple_getitem, + + # Native initialisers: + + "__builtins__.object.__init__" : builtins_object_init, # NOTE: A no-operation. + "__builtins__.BaseException.__init__" : builtins_object_init, # NOTE: To be made distinct, potentially in the builtins module. + + # Native instantiators: + + "__builtins__.list" : builtins_list_new, + } + +# vim: tabstop=4 expandtab shiftwidth=4