1.1 --- a/docs/concepts.txt Tue Jun 02 20:17:59 2009 +0200
1.2 +++ b/docs/concepts.txt Wed Jun 03 00:48:57 2009 +0200
1.3 @@ -67,21 +67,47 @@
1.4
1.5 See invocation.txt for details.
1.6
1.7 +Context Value Types
1.8 +-------------------
1.9 +
1.10 +The following types of context value exist:
1.11 +
1.12 + Type Usage Transformations
1.13 + ---- ----- ---------------
1.14 +
1.15 + Replaceable With functions (not methods) May be replaced with an
1.16 + instance or a class when a
1.17 + value is stored on an
1.18 + instance or class
1.19 +
1.20 + Placeholder With classes May not be replaced
1.21 +
1.22 + Instance With instances (and constants) May not be replaced
1.23 + or functions as methods
1.24 +
1.25 + Class With functions as methods May be replaced when a
1.26 + value is loaded from a
1.27 + class attribute via an
1.28 + instance
1.29 +
1.30 Contexts in Acquired Values
1.31 ---------------------------
1.32
1.33 -There are three classes of instructions which provide values:
1.34 +There are four classes of instructions which provide values:
1.35
1.36 Instruction Purpose Context Operations
1.37 ----------- ------- ------------------
1.38
1.39 -1) LoadConst Load class, module, Use loaded object with itself
1.40 - constant as context
1.41 +1) LoadConst Load module, constant Use loaded object with itself
1.42 + as context
1.43
1.44 -2) LoadFunction Load function Combine null context with
1.45 - loaded object
1.46 +2) LoadFunction Load function Combine replaceable context
1.47 + with loaded object
1.48
1.49 -3) LoadAddress* Load attribute from Preserve or override stored
1.50 +3) LoadClass Load class Combine placeholder context
1.51 + with loaded object
1.52 +
1.53 +4) LoadAddress* Load attribute from Preserve or override stored
1.54 LoadAttr* class, module, context (as described in
1.55 instance assignment.txt)
1.56
1.57 @@ -118,9 +144,9 @@
1.58 assignments to classes
1.59
1.60 2) StoreAddressContext Store attribute in a Override context if appropriate;
1.61 - known object if the value has a null context,
1.62 - permit the target to take
1.63 - ownership of the value
1.64 + known object if the value has a replaceable
1.65 + context, permit the target to
1.66 + take ownership of the value
1.67
1.68 See assignment.txt for details.
1.69
2.1 --- a/micropython/ast.py Tue Jun 02 20:17:59 2009 +0200
2.2 +++ b/micropython/ast.py Wed Jun 03 00:48:57 2009 +0200
2.3 @@ -552,7 +552,7 @@
2.4
2.5 # Store the name.
2.6
2.7 - self.new_op(LoadConst(node.unit))
2.8 + self.new_op(LoadClass(node.unit))
2.9 self.record_value()
2.10 self._visitName(node, self.name_store_instructions)
2.11 self.set_source()
3.1 --- a/micropython/data.py Tue Jun 02 20:17:59 2009 +0200
3.2 +++ b/micropython/data.py Wed Jun 03 00:48:57 2009 +0200
3.3 @@ -44,7 +44,7 @@
3.4 where each such object is defined.
3.5 """
3.6
3.7 -from micropython.program import DataObject
3.8 +from micropython.program import DataObject, ReplaceableContext, PlaceholderContext
3.9
3.10 def shortrepr(obj):
3.11 if obj is None:
3.12 @@ -184,17 +184,34 @@
3.13 attr = self.namespace[name]
3.14
3.15 # Handle attribute assignment as well as assignment of basic objects.
3.16 + # Attempt to fix the context if not explicitly defined.
3.17
3.18 if isinstance(attr_or_value, Attr):
3.19 + context_values = self.get_updated_context_values(attr_or_value.context_values)
3.20 + else:
3.21 + context_values = self.get_updated_context_values([self.get_context_and_value(attr_or_value)])
3.22
3.23 - # Attempt to fix the context if not explicitly defined.
3.24 + attr.update(context_values, single_assignment)
3.25 +
3.26 + def get_context_and_value(self, value):
3.27 +
3.28 + "Return a context, value tuple for the given 'value'."
3.29 +
3.30 + # Functions have a replaceable context.
3.31
3.32 - context_values = self.get_updated_context_values(attr_or_value.context_values)
3.33 + if isinstance(value, Function):
3.34 + return (ReplaceableContext, value)
3.35 +
3.36 + # Classes use placeholder contexts which cannot be replaced but which
3.37 + # do not communicate useful contextual information.
3.38 +
3.39 + elif isinstance(value, Class):
3.40 + return (PlaceholderContext, value)
3.41 +
3.42 + # Other values employ themselves as the context.
3.43
3.44 else:
3.45 - context_values = self.get_updated_context_values([(None, attr_or_value)])
3.46 -
3.47 - attr.update(context_values, single_assignment)
3.48 + return (value, value)
3.49
3.50 def get_updated_context_values(self, context_values):
3.51
3.52 @@ -293,10 +310,16 @@
3.53 return [v for (c, v) in self.context_values]
3.54
3.55 def get_context(self):
3.56 - return len(self.context_values) == 1 and self.get_contexts()[0] or None
3.57 + if len(self.context_values) == 1:
3.58 + return self.get_contexts()[0]
3.59 + else:
3.60 + return None
3.61
3.62 def get_value(self):
3.63 - return len(self.context_values) == 1 and self.get_values()[0] or None
3.64 + if len(self.context_values) == 1:
3.65 + return self.get_values()[0]
3.66 + else:
3.67 + return None
3.68
3.69 def update(self, context_values, single_assignment):
3.70
3.71 @@ -623,7 +646,7 @@
3.72
3.73 # Change the ownership of functions.
3.74
3.75 - if context is None and value is not None and isinstance(value, Function):
3.76 + if context is ReplaceableContext and value is not None and isinstance(value, Function):
3.77 results.add((self, value))
3.78 else:
3.79 results.add((context, value))
3.80 @@ -999,7 +1022,7 @@
3.81
3.82 def store_default(self, value):
3.83 attr = Attr(None, self, None)
3.84 - attr.update([(None, value)], 1)
3.85 + attr.update([self.get_context_and_value(value)], 1)
3.86 self.default_attrs.append(attr)
3.87
3.88 def make_global(self, name):
4.1 --- a/micropython/opt.py Tue Jun 02 20:17:59 2009 +0200
4.2 +++ b/micropython/opt.py Wed Jun 03 00:48:57 2009 +0200
4.3 @@ -153,7 +153,7 @@
4.4 "Return whether 'instruction' provides a constant input."
4.5
4.6 return isinstance(instruction, LoadAddress) and instruction.attr.assignments == 1 or \
4.7 - isinstance(instruction, (LoadConst, LoadFunction))
4.8 + isinstance(instruction, (LoadConst, LoadClass, LoadFunction))
4.9
4.10 def is_constant_target(self, instruction):
4.11
4.12 @@ -173,7 +173,7 @@
4.13 a load operation from a CPU register or special memory location.
4.14 """
4.15
4.16 - return isinstance(instruction, (LoadConst, LoadFunction, LoadName, LoadTemp, LoadResult, LoadException, LoadAddress))
4.17 + return isinstance(instruction, (LoadConst, LoadClass, LoadFunction, LoadName, LoadTemp, LoadResult, LoadException, LoadAddress))
4.18
4.19 def is_simple_input_user(self, instruction):
4.20
4.21 @@ -275,7 +275,7 @@
4.22 # LoadResult cannot be relied upon in general since the result register
4.23 # could be updated since first being referenced.
4.24
4.25 - return isinstance(self.active_value, (LoadName, LoadTemp, LoadAddress, LoadConst, LoadFunction)) or \
4.26 + return isinstance(self.active_value, (LoadName, LoadTemp, LoadAddress, LoadConst, LoadClass, LoadFunction)) or \
4.27 isinstance(self.active_value, LoadResult) and self.active_value is self.active or \
4.28 isinstance(self.active_value, LoadException) and self.active_value is self.active
4.29
5.1 --- a/micropython/program.py Tue Jun 02 20:17:59 2009 +0200
5.2 +++ b/micropython/program.py Wed Jun 03 00:48:57 2009 +0200
5.3 @@ -44,4 +44,32 @@
5.4 (self.classcode, self.attrcode, self.codeaddr, self.funccode, self.size), self.name
5.5 )
5.6
5.7 +class Context:
5.8 +
5.9 + """
5.10 + A representation of a context used in a program, providing the special
5.11 + context value types.
5.12 + """
5.13 +
5.14 + def __init__(self, truth_value, repr):
5.15 + self.truth_value = truth_value
5.16 + self.repr = repr
5.17 +
5.18 + def __repr__(self):
5.19 + return self.repr
5.20 +
5.21 + def __nonzero__(self):
5.22 + return self.truth_value
5.23 +
5.24 +# A representation of a context that is replaced upon certain assignment
5.25 +# operations.
5.26 +
5.27 +ReplaceableContext = Context(0, "Replace")
5.28 +
5.29 +# A representation of a context that is employed by classes so that
5.30 +# instantiators have enough slots in the invocation frame, yet does not cause
5.31 +# testing of the context or adjustment of the frame.
5.32 +
5.33 +PlaceholderContext = Context(0, "Placeholder")
5.34 +
5.35 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/micropython/rsvp.py Tue Jun 02 20:17:59 2009 +0200
6.2 +++ b/micropython/rsvp.py Wed Jun 03 00:48:57 2009 +0200
6.3 @@ -154,7 +154,8 @@
6.4
6.5 # Access to stored constant data.
6.6
6.7 -class LoadConst(Address): "Load the constant, class, module from the specified location."
6.8 +class LoadConst(Address): "Load the constant or module from the specified location."
6.9 +class LoadClass(Address): "Load the class from the specified location."
6.10 class LoadFunction(Address): "Load the function from the specified location."
6.11
6.12 # Access within an invocation frame.
6.13 @@ -245,7 +246,7 @@
6.14 # Instructions which affect the current value. (LoadAttrIndexContext not defined.)
6.15
6.16 current_value_instructions = (
6.17 - LoadConst, LoadFunction, LoadName, LoadTemp,
6.18 + LoadConst, LoadClass, LoadFunction, LoadName, LoadTemp,
6.19 LoadAddress, LoadAddressContext, LoadAddressContextCond,
6.20 LoadAttr, LoadAttrIndex, LoadAttrIndexContextCond,
6.21 LoadCallable, LoadContext, LoadResult,
7.1 --- a/micropython/trans.py Tue Jun 02 20:17:59 2009 +0200
7.2 +++ b/micropython/trans.py Wed Jun 03 00:48:57 2009 +0200
7.3 @@ -826,19 +826,16 @@
7.4
7.5 if target is None:
7.6
7.7 - # Skip adjustment and tests if a class is being invoked.
7.8 -
7.9 - self.new_op(temp_target)
7.10 - self.new_op(CheckClass())
7.11 - self.new_op(JumpIfTrue(continue_block))
7.12 -
7.13 - # Adjust the frame is no usable context is provided.
7.14 + # Adjust the frame if a replaceable context is provided.
7.15
7.16 self.new_op(temp_context)
7.17 self.new_op(CheckContext())
7.18 self.new_op(JumpIfFalse(adjust_block))
7.19
7.20 # Skip adjustment and tests if the context is not a class.
7.21 + # Classes themselves employ a placeholder context so that
7.22 + # instantiators can be callable with a context which will be
7.23 + # overwritten in the frame.
7.24
7.25 self.new_op(temp_context)
7.26 self.new_op(CheckClass())
8.1 --- a/rsvp.py Tue Jun 02 20:17:59 2009 +0200
8.2 +++ b/rsvp.py Wed Jun 03 00:48:57 2009 +0200
8.3 @@ -52,6 +52,7 @@
8.4 current callable
8.5 """
8.6
8.7 +from micropython.program import ReplaceableContext, PlaceholderContext
8.8 import operator
8.9
8.10 class IllegalInstruction(Exception):
8.11 @@ -386,8 +387,11 @@
8.12 def LoadConst(self):
8.13 self.value = self.operand, self.operand
8.14
8.15 + def LoadClass(self):
8.16 + self.value = PlaceholderContext, self.operand
8.17 +
8.18 def LoadFunction(self):
8.19 - self.value = None, self.operand
8.20 + self.value = ReplaceableContext, self.operand
8.21
8.22 def LoadName(self):
8.23 frame = self.local_sp_stack[-1]
8.24 @@ -425,7 +429,7 @@
8.25 # Overwrite context if null.
8.26 context_context, context_ref = self.value
8.27 source_context, source_ref = self.source
8.28 - if source_context is None:
8.29 + if source_context is ReplaceableContext:
8.30 context = context_ref
8.31 else:
8.32 context = source_context
8.33 @@ -546,10 +550,14 @@
8.34 self.value = context, context
8.35
8.36 def CheckContext(self):
8.37 - self.status = self.value[1] is not None
8.38 + self.status = self.value[1] is not ReplaceableContext
8.39
8.40 def CheckClass(self):
8.41 context, ref = self.value
8.42 + if ref in (ReplaceableContext, PlaceholderContext):
8.43 + self.status = 0
8.44 + return
8.45 +
8.46 data = self.load(ref)
8.47
8.48 # Classes are not themselves usable as the self argument.
8.49 @@ -721,7 +729,7 @@
8.50 def _LoadAddressContextCond(self, context, ref, inst_ref):
8.51 # Check the instance context against the target's context.
8.52 # This provides the context overriding for methods.
8.53 - if context is not None and self._CheckInstance(inst_ref, context):
8.54 + if context is not ReplaceableContext and self._CheckInstance(inst_ref, context):
8.55 # Replace the context with the instance.
8.56 return inst_ref, ref
8.57 else: