[Types-sig] Plea for help.

Jeremy Hylton jeremy@cnri.reston.va.us
Wed, 8 Dec 1999 12:45:37 -0500 (EST)


  >> Paul Prescod wrote:
  >> 
  >> > Here's my plea for help: among the many "Python compiler" >
  >> projects out there there must be some good Python code for >
  >> walking around ASTs building type (or at least module) >
  >> representation objects. I think that JPython is wirtten in Java.
  >> > What else should I be looking at?

Gordon and Guido offered some suggestions.

I have done some noodling with the Py2C AST, and I think it is an
excellent candidate.  

I was going to suggest that a good near-term goal for the type sig
would be to write a Python compiler in Python, but I see that Paul has
beaten me to it.  I believe this project was also discussed on
python-dev a few months ago (as part of the warnings discussion).  I
think it's a good project to tackle because it has usefulness beyond
the specific approaches to static type, which remain controversial.

When I was using the Py2C transformer class, I made some modifications
to the AST generated to make it a little easier to use interactively.
The original defintion for the AST was:

class Node:
  def __init__(self, *args):
    self.__children = args
    self.lineno = None
  def __getitem__(self, index):
    return self.__children[index]
  def __str__(self):
    return str(self.__children)
  def __repr__(self):
    return "<Node %s>" % self.__children[0]
  def __len__(self):
    return len(self.__children)
  def __getslice__(self, low, high):
    return self.__children[low:high]
  def getChildren(self):
    return self.__children
  def getType(self):
    return self.__children[0]
  def asList(self):
    return tuple(asList(self.__children))

A tree of these nodes is created by the Transformer class, which walks
the parse trees created by the parser module.

I modified Node to be BaseNode and created specific classes for each
of type of node:

class Function(BaseNode):
  def __init__(self, name, argnames, defaults, flags, doc, code):
    self.name = name
    self.argnames = argnames
    self.defaults = defaults
    self.flags = flags
    self.doc = doc
    self.code = code
    self._children = ('function', name, argnames, defaults, flags,
                      doc, code)
  def __repr__(self):
      return "Function(%s,%s,%s,%s,%s,%s)" % self._children[1:]
  def __str__(self):
      return "func:%s" % self.name

Jeremy