| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | """Python bytecode generator
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Currently contains generic ASTVisitor code, a LocalNameFinder, and a | 
					
						
							|  |  |  | CodeGenerator.  Eventually, this will get split into the ASTVisitor as | 
					
						
							|  |  |  | a generic tool and CodeGenerator as a specific tool. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from p2c import transformer, ast | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | from pyassem import StackRef, PyAssembler | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | import dis | 
					
						
							|  |  |  | import misc | 
					
						
							| 
									
										
										
										
											2000-02-04 19:37:35 +00:00
										 |  |  | import marshal | 
					
						
							|  |  |  | import new | 
					
						
							|  |  |  | import string | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  | import sys | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import stat | 
					
						
							|  |  |  | import struct | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def parse(path): | 
					
						
							|  |  |  |     f = open(path) | 
					
						
							|  |  |  |     src = f.read() | 
					
						
							|  |  |  |     f.close() | 
					
						
							|  |  |  |     t = transformer.Transformer() | 
					
						
							|  |  |  |     return t.parsesuite(src) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | def walk(tree, visitor, verbose=None, walker=None): | 
					
						
							|  |  |  |     if walker: | 
					
						
							|  |  |  |         w = walker() | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         w = ASTVisitor() | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     if verbose is not None: | 
					
						
							|  |  |  |         w.VERBOSE = verbose | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     w.preorder(tree, visitor) | 
					
						
							|  |  |  |     return w.visitor | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | def dumpNode(node): | 
					
						
							|  |  |  |     print node.__class__ | 
					
						
							|  |  |  |     for attr in dir(node): | 
					
						
							|  |  |  |         if attr[0] != '_': | 
					
						
							|  |  |  |             print "\t", "%-10.10s" % attr, getattr(node, attr) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | class ASTVisitor: | 
					
						
							|  |  |  |     """Performs a depth-first walk of the AST
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The ASTVisitor will walk the AST, performing either a preorder or | 
					
						
							|  |  |  |     postorder traversal depending on which method is called. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     methods: | 
					
						
							|  |  |  |     preorder(tree, visitor) | 
					
						
							|  |  |  |     postorder(tree, visitor) | 
					
						
							|  |  |  |         tree: an instance of ast.Node | 
					
						
							|  |  |  |         visitor: an instance with visitXXX methods | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The ASTVisitor is responsible for walking over the tree in the | 
					
						
							|  |  |  |     correct order.  For each node, it checks the visitor argument for | 
					
						
							|  |  |  |     a method named 'visitNodeType' where NodeType is the name of the | 
					
						
							|  |  |  |     node's class, e.g. Classdef.  If the method exists, it is called | 
					
						
							|  |  |  |     with the node as its sole argument. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The visitor method for a particular node type can control how | 
					
						
							|  |  |  |     child nodes are visited during a preorder walk.  (It can't control | 
					
						
							|  |  |  |     the order during a postorder walk, because it is called _after_ | 
					
						
							|  |  |  |     the walk has occurred.)  The ASTVisitor modifies the visitor | 
					
						
							|  |  |  |     argument by adding a visit method to the visitor; this method can | 
					
						
							|  |  |  |     be used to visit a particular child node.  If the visitor method | 
					
						
							|  |  |  |     returns a true value, the ASTVisitor will not traverse the child | 
					
						
							|  |  |  |     nodes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     XXX The interface for controlling the preorder walk needs to be | 
					
						
							|  |  |  |     re-considered.  The current interface is convenient for visitors | 
					
						
							|  |  |  |     that mostly let the ASTVisitor do everything.  For something like | 
					
						
							|  |  |  |     a code generator, where you want to walk to occur in a specific | 
					
						
							|  |  |  |     order, it's a pain to add "return 1" to the end of each method. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     XXX Perhaps I can use a postorder walk for the code generator? | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     VERBOSE = 0 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  | 	self.node = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def preorder(self, tree, visitor): | 
					
						
							|  |  |  |         """Do preorder walk of tree using visitor""" | 
					
						
							|  |  |  |         self.visitor = visitor | 
					
						
							|  |  |  |         visitor.visit = self._preorder | 
					
						
							|  |  |  |         self._preorder(tree) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _preorder(self, node): | 
					
						
							|  |  |  |         stop = self.dispatch(node) | 
					
						
							|  |  |  |         if stop: | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |         for child in node.getChildren(): | 
					
						
							|  |  |  |             if isinstance(child, ast.Node): | 
					
						
							|  |  |  |                 self._preorder(child) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def postorder(self, tree, visitor): | 
					
						
							|  |  |  |         """Do preorder walk of tree using visitor""" | 
					
						
							|  |  |  |         self.visitor = visitor | 
					
						
							|  |  |  |         visitor.visit = self._postorder | 
					
						
							|  |  |  |         self._postorder(tree) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def _postorder(self, tree): | 
					
						
							|  |  |  |         for child in node.getChildren(): | 
					
						
							|  |  |  |             if isinstance(child, ast.Node): | 
					
						
							|  |  |  |                 self._preorder(child) | 
					
						
							|  |  |  |         self.dispatch(node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def dispatch(self, node): | 
					
						
							|  |  |  |         self.node = node | 
					
						
							|  |  |  |         className = node.__class__.__name__ | 
					
						
							|  |  |  |         meth = getattr(self.visitor, 'visit' + className, None) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         if self.VERBOSE > 0: | 
					
						
							|  |  |  |             if self.VERBOSE == 1: | 
					
						
							|  |  |  |                 if meth is None: | 
					
						
							|  |  |  |                     print "dispatch", className | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 print "dispatch", className, (meth and meth.__name__ or '') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |         if meth: | 
					
						
							|  |  |  |             return meth(node) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | class ExampleASTVisitor(ASTVisitor): | 
					
						
							| 
									
										
										
										
											2000-02-14 23:57:56 +00:00
										 |  |  |     """Prints examples of the nodes that aren't visited
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This visitor-driver is only useful for development, when it's | 
					
						
							|  |  |  |     helpful to develop a visitor incremently, and get feedback on what | 
					
						
							|  |  |  |     you still have to do. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     examples = {} | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     def dispatch(self, node): | 
					
						
							|  |  |  |         self.node = node | 
					
						
							|  |  |  |         className = node.__class__.__name__ | 
					
						
							|  |  |  |         meth = getattr(self.visitor, 'visit' + className, None) | 
					
						
							|  |  |  |         if self.VERBOSE > 0: | 
					
						
							|  |  |  |             if self.VERBOSE == 1: | 
					
						
							|  |  |  |                 if meth is None: | 
					
						
							|  |  |  |                     print "dispatch", className | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 print "dispatch", className, (meth and meth.__name__ or '') | 
					
						
							|  |  |  |         if meth: | 
					
						
							|  |  |  |             return meth(node) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             klass = node.__class__ | 
					
						
							|  |  |  |             if self.VERBOSE < 2: | 
					
						
							|  |  |  |                 if self.examples.has_key(klass): | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |             self.examples[klass] = klass | 
					
						
							|  |  |  |             print | 
					
						
							|  |  |  |             print klass | 
					
						
							|  |  |  |             for attr in dir(node): | 
					
						
							|  |  |  |                 if attr[0] != '_': | 
					
						
							|  |  |  |                     print "\t", "%-12.12s" % attr, getattr(node, attr) | 
					
						
							|  |  |  |             print | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | class CodeGenerator: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     """TODO
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     EmptyNode | 
					
						
							|  |  |  |     Sliceobj | 
					
						
							|  |  |  |     Tryexcept | 
					
						
							|  |  |  |     Tryfinally | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     OPTIMIZED = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     # XXX should clean up initialization and generateXXX funcs | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def __init__(self, filename="<?>"): | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  |         self.filename = filename | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.code = PyAssembler() | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  |         self.code.setFlags(0) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	self.locals = misc.Stack() | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         self.loops = misc.Stack() | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         self.namespace = 0 | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  |         self.curStack = 0 | 
					
						
							|  |  |  |         self.maxStack = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def emit(self, *args): | 
					
						
							|  |  |  | 	# XXX could just use self.emit = self.code.emit | 
					
						
							|  |  |  | 	apply(self.code.emit, args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def _generateFunctionOrLambdaCode(self, func): | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         self.name = func.name | 
					
						
							|  |  |  |         self.filename = filename | 
					
						
							|  |  |  |         args = func.argnames | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.code = PyAssembler(args=args, name=func.name, | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |                                  filename=filename) | 
					
						
							|  |  |  |         self.namespace = self.OPTIMIZED | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         if func.varargs: | 
					
						
							|  |  |  |             self.code.setVarArgs() | 
					
						
							|  |  |  |         if func.kwargs: | 
					
						
							|  |  |  |             self.code.setKWArgs() | 
					
						
							|  |  |  |         lnf = walk(func.code, LocalNameFinder(args), 0) | 
					
						
							|  |  |  |         self.locals.push(lnf.getLocals()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('SET_LINENO', func.lineno) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         walk(func.code, self) | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def generateFunctionCode(self, func): | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  |         """Generate code for a function body""" | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         self._generateFunctionOrLambdaCode(func) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_CONST', None) | 
					
						
							|  |  |  |         self.emit('RETURN_VALUE') | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def generateLambdaCode(self, func): | 
					
						
							|  |  |  |         self._generateFunctionOrLambdaCode(func) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('RETURN_VALUE') | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def generateClassCode(self, klass): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.code = PyAssembler(name=klass.name, | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |                                  filename=filename) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', klass.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         lnf = walk(klass.code, LocalNameFinder(), 0) | 
					
						
							|  |  |  |         self.locals.push(lnf.getLocals()) | 
					
						
							|  |  |  |         walk(klass.code, self) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_LOCALS') | 
					
						
							|  |  |  |         self.emit('RETURN_VALUE') | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def asConst(self): | 
					
						
							|  |  |  |         """Create a Python code object.""" | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         if self.namespace == self.OPTIMIZED: | 
					
						
							|  |  |  |             self.code.setOptimized() | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         return self.code.makeCodeObject() | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def isLocalName(self, name): | 
					
						
							|  |  |  | 	return self.locals.top().has_elt(name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |     def _nameOp(self, prefix, name): | 
					
						
							|  |  |  |         if self.isLocalName(name): | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |             if self.namespace == self.OPTIMIZED: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |                 self.emit(prefix + '_FAST', name) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |             else: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |                 self.emit(prefix + '_NAME', name) | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit(prefix + '_GLOBAL', name) | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def storeName(self, name): | 
					
						
							|  |  |  |         self._nameOp('STORE', name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def loadName(self, name): | 
					
						
							|  |  |  |         self._nameOp('LOAD', name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def delName(self, name): | 
					
						
							|  |  |  |         self._nameOp('DELETE', name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitNULL(self, node): | 
					
						
							|  |  |  |         """Method exists only to stop warning in -v mode""" | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     visitStmt = visitNULL | 
					
						
							|  |  |  |     visitGlobal = visitNULL | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitDiscard(self, node): | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         self.visit(node.expr) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitPass(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitModule(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  | 	lnf = walk(node.node, LocalNameFinder(), 0) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	self.locals.push(lnf.getLocals()) | 
					
						
							| 
									
										
										
										
											2000-02-04 19:37:35 +00:00
										 |  |  |         self.visit(node.node) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_CONST', None) | 
					
						
							|  |  |  |         self.emit('RETURN_VALUE') | 
					
						
							| 
									
										
										
										
											2000-02-04 19:37:35 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitImport(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         for name in node.names: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('IMPORT_NAME', name) | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |             self.storeName(name) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def visitFrom(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  |         self.emit('IMPORT_NAME', node.modname) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         for name in node.names: | 
					
						
							| 
									
										
										
										
											2000-02-14 21:33:10 +00:00
										 |  |  |             if name == '*': | 
					
						
							|  |  |  |                 self.namespace = 0 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('IMPORT_FROM', name) | 
					
						
							|  |  |  |         self.emit('POP_TOP') | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def visitClassdef(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  |         self.emit('LOAD_CONST', node.name) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         for base in node.bases: | 
					
						
							|  |  |  |             self.visit(base) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('BUILD_TUPLE', len(node.bases)) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         classBody = CodeGenerator(self.filename) | 
					
						
							|  |  |  |         classBody.generateClassCode(node) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_CONST', classBody) | 
					
						
							|  |  |  |         self.emit('MAKE_FUNCTION', 0) | 
					
						
							|  |  |  |         self.emit('CALL_FUNCTION', 0) | 
					
						
							|  |  |  |         self.emit('BUILD_CLASS') | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         self.storeName(node.name) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  |     def _visitFuncOrLambda(self, node, kind): | 
					
						
							|  |  |  |         """Code common to Function and Lambda nodes""" | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         codeBody = CodeGenerator(self.filename) | 
					
						
							|  |  |  |         getattr(codeBody, 'generate%sCode' % kind)(node) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         for default in node.defaults: | 
					
						
							|  |  |  |             self.visit(default) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_CONST', codeBody) | 
					
						
							|  |  |  |         self.emit('MAKE_FUNCTION', len(node.defaults)) | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def visitFunction(self, node): | 
					
						
							|  |  |  |         self._visitFuncOrLambda(node, 'Function') | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |         self.storeName(node.name) | 
					
						
							| 
									
										
										
										
											2000-02-04 19:37:35 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  |     def visitLambda(self, node): | 
					
						
							|  |  |  |         node.name = '<lambda>' | 
					
						
							|  |  |  |         node.varargs = node.kwargs = None | 
					
						
							|  |  |  |         self._visitFuncOrLambda(node, 'Lambda') | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitCallFunc(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         pos = 0 | 
					
						
							|  |  |  |         kw = 0 | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         if hasattr(node, 'lineno'): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	self.visit(node.node) | 
					
						
							|  |  |  | 	for arg in node.args: | 
					
						
							|  |  |  | 	    self.visit(arg) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |             if isinstance(arg, ast.Keyword): | 
					
						
							|  |  |  |                 kw = kw + 1 | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 pos = pos + 1 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('CALL_FUNCTION', kw << 8 | pos) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |     def visitKeyword(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_CONST', node.name) | 
					
						
							| 
									
										
										
										
											2000-02-12 00:12:38 +00:00
										 |  |  |         self.visit(node.expr) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitIf(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  | 	after = StackRef() | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	for test, suite in node.tests: | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |             if hasattr(test, 'lineno'): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |                 self.emit('SET_LINENO', test.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 print "warning", "no line number" | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	    self.visit(test) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  | 	    dest = StackRef() | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('JUMP_IF_FALSE', dest) | 
					
						
							|  |  |  | 	    self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	    self.visit(suite) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('JUMP_FORWARD', after) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	    dest.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	if node.else_: | 
					
						
							|  |  |  | 	    self.visit(node.else_) | 
					
						
							|  |  |  | 	after.bind(self.code.getCurInst()) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |     def startLoop(self): | 
					
						
							|  |  |  |         l = Loop() | 
					
						
							|  |  |  |         self.loops.push(l) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SETUP_LOOP', l.extentAnchor) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         return l | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def finishLoop(self): | 
					
						
							|  |  |  |         l = self.loops.pop() | 
					
						
							|  |  |  |         i = self.code.getCurInst() | 
					
						
							|  |  |  |         l.extentAnchor.bind(self.code.getCurInst()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def visitFor(self, node): | 
					
						
							|  |  |  |         # three refs needed | 
					
						
							|  |  |  |         anchor = StackRef() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         l = self.startLoop() | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         self.visit(node.list) | 
					
						
							|  |  |  |         self.visit(ast.Const(0)) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         l.startAnchor.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  |         self.emit('FOR_LOOP', anchor) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         self.visit(node.assign) | 
					
						
							|  |  |  |         self.visit(node.body) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('JUMP_ABSOLUTE', l.startAnchor) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         anchor.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('POP_BLOCK') | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         if node.else_: | 
					
						
							|  |  |  |             self.visit(node.else_) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         self.finishLoop() | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |     def visitWhile(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         l = self.startLoop() | 
					
						
							|  |  |  |         if node.else_: | 
					
						
							|  |  |  |             lElse = StackRef() | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             lElse = l.breakAnchor | 
					
						
							|  |  |  |         l.startAnchor.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.test.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         self.visit(node.test) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('JUMP_IF_FALSE', lElse) | 
					
						
							|  |  |  |         self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         self.visit(node.body) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('JUMP_ABSOLUTE', l.startAnchor) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         # note that lElse may be an alias for l.breakAnchor | 
					
						
							|  |  |  |         lElse.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('POP_TOP') | 
					
						
							|  |  |  |         self.emit('POP_BLOCK') | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  |         if node.else_: | 
					
						
							|  |  |  |             self.visit(node.else_) | 
					
						
							|  |  |  |         self.finishLoop() | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitBreak(self, node): | 
					
						
							|  |  |  |         if not self.loops: | 
					
						
							|  |  |  |             raise SyntaxError, "'break' outside loop" | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  |         self.emit('BREAK_LOOP') | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def visitContinue(self, node): | 
					
						
							|  |  |  |         if not self.loops: | 
					
						
							|  |  |  |             raise SyntaxError, "'continue' outside loop" | 
					
						
							|  |  |  |         l = self.loops.top() | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  |         self.emit('JUMP_ABSOLUTE', l.startAnchor) | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitCompare(self, node): | 
					
						
							|  |  |  | 	"""Comment from compile.c follows:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	The following code is generated for all but the last | 
					
						
							|  |  |  | 	comparison in a chain: | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	label:	on stack:	opcode:		jump to: | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 		a		<code to load b> | 
					
						
							|  |  |  | 		a, b		DUP_TOP | 
					
						
							|  |  |  | 		a, b, b		ROT_THREE | 
					
						
							|  |  |  | 		b, a, b		COMPARE_OP | 
					
						
							|  |  |  | 		b, 0-or-1	JUMP_IF_FALSE	L1 | 
					
						
							|  |  |  | 		b, 1		POP_TOP | 
					
						
							|  |  |  | 		b		 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	We are now ready to repeat this sequence for the next | 
					
						
							|  |  |  | 	comparison in the chain. | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	For the last we generate: | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	   	b		<code to load c> | 
					
						
							|  |  |  | 	   	b, c		COMPARE_OP | 
					
						
							|  |  |  | 	   	0-or-1		 | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	If there were any jumps to L1 (i.e., there was more than one | 
					
						
							|  |  |  | 	comparison), we generate: | 
					
						
							|  |  |  | 	    | 
					
						
							|  |  |  | 	   	0-or-1		JUMP_FORWARD	L2 | 
					
						
							|  |  |  | 	   L1:	b, 0		ROT_TWO | 
					
						
							|  |  |  | 	   	0, b		POP_TOP | 
					
						
							|  |  |  | 	   	0 | 
					
						
							|  |  |  | 	   L2:	0-or-1 | 
					
						
							|  |  |  | 	"""
 | 
					
						
							|  |  |  | 	self.visit(node.expr) | 
					
						
							|  |  |  | 	# if refs are never emitted, subsequent bind call has no effect | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  | 	l1 = StackRef() | 
					
						
							|  |  |  | 	l2 = StackRef() | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	for op, code in node.ops[:-1]: | 
					
						
							|  |  |  | 	    # emit every comparison except the last | 
					
						
							|  |  |  | 	    self.visit(code) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('DUP_TOP') | 
					
						
							|  |  |  | 	    self.emit('ROT_THREE') | 
					
						
							|  |  |  | 	    self.emit('COMPARE_OP', op) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |             # dupTop and compareOp cancel stack effect | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('JUMP_IF_FALSE', l1) | 
					
						
							|  |  |  | 	    self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	if node.ops: | 
					
						
							|  |  |  | 	    # emit the last comparison | 
					
						
							|  |  |  | 	    op, code = node.ops[-1] | 
					
						
							|  |  |  | 	    self.visit(code) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('COMPARE_OP', op) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	if len(node.ops) > 1: | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('JUMP_FORWARD', l2) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	    l1.bind(self.code.getCurInst()) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('ROT_TWO') | 
					
						
							|  |  |  | 	    self.emit('POP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	    l2.bind(self.code.getCurInst()) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitGetattr(self, node): | 
					
						
							|  |  |  |         self.visit(node.expr) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('LOAD_ATTR', node.attrname) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitSubscript(self, node): | 
					
						
							|  |  |  |         self.visit(node.expr) | 
					
						
							|  |  |  |         for sub in node.subs[:-1]: | 
					
						
							|  |  |  |             self.visit(sub) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('BINARY_SUBSCR') | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         self.visit(node.subs[-1]) | 
					
						
							|  |  |  |         if node.flags == 'OP_APPLY': | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('BINARY_SUBSCR') | 
					
						
							|  |  |  |         elif node.flags == 'OP_ASSIGN': | 
					
						
							|  |  |  |             self.emit('STORE_SUBSCR') | 
					
						
							|  |  |  | 	elif node.flags == 'OP_DELETE': | 
					
						
							|  |  |  |             self.emit('DELETE_SUBSCR') | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |              | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitSlice(self, node): | 
					
						
							|  |  |  |         self.visit(node.expr) | 
					
						
							|  |  |  |         slice = 0 | 
					
						
							|  |  |  |         if node.lower: | 
					
						
							|  |  |  |             self.visit(node.lower) | 
					
						
							|  |  |  |             slice = slice | 1 | 
					
						
							|  |  |  |         if node.upper: | 
					
						
							|  |  |  |             self.visit(node.upper) | 
					
						
							|  |  |  |             slice = slice | 2 | 
					
						
							|  |  |  |         if node.flags == 'OP_APPLY': | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('SLICE+%d' % slice) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         elif node.flags == 'OP_ASSIGN': | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('STORE_SLICE+%d' % slice) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         elif node.flags == 'OP_DELETE': | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit('DELETE_SLICE+%d' % slice) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             print node.flags | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def visitAssign(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         self.visit(node.expr) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	dups = len(node.nodes) - 1 | 
					
						
							|  |  |  |         for i in range(len(node.nodes)): | 
					
						
							|  |  |  | 	    elt = node.nodes[i] | 
					
						
							|  |  |  | 	    if i < dups: | 
					
						
							|  |  |  | 		self.emit('DUP_TOP') | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |             if isinstance(elt, ast.Node): | 
					
						
							|  |  |  |                 self.visit(elt) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitAssName(self, node): | 
					
						
							|  |  |  |         if node.flags != 'OP_ASSIGN': | 
					
						
							|  |  |  |             print "oops", node.flags | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |         self.storeName(node.name) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitAssAttr(self, node): | 
					
						
							|  |  |  |         if node.flags != 'OP_ASSIGN': | 
					
						
							|  |  |  |             print "warning: unexpected flags:", node.flags | 
					
						
							|  |  |  |             print node | 
					
						
							|  |  |  |         self.visit(node.expr) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('STORE_ATTR', node.attrname) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitAssTuple(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('UNPACK_TUPLE', len(node.nodes)) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         for child in node.nodes: | 
					
						
							|  |  |  |             self.visit(child) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     visitAssList = visitAssTuple | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def binaryOp(self, node, op): | 
					
						
							|  |  |  | 	self.visit(node.left) | 
					
						
							|  |  |  | 	self.visit(node.right) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit(op) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def unaryOp(self, node, op): | 
					
						
							|  |  |  |         self.visit(node.expr) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit(op) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitAdd(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_ADD') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitSub(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_SUBTRACT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitMul(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_MULTIPLY') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitDiv(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_DIVIDE') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitMod(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_MODULO') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 21:33:10 +00:00
										 |  |  |     def visitPower(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_POWER') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitLeftShift(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_LSHIFT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitRightShift(self, node): | 
					
						
							|  |  |  | 	return self.binaryOp(node, 'BINARY_RSHIFT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitInvert(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_INVERT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def visitUnarySub(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_NEGATIVE') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitUnaryAdd(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_POSITIVE') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitUnaryInvert(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_INVERT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitNot(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_NOT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def visitBackquote(self, node): | 
					
						
							|  |  |  |         return self.unaryOp(node, 'UNARY_CONVERT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def bitOp(self, nodes, op): | 
					
						
							|  |  |  | 	self.visit(nodes[0]) | 
					
						
							|  |  |  | 	for node in nodes[1:]: | 
					
						
							|  |  |  | 	    self.visit(node) | 
					
						
							|  |  |  | 	    self.emit(op) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitBitand(self, node): | 
					
						
							|  |  |  | 	return self.bitOp(node.nodes, 'BINARY_AND') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitBitor(self, node): | 
					
						
							|  |  |  | 	return self.bitOp(node.nodes, 'BINARY_OR') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitBitxor(self, node): | 
					
						
							|  |  |  | 	return self.bitOp(node.nodes, 'BINARY_XOR') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitTest(self, node, jump): | 
					
						
							|  |  |  |         end = StackRef() | 
					
						
							|  |  |  |         for child in node.nodes[:-1]: | 
					
						
							|  |  |  |             self.visit(child) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |             self.emit(jump, end) | 
					
						
							|  |  |  |             self.emit('POP_TOP') | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         self.visit(node.nodes[-1]) | 
					
						
							|  |  |  |         end.bind(self.code.getCurInst()) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def visitAssert(self, node): | 
					
						
							|  |  |  | 	# XXX __debug__ and AssertionError appear to be special cases | 
					
						
							|  |  |  | 	# -- they are always loaded as globals even if there are local | 
					
						
							|  |  |  | 	# names.  I guess this is a sort of renaming op. | 
					
						
							|  |  |  | 	skip = StackRef() | 
					
						
							|  |  |  | 	self.emit('SET_LINENO', node.lineno) | 
					
						
							|  |  |  | 	self.emit('LOAD_GLOBAL', '__debug__') | 
					
						
							|  |  |  | 	self.emit('JUMP_IF_FALSE', skip) | 
					
						
							|  |  |  | 	self.emit('POP_TOP') | 
					
						
							|  |  |  | 	self.visit(node.test) | 
					
						
							|  |  |  | 	self.emit('JUMP_IF_TRUE', skip) | 
					
						
							|  |  |  | 	self.emit('LOAD_GLOBAL', 'AssertionError') | 
					
						
							|  |  |  | 	self.visit(node.fail) | 
					
						
							|  |  |  | 	self.emit('RAISE_VARARGS', 2) | 
					
						
							|  |  |  | 	skip.bind(self.code.getCurInst()) | 
					
						
							|  |  |  | 	self.emit('POP_TOP') | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitAnd(self, node): | 
					
						
							|  |  |  |         return self.visitTest(node, 'JUMP_IF_FALSE') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitOr(self, node): | 
					
						
							|  |  |  |         return self.visitTest(node, 'JUMP_IF_TRUE') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitName(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-10 17:20:39 +00:00
										 |  |  |         self.loadName(node.name) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def visitConst(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('LOAD_CONST', node.value) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def visitEllipsis(self, node): | 
					
						
							|  |  |  | 	self.emit('LOAD_CONST', Ellipsis) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     def visitTuple(self, node): | 
					
						
							|  |  |  |         for elt in node.nodes: | 
					
						
							|  |  |  |             self.visit(elt) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('BUILD_TUPLE', len(node.nodes)) | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitList(self, node): | 
					
						
							|  |  |  |         for elt in node.nodes: | 
					
						
							|  |  |  |             self.visit(elt) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.emit('BUILD_LIST', len(node.nodes)) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def visitDict(self, node): | 
					
						
							|  |  |  | 	self.emit('BUILD_MAP', 0) | 
					
						
							|  |  |  | 	for k, v in node.items: | 
					
						
							|  |  |  | 	    # XXX need to add set lineno when there aren't constants | 
					
						
							|  |  |  | 	    self.emit('DUP_TOP') | 
					
						
							|  |  |  | 	    self.visit(v) | 
					
						
							|  |  |  | 	    self.emit('ROT_TWO') | 
					
						
							|  |  |  | 	    self.visit(k) | 
					
						
							|  |  |  | 	    self.emit('STORE_SUBSCR') | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitReturn(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	self.visit(node.value) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('RETURN_VALUE') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitRaise(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	n = 0 | 
					
						
							|  |  |  | 	if node.expr1: | 
					
						
							|  |  |  | 	    self.visit(node.expr1) | 
					
						
							|  |  |  | 	    n = n + 1 | 
					
						
							|  |  |  | 	if node.expr2: | 
					
						
							|  |  |  | 	    self.visit(node.expr2) | 
					
						
							|  |  |  | 	    n = n + 1 | 
					
						
							|  |  |  | 	if node.expr3: | 
					
						
							|  |  |  | 	    self.visit(node.expr3) | 
					
						
							|  |  |  | 	    n = n + 1 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('RAISE_VARARGS', n) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitPrint(self, node): | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('SET_LINENO', node.lineno) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	for child in node.nodes: | 
					
						
							|  |  |  | 	    self.visit(child) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	    self.emit('PRINT_ITEM') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitPrintnl(self, node): | 
					
						
							|  |  |  | 	self.visitPrint(node) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  | 	self.emit('PRINT_NEWLINE') | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return 1 | 
					
						
							| 
									
										
										
										
											2000-02-04 19:37:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def visitExec(self, node): | 
					
						
							|  |  |  | 	self.visit(node.expr) | 
					
						
							|  |  |  | 	if node.locals is None: | 
					
						
							|  |  |  | 	    self.emit('LOAD_CONST', None) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 	    self.visit(node.locals) | 
					
						
							|  |  |  | 	if node.globals is None: | 
					
						
							|  |  |  | 	    self.emit('DUP_TOP') | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 	    self.visit(node.globals) | 
					
						
							|  |  |  | 	self.emit('EXEC_STMT') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | class LocalNameFinder: | 
					
						
							|  |  |  |     def __init__(self, names=()): | 
					
						
							|  |  |  | 	self.names = misc.Set() | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         self.globals = misc.Set() | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	for name in names: | 
					
						
							|  |  |  | 	    self.names.add(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def getLocals(self): | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         for elt in self.globals.items(): | 
					
						
							|  |  |  |             if self.names.has_elt(elt): | 
					
						
							|  |  |  |                 self.names.remove(elt) | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 	return self.names | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |     def visitDict(self, node): | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     def visitGlobal(self, node): | 
					
						
							|  |  |  |         for name in node.names: | 
					
						
							|  |  |  |             self.globals.add(name) | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitFunction(self, node): | 
					
						
							|  |  |  |         self.names.add(node.name) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-11 20:27:07 +00:00
										 |  |  |     def visitLambda(self, node): | 
					
						
							|  |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  |     def visitImport(self, node): | 
					
						
							|  |  |  | 	for name in node.names: | 
					
						
							|  |  |  | 	    self.names.add(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitFrom(self, node): | 
					
						
							|  |  |  | 	for name in node.names: | 
					
						
							|  |  |  | 	    self.names.add(name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitClassdef(self, node): | 
					
						
							|  |  |  | 	self.names.add(node.name) | 
					
						
							|  |  |  | 	return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def visitAssName(self, node): | 
					
						
							|  |  |  | 	self.names.add(node.name) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-10 20:55:50 +00:00
										 |  |  | class Loop: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.startAnchor = StackRef() | 
					
						
							|  |  |  |         self.breakAnchor = StackRef() | 
					
						
							|  |  |  |         self.extentAnchor = StackRef() | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  | class CompiledModule: | 
					
						
							|  |  |  |     """Store the code object for a compiled module
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     XXX Not clear how the code objects will be stored.  Seems possible | 
					
						
							|  |  |  |     that a single code attribute is sufficient, because it will | 
					
						
							|  |  |  |     contains references to all the need code objects.  That might be | 
					
						
							|  |  |  |     messy, though. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     MAGIC = (20121 | (ord('\r')<<16) | (ord('\n')<<24)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, source, filename): | 
					
						
							|  |  |  |         self.source = source | 
					
						
							|  |  |  |         self.filename = filename | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def compile(self): | 
					
						
							|  |  |  |         t = transformer.Transformer() | 
					
						
							|  |  |  |         self.ast = t.parsesuite(self.source) | 
					
						
							|  |  |  |         cg = CodeGenerator(self.filename) | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         walk(self.ast, cg, walker=ExampleASTVisitor) | 
					
						
							| 
									
										
										
										
											2000-02-14 14:14:29 +00:00
										 |  |  |         self.code = cg.asConst() | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def dump(self, path): | 
					
						
							|  |  |  |         """create a .pyc file""" | 
					
						
							|  |  |  |         f = open(path, 'wb') | 
					
						
							|  |  |  |         f.write(self._pyc_header()) | 
					
						
							|  |  |  |         marshal.dump(self.code, f) | 
					
						
							|  |  |  |         f.close() | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     def _pyc_header(self): | 
					
						
							|  |  |  |         # compile.c uses marshal to write a long directly, with | 
					
						
							|  |  |  |         # calling the interface that would also generate a 1-byte code | 
					
						
							|  |  |  |         # to indicate the type of the value.  simplest way to get the | 
					
						
							|  |  |  |         # same effect is to call marshal and then skip the code. | 
					
						
							|  |  |  |         magic = marshal.dumps(self.MAGIC)[1:] | 
					
						
							|  |  |  |         mtime = os.stat(self.filename)[stat.ST_MTIME] | 
					
						
							|  |  |  |         mtime = struct.pack('i', mtime) | 
					
						
							|  |  |  |         return magic + mtime | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-02-04 00:28:21 +00:00
										 |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     import getopt | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |     opts, args = getopt.getopt(sys.argv[1:], 'vq') | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     for k, v in opts: | 
					
						
							|  |  |  |         if k == '-v': | 
					
						
							|  |  |  |             ASTVisitor.VERBOSE = ASTVisitor.VERBOSE + 1 | 
					
						
							| 
									
										
										
											
												add ExampleASTVisitor:
* prints out examples of nodes that are handled by visitor.  simply a
  development convenience
remove NestedCodeGenerator -- it was bogus after all
replace with generateFunctionCode, a method to call to generate code
  for a function instead of a top-level module
fix impl of visitDiscard (most pop stack)
emit lineno for pass
handle the following new node types: Import, From, Getattr, Subscript,
Slice, AssAttr, AssTuple, Mod, Not, And, Or, List
LocalNameFinder: remove names declared as globals for locals
PythonVMCode: pass arg names to constructor, force varnames to contain
them all (even if they aren't referenced)
add -q option on command line to disable stdout
											
										 
											2000-02-10 00:47:08 +00:00
										 |  |  |         if k == '-q': | 
					
						
							|  |  |  |             f = open('/dev/null', 'wb') | 
					
						
							|  |  |  |             sys.stdout = f | 
					
						
							| 
									
										
										
										
											2000-02-08 21:15:48 +00:00
										 |  |  |     if args: | 
					
						
							|  |  |  |         filename = args[0] | 
					
						
							| 
									
										
										
										
											2000-02-08 19:01:29 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         filename = 'test.py' | 
					
						
							|  |  |  |     buf = open(filename).read() | 
					
						
							|  |  |  |     mod = CompiledModule(buf, filename) | 
					
						
							|  |  |  |     mod.compile() | 
					
						
							|  |  |  |     mod.dump(filename + 'c') |