[Compiler-sig] Re: [Python-checkins] CVS: /python/nondist/src/Compiler compile.py,1.13,1.14

Greg Stein gstein@lyra.org
Tue, 15 Feb 2000 16:27:48 -0800 (PST)


Yay! I'm glad that you chose an "emit" model for pumping out the opcodes.
I'm using the same model for another VM and it is much superior to the
"return the code" model used by P2C's C source generator.

Coolness.

Bill and I want to change P2C's C gen over to that, but it will be a big
change. I'd also hope that we can find some common utilities and stuff
between the PVM generator and the C generator. In particular: namespace
abstractions/handling would be nice.

Cheers,
-g

On Tue, 15 Feb 2000, Jeremy Hylton wrote:
> Update of /projects/cvsroot//python/nondist/src/Compiler
> In directory goon.cnri.reston.va.us:/home/jhylton/python/nondist/src/Compiler
> 
> Modified Files:
> 	compile.py 
> Log Message:
> finish first impl of code generator
> 
> add support for nodes TryExcept, TryFinally, Sliceobj
> fix visitSubscript to properly handle x[a,b,c]
> 
> 
> 
> 
> 
> Index: compile.py
> ===================================================================
> RCS file: /projects/cvsroot//python/nondist/src/Compiler/compile.py,v
> retrieving revision 1.13
> retrieving revision 1.14
> diff -C2 -r1.13 -r1.14
> *** compile.py	2000/02/14 23:57:56	1.13
> --- compile.py	2000/02/15 23:45:26	1.14
> ***************
> *** 156,167 ****
>   
>   class CodeGenerator:
> !     """TODO
>   
> -     EmptyNode
> -     Sliceobj
> -     Tryexcept
> -     Tryfinally
> -     """
> - 
>       OPTIMIZED = 1
>   
> --- 156,161 ----
>   
>   class CodeGenerator:
> !     """Generate bytecode for the Python VM"""
>   
>       OPTIMIZED = 1
>   
> ***************
> *** 426,429 ****
> --- 420,480 ----
>           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):
>   	"""Comment from compile.c follows:
> ***************
> *** 493,500 ****
>       def visitSubscript(self, node):
>           self.visit(node.expr)
> !         for sub in node.subs[:-1]:
>               self.visit(sub)
> !             self.emit('BINARY_SUBSCR')
> !         self.visit(node.subs[-1])
>           if node.flags == 'OP_APPLY':
>               self.emit('BINARY_SUBSCR')
> --- 544,551 ----
>       def visitSubscript(self, node):
>           self.visit(node.expr)
> !         for sub in node.subs:
>               self.visit(sub)
> !         if len(node.subs) > 1:
> !             self.emit('BUILD_TUPLE', len(node.subs))
>           if node.flags == 'OP_APPLY':
>               self.emit('BINARY_SUBSCR')
> ***************
> *** 503,507 ****
>   	elif node.flags == 'OP_DELETE':
>               self.emit('DELETE_SUBSCR')
> !             
>           return 1
>   
> --- 554,558 ----
>   	elif node.flags == 'OP_DELETE':
>               self.emit('DELETE_SUBSCR')
> !         print
>           return 1
>   
> ***************
> *** 522,527 ****
>               self.emit('DELETE_SLICE+%d' % slice)
>           else:
> !             print node.flags
>               raise
>           return 1
>   
> --- 573,585 ----
>               self.emit('DELETE_SLICE+%d' % slice)
>           else:
> !             print "weird slice", node.flags
>               raise
> +         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

-- 
Greg Stein, http://www.lyra.org/