mirror of https://github.com/python/cpython.git
finish first impl of code generator
add support for nodes TryExcept, TryFinally, Sliceobj fix visitSubscript to properly handle x[a,b,c]
This commit is contained in:
parent
1ebba96871
commit
4f6bcd80fc
|
@ -155,13 +155,7 @@ def dispatch(self, node):
|
||||||
print
|
print
|
||||||
|
|
||||||
class CodeGenerator:
|
class CodeGenerator:
|
||||||
"""TODO
|
"""Generate bytecode for the Python VM"""
|
||||||
|
|
||||||
EmptyNode
|
|
||||||
Sliceobj
|
|
||||||
Tryexcept
|
|
||||||
Tryfinally
|
|
||||||
"""
|
|
||||||
|
|
||||||
OPTIMIZED = 1
|
OPTIMIZED = 1
|
||||||
|
|
||||||
|
@ -425,6 +419,63 @@ def visitContinue(self, node):
|
||||||
self.emit('SET_LINENO', node.lineno)
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.emit('JUMP_ABSOLUTE', l.startAnchor)
|
self.emit('JUMP_ABSOLUTE', l.startAnchor)
|
||||||
|
|
||||||
|
def visitTryExcept(self, node):
|
||||||
|
# XXX need to figure out exactly what is on the stack when an
|
||||||
|
# exception is raised and the first handler is checked
|
||||||
|
handlers = StackRef()
|
||||||
|
end = StackRef()
|
||||||
|
if node.else_:
|
||||||
|
lElse = StackRef()
|
||||||
|
else:
|
||||||
|
lElse = end
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
|
self.emit('SETUP_EXCEPT', handlers)
|
||||||
|
self.visit(node.body)
|
||||||
|
self.emit('POP_BLOCK')
|
||||||
|
self.emit('JUMP_FORWARD', lElse)
|
||||||
|
handlers.bind(self.code.getCurInst())
|
||||||
|
|
||||||
|
last = len(node.handlers) - 1
|
||||||
|
for i in range(len(node.handlers)):
|
||||||
|
expr, target, body = node.handlers[i]
|
||||||
|
if hasattr(expr, 'lineno'):
|
||||||
|
self.emit('SET_LINENO', expr.lineno)
|
||||||
|
if expr:
|
||||||
|
self.emit('DUP_TOP')
|
||||||
|
self.visit(expr)
|
||||||
|
self.emit('COMPARE_OP', "exception match")
|
||||||
|
next = StackRef()
|
||||||
|
self.emit('JUMP_IF_FALSE', next)
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
if target:
|
||||||
|
self.visit(target)
|
||||||
|
else:
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.visit(body)
|
||||||
|
self.emit('JUMP_FORWARD', end)
|
||||||
|
next.bind(self.code.getCurInst())
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('END_FINALLY')
|
||||||
|
if node.else_:
|
||||||
|
lElse.bind(self.code.getCurInst())
|
||||||
|
self.visit(node.else_)
|
||||||
|
end.bind(self.code.getCurInst())
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def visitTryFinally(self, node):
|
||||||
|
final = StackRef()
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
|
self.emit('SETUP_FINALLY', final)
|
||||||
|
self.visit(node.body)
|
||||||
|
self.emit('POP_BLOCK')
|
||||||
|
self.emit('LOAD_CONST', None)
|
||||||
|
final.bind(self.code.getCurInst())
|
||||||
|
self.visit(node.final)
|
||||||
|
self.emit('END_FINALLY')
|
||||||
|
return 1
|
||||||
|
|
||||||
def visitCompare(self, node):
|
def visitCompare(self, node):
|
||||||
"""Comment from compile.c follows:
|
"""Comment from compile.c follows:
|
||||||
|
|
||||||
|
@ -492,17 +543,17 @@ def visitGetattr(self, node):
|
||||||
|
|
||||||
def visitSubscript(self, node):
|
def visitSubscript(self, node):
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
for sub in node.subs[:-1]:
|
for sub in node.subs:
|
||||||
self.visit(sub)
|
self.visit(sub)
|
||||||
self.emit('BINARY_SUBSCR')
|
if len(node.subs) > 1:
|
||||||
self.visit(node.subs[-1])
|
self.emit('BUILD_TUPLE', len(node.subs))
|
||||||
if node.flags == 'OP_APPLY':
|
if node.flags == 'OP_APPLY':
|
||||||
self.emit('BINARY_SUBSCR')
|
self.emit('BINARY_SUBSCR')
|
||||||
elif node.flags == 'OP_ASSIGN':
|
elif node.flags == 'OP_ASSIGN':
|
||||||
self.emit('STORE_SUBSCR')
|
self.emit('STORE_SUBSCR')
|
||||||
elif node.flags == 'OP_DELETE':
|
elif node.flags == 'OP_DELETE':
|
||||||
self.emit('DELETE_SUBSCR')
|
self.emit('DELETE_SUBSCR')
|
||||||
|
print
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def visitSlice(self, node):
|
def visitSlice(self, node):
|
||||||
|
@ -521,10 +572,17 @@ def visitSlice(self, node):
|
||||||
elif node.flags == 'OP_DELETE':
|
elif node.flags == 'OP_DELETE':
|
||||||
self.emit('DELETE_SLICE+%d' % slice)
|
self.emit('DELETE_SLICE+%d' % slice)
|
||||||
else:
|
else:
|
||||||
print node.flags
|
print "weird slice", node.flags
|
||||||
raise
|
raise
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def visitSliceobj(self, node):
|
||||||
|
for child in node.nodes:
|
||||||
|
print child
|
||||||
|
self.visit(child)
|
||||||
|
self.emit('BUILD_SLICE', len(node.nodes))
|
||||||
|
return 1
|
||||||
|
|
||||||
def visitAssign(self, node):
|
def visitAssign(self, node):
|
||||||
self.emit('SET_LINENO', node.lineno)
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
|
|
|
@ -155,13 +155,7 @@ def dispatch(self, node):
|
||||||
print
|
print
|
||||||
|
|
||||||
class CodeGenerator:
|
class CodeGenerator:
|
||||||
"""TODO
|
"""Generate bytecode for the Python VM"""
|
||||||
|
|
||||||
EmptyNode
|
|
||||||
Sliceobj
|
|
||||||
Tryexcept
|
|
||||||
Tryfinally
|
|
||||||
"""
|
|
||||||
|
|
||||||
OPTIMIZED = 1
|
OPTIMIZED = 1
|
||||||
|
|
||||||
|
@ -425,6 +419,63 @@ def visitContinue(self, node):
|
||||||
self.emit('SET_LINENO', node.lineno)
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.emit('JUMP_ABSOLUTE', l.startAnchor)
|
self.emit('JUMP_ABSOLUTE', l.startAnchor)
|
||||||
|
|
||||||
|
def visitTryExcept(self, node):
|
||||||
|
# XXX need to figure out exactly what is on the stack when an
|
||||||
|
# exception is raised and the first handler is checked
|
||||||
|
handlers = StackRef()
|
||||||
|
end = StackRef()
|
||||||
|
if node.else_:
|
||||||
|
lElse = StackRef()
|
||||||
|
else:
|
||||||
|
lElse = end
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
|
self.emit('SETUP_EXCEPT', handlers)
|
||||||
|
self.visit(node.body)
|
||||||
|
self.emit('POP_BLOCK')
|
||||||
|
self.emit('JUMP_FORWARD', lElse)
|
||||||
|
handlers.bind(self.code.getCurInst())
|
||||||
|
|
||||||
|
last = len(node.handlers) - 1
|
||||||
|
for i in range(len(node.handlers)):
|
||||||
|
expr, target, body = node.handlers[i]
|
||||||
|
if hasattr(expr, 'lineno'):
|
||||||
|
self.emit('SET_LINENO', expr.lineno)
|
||||||
|
if expr:
|
||||||
|
self.emit('DUP_TOP')
|
||||||
|
self.visit(expr)
|
||||||
|
self.emit('COMPARE_OP', "exception match")
|
||||||
|
next = StackRef()
|
||||||
|
self.emit('JUMP_IF_FALSE', next)
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
if target:
|
||||||
|
self.visit(target)
|
||||||
|
else:
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.visit(body)
|
||||||
|
self.emit('JUMP_FORWARD', end)
|
||||||
|
next.bind(self.code.getCurInst())
|
||||||
|
self.emit('POP_TOP')
|
||||||
|
self.emit('END_FINALLY')
|
||||||
|
if node.else_:
|
||||||
|
lElse.bind(self.code.getCurInst())
|
||||||
|
self.visit(node.else_)
|
||||||
|
end.bind(self.code.getCurInst())
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def visitTryFinally(self, node):
|
||||||
|
final = StackRef()
|
||||||
|
self.emit('SET_LINENO', node.lineno)
|
||||||
|
self.emit('SETUP_FINALLY', final)
|
||||||
|
self.visit(node.body)
|
||||||
|
self.emit('POP_BLOCK')
|
||||||
|
self.emit('LOAD_CONST', None)
|
||||||
|
final.bind(self.code.getCurInst())
|
||||||
|
self.visit(node.final)
|
||||||
|
self.emit('END_FINALLY')
|
||||||
|
return 1
|
||||||
|
|
||||||
def visitCompare(self, node):
|
def visitCompare(self, node):
|
||||||
"""Comment from compile.c follows:
|
"""Comment from compile.c follows:
|
||||||
|
|
||||||
|
@ -492,17 +543,17 @@ def visitGetattr(self, node):
|
||||||
|
|
||||||
def visitSubscript(self, node):
|
def visitSubscript(self, node):
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
for sub in node.subs[:-1]:
|
for sub in node.subs:
|
||||||
self.visit(sub)
|
self.visit(sub)
|
||||||
self.emit('BINARY_SUBSCR')
|
if len(node.subs) > 1:
|
||||||
self.visit(node.subs[-1])
|
self.emit('BUILD_TUPLE', len(node.subs))
|
||||||
if node.flags == 'OP_APPLY':
|
if node.flags == 'OP_APPLY':
|
||||||
self.emit('BINARY_SUBSCR')
|
self.emit('BINARY_SUBSCR')
|
||||||
elif node.flags == 'OP_ASSIGN':
|
elif node.flags == 'OP_ASSIGN':
|
||||||
self.emit('STORE_SUBSCR')
|
self.emit('STORE_SUBSCR')
|
||||||
elif node.flags == 'OP_DELETE':
|
elif node.flags == 'OP_DELETE':
|
||||||
self.emit('DELETE_SUBSCR')
|
self.emit('DELETE_SUBSCR')
|
||||||
|
print
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def visitSlice(self, node):
|
def visitSlice(self, node):
|
||||||
|
@ -521,10 +572,17 @@ def visitSlice(self, node):
|
||||||
elif node.flags == 'OP_DELETE':
|
elif node.flags == 'OP_DELETE':
|
||||||
self.emit('DELETE_SLICE+%d' % slice)
|
self.emit('DELETE_SLICE+%d' % slice)
|
||||||
else:
|
else:
|
||||||
print node.flags
|
print "weird slice", node.flags
|
||||||
raise
|
raise
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def visitSliceobj(self, node):
|
||||||
|
for child in node.nodes:
|
||||||
|
print child
|
||||||
|
self.visit(child)
|
||||||
|
self.emit('BUILD_SLICE', len(node.nodes))
|
||||||
|
return 1
|
||||||
|
|
||||||
def visitAssign(self, node):
|
def visitAssign(self, node):
|
||||||
self.emit('SET_LINENO', node.lineno)
|
self.emit('SET_LINENO', node.lineno)
|
||||||
self.visit(node.expr)
|
self.visit(node.expr)
|
||||||
|
|
Loading…
Reference in New Issue