1.1 --- a/micropython/ast.py Sun May 18 19:59:26 2008 +0200
1.2 +++ b/micropython/ast.py Mon May 19 00:22:00 2008 +0200
1.3 @@ -25,17 +25,6 @@
1.4 import compiler.ast
1.5 from compiler.visitor import ASTVisitor
1.6
1.7 -class Label:
1.8 -
1.9 - "A reference to a location."
1.10 -
1.11 - def __init__(self, number, location=None):
1.12 - self.number = number
1.13 - self.location = location
1.14 -
1.15 - def __repr__(self):
1.16 - return "Label(%r, location=%r)" % (self.number, self.location)
1.17 -
1.18 # Program visitors.
1.19
1.20 class Translation(ASTVisitor):
1.21 @@ -399,7 +388,7 @@
1.22
1.23 # NOTE: Fix context for self-accessed methods.
1.24
1.25 - if context is not None:
1.26 + if context is not None and isinstance(context, Instance):
1.27 ncontext = 1
1.28 else:
1.29 ncontext = 0
1.30 @@ -1015,6 +1004,14 @@
1.31 self._endCallFunc(temp)
1.32
1.33 def visitClass(self, node):
1.34 +
1.35 + # Store the name.
1.36 +
1.37 + self.new_op(LoadConst(node.unit))
1.38 + self._visitName(node, (StoreName, StoreAddress))
1.39 +
1.40 + # Visit the code.
1.41 +
1.42 unit = self.unit
1.43 self.unit = node.unit
1.44 self.unit.code_location = self.module.code_location # class body code is not independently addressable
1.45 @@ -1048,6 +1045,7 @@
1.46
1.47 def visitDiscard(self, node):
1.48 self.dispatch(node.expr)
1.49 + self.new_op(Pop())
1.50
1.51 def visitDiv(self, node):
1.52 self._visitBinary(node, "__div__", "__rdiv__")
2.1 --- a/micropython/common.py Sun May 18 19:59:26 2008 +0200
2.2 +++ b/micropython/common.py Mon May 19 00:22:00 2008 +0200
2.3 @@ -65,6 +65,19 @@
2.4
2.5 pass
2.6
2.7 +# Program code representations.
2.8 +
2.9 +class Label:
2.10 +
2.11 + "A reference to a location."
2.12 +
2.13 + def __init__(self, number, location=None):
2.14 + self.number = number
2.15 + self.location = location
2.16 +
2.17 + def __repr__(self):
2.18 + return "Label(%r, location=%r)" % (self.number, self.location)
2.19 +
2.20 # Inspection representations.
2.21
2.22 class AtLeast:
3.1 --- a/micropython/rsvp.py Sun May 18 19:59:26 2008 +0200
3.2 +++ b/micropython/rsvp.py Mon May 19 00:22:00 2008 +0200
3.3 @@ -19,8 +19,18 @@
3.4 this program. If not, see <http://www.gnu.org/licenses/>.
3.5 """
3.6
3.7 +from micropython.common import Label
3.8 from micropython.data import Attr, Const, Instance
3.9
3.10 +def raw(code):
3.11 + new_code = []
3.12 + for item in code:
3.13 + if isinstance(item, Attr):
3.14 + new_code.append((item.context and item.context.location, item.value and item.value.location))
3.15 + else:
3.16 + new_code.append(item)
3.17 + return new_code
3.18 +
3.19 class Instruction:
3.20
3.21 "A generic instruction."
3.22 @@ -41,7 +51,10 @@
3.23 "An instruction operating on the local value stack."
3.24
3.25 def __repr__(self):
3.26 - return "%s(%r)" % (self.__class__.__name__, self.attr.position)
3.27 + return "%s(%r)" % (self.__class__.__name__, self.get_operand())
3.28 +
3.29 + def get_operand(self):
3.30 + return self.attr.position
3.31
3.32 SR = StackRelativeInstruction
3.33
3.34 @@ -50,10 +63,10 @@
3.35 "An instruction accessing an object's attribute."
3.36
3.37 def __repr__(self):
3.38 - position = self.attr.position
3.39 - location = "instance"
3.40 - result = position
3.41 - return "%s(%r, %r -> %r)" % (self.__class__.__name__, location, position, result)
3.42 + return "%s(%r)" % (self.__class__.__name__, self.get_operand())
3.43 +
3.44 + def get_operand(self):
3.45 + return self.attr.position
3.46
3.47 AR = AddressRelativeInstruction
3.48
3.49 @@ -62,6 +75,13 @@
3.50 "An instruction loading an address directly."
3.51
3.52 def __repr__(self):
3.53 + location, position, result = self.get_operands()
3.54 + if location is not None:
3.55 + return "%s(%r, %r -> %r)" % (self.__class__.__name__, location, position, result)
3.56 + else:
3.57 + return "%s(%r)" % (self.__class__.__name__, result)
3.58 +
3.59 + def get_operands(self):
3.60 if isinstance(self.attr, Attr):
3.61 position = self.attr.position
3.62 location = self.attr.parent.location
3.63 @@ -74,9 +94,14 @@
3.64 location = self.attr.parent.name
3.65 position = self.attr.name
3.66 result = None
3.67 - return "%s(%r, %r -> %r)" % (self.__class__.__name__, location, position, result)
3.68 + return location, position, result
3.69 + elif isinstance(self.attr, Label):
3.70 + return None, None, self.attr.location
3.71 else:
3.72 - return "%s(%r)" % (self.__class__.__name__, self.attr.location)
3.73 + return None, None, self.attr.location
3.74 +
3.75 + def get_operand(self):
3.76 + return self.get_operands()[-1]
3.77
3.78 Address = AddressInstruction
3.79
3.80 @@ -87,6 +112,9 @@
3.81 def __repr__(self):
3.82 return "%s(%r)" % (self.__class__.__name__, self.attr)
3.83
3.84 + def get_operand(self):
3.85 + return self.attr
3.86 +
3.87 Immediate = ImmediateInstruction
3.88
3.89 # Mix-in classes for stack effects.
3.90 @@ -143,16 +171,16 @@
3.91 class MakeFrame(Instruction): "Make a new invocation frame."
3.92 class ReserveFrame(Immediate): "Reserve the given number of entries for the invocation frame."
3.93 class DropFrame(Instruction): "Drop an invocation frame."
3.94 -class StoreFrame(StackRemove, Instruction): "Store an argument at the given frame location."
3.95 +class StoreFrame(StackRemove, Immediate): "Store an argument at the given frame location."
3.96 class StoreFrameIndex(StackRemove, Immediate): "Store an argument for the parameter with the given index."
3.97 class CheckFrame(Instruction): "Check the invocation frame for the target."
3.98 -class JumpWithFrame(Instruction): "Jump, adopting the invocation frame."
3.99 +class JumpWithFrame(Instruction): "Jump, adopting the invocation frame, to the callable found on the stack."
3.100
3.101 # Invocation-related instructions.
3.102
3.103 -class Jump(Instruction): "Jump unconditionally."
3.104 -class JumpIfFalse(Instruction): "Jump if the last evaluation gave a false result."
3.105 -class JumpIfTrue(Instruction): "Jump if the last evaluation gave a true result."
3.106 +class Jump(Address): "Jump unconditionally."
3.107 +class JumpIfFalse(Address): "Jump if the last evaluation gave a false result."
3.108 +class JumpIfTrue(Address): "Jump if the last evaluation gave a true result."
3.109 class LoadCallable(Instruction): "Load the target of an invocation."
3.110 class LoadContext(Instruction): "Load the context of an invocation."
3.111 class CheckContext(Instruction): """Check the context of an invocation against the target,
4.1 --- a/rsvp.py Sun May 18 19:59:26 2008 +0200
4.2 +++ b/rsvp.py Mon May 19 00:22:00 2008 +0200
4.3 @@ -151,23 +151,29 @@
4.4 except IndexError:
4.5 raise EmptyMetadataStack
4.6
4.7 - def execute(self):
4.8 + def run(self):
4.9
4.10 "Execute code in the memory, starting from the current PC address."
4.11
4.12 try:
4.13 while 1:
4.14 - instruction = self.load(self.pc)
4.15 - if self.debug:
4.16 - print "%8d %s" % (self.pc, instruction)
4.17 - method = getattr(self, instruction, None)
4.18 - if method is None:
4.19 - raise IllegalInstruction, self.pc
4.20 - else:
4.21 - method()
4.22 + self.execute()
4.23 except EmptyPCStack:
4.24 pass
4.25
4.26 + def execute(self):
4.27 +
4.28 + "Execute code in the memory at the current PC address."
4.29 +
4.30 + instruction = self.load(self.pc).__class__.__name__
4.31 + if self.debug:
4.32 + print "%8d %s" % (self.pc, instruction)
4.33 + method = getattr(self, instruction, None)
4.34 + if method is None:
4.35 + raise IllegalInstruction, self.pc
4.36 + else:
4.37 + method()
4.38 +
4.39 def jump(self, addr, next):
4.40
4.41 """
4.42 @@ -198,9 +204,9 @@
4.43 self.pc += 1
4.44
4.45 def JumpWithFrame(self):
4.46 - addr = self.load(self.pc + 1)
4.47 + addr = self.pull()
4.48 self.frame_sp += 1 # adopt the added frame
4.49 - self.jump(addr, self.pc + 2)
4.50 + self.jump(addr, self.pc + 1) # return to the instruction after this one
4.51
4.52 def LoadName(self):
4.53
4.54 @@ -210,10 +216,10 @@
4.55 frame, push the retrieved value onto the stack.
4.56 """
4.57
4.58 - n = self.load(self.pc + 1)
4.59 + n = self.load(self.pc).get_operand()
4.60 frame = self.frame_stack[self.frame_sp]
4.61 self.push(self.value_stack[frame + n])
4.62 - self.pc += 2
4.63 + self.pc += 1
4.64
4.65 def StoreName(self):
4.66
4.67 @@ -223,10 +229,10 @@
4.68 position n in the current stack frame.
4.69 """
4.70
4.71 - n = self.load(self.pc + 1)
4.72 + n = self.load(self.pc).get_operand()
4.73 frame = self.frame_stack[self.frame_sp]
4.74 self.value_stack[frame + n] = self.pull()
4.75 - self.pc += 2
4.76 + self.pc += 1
4.77
4.78 LoadTemp = LoadName
4.79 StoreTemp = StoreName
4.80 @@ -242,9 +248,10 @@
4.81 NOTE: This assumes that constants are encoded with context.
4.82 """
4.83
4.84 - addr = self.load(self.pc + 1)
4.85 - self.push(addr)
4.86 - self.pc += 2
4.87 + addr = self.load(self.pc).get_operand()
4.88 + value = (None, addr)
4.89 + self.push(value)
4.90 + self.pc += 1
4.91
4.92 def LoadAttr(self):
4.93
4.94 @@ -255,10 +262,11 @@
4.95 value on the top of the stack with the retrieved value.
4.96 """
4.97
4.98 - n = self.load(self.pc + 1)
4.99 - ref = self.pull()
4.100 - self.push(self.load(ref + n))
4.101 - self.pc += 2
4.102 + n = self.load(self.pc).get_operand()
4.103 + context, ref = self.pull()
4.104 + value = self.load(ref + n)
4.105 + self.push(value)
4.106 + self.pc += 1
4.107
4.108 def StoreAttr(self):
4.109
4.110 @@ -269,39 +277,38 @@
4.111 also removing the next value on the stack.
4.112 """
4.113
4.114 - n = self.load(self.pc + 1)
4.115 + n = self.load(self.pc).get_operand()
4.116 value = self.pull()
4.117 - self.save(self.pull() + n, value)
4.118 - self.pc += 2
4.119 + context, ref = self.pull()
4.120 + self.save(ref + n, value)
4.121 + self.pc += 1
4.122
4.123 def LoadAddress(self):
4.124
4.125 """
4.126 - LoadAddress addr, #n
4.127 - Load from position n in reference at addr: get the contents of position
4.128 - n in the memory referenced by addr, adding the retrieved value to the
4.129 - top of the stack.
4.130 + LoadAddress addr
4.131 + Load from addr: get the contents of the location in memory referenced by
4.132 + addr, adding the retrieved value to the top of the stack.
4.133 """
4.134
4.135 - red = self.load(self.pc + 1)
4.136 - n = self.load(self.pc + 2)
4.137 - self.push(self.load(ref + n))
4.138 - self.pc += 3
4.139 + addr = self.load(self.pc).get_operand()
4.140 + value = self.load(addr)
4.141 + self.push(value)
4.142 + self.pc += 1
4.143
4.144 def StoreAddress(self):
4.145
4.146 """
4.147 - StoreAddress addr, #n
4.148 - Save to position n in reference at addr: pull a value from the stack and
4.149 - save it to position n in the memory referenced by addr, also removing
4.150 - the value on the top of the stack.
4.151 + StoreAddress addr
4.152 + Save to addr: pull a value from the stack and save it to the location in
4.153 + memory referenced by addr, also removing the value on the top of the
4.154 + stack.
4.155 """
4.156
4.157 - ref = self.load(self.pc + 1)
4.158 - n = self.load(self.pc + 2)
4.159 + addr = self.load(self.pc).get_operand()
4.160 value = self.pull()
4.161 - self.save(ref + n, value)
4.162 - self.pc += 3
4.163 + self.save(addr, value)
4.164 + self.pc += 1
4.165
4.166 def Return(self):
4.167
4.168 @@ -321,12 +328,12 @@
4.169 represents a true value, jump to address addr.
4.170 """
4.171
4.172 - addr = self.load(self.pc + 1)
4.173 + addr = self.load(self.pc).get_operand()
4.174 value = self.pull()
4.175 if value:
4.176 self.pc = addr
4.177 else:
4.178 - self.pc += 2
4.179 + self.pc += 1
4.180
4.181 def JumpIfFalse(self):
4.182
4.183 @@ -336,12 +343,12 @@
4.184 represents a false value, jump to address addr.
4.185 """
4.186
4.187 - addr = self.load(self.pc + 1)
4.188 + addr = self.load(self.pc).get_operand()
4.189 value = self.pull()
4.190 if not value:
4.191 self.pc = addr
4.192 else:
4.193 - self.pc += 2
4.194 + self.pc += 1
4.195
4.196 def StoreFrame(self):
4.197
4.198 @@ -352,11 +359,11 @@
4.199 given position.
4.200 """
4.201
4.202 - pos = self.load(self.pc + 1)
4.203 + pos = self.load(self.pc).get_operand()
4.204 value = self.pull()
4.205 frame = self.frame_stack[-1] # different from the current frame after MakeFrame
4.206 self.value_stack[frame + pos] = value
4.207 - self.pc += 2
4.208 + self.pc += 1
4.209
4.210 # Library functions.
4.211
5.1 --- a/test.py Sun May 18 19:59:26 2008 +0200
5.2 +++ b/test.py Mon May 19 00:22:00 2008 +0200
5.3 @@ -1,17 +1,31 @@
5.4 #!/usr/bin/env python
5.5
5.6 import micropython
5.7 +from micropython.rsvp import raw
5.8 +import rsvp
5.9 import sys
5.10
5.11 code = None
5.12
5.13 def show(importer, with_builtins=0, optimisations=None):
5.14 + make(importer, with_builtins, optimisations)
5.15 + show_code(code)
5.16 +
5.17 +def make(importer, with_builtins=0, optimisations=None):
5.18 optimisations = optimisations or requested_optimisations
5.19 global code
5.20 code = importer.get_image(with_builtins, optimisations)
5.21 +
5.22 +def show_code(code):
5.23 for i, x in enumerate(code):
5.24 print i, x
5.25
5.26 +def machine(code, code_location):
5.27 + rc = raw(code)
5.28 + rm = rsvp.RSVPMachine(rc)
5.29 + rm.pc = code_location
5.30 + return rm
5.31 +
5.32 def attrs(obj):
5.33 for name, attr in obj.items():
5.34 print name, attr