[Python-checkins] python/dist/src/Lib/compiler pyassem.py,1.30,1.31 pycodegen.py,1.62,1.63 symbols.py,1.11,1.12 transformer.py,1.34,1.35

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
2002年12月31日 10:18:16 -0800


Update of /cvsroot/python/python/dist/src/Lib/compiler
In directory sc8-pr-cvs1:/tmp/cvs-serv3342/Lib/compiler
Modified Files:
	pyassem.py pycodegen.py symbols.py transformer.py 
Log Message:
SF patch [ 597919 ] compiler package and SET_LINENO
A variety of changes from Michael Hudson to get the compiler working
with 2.3. The primary change is the handling of SET_LINENO:
# The set_lineno() function and the explicit emit() calls for
# SET_LINENO below are only used to generate the line number table.
# As of Python 2.3, the interpreter does not have a SET_LINENO
# instruction. pyassem treats SET_LINENO opcodes as a special case.
A few other small changes:
 - Remove unused code from pycodegen and pyassem.
 - Fix error handling in parsermodule. When PyParser_SimplerParseString()
 fails, it sets an exception with detailed info. The parsermodule
 was clobbering that exception and replacing it was a generic
 "could not parse string" exception. Keep the original exception.
Index: pyassem.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/compiler/pyassem.py,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** pyassem.py	6 Jun 2002 18:30:10 -0000	1.30
--- pyassem.py	31 Dec 2002 18:17:42 -0000	1.31
***************
*** 7,19 ****
 
 from compiler import misc
! from compiler.consts import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, \
! CO_VARKEYWORDS
! 
! def xxx_sort(l):
! l = l[:]
! def sorter(a, b):
! return cmp(a.bid, b.bid)
! l.sort(sorter)
! return l
 
 class FlowGraph:
--- 7,12 ----
 
 from compiler import misc
! from compiler.consts \
! import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
 
 class FlowGraph:
***************
*** 78,82 ****
 if self._debug:
 print "\t", inst
! if inst[0] == 'RETURN_VALUE':
 self.current.addOutEdge(self.exit)
 if len(inst) == 2 and isinstance(inst[1], Block):
--- 71,75 ----
 if self._debug:
 print "\t", inst
! if inst[0] in ['RETURN_VALUE', 'YIELD_VALUE']:
 self.current.addOutEdge(self.exit)
 if len(inst) == 2 and isinstance(inst[1], Block):
***************
*** 267,271 ****
 assert len(self.next) == 1, map(str, self.next)
 
! _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS',
 'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP')
 
--- 260,264 ----
 assert len(self.next) == 1, map(str, self.next)
 
! _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS', 'YIELD_VALUE',
 'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP')
 
***************
*** 444,448 ****
 if len(inst) == 1:
 pc = pc + 1
! else:
 # arg takes 2 bytes
 pc = pc + 3
--- 437,441 ----
 if len(inst) == 1:
 pc = pc + 1
! elif inst[0] != "SET_LINENO":
 # arg takes 2 bytes
 pc = pc + 3
***************
*** 453,457 ****
 if len(inst) == 1:
 pc = pc + 1
! else:
 pc = pc + 3
 opname = inst[0]
--- 446,450 ----
 if len(inst) == 1:
 pc = pc + 1
! elif inst[0] != "SET_LINENO":
 pc = pc + 3
 opname = inst[0]
***************
*** 581,584 ****
--- 574,578 ----
 if opname == "SET_LINENO":
 lnotab.nextLine(oparg)
+ continue
 hi, lo = twobyte(oparg)
 try:
***************
*** 698,702 ****
 # compiler because it only generates a SET_LINENO instruction
 # for the assignment.
! if line > 0:
 push = self.lnotab.append
 while addr > 255:
--- 692,696 ----
 # compiler because it only generates a SET_LINENO instruction
 # for the assignment.
! if line >= 0:
 push = self.lnotab.append
 while addr > 255:
***************
*** 769,772 ****
--- 763,767 ----
 'PRINT_ITEM': -1,
 'RETURN_VALUE': -1,
+ 'YIELD_VALUE': -1,
 'EXEC_STMT': -3,
 'BUILD_CLASS': -2,
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/compiler/pycodegen.py,v
retrieving revision 1.62
retrieving revision 1.63
diff -C2 -d -r1.62 -r1.63
*** pycodegen.py	16 Dec 2002 13:54:01 -0000	1.62
--- pycodegen.py	31 Dec 2002 18:17:42 -0000	1.63
***************
*** 14,17 ****
--- 14,18 ----
 from compiler.pyassem import TupleArg
 
