# HG changeset patch # User paulb@jeremy # Date 1153261309 -7200 # Node ID 8b5735c2af54ba37f15719d532d478f4f89c744e # Parent d992c0a04de0f75b015f256abf3da8249f1ff6dc Renamed various classes and methods, adjusting the test program appropriately. Introduced program node rewriting to support classes as local namespaces. diff -r d992c0a04de0 -r 8b5735c2af54 annotate.py --- a/annotate.py Tue Jul 18 00:34:32 2006 +0200 +++ b/annotate.py Wed Jul 19 00:21:49 2006 +0200 @@ -25,15 +25,25 @@ import compiler class Namespace: - def __init__(self, parent=None): + def __init__(self, local_is_structure=0, parent=None): + if local_is_structure: + self.local = "structure" + else: + self.local = "local" + self.parent = parent self.names = {} self.not_local = [] - self.parent = parent def make_global(self, name): if name not in self.not_local: self.not_local.append(name) + def find(self, name): + if name not in self.not_local: + return self.local + else: + return "global" + def store(self, name, types): if name not in self.not_local: self.names[name] = types @@ -68,58 +78,100 @@ node.types.append(type) self.count += 1 -class Traverser(Visitor): +class Annotator(Visitor): def __init__(self): Visitor.__init__(self) self.system = System() self.types = None self.temp = {} - def traverse(self, node): - self.namespace = Namespace() - compiler.walk(node, self, self) + def process(self, node): if hasattr(node, "structure"): + self.structure = node.structure + has_structure = 1 + else: + self.structure = None + has_structure = 0 + + self.namespace = Namespace(self.structure is not None) + if has_structure: node.structure.namespace = self.namespace + self.visitor = self + result = self.dispatch(node) + + return result + def default(self, node): for attr in ("args", "params"): value = getattr(node, attr, None) if value is not None: - self.dispatches(value) + setattr(node, attr, self.dispatches(value)) for attr in ("expr", "lvalue", "test", "handler", "star", "dstar"): value = getattr(node, attr, None) if value is not None: - self.dispatch(value) + setattr(node, attr, self.dispatch(value)) for attr in ("body", "else_", "finally_", "code"): value = getattr(node, attr, None) if value is not None: - for n in value: - self.dispatch(n) - print node + setattr(node, attr, self.dispatches(value)) + return node + + def dispatch(self, node, *args): + return Visitor.dispatch(self, node, *args) def visitGlobal(self, global_): for name in global_.names: self.make_global(name) + return global_ def visitLoadRef(self, loadref): self.types = [loadref.ref] + return loadref def visitLoadName(self, loadname): - self.types = self.namespace.load(loadname.name) + if self.namespace.find(loadname.name) == "structure": + return self.dispatch(LoadAttr(expr=LoadRef(ref=self.structure), name=loadname.name)) + else: + self.types = self.namespace.load(loadname, loadname.name) + return loadname def visitStoreName(self, storename): - self.namespace.store(storename.name, self.types) + if self.namespace.find(storename.name) == "structure": + return self.dispatch(StoreAttr(lvalue=LoadRef(ref=self.structure), name=storename.name, expr=storename.expr)) + else: + self.namespace.store(storename, storename.name, self.types) + return storename def visitLoadTemp(self, loadtemp): index = getattr(loadtemp, "index", None) self.types = self.temp[index] + return loadtemp def visitStoreTemp(self, storetemp): index = getattr(storetemp, "index", None) self.temp[index] = self.types + return storetemp def visitReleaseTemp(self, releasetemp): index = getattr(releasetemp, "index", None) del self.temp[index] + return releasetemp + + def visitLoadAttr(self, loadattr): + self.dispatch(loadattr.expr) + types = [] + for ref in self.types: + types += ref.namespace.load(loadattr.name) + self.types = types + return loadattr + + def visitStoreAttr(self, storeattr): + self.dispatch(storeattr.expr) + expr = self.types + self.dispatch(storeattr.lvalue) + for ref in self.types: + ref.namespace.store(storeattr.name, expr) + return storeattr # vim: tabstop=4 expandtab shiftwidth=4 diff -r d992c0a04de0 -r 8b5735c2af54 simplified.py --- a/simplified.py Tue Jul 18 00:34:32 2006 +0200 +++ b/simplified.py Wed Jul 19 00:21:49 2006 +0200 @@ -138,6 +138,9 @@ class Not(Node): "A negation of an expression." class Visitor(ASTVisitor): + + "A visitor base class." + def __init__(self): ASTVisitor.__init__(self) diff -r d992c0a04de0 -r 8b5735c2af54 simplify.py --- a/simplify.py Tue Jul 18 00:34:32 2006 +0200 +++ b/simplify.py Wed Jul 19 00:21:49 2006 +0200 @@ -49,6 +49,10 @@ self.structures = [] # Structures/classes self.current_subprograms = [] # Current subprograms being processed. + def process(self, node): + self.visitor = self + return self.dispatch(node) + def dispatch_or_none(self, node, *args): if node is not None: return self.dispatch(node, *args) diff -r d992c0a04de0 -r 8b5735c2af54 test.py --- a/test.py Tue Jul 18 00:34:32 2006 +0200 +++ b/test.py Wed Jul 19 00:21:49 2006 +0200 @@ -1,11 +1,7 @@ import simplify, compiler, sys import annotate -def traverse(n): - traverser = annotate.Traverser() - traverser.traverse(n) - return traverser - -visitor = simplify.Simplifier() +v = simplify.Simplifier() +a = annotate.Annotator() m = compiler.parseFile(sys.argv[1]) -v = compiler.walk(m, visitor, visitor) +r = v.process(m)