1.1 --- a/annotate.py Fri Feb 23 00:12:44 2007 +0100
1.2 +++ b/annotate.py Fri Feb 23 01:29:50 2007 +0100
1.3 @@ -892,6 +892,9 @@
1.4 try_.finally_ = self.dispatches(try_.finally_)
1.5 return try_
1.6
1.7 + def visitYield(self, yield_):
1.8 + raise NotImplementedError, "The yield statement is not currently supported."
1.9 +
1.10 # Utility methods.
1.11
1.12 def get_builtin_instances(self, node, name):
1.13 @@ -1539,13 +1542,20 @@
1.14 package, or None if no such module or package exists.
1.15 """
1.16
1.17 + if self.modules.has_key(name):
1.18 + return Attribute(None, self.modules[name])
1.19 +
1.20 path = name.split(".")
1.21 m = self.find_in_path(path[0])
1.22 if not m:
1.23 return None # NOTE: Import error.
1.24 d, filename = m
1.25 - top = module = self.modules.get(path[0], load(filename, builtins, path[0], self))
1.26 - self.modules[path[0]] = module
1.27 +
1.28 + if self.modules.has_key(path[0]):
1.29 + top = module = self.modules[path[0]]
1.30 + else:
1.31 + top = module = self.modules[path[0]] = load(filename, builtins, path[0], self, no_annotate=1)
1.32 + annotate(module, builtins, self)
1.33
1.34 if len(path) > 1:
1.35 path_so_far = path[:1]
1.36 @@ -1556,8 +1566,12 @@
1.37 return None # NOTE: Import error.
1.38 d, filename = m
1.39 module_name = ".".join(path_so_far)
1.40 - submodule = self.modules.get(module_name, load(filename, builtins, module_name, self))
1.41 - self.modules[module_name] = submodule
1.42 +
1.43 + if self.modules.has_key(module_name):
1.44 + submodule = self.modules[module_name]
1.45 + else:
1.46 + submodule = self.modules[module_name] = load(filename, builtins, module_name, self, no_annotate=1)
1.47 + annotate(submodule, builtins, self)
1.48
1.49 # Store the submodule within its parent module.
1.50
1.51 @@ -1670,7 +1684,7 @@
1.52
1.53 # Convenience functions.
1.54
1.55 -def load(name, builtins=None, module_name=None, importer=None):
1.56 +def load(name, builtins=None, module_name=None, importer=None, no_annotate=0):
1.57
1.58 """
1.59 Load the module with the given 'name' (which may be a full module path),
1.60 @@ -1680,7 +1694,8 @@
1.61
1.62 module = simplify.simplify(name, builtins is None, module_name)
1.63 fixnames.fix(module, builtins)
1.64 - annotate(module, builtins, importer)
1.65 + if not no_annotate:
1.66 + annotate(module, builtins, importer)
1.67 return module
1.68
1.69 def annotate(module, builtins=None, importer=None):
2.1 --- a/lib/builtins.py Fri Feb 23 00:12:44 2007 +0100
2.2 +++ b/lib/builtins.py Fri Feb 23 01:29:50 2007 +0100
2.3 @@ -373,6 +373,42 @@
2.4 else:
2.5 raise TypeError
2.6
2.7 + def __and__(self, other):
2.8 + if isinstance(other, int):
2.9 + return int()
2.10 + else:
2.11 + raise TypeError
2.12 +
2.13 + def __rand__(self, other):
2.14 + if isinstance(other, int):
2.15 + return int()
2.16 + else:
2.17 + raise TypeError
2.18 +
2.19 + def __or__(self, other):
2.20 + if isinstance(other, int):
2.21 + return int()
2.22 + else:
2.23 + raise TypeError
2.24 +
2.25 + def __ror__(self, other):
2.26 + if isinstance(other, int):
2.27 + return int()
2.28 + else:
2.29 + raise TypeError
2.30 +
2.31 + def __xor__(self, other):
2.32 + if isinstance(other, int):
2.33 + return int()
2.34 + else:
2.35 + raise TypeError
2.36 +
2.37 + def __rxor__(self, other):
2.38 + if isinstance(other, int):
2.39 + return int()
2.40 + else:
2.41 + raise TypeError
2.42 +
2.43 def __lt__(self, other):
2.44 if isinstance(other, int):
2.45 return bool()
2.46 @@ -542,6 +578,54 @@
2.47 else:
2.48 raise TypeError
2.49
2.50 + def __and__(self, other):
2.51 + if isinstance(other, int):
2.52 + return long()
2.53 + elif isinstance(other, long):
2.54 + return long()
2.55 + else:
2.56 + raise TypeError
2.57 +
2.58 + def __rand__(self, other):
2.59 + if isinstance(other, int):
2.60 + return long()
2.61 + elif isinstance(other, long):
2.62 + return long()
2.63 + else:
2.64 + raise TypeError
2.65 +
2.66 + def __or__(self, other):
2.67 + if isinstance(other, int):
2.68 + return long()
2.69 + elif isinstance(other, long):
2.70 + return long()
2.71 + else:
2.72 + raise TypeError
2.73 +
2.74 + def __ror__(self, other):
2.75 + if isinstance(other, int):
2.76 + return long()
2.77 + elif isinstance(other, long):
2.78 + return long()
2.79 + else:
2.80 + raise TypeError
2.81 +
2.82 + def __xor__(self, other):
2.83 + if isinstance(other, int):
2.84 + return long()
2.85 + elif isinstance(other, long):
2.86 + return long()
2.87 + else:
2.88 + raise TypeError
2.89 +
2.90 + def __rxor__(self, other):
2.91 + if isinstance(other, int):
2.92 + return long()
2.93 + elif isinstance(other, long):
2.94 + return long()
2.95 + else:
2.96 + raise TypeError
2.97 +
2.98 def __lt__(self, other):
2.99 if isinstance(other, int):
2.100 return bool()
3.1 --- a/simplified.py Fri Feb 23 00:12:44 2007 +0100
3.2 +++ b/simplified.py Fri Feb 23 01:29:50 2007 +0100
3.3 @@ -425,6 +425,13 @@
3.4 class ReturnFromBlock(Return):
3.5 pass
3.6
3.7 +# NOTE: Not actually supported.
3.8 +# Additionally, yield statements act like return statements for the purposes
3.9 +# of this system.
3.10 +
3.11 +class Yield(ReturnFromFunction):
3.12 + pass
3.13 +
3.14 # Some behaviour is set as the default in conditional nodes but may be
3.15 # overridden.
3.16
4.1 --- a/simplify.py Fri Feb 23 00:12:44 2007 +0100
4.2 +++ b/simplify.py Fri Feb 23 01:29:50 2007 +0100
4.3 @@ -48,15 +48,16 @@
4.4 A simplifying visitor for AST nodes.
4.5
4.6 Covered: Add, And, Assert, AssAttr, AssList, AssName, AssTuple, Assign,
4.7 - AugAssign, Break, CallFunc, Class, Compare, Const, Continue, Dict,
4.8 - Discard, Div, FloorDiv, For, From, Function, Getattr, Global, If,
4.9 - Import, Invert, Keyword, Lambda, List, ListComp, ListCompFor,
4.10 - ListCompIf, Mod, Module, Mul, Name, Not, Or, Pass, Power, Print,
4.11 - Printnl, Raise, Return, Slice, Sliceobj, Stmt, Sub, Subscript,
4.12 - TryExcept, TryFinally, Tuple, While, UnaryAdd, UnarySub.
4.13 + AugAssign, Bitand, Break, CallFunc, Class, Compare, Const,
4.14 + Continue, Dict, Discard, Div, FloorDiv, For, From, Function,
4.15 + Getattr, Global, If, Import, Invert, Keyword, Lambda, List,
4.16 + ListComp, ListCompFor, ListCompIf, Mod, Module, Mul, Name, Not, Or,
4.17 + Pass, Power, Print, Printnl, Raise, Return, Slice, Sliceobj, Stmt,
4.18 + Sub, Subscript, TryExcept, TryFinally, Tuple, While, UnaryAdd,
4.19 + UnarySub.
4.20
4.21 - Missing: Backquote, Bitand, Bitor, Bitxor, Decorators, Ellipsis,
4.22 - Exec, LeftShift, RightShift, Yield.
4.23 + Missing: Backquote, Bitor, Bitxor, Decorators, Ellipsis, Exec, LeftShift,
4.24 + RightShift, Yield.
4.25 """
4.26
4.27 def __init__(self, builtins=0):
4.28 @@ -457,6 +458,95 @@
4.29
4.30 return result
4.31
4.32 + def visitBitand(self, bitand):
4.33 +
4.34 + """
4.35 + Make a subprogram for the 'bitand' node and record its contents inside the
4.36 + subprogram. Convert...
4.37 +
4.38 + Bitand (node)
4.39 + (node)
4.40 + ...
4.41 +
4.42 + ...to:
4.43 +
4.44 + Subprogram -> Conditional (test) -> ReturnFromBlock ...
4.45 + (else) -> Conditional (test) -> ReturnFromBlock ...
4.46 + (else) -> ...
4.47 + """
4.48 +
4.49 + subprogram = Subprogram(name=None, module=self.module, internal=1, returns_value=1, params=[], star=None, dstar=None)
4.50 + self.current_subprograms.append(subprogram)
4.51 +
4.52 + # In the subprogram, make instructions which store each operand, test
4.53 + # for each operand's truth status, and if appropriate return from the
4.54 + # subprogram with the value of the operand.
4.55 +
4.56 + last = bitand.nodes[-1]
4.57 + results = nodes = []
4.58 +
4.59 + # Start by storing the first operand.
4.60 +
4.61 + nodes += [
4.62 + StoreTemp(expr=self.dispatch(bitand.nodes[0]))
4.63 + ]
4.64 +
4.65 + # For viewing purposes, record invocations on the AST node.
4.66 +
4.67 + bitand._ops = []
4.68 +
4.69 + for node in bitand.nodes[1:]:
4.70 +
4.71 + # Make a new AST-style node to wrap the operation program nodes.
4.72 +
4.73 + new_op = Op("&", node)
4.74 + bitand._ops.append(new_op)
4.75 +
4.76 + # Generate the operation involving the previous result and the
4.77 + # current operand.
4.78 +
4.79 + expr = self._visitBinaryOp(new_op, LoadTemp(), self.dispatch(node), "__and__", "__rand__")
4.80 +
4.81 + # Return from the subprogram where the test is not satisfied.
4.82 +
4.83 + if node is not last:
4.84 + nodes += [
4.85 + StoreTemp(expr=expr),
4.86 + Conditional(
4.87 + test=self._visitNot(LoadTemp()),
4.88 + body=[
4.89 + ReturnFromBlock(
4.90 + expr=LoadTemp()
4.91 + )
4.92 + ],
4.93 + else_=[
4.94 + # Subsequent operations go here!
4.95 + ]
4.96 + )
4.97 + ]
4.98 +
4.99 + # Put subsequent operations in the else section of this conditional.
4.100 +
4.101 + nodes = nodes[-1].else_
4.102 +
4.103 + # For the last operation, return the result.
4.104 +
4.105 + else:
4.106 + nodes.append(ReturnFromBlock(expr=expr))
4.107 +
4.108 + # Finish the subprogram definition.
4.109 +
4.110 + subprogram.code = results
4.111 +
4.112 + self.current_subprograms.pop()
4.113 + self.subprograms.append(subprogram); self.subnames[subprogram.full_name()] = subprogram
4.114 +
4.115 + # Make an invocation of the subprogram.
4.116 +
4.117 + result = InvokeBlock(bitand, 1, produces_result=1)
4.118 + result.expr = LoadRef(ref=subprogram)
4.119 + return result
4.120 +
4.121 def visitBreak(self, break_):
4.122 result = ReturnFromBlock(break_, 1)
4.123 return result
4.124 @@ -567,6 +657,8 @@
4.125 # Make a new AST-style node to wrap the operation program nodes.
4.126
4.127 new_op = Op(op_name, node)
4.128 + compare._ops.append(new_op)
4.129 +
4.130 expr = self.dispatch(node)
4.131
4.132 # Identify the operation and produce the appropriate method call.
4.133 @@ -624,7 +716,6 @@
4.134 raise NotImplementedError, op_name
4.135
4.136 nodes.append(StoreTemp(expr=invocation))
4.137 - compare._ops.append(new_op)
4.138
4.139 # Return from the subprogram where the test is not satisfied.
4.140
4.141 @@ -1594,6 +1685,15 @@
4.142
4.143 return result
4.144
4.145 + # NOTE: Not actually supported.
4.146 + # NOTE: Virtually the same as visitReturn...
4.147 +
4.148 + def visitYield(self, yield_):
4.149 + result = Yield(yield_, 1,
4.150 + expr=self.dispatch(yield_.value)
4.151 + )
4.152 + return result
4.153 +
4.154 # Convenience methods.
4.155
4.156 def _visitBinary(self, binary, left_name, right_name):
5.1 --- a/test.py Fri Feb 23 00:12:44 2007 +0100
5.2 +++ b/test.py Fri Feb 23 01:29:50 2007 +0100
5.3 @@ -19,7 +19,7 @@
5.4 importer = Importer(sys.path)
5.5 try:
5.6 builtins = load(os.path.join("lib", "builtins.py"))
5.7 - module = load(sys.argv[1], builtins, None, importer)
5.8 + module = load(sys.argv[1], builtins, None, importer, "-na" in sys.argv)
5.9 except simplified.SimplifiedError, exc:
5.10 raise
5.11 else:
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/bitand.py Fri Feb 23 01:29:50 2007 +0100
6.3 @@ -0,0 +1,4 @@
6.4 +a = 0x100
6.5 +b = 0x110
6.6 +c = 0x101
6.7 +d = a & b & c
7.1 --- a/viewer.py Fri Feb 23 00:12:44 2007 +0100
7.2 +++ b/viewer.py Fri Feb 23 01:29:50 2007 +0100
7.3 @@ -127,14 +127,14 @@
7.4 A browsing visitor for AST nodes.
7.5
7.6 Covered: Add, And, Assert, AssAttr, AssList, AssName, AssTuple, Assign,
7.7 - AugAssign, Break, CallFunc, Class, Compare, Const, Continue, Dict,
7.8 - Discard, Div, FloorDiv, For, From, Function, Getattr, Global, If,
7.9 - Import, Keyword, Lambda, List, ListComp, ListCompFor, ListCompIf,
7.10 - Mod, Module, Mul, Name, Not, Or, Pass, Power, Print, Printnl,
7.11 - Raise, Return, Slice, Sliceobj, Stmt, Sub, Subscript, TryExcept,
7.12 - TryFinally, Tuple, UnaryAdd, UnarySub, While.
7.13 + AugAssign, Bitand, Break, CallFunc, Class, Compare, Const,
7.14 + Continue, Dict, Discard, Div, FloorDiv, For, From, Function,
7.15 + Getattr, Global, If, Import, Keyword, Lambda, List, ListComp,
7.16 + ListCompFor, ListCompIf, Mod, Module, Mul, Name, Not, Or, Pass,
7.17 + Power, Print, Printnl, Raise, Return, Slice, Sliceobj, Stmt, Sub,
7.18 + Subscript, TryExcept, TryFinally, Tuple, UnaryAdd, UnarySub, While.
7.19
7.20 - Missing: Backquote, Bitand, Bitor, Bitxor, Decorators, Ellipsis,
7.21 + Missing: Backquote, Bitor, Bitxor, Decorators, Ellipsis,
7.22 Exec, Invert, LeftShift, RightShift, Yield.
7.23 """
7.24
7.25 @@ -610,6 +610,19 @@
7.26 self.stream.write(")\n")
7.27 self.stream.write("</span>\n")
7.28
7.29 + def visitBitand(self, node):
7.30 + self.stream.write("<span class='bitand'>\n")
7.31 + self.dispatch(node.nodes[0])
7.32 + for op in node._ops:
7.33 + self.stream.write("<span class='op'>\n")
7.34 + self.stream.write(op.name)
7.35 + self._popup(
7.36 + self._op(op)
7.37 + )
7.38 + self.stream.write("</span>\n")
7.39 + self.dispatch(op.expr)
7.40 + self.stream.write("</span>")
7.41 +
7.42 def visitCallFunc(self, node):
7.43 target = node._node
7.44 targets = target.active()