[Python-checkins] python/nondist/sandbox/parrot parrot-gen.py,1.3,1.4

akuchling@users.sourceforge.net akuchling@users.sourceforge.net
Sat, 20 Jul 2002 04:31:33 -0700


Update of /cvsroot/python/python/nondist/sandbox/parrot
In directory usw-pr-cvs1:/tmp/cvs-serv18180

Modified Files:
	parrot-gen.py 
Log Message:
Various old changes:
    * Use PMC registers instead of integer registers
    * Allow strings as well as integers
    * Add setline opcodes to the output; also, set filename in compiled code
    * Implement the 'pass' statement :)
Use correct executable filename for Parrot 0.0.7


Index: parrot-gen.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/parrot/parrot-gen.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** parrot-gen.py	17 Dec 2001 13:42:31 -0000	1.3
--- parrot-gen.py	20 Jul 2002 11:31:31 -0000	1.4
***************
*** 27,34 ****
  from compiler.pycodegen import LocalNameFinder
  
! # List 31 of the 32 integer registers as being available
  FREE_REGISTERS = []
  for i in range(1, 32):
!     FREE_REGISTERS.append('I' + str(i))
  
  # Global variable: maps local variable names to their assigned register
--- 27,34 ----
  from compiler.pycodegen import LocalNameFinder
  
! # List 31 of the 32 PMC registers as being available
  FREE_REGISTERS = []
  for i in range(1, 32):
!     FREE_REGISTERS.append('P' + str(i))
  
  # Global variable: maps local variable names to their assigned register
***************
*** 57,61 ****
          self.lines = []
          self.symcount = 0
! 
      def add_line (self, line):
          """add_line(line:string)
--- 57,62 ----
          self.lines = []
          self.symcount = 0
!         self._last_lineno = None
!         
      def add_line (self, line):
          """add_line(line:string)
***************
*** 64,68 ****
          and is indented properly.
          """
!         
          line = line.rstrip() + '\n'
  
--- 65,69 ----
          and is indented properly.
          """
! 
          line = line.rstrip() + '\n'
  
***************
*** 80,88 ****
              self.add_line(line)
  
!     # Visitor methods.  Most of the
      def visitAssign (self, node):
          a_name = node.nodes[0].name
          reg = LOCAL_REGS[a_name]
!         lines = compile_expr(node.expr, reg, FREE_REGISTERS)
          self.add_lines(lines)
          # XXX assign result to 'a_name.name'
--- 81,98 ----
              self.add_line(line)
  
!     def set_lineno (self, node):
!         if (node.lineno is not None and
!             node.lineno != self._last_lineno):
!             self._last_lineno = node.lineno
!             return ['setline %i' % node.lineno]
!         else:
!             return []
!         
!     # Visitor methods.  Most of them are currently unimplemented.
      def visitAssign (self, node):
          a_name = node.nodes[0].name
          reg = LOCAL_REGS[a_name]
!         lines = (self.set_lineno(node) + 
!                  compile_expr(node.expr, reg, FREE_REGISTERS) )
          self.add_lines(lines)
          # XXX assign result to 'a_name.name'
***************
*** 97,102 ****
          sym2 = gensym()
  
!         lines = (compile_expr(test_expr, 'I0', FREE_REGISTERS) +
!                  ["if I0, %s" % sym,
                    "branch %s" % sym2,
                    "%s:" % sym])
--- 107,113 ----
          sym2 = gensym()
  
!         lines = self.set_lineno(test_expr)
!         lines += (compile_expr(test_expr, 'P0', FREE_REGISTERS) +
!                  ["if P0, %s" % sym,
                    "branch %s" % sym2,
                    "%s:" % sym])
***************
*** 112,118 ****
          lines = []
          for n in node.nodes:
!             lines += compile_expr(n, 'I0', FREE_REGISTERS)
!             lines += ["print I0", 'print " "']
!         lines += ['print "\\n"']
          self.add_lines(lines)
  
--- 123,130 ----
          lines = []
          for n in node.nodes:
!             lines.extend(self.set_lineno(n))
!             lines.extend(compile_expr(n, 'P0', FREE_REGISTERS))
!             lines.extend(["print P0", 'print " "'])
!         lines.append('print "\\n"')
          self.add_lines(lines)
  
***************
*** 168,172 ****
  ##         assert 0, "not implemented"
      def visitDiscard(self, node):
!         lines = compile_expr(node.expr, 'I0', FREE_REGISTERS)
          self.add_lines(lines)
  ##     def visitEllipsis(self, node):
--- 180,185 ----
  ##         assert 0, "not implemented"
      def visitDiscard(self, node):
!         lines = (self.set_lineno(node) +
!                  compile_expr(node.expr, 'P0', FREE_REGISTERS) )
          self.add_lines(lines)
  ##     def visitEllipsis(self, node):
***************
*** 223,228 ****
  ##     def visitOr(self, node):
  ##         assert 0, "not implemented"
