[Python-checkins] CVS: /python/nondist/src/Compiler/compiler ast.py,1.8,1.9 pyassem.py,1.8,1.9 pycodegen.py,1.19,1.20 transformer.py,1.9,1.10
Jeremy Hylton
python-dev@python.org
Tue, 2 May 2000 18:33:02 -0400
Update of /projects/cvsroot//python/nondist/src/Compiler/compiler
In directory goon.cnri.reston.va.us:/tmp/Compiler/compiler
Modified Files:
ast.py pyassem.py pycodegen.py transformer.py
Log Message:
patches from Mark Hammond
Attached is a set of diffs for the .py compiler that adds support
for the new extended call syntax.
compiler/ast.py:
CallFunc node gets 2 new children to support extended call syntax -
"star_args" (for "*args") and "dstar_args" (for "**args")
compiler/pyassem.py
It appear that self.lnotab is supposed to be responsible for
tracking line numbers, but self.firstlineno was still hanging
around. Removed self.firstlineno completely. NOTE - I didnt
actually test that the generated code has the correct line numbers!!
Stack depth tracking appeared a little broken - the checks never
made it beyond the "self.patterns" check - thus, the custom methods
were never called! Fixed this.
(XXX Jeremy notes: I think this code is still broken because it
doesn't track stack effects across block bounaries.)
Added support for the new extended call syntax opcodes for depth
calculations.
compiler/pycodegen.py
Added support for the new extended call syntax opcodes.
compiler/transformer.py
Added support for the new extended call syntax.
Index: ast.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compiler/ast.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** ast.py 2000/03/06 18:50:48 1.8
--- ast.py 2000/05/02 22:32:59 1.9
***************
*** 446,456 ****
nodes['call_func'] = 'CallFunc'
! def __init__(self, node, args):
self.node = node
self.args = args
! self._children = ('call_func', node, args)
def __repr__(self):
! return "CallFunc(%s,%s)" % self._children[1:]
class Keyword(Node):
--- 446,458 ----
nodes['call_func'] = 'CallFunc'
! def __init__(self, node, args, star_args = None, dstar_args = None):
self.node = node
self.args = args
! self.star_args = star_args
! self.dstar_args = dstar_args
! self._children = ('call_func', node, args, star_args, dstar_args)
def __repr__(self):
! return "CallFunc(%s,%s,*%s, **%s)" % self._children[1:]
class Keyword(Node):
Index: pyassem.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compiler/pyassem.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -r1.8 -r1.9
*** pyassem.py 2000/03/16 20:06:59 1.8
--- pyassem.py 2000/05/02 22:32:59 1.9
***************
*** 150,154 ****
else:
self.flags = 0
- self.firstlineno = None
self.consts = []
self.names = []
--- 150,153 ----
***************
*** 315,320 ****
if opname == "SET_LINENO":
lnotab.nextLine(oparg)
- if self.firstlineno is None:
- self.firstlineno = oparg
hi, lo = twobyte(oparg)
try:
--- 314,317 ----
***************
*** 343,347 ****
self.lnotab.getCode(), self.getConsts(),
tuple(self.names), tuple(self.varnames),
! self.filename, self.name, self.firstlineno,
self.lnotab.getTable())
--- 340,344 ----
self.lnotab.getCode(), self.getConsts(),
tuple(self.names), tuple(self.varnames),
! self.filename, self.name, self.lnotab.firstline,
self.lnotab.getTable())
***************
*** 465,476 ****
maxDepth = depth
# now check patterns
! for pat, delta in self.patterns:
if opname[:len(pat)] == pat:
depth = depth + delta
break
# if we still haven't found a match
if delta == 0:
! meth = getattr(self, opname)
! depth = depth + meth(i[1])
if depth < 0:
depth = 0
--- 462,475 ----
maxDepth = depth
# now check patterns
! for pat, pat_delta in self.patterns:
if opname[:len(pat)] == pat:
+ delta = pat_delta
depth = depth + delta
break
# if we still haven't found a match
if delta == 0:
! meth = getattr(self, opname, None)
! if meth is not None:
! depth = depth + meth(i[1])
if depth < 0:
depth = 0
***************
*** 528,531 ****
--- 527,536 ----
hi, lo = divmod(argc, 256)
return lo + hi * 2
+ def CALL_FUNCTION_VAR(self, argc):
+ return self.CALL_FUNCTION(argc)+1
+ def CALL_FUNCTION_KW(self, argc):
+ return self.CALL_FUNCTION(argc)+1
+ def CALL_FUNCTION_VAR_KW(self, argc):
+ return self.CALL_FUNCTION(argc)+2
def MAKE_FUNCTION(self, argc):
return -argc
Index: pycodegen.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compiler/pycodegen.py,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -r1.19 -r1.20
*** pycodegen.py 2000/03/16 20:06:59 1.19
--- pycodegen.py 2000/05/02 22:32:59 1.20
***************
*** 10,13 ****
--- 10,21 ----
from compiler.pyassem import CO_VARARGS, CO_VARKEYWORDS, TupleArg
+ callfunc_opcode_info = {
+ # (Have *args, Have **args) : opcode
+ (0,0) : "CALL_FUNCTION",
+ (1,0) : "CALL_FUNCTION_VAR",
+ (0,1) : "CALL_FUNCTION_KW",
+ (1,1) : "CALL_FUNCTION_VAR_KW",
+ }
+
def compile(filename):
f = open(filename)
***************
*** 479,483 ****
else:
pos = pos + 1
! self.emit('CALL_FUNCTION', kw << 8 | pos)
def visitPrint(self, node):
--- 487,498 ----
else:
pos = pos + 1
! if node.star_args is not None:
! self.visit(node.star_args)
! if node.dstar_args is not None:
! self.visit(node.dstar_args)
! have_star = node.star_args is not None
! have_dstar = node.dstar_args is not None
! opcode = callfunc_opcode_info[have_star, have_dstar]
! self.emit(opcode, kw << 8 | pos)
def visitPrint(self, node):
Index: transformer.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compiler/transformer.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** transformer.py 2000/03/16 20:03:04 1.9
--- transformer.py 2000/05/02 22:32:59 1.10
***************
*** 985,992 ****
args = [ ]
kw = 0
! for i in range(1, len(nodelist), 2):
! kw, result = self.com_argument(nodelist[i], kw)
args.append(result)
! return Node('call_func', primaryNode, args)
def com_argument(self, nodelist, kw):
--- 985,1014 ----
args = [ ]
kw = 0
! len_nodelist = len(nodelist)
! for i in range(1, len_nodelist, 2):
! node = nodelist[i]
! if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
! break
! kw, result = self.com_argument(node, kw)
args.append(result)
! else:
! i = i + 1 # No broken by star arg, so skip the last one we processed.
! star_node = dstar_node = None
! while i < len_nodelist:
! tok = nodelist[i]
! ch = nodelist[i+1]
! i = i + 3
! if tok[0]==token.STAR:
! if star_node is not None:
! raise SyntaxError, 'already have the varargs indentifier'
! star_node = self.com_node(ch)
! elif tok[0]==token.DOUBLESTAR:
! if dstar_node is not None:
! raise SyntaxError, 'already have the kwargs indentifier'
! dstar_node = self.com_node(ch)
! else:
! raise SyntaxError, 'unknown node type: %s' % tok
!
! return Node('call_func', primaryNode, args, star_node, dstar_node)
def com_argument(self, nodelist, kw):