+ # XXX The version-specific code can go, since this code only works with 2.x.
 # Do we have Python 1.x or Python 2.x?
 try:
***************
*** 33,46 ****
 END_FINALLY = 4
 
- # XXX this doesn't seem to be used
- class BlockStack(misc.Stack):
- __super_init = misc.Stack.__init__
- 
- def __init__(self):
- self.__super_init(self)
- self.loop = None
- 
 def compileFile(filename, display=0):
! f = open(filename)
 buf = f.read()
 f.close()
--- 34,39 ----
 END_FINALLY = 4
 
 def compileFile(filename, display=0):
! f = open(filename, 'U')
 buf = f.read()
 f.close()
***************
*** 48,52 ****
 try:
 mod.compile(display)
! except SyntaxError, err:
 raise
 else:
--- 41,45 ----
 try:
 mod.compile(display)
! except SyntaxError:
 raise
 else:
***************
*** 135,139 ****
 # same effect is to call marshal and then skip the code.
 mtime = os.path.getmtime(self.filename)
! mtime = struct.pack('i', mtime)
 return self.MAGIC + mtime
 
--- 128,132 ----
 # same effect is to call marshal and then skip the code.
 mtime = os.path.getmtime(self.filename)
! mtime = struct.pack('<i', mtime)
 return self.MAGIC + mtime
 
***************
*** 311,317 ****
 self.emit(prefix + '_NAME', name)
 
! def set_lineno(self, node, force=0):
! """Emit SET_LINENO if node has lineno attribute and it is
! different than the last lineno emitted.
 
 Returns true if SET_LINENO was emitted.
--- 304,318 ----
 self.emit(prefix + '_NAME', name)
 
! # The set_lineno() function and the explicit emit() calls for
! # SET_LINENO below are only used to generate the line number table.
! # As of Python 2.3, the interpreter does not have a SET_LINENO
! # instruction. pyassem treats SET_LINENO opcodes as a special case.
! 
! def set_lineno(self, node, force=False):
! """Emit SET_LINENO if necessary.
! 
! The instruction is considered necessary if the node has a
! lineno attribute and it is different than the last lineno
! emitted.
 
 Returns true if SET_LINENO was emitted.
***************
*** 327,332 ****
 self.emit('SET_LINENO', lineno)
 self.last_lineno = lineno
! return 1
! return 0
 
 # The first few visitor methods handle nodes that generator new
--- 328,333 ----
 self.emit('SET_LINENO', lineno)
 self.last_lineno = lineno
! return True
! return False
 
 # The first few visitor methods handle nodes that generator new
***************
*** 388,394 ****
 gen = self.ClassGen(node, self.scopes,
 self.get_module())
- if node.doc:
- self.emit('LOAD_CONST', node.doc)
- self.storeName('__doc__')
 walk(node.code, gen)
 gen.finish()
--- 389,392 ----
***************
*** 448,452 ****
 self.setups.push((LOOP, loop))
 
! self.set_lineno(node, force=1)
 self.visit(node.test)
 self.emit('JUMP_IF_FALSE', else_ or after)
--- 446,450 ----
 self.setups.push((LOOP, loop))
 
! self.set_lineno(node, force=True)
 self.visit(node.test)
 self.emit('JUMP_IF_FALSE', else_ or after)
***************
*** 618,622 ****
 
 def visitListCompIf(self, node, branch):
! self.set_lineno(node, force=1)
 self.visit(node.test)
 self.emit('JUMP_IF_FALSE', branch)
--- 616,620 ----
 
 def visitListCompIf(self, node, branch):
! self.set_lineno(node, force=True)
 self.visit(node.test)
 self.emit('JUMP_IF_FALSE', branch)
***************
*** 976,980 ****
 self.set_lineno(node)
 self.visit(node.value)
! self.emit('YIELD_STMT')
 
 # slice and subscript stuff
--- 974,978 ----
 self.set_lineno(node)
 self.visit(node.value)
! self.emit('YIELD_VALUE')
 
 # slice and subscript stuff