! ##     def visitPass(self, node):
! ##         assert 0, "not implemented"
  ##     def visitPower(self, node):
  ##         assert 0, "not implemented"
--- 236,242 ----
  ##     def visitOr(self, node):
  ##         assert 0, "not implemented"
!     def visitPass(self, node):
!         self.add_lines(self.set_lineno(node))
!         self.add_lines(["noop"])
  ##     def visitPower(self, node):
  ##         assert 0, "not implemented"
***************
*** 258,269 ****
      def visitWhile(self, node):
          assert node.else_ is None, "while...else not supported"
          start = gensym()
          end = gensym()
  
          self.add_line("%s:" % start)
!         self.add_lines(compile_expr(node.test, 'I0', FREE_REGISTERS))
!         self.add_line('EQ I0, 0, %s' % end)
          self.visit(node.body)
!         self.add_line('BRANCH %s' % start)
          self.add_line("%s:" % end)
  
--- 272,285 ----
      def visitWhile(self, node):
          assert node.else_ is None, "while...else not supported"
+         self.add_lines(self.set_lineno(node))
          start = gensym()
          end = gensym()
  
          self.add_line("%s:" % start)
!         self.add_lines(self.set_lineno(node))
!         self.add_lines(compile_expr(node.test, 'P0', FREE_REGISTERS))
!         self.add_line('if P0, %s' % end)
          self.visit(node.body)
!         self.add_line('branch %s' % start)
          self.add_line("%s:" % end)
  
***************
*** 276,282 ****
      'avail_registers' is a list of unused registers.
      
      
      XXX This handles registers really stupidly, and always leaves its
!     result in I0; it should allocate registers more efficiently.
      XXX how to handle string constants, or constants of other types?
      """
--- 292,299 ----
      'avail_registers' is a list of unused registers.
      
+     self.add_lines(self.set_lineno(expr))
      
      XXX This handles registers really stupidly, and always leaves its
!     result in P0; it should allocate registers more efficiently.
      XXX how to handle string constants, or constants of other types?
      """
***************
*** 290,301 ****
      
      if isinstance(expr, ast.Const):
!         assert type(expr.value) == types.IntType, "Only int type is supported"
!         return ["set %s, %r" % (dest_register, expr.value)]
  
      elif isinstance(expr, ast.Name):
          reg = LOCAL_REGS[expr.name]
!         temp = random.choice(FREE_REGISTERS)
!         return ["set %s, 0" % temp,
!                 "add %s, %s, %s" % (dest_register, reg, temp)]
      
      elif (isinstance(expr, ast.Add) or
--- 307,327 ----
      
      if isinstance(expr, ast.Const):
!         t = type(expr.value) 
!         assert t in [types.IntType, types.StringType,
!                                     types.FloatType], \
!                                     "Unsupported type: %r" % t
!         if t is types.StringType:
!             return ["new %s, .PerlString" % dest_register,
!                     "set %s, %r" % (dest_register, expr.value)
!                     ]
!         else:
!             # A number of some sort
!             return ["new %s, .PerlNum" % dest_register,
!                     "set %s, %r" % (dest_register, expr.value)
!                     ]
  
      elif isinstance(expr, ast.Name):
          reg = LOCAL_REGS[expr.name]
!         return ["set %s, %s" % (dest_register, reg)]
      
      elif (isinstance(expr, ast.Add) or
***************
*** 365,374 ****
      vtor = visitor.ASTVisitor()
      pv = ParrotVisitor()
      vtor.preorder(ast, pv)
      
      # Write the generated assembly code
      lines = ["main:\n"] + pv.lines + ["\tend\n"]
      output = open(output_name, 'w')
!     output.writelines(lines)
      output.close()
  
--- 391,409 ----
      vtor = visitor.ASTVisitor()
      pv = ParrotVisitor()
+ 
+     for line in ["main:",
+                  'setfile "%s"' % input_name,
+                  'setpackage "__main__"']:
+         pv.add_line(line)
+ 
+     # Generate lines of assembly code
      vtor.preorder(ast, pv)
+ 
+     pv.add_line('end')
      
      # Write the generated assembly code
      lines = ["main:\n"] + pv.lines + ["\tend\n"]
      output = open(output_name, 'w')
!     output.writelines(pv.lines)
      output.close()
  
***************
*** 403,411 ****
              if err: sys.exit(err)
          if do_run:
!             err = os.system('%s/test_parrot %s' % (PARROT_SRC,
                                                     bytecode_filename))
              if err == 139:
                  print 'Parrot interpreter dumped core'
!             if err: sys.exit(err)
      
  if __name__ == '__main__':
--- 438,447 ----
              if err: sys.exit(err)
          if do_run:
!             err = os.system('%s/parrot -t %s' % (PARROT_SRC,
                                                     bytecode_filename))
              if err == 139:
                  print 'Parrot interpreter dumped core'
!             if err:
!                 sys.exit(err)
      
  if __name__ == '__main__':