# HG changeset patch # User Paul Boddie # Date 1195605012 -3600 # Node ID 1427b21ed257ecfb5c0d333efe7253ad53e78b8d # Parent d7e84d0d79d8429679eff23575096b9f74214a4d Replaced the module "main program" dictionary from get_image with code_location attributes on each Module, Class and Function object. Introduced code writing support to the Translation class, replacing the usage of lists as return values from the visitor methods. diff -r d7e84d0d79d8 -r 1427b21ed257 micropython/__init__.py --- a/micropython/__init__.py Tue Nov 20 00:36:00 2007 +0100 +++ b/micropython/__init__.py Wed Nov 21 01:30:12 2007 +0100 @@ -78,7 +78,6 @@ "Return a dictionary mapping modules to structures." image = [] - module_main = {} for module_name, module in self.modules.items(): pos = len(image) @@ -104,7 +103,7 @@ # Position the class in the image. - obj.location = pos + obj.code_location = obj.location = pos # Append class attributes to the image. @@ -132,7 +131,7 @@ # Position the function in the image. - obj.location = pos + obj.code_location = obj.location = pos # Append the function code to the image. @@ -142,7 +141,7 @@ # Remember the position of the module code. - module_main[module_name] = pos + module.code_location = pos # Append the module top-level code to the image. @@ -150,7 +149,7 @@ image += code pos += len(code) - return image, module_main + return image def get_object_table(self): diff -r d7e84d0d79d8 -r 1427b21ed257 micropython/ast.py --- a/micropython/ast.py Tue Nov 20 00:36:00 2007 +0100 +++ b/micropython/ast.py Wed Nov 21 01:30:12 2007 +0100 @@ -34,6 +34,17 @@ pass +class Label: + + "A reference to a location." + + def __init__(self, number, location=None): + self.number = number + self.location = location + + def __repr__(self): + return "Label(%r, location=%r)" % (self.number, self.location) + # Program visitors. class Translation(ASTVisitor): @@ -49,19 +60,29 @@ self.module = module self.unit = None + # Wiring within the code. + + self.labels = {} + self.label_number = 0 + self.code = None + def get_module_code(self): "Return the top-level module code." self.unit = self.module - return self.dispatch(self.module.module) + self.code = [] + self.dispatch(self.module.module) + return self.code def get_code(self, unit): "Return the code for the given 'unit'." self.unit = unit - return self.dispatch(unit.node) + self.code = [] + self.dispatch(unit.node) + return self.code def __repr__(self): return "Translation(%r)" % self.module @@ -74,6 +95,27 @@ else: return "builtins" + # Code writing methods. + + def new_label(self): + number = self.label_number + label = Label(number) + self.labels[label] = label + self.label_number += 1 + return label + + def set_label(self, label): + + """ + Set the location of 'label' to that within the entire image: the + location within the code combined with location of the code unit. + """ + + label.location = len(self.code) + self.unit.code_location + + def new_op(self, op): + self.code.append(op) + # Visitor methods. def default(self, node, *args): @@ -90,26 +132,26 @@ if scope == "local": unit = self.unit if isinstance(unit, micropython.inspect.Function): - return [NameInstruction(unit.locals()[name])] + self.new_op(NameInstruction(unit.locals()[name])) elif isinstance(unit, micropython.inspect.Class): - return [AttrInstruction(unit.all_class_attributes()[name])] + self.new_op(AttrInstruction(unit.all_class_attributes()[name])) elif isinstance(unit, micropython.inspect.Module): - return [AttrInstruction(unit.module_attributes()[name])] + self.new_op(AttrInstruction(unit.module_attributes()[name])) else: raise TranslateError, "Program unit %r has no local %r" % (unit, name) elif scope == "global": globals = self.module.module_attributes() if globals.has_key(name): - return [AttrInstruction(globals[name])] + self.new_op(AttrInstruction(globals[name])) else: raise TranslateError, "Module %r has no attribute %r" % (self.module, name) else: builtins = micropython.inspect.builtins.module_attributes() - return [AttrInstruction(builtins[name])] + self.new_op(AttrInstruction(builtins[name])) - def visitAdd(self, node): return [] + def visitAdd(self, node): pass """ _t1 = node.left @@ -120,169 +162,177 @@ _t2.__radd__(_t1) """ - def visitAnd(self, node): return [] + def visitAnd(self, node): pass - def visitAssert(self, node): return [] + def visitAssert(self, node): pass def visitAssign(self, node): - results = [] - results += self.dispatch(node.expr) + self.dispatch(node.expr) for n in node.nodes: - results += self.dispatch(n) - return results + self.dispatch(n) - def visitAssAttr(self, node): return [] + def visitAssAttr(self, node): pass - def visitAssList(self, node): return [] + def visitAssList(self, node): pass def visitAssName(self, node): - return self._visitName(node, (StoreName, StoreAttr)) + self._visitName(node, (StoreName, StoreAttr)) visitAssTuple = visitAssList - def visitAugAssign(self, node): return [] + def visitAugAssign(self, node): pass - def visitBackquote(self, node): return [] + def visitBackquote(self, node): pass - def visitBitand(self, node): return [] + def visitBitand(self, node): pass - def visitBitor(self, node): return [] + def visitBitor(self, node): pass - def visitBitxor(self, node): return [] + def visitBitxor(self, node): pass - def visitBreak(self, node): return [] + def visitBreak(self, node): pass - def visitCallFunc(self, node): return [] + def visitCallFunc(self, node): pass - def visitClass(self, node): return [] + def visitClass(self, node): pass - def visitCompare(self, node): return [] + def visitCompare(self, node): pass - def visitConst(self, node): return [] + def visitConst(self, node): pass - def visitContinue(self, node): return [] + def visitContinue(self, node): pass - def visitDecorators(self, node): return [] + def visitDecorators(self, node): pass - def visitDict(self, node): return [] + def visitDict(self, node): pass def visitDiscard(self, node): - return self.dispatch(node.expr) + self.dispatch(node.expr) - def visitDiv(self, node): return [] + def visitDiv(self, node): pass - def visitEllipsis(self, node): return [] + def visitEllipsis(self, node): pass - def visitExec(self, node): return [] + def visitExec(self, node): pass - def visitExpression(self, node): return [] + def visitExpression(self, node): pass - def visitFloorDiv(self, node): return [] + def visitFloorDiv(self, node): pass - def visitFor(self, node): return [] + def visitFor(self, node): pass - def visitFrom(self, node): return [] + def visitFrom(self, node): pass def visitFunction(self, node): # Only store the name when visiting this node from outside. if self.unit is self.module: - return self._visitName(node, (StoreName, StoreAttr)) + self._visitName(node, (StoreName, StoreAttr)) else: - return self.dispatch(node.code) + self.dispatch(node.code) - def visitGenExpr(self, node): return [] + def visitGenExpr(self, node): pass - def visitGenExprFor(self, node): return [] + def visitGenExprFor(self, node): pass - def visitGenExprIf(self, node): return [] + def visitGenExprIf(self, node): pass - def visitGenExprInner(self, node): return [] + def visitGenExprInner(self, node): pass - def visitGetattr(self, node): return [] + def visitGetattr(self, node): pass - def visitGlobal(self, node): return [] + def visitGlobal(self, node): pass def visitIf(self, node): - for test, body in node.tests: - self.dispatch(body) - if node.else_ is not None: - self.dispatch(node.else_) - return None + first = 1 + exit_label = self.new_label() - def visitImport(self, node): return [] + for test, body in node.tests + [(None, node.else_)]: + if body is None: + break + if not first: + self.set_label(next_label) + if test is not None: + self.dispatch(test) + next_label = self.new_label() + self.new_op(Jump(next_label)) + self.dispatch(body) + self.new_op(Jump(exit_label)) + first = 0 - def visitInvert(self, node): return [] - - def visitKeyword(self, node): return [] + self.set_label(exit_label) - def visitLambda(self, node): return [] + def visitImport(self, node): pass + + def visitInvert(self, node): pass - def visitLeftShift(self, node): return [] + def visitKeyword(self, node): pass - def visitList(self, node): return [] + def visitLambda(self, node): pass + + def visitLeftShift(self, node): pass - def visitListComp(self, node): return [] + def visitList(self, node): pass - def visitListCompFor(self, node): return [] + def visitListComp(self, node): pass - def visitListCompIf(self, node): return [] + def visitListCompFor(self, node): pass - def visitMod(self, node): return [] + def visitListCompIf(self, node): pass + + def visitMod(self, node): pass def visitModule(self, node): - return self.dispatch(node.node) + self.dispatch(node.node) - def visitMul(self, node): return [] + def visitMul(self, node): pass def visitName(self, node): - return self._visitName(node, (LoadName, LoadAttr)) + self._visitName(node, (LoadName, LoadAttr)) - def visitNot(self, node): return [] + def visitNot(self, node): pass - def visitOr(self, node): return [] + def visitOr(self, node): pass - def visitPass(self, node): return [] + def visitPass(self, node): pass - def visitPower(self, node): return [] + def visitPower(self, node): pass - def visitPrint(self, node): return [] + def visitPrint(self, node): pass - def visitPrintnl(self, node): return [] + def visitPrintnl(self, node): pass - def visitRaise(self, node): return [] + def visitRaise(self, node): pass - def visitReturn(self, node): return [] + def visitReturn(self, node): pass - def visitRightShift(self, node): return [] + def visitRightShift(self, node): pass - def visitSlice(self, node): return [] + def visitSlice(self, node): pass def visitStmt(self, node): - result = [] for n in node.nodes: - result += self.dispatch(n) - return result + self.dispatch(n) + + def visitSub(self, node): pass - def visitSub(self, node): return [] + def visitSubscript(self, node): pass - def visitSubscript(self, node): return [] + def visitTryExcept(self, node): pass - def visitTryExcept(self, node): return [] + def visitTryFinally(self, node): pass - def visitTryFinally(self, node): return [] + def visitTuple(self, node): pass - def visitTuple(self, node): return [] + def visitUnaryAdd(self, node): pass - def visitUnaryAdd(self, node): return [] + def visitUnarySub(self, node): pass - def visitUnarySub(self, node): return [] - - def visitWhile(self, node): return [] + def visitWhile(self, node): pass - def visitWith(self, node): return [] + def visitWith(self, node): pass - def visitYield(self, node): return [] + def visitYield(self, node): pass # vim: tabstop=4 expandtab shiftwidth=4 diff -r d7e84d0d79d8 -r 1427b21ed257 micropython/inspect.py --- a/micropython/inspect.py Tue Nov 20 00:36:00 2007 +0100 +++ b/micropython/inspect.py Wed Nov 21 01:30:12 2007 +0100 @@ -122,6 +122,7 @@ # Image generation details. self.location = None + self.code_location = None def __repr__(self): return "Class(%r, %r, location=%r)" % (self.name, self.parent_name, self.location) @@ -262,6 +263,7 @@ # Image generation details. self.location = None + self.code_location = None def __repr__(self): return "Function(%r, %r, %r, %r, %r, location=%r)" % ( @@ -346,6 +348,7 @@ # Image generation details. self.location = None + self.code_location = None def full_name(self): return self.name @@ -469,7 +472,7 @@ return ASTVisitor.dispatch(self, node, *args) def NOP(self, node): - return node + return None visitAdd = NOP @@ -533,7 +536,7 @@ self.dispatch(node.code) self.namespaces.pop() - return node + return None visitCompare = NOP diff -r d7e84d0d79d8 -r 1427b21ed257 micropython/rsvp.py --- a/micropython/rsvp.py Tue Nov 20 00:36:00 2007 +0100 +++ b/micropython/rsvp.py Wed Nov 21 01:30:12 2007 +0100 @@ -33,5 +33,6 @@ class LoadAttr(Instruction): pass class StoreName(Instruction): pass class StoreAttr(Instruction): pass +class Jump(Instruction): pass # vim: tabstop=4 expandtab shiftwidth=4