***************
*** 1267,1273 ****
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
! if self.graph.checkFlag(CO_GENERATOR_ALLOWED):
! if self.scope.generator is not None:
! self.graph.setFlag(CO_GENERATOR)
 
 class AbstractClassCode:
--- 1265,1270 ----
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
! if self.scope.generator is not None:
! self.graph.setFlag(CO_GENERATOR)
 
 class AbstractClassCode:
***************
*** 1305,1308 ****
--- 1302,1311 ----
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
+ self.set_lineno(klass)
+ self.emit("LOAD_GLOBAL", "__name__")
+ self.storeName("__module__")
+ if klass.doc:
+ self.emit("LOAD_CONST", klass.doc)
+ self.storeName('__doc__')
 
 def generateArgList(arglist):
***************
*** 1380,1385 ****
 
 if __name__ == "__main__":
- import sys
- 
 for file in sys.argv[1:]:
 compileFile(file)
--- 1383,1386 ----
Index: symbols.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/compiler/symbols.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** symbols.py	21 Dec 2001 20:03:35 -0000	1.11
--- symbols.py	31 Dec 2002 18:17:42 -0000	1.12
***************
*** 250,253 ****
--- 250,256 ----
 if parent.nested or isinstance(parent, FunctionScope):
 scope.nested = 1
+ if node.doc is not None:
+ scope.add_def('__doc__')
+ scope.add_def('__module__')
 self.scopes[node] = scope
 prev = self.klass
Index: transformer.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** transformer.py	6 Jun 2002 18:30:10 -0000	1.34
--- transformer.py	31 Dec 2002 18:17:42 -0000	1.35
***************
*** 38,42 ****
 def parseFile(path):
 f = open(path)
! src = f.read()
 f.close()
 return parse(src)
--- 38,46 ----
 def parseFile(path):
 f = open(path)
! # XXX The parser API tolerates files without a trailing newline,
! # but not strings without a trailing newline. Always add an extra
! # newline to the file contents, since we're going through the string
! # version of the API.
! src = f.read() + "\n"
 f.close()
 return parse(src)
***************
*** 101,104 ****
--- 105,109 ----
 token.NAME: self.atom_name,
 }
+ self.encoding = None
 
 def transform(self, tree):
***************
*** 111,114 ****
--- 116,120 ----
 """Return a modified parse tree for the given suite text."""
 # Hack for handling non-native line endings on non-DOS like OSs.
+ # this can go now we have universal newlines?
 text = text.replace('\x0d', '')
 return self.transform(parser.suite(text))
***************
*** 132,135 ****
--- 138,147 ----
 ### emit a line-number node?
 n = node[0]
+ 
+ if n == symbol.encoding_decl:
+ self.encoding = node[2]
+ node = node[1]
+ n = node[0]
+ 
 if n == symbol.single_input:
 return self.single_input(node[1:])
***************
*** 520,523 ****
--- 532,536 ----
 
 testlist_safe = testlist # XXX
+ testlist1 = testlist
 exprlist = testlist
 
***************
*** 638,646 ****
--- 651,662 ----
 elt = nodelist[0]
 t = elt[0]
+ print "source", nodelist[-1]
 node = self.com_node(nodelist[-1])
+ # need to handle (unary op)constant here...
 if t == token.PLUS:
 node = UnaryAdd(node)
 node.lineno = elt[2]
 elif t == token.MINUS:
+ print node
 node = UnarySub(node)
 node.lineno = elt[2]
***************
*** 700,708 ****
 return n
 
 def atom_string(self, nodelist):
- ### need to verify this matches compile.c
 k = ''
 for node in nodelist:
! k = k + eval(node[1])
 n = Const(k)
 n.lineno = nodelist[0][2]
--- 716,734 ----
 return n
 
+ def decode_literal(self, lit):
+ if self.encoding:
+ # this is particularly fragile & a bit of a
+ # hack... changes in compile.c:parsestr and
+ # tokenizer.c must be reflected here.
+ if self.encoding not in ['utf-8', 'iso-8859-1']:
+ lit = unicode(lit, 'utf-8').encode(self.encoding)
+ return eval("# coding: %s\n%s" % (self.encoding, lit))
+ else:
+ return eval(lit)
+ 
 def atom_string(self, nodelist):
 k = ''
 for node in nodelist:
! k += self.decode_literal(node[1])
 n = Const(k)
 n.lineno = nodelist[0][2]

AltStyle によって変換されたページ (->オリジナル) /