[Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.62,2.63

Fred L. Drake fdrake@users.sourceforge.net
Tue, 17 Jul 2001 12:32:09 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv6018/Modules

Modified Files:
	parsermodule.c 
Log Message:

The syntax trees handled by this module are not "abstract," so take the
"A" out of the internal abbreviations.  For published functions with
"ast" in their names, make alternate offerings using just "st".


Index: parsermodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v
retrieving revision 2.62
retrieving revision 2.63
diff -C2 -r2.62 -r2.63
*** parsermodule.c	2001/07/17 02:59:15	2.62
--- parsermodule.c	2001/07/17 19:32:05	2.63
***************
*** 134,153 ****
  
  /*  There are two types of intermediate objects we're interested in:
!  *  'eval' and 'exec' types.  These constants can be used in the ast_type
   *  field of the object type to identify which any given object represents.
   *  These should probably go in an external header to allow other extensions
   *  to use them, but then, we really should be using C++ too.  ;-)
-  *
-  *  The PyAST_FRAGMENT type is not currently supported.  Maybe not useful?
-  *  Haven't decided yet.
   */
  
! #define PyAST_EXPR      1
! #define PyAST_SUITE     2
! #define PyAST_FRAGMENT  3
  
  
  /*  These are the internal objects and definitions required to implement the
!  *  AST type.  Most of the internal names are more reminiscent of the 'old'
   *  naming style, but the code uses the new naming convention.
   */
--- 134,149 ----
  
  /*  There are two types of intermediate objects we're interested in:
!  *  'eval' and 'exec' types.  These constants can be used in the st_type
   *  field of the object type to identify which any given object represents.
   *  These should probably go in an external header to allow other extensions
   *  to use them, but then, we really should be using C++ too.  ;-)
   */
  
! #define PyST_EXPR  1
! #define PyST_SUITE 2
  
  
  /*  These are the internal objects and definitions required to implement the
!  *  ST type.  Most of the internal names are more reminiscent of the 'old'
   *  naming style, but the code uses the new naming convention.
   */
***************
*** 157,172 ****
  
  
! typedef struct _PyAST_Object {
      PyObject_HEAD                       /* standard object header           */
!     node* ast_node;                     /* the node* returned by the parser */
!     int   ast_type;                     /* EXPR or SUITE ?                  */
! } PyAST_Object;
  
  
  staticforward void
! parser_free(PyAST_Object *ast);
  
  staticforward int
! parser_compare(PyAST_Object *left, PyAST_Object *right);
  
  staticforward PyObject *
--- 153,168 ----
  
  
! typedef struct {
      PyObject_HEAD                       /* standard object header           */
!     node* st_node;                      /* the node* returned by the parser */
!     int   st_type;                      /* EXPR or SUITE ?                  */
! } PyST_Object;
  
  
  staticforward void
! parser_free(PyST_Object *st);
  
  staticforward int
! parser_compare(PyST_Object *left, PyST_Object *right);
  
  staticforward PyObject *
***************
*** 175,183 ****
  
  static
! PyTypeObject PyAST_Type = {
      PyObject_HEAD_INIT(NULL)
      0,
!     "ast",                              /* tp_name              */
!     (int) sizeof(PyAST_Object),         /* tp_basicsize         */
      0,                                  /* tp_itemsize          */
      (destructor)parser_free,            /* tp_dealloc           */
--- 171,179 ----
  
  static
! PyTypeObject PyST_Type = {
      PyObject_HEAD_INIT(NULL)
      0,
!     "st",                               /* tp_name              */
!     (int) sizeof(PyST_Object),          /* tp_basicsize         */
      0,                                  /* tp_itemsize          */
      (destructor)parser_free,            /* tp_dealloc           */
***************
*** 203,207 ****
      /* __doc__ */
      "Intermediate representation of a Python parse tree."
! };  /* PyAST_Type */
  
  
--- 199,203 ----
      /* __doc__ */
      "Intermediate representation of a Python parse tree."
! };  /* PyST_Type */
  
  
***************
*** 236,240 ****
  
  
! /*  int parser_compare(PyAST_Object* left, PyAST_Object* right)
   *
   *  Comparison function used by the Python operators ==, !=, <, >, <=, >=
--- 232,236 ----
  
  
! /*  int parser_compare(PyST_Object* left, PyST_Object* right)
   *
   *  Comparison function used by the Python operators ==, !=, <, >, <=, >=
***************
*** 244,248 ****
   */
  static int
! parser_compare(PyAST_Object *left, PyAST_Object *right)
  {
      if (left == right)
--- 240,244 ----
   */
  static int
! parser_compare(PyST_Object *left, PyST_Object *right)
  {
      if (left == right)
***************
*** 252,262 ****
          return (-1);
  
!     return (parser_compare_nodes(left->ast_node, right->ast_node));
  }
  
  
! /*  parser_newastobject(node* ast)
   *
!  *  Allocates a new Python object representing an AST.  This is simply the
   *  'wrapper' object that holds a node* and allows it to be passed around in
   *  Python code.
--- 248,258 ----
          return (-1);
  
!     return (parser_compare_nodes(left->st_node, right->st_node));
  }
  
  
! /*  parser_newstobject(node* st)
   *
!  *  Allocates a new Python object representing an ST.  This is simply the
   *  'wrapper' object that holds a node* and allows it to be passed around in
   *  Python code.
***************
*** 264,277 ****
   */
  static PyObject*
! parser_newastobject(node *ast, int type)
  {
!     PyAST_Object* o = PyObject_New(PyAST_Object, &PyAST_Type);
  
      if (o != 0) {
!         o->ast_node = ast;
!         o->ast_type = type;
      }
      else {
!         PyNode_Free(ast);
      }
      return ((PyObject*)o);
--- 260,273 ----
   */
  static PyObject*
! parser_newstobject(node *st, int type)
  {
!     PyST_Object* o = PyObject_New(PyST_Object, &PyST_Type);
  
      if (o != 0) {
!         o->st_node = st;
!         o->st_type = type;
      }
      else {
!         PyNode_Free(st);
      }
      return ((PyObject*)o);
***************
*** 279,283 ****
  
  
! /*  void parser_free(PyAST_Object* ast)
   *
   *  This is called by a del statement that reduces the reference count to 0.
--- 275,279 ----
  
  
! /*  void parser_free(PyST_Object* st)
   *
   *  This is called by a del statement that reduces the reference count to 0.
***************
*** 285,303 ****
   */
  static void
! parser_free(PyAST_Object *ast)
  {
!     PyNode_Free(ast->ast_node);
!     PyObject_Del(ast);
  }
  
  
! /*  parser_ast2tuple(PyObject* self, PyObject* args, PyObject* kw)
   *
   *  This provides conversion from a node* to a tuple object that can be
!  *  returned to the Python-level caller.  The AST object is not modified.
   *
   */
  static PyObject*
! parser_ast2tuple(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject *line_option = 0;
--- 281,299 ----
   */
  static void
! parser_free(PyST_Object *st)
  {
!     PyNode_Free(st->st_node);
!     PyObject_Del(st);
  }
  
  
! /*  parser_st2tuple(PyObject* self, PyObject* args, PyObject* kw)
   *
   *  This provides conversion from a node* to a tuple object that can be
!  *  returned to the Python-level caller.  The ST object is not modified.
   *
   */
  static PyObject*
! parser_st2tuple(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject *line_option = 0;
***************
*** 308,313 ****
  
      if (self == NULL) {
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2tuple", keywords,
!                                          &PyAST_Type, &self, &line_option);
      }
      else
--- 304,309 ----
  
      if (self == NULL) {
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2tuple", keywords,
!                                          &PyST_Type, &self, &line_option);
      }
      else
***************
*** 320,327 ****
          }
          /*
!          *  Convert AST into a tuple representation.  Use Guido's function,
           *  since it's known to work already.
           */
!         res = node2tuple(((PyAST_Object*)self)->ast_node,
                           PyTuple_New, PyTuple_SetItem, lineno);
      }
--- 316,323 ----
          }
          /*
!          *  Convert ST into a tuple representation.  Use Guido's function,
           *  since it's known to work already.
           */
!         res = node2tuple(((PyST_Object*)self)->st_node,
                           PyTuple_New, PyTuple_SetItem, lineno);
      }
***************
*** 330,341 ****
  
  
! /*  parser_ast2list(PyObject* self, PyObject* args, PyObject* kw)
   *
   *  This provides conversion from a node* to a list object that can be
!  *  returned to the Python-level caller.  The AST object is not modified.
   *
   */
  static PyObject*
! parser_ast2list(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject *line_option = 0;
--- 326,337 ----
  
  
! /*  parser_st2list(PyObject* self, PyObject* args, PyObject* kw)
   *
   *  This provides conversion from a node* to a list object that can be
!  *  returned to the Python-level caller.  The ST object is not modified.
   *
   */
  static PyObject*
! parser_st2list(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject *line_option = 0;
***************
*** 346,351 ****
  
      if (self == NULL)
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:ast2list", keywords,
!                                          &PyAST_Type, &self, &line_option);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
--- 342,347 ----
  
      if (self == NULL)
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|O:st2list", keywords,
!                                          &PyST_Type, &self, &line_option);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, "|O:tolist", &keywords[1],
***************
*** 357,364 ****
          }
          /*
!          *  Convert AST into a tuple representation.  Use Guido's function,
           *  since it's known to work already.
           */
!         res = node2tuple(self->ast_node,
                           PyList_New, PyList_SetItem, lineno);
      }
--- 353,360 ----
          }
          /*
!          *  Convert ST into a tuple representation.  Use Guido's function,
           *  since it's known to work already.
           */
!         res = node2tuple(self->st_node,
                           PyList_New, PyList_SetItem, lineno);
      }
***************
*** 367,371 ****
  
  
! /*  parser_compileast(PyObject* self, PyObject* args)
   *
   *  This function creates code objects from the parse tree represented by
--- 363,367 ----
  
  
! /*  parser_compilest(PyObject* self, PyObject* args)
   *
   *  This function creates code objects from the parse tree represented by
***************
*** 374,381 ****
   */
  static PyObject*
! parser_compileast(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject*     res = 0;
!     char*         str = "<ast>";
      int ok;
  
--- 370,377 ----
   */
  static PyObject*
! parser_compilest(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject*     res = 0;
!     char*         str = "<syntax-tree>";
      int ok;
  
***************
*** 383,388 ****
  
      if (self == NULL)
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compileast", keywords,
!                                          &PyAST_Type, &self, &str);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
--- 379,384 ----
  
      if (self == NULL)
!         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
!                                          &PyST_Type, &self, &str);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, "|s:compile", &keywords[1],
***************
*** 390,394 ****
  
      if (ok)
!         res = (PyObject *)PyNode_Compile(self->ast_node, str);
  
      return (res);
--- 386,390 ----
  
      if (ok)
!         res = (PyObject *)PyNode_Compile(self->st_node, str);
  
      return (res);
***************
*** 399,408 ****
   *  PyObject* parser_issuite(PyObject* self, PyObject* args)
   *
!  *  Checks the passed-in AST object to determine if it is an expression or
   *  a statement suite, respectively.  The return is a Python truth value.
   *
   */
  static PyObject*
! parser_isexpr(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject* res = 0;
--- 395,404 ----
   *  PyObject* parser_issuite(PyObject* self, PyObject* args)
   *
!  *  Checks the passed-in ST object to determine if it is an expression or
   *  a statement suite, respectively.  The return is a Python truth value.
   *
   */
  static PyObject*
! parser_isexpr(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject* res = 0;
***************
*** 413,423 ****
      if (self == NULL)
          ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
!                                          &PyAST_Type, &self);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
  
      if (ok) {
!         /* Check to see if the AST represents an expression or not. */
!         res = (self->ast_type == PyAST_EXPR) ? Py_True : Py_False;
          Py_INCREF(res);
      }
--- 409,419 ----
      if (self == NULL)
          ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
!                                          &PyST_Type, &self);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, ":isexpr", &keywords[1]);
  
      if (ok) {
!         /* Check to see if the ST represents an expression or not. */
!         res = (self->st_type == PyST_EXPR) ? Py_True : Py_False;
          Py_INCREF(res);
      }
***************
*** 427,431 ****
  
  static PyObject*
! parser_issuite(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject* res = 0;
--- 423,427 ----
  
  static PyObject*
! parser_issuite(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      PyObject* res = 0;
***************
*** 436,446 ****
      if (self == NULL)
          ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
!                                          &PyAST_Type, &self);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
  
      if (ok) {
!         /* Check to see if the AST represents an expression or not. */
!         res = (self->ast_type == PyAST_EXPR) ? Py_False : Py_True;
          Py_INCREF(res);
      }
--- 432,442 ----
      if (self == NULL)
          ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
!                                          &PyST_Type, &self);
      else
          ok = PyArg_ParseTupleAndKeywords(args, kw, ":issuite", &keywords[1]);
  
      if (ok) {
!         /* Check to see if the ST represents an expression or not. */
!         res = (self->st_type == PyST_EXPR) ? Py_False : Py_True;
          Py_INCREF(res);
      }
***************
*** 453,466 ****
  static PyMethodDef
  parser_methods[] = {
!     {"compile",         (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
!         "Compile this AST object into a code object."},
      {"isexpr",          (PyCFunction)parser_isexpr,     PUBLIC_METHOD_TYPE,
!         "Determines if this AST object was created from an expression."},
      {"issuite",         (PyCFunction)parser_issuite,    PUBLIC_METHOD_TYPE,
!         "Determines if this AST object was created from a suite."},
!     {"tolist",          (PyCFunction)parser_ast2list,   PUBLIC_METHOD_TYPE,
!         "Creates a list-tree representation of this AST."},
!     {"totuple",         (PyCFunction)parser_ast2tuple,  PUBLIC_METHOD_TYPE,
!         "Creates a tuple-tree representation of this AST."},
  
      {NULL, NULL, 0, NULL}
--- 449,462 ----
  static PyMethodDef
  parser_methods[] = {
!     {"compile",         (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
!         "Compile this ST object into a code object."},
      {"isexpr",          (PyCFunction)parser_isexpr,     PUBLIC_METHOD_TYPE,
!         "Determines if this ST object was created from an expression."},
      {"issuite",         (PyCFunction)parser_issuite,    PUBLIC_METHOD_TYPE,
!         "Determines if this ST object was created from a suite."},
!     {"tolist",          (PyCFunction)parser_st2list,    PUBLIC_METHOD_TYPE,
!         "Creates a list-tree representation of this ST."},
!     {"totuple",         (PyCFunction)parser_st2tuple,   PUBLIC_METHOD_TYPE,
!         "Creates a tuple-tree representation of this ST."},
  
      {NULL, NULL, 0, NULL}
***************
*** 503,511 ****
      if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
          node* n = PyParser_SimpleParseString(string,
!                                              (type == PyAST_EXPR)
                                               ? eval_input : file_input);
  
          if (n != 0)
!             res = parser_newastobject(n, type);
          else
              err_string("could not parse string");
--- 499,507 ----
      if (PyArg_ParseTupleAndKeywords(args, kw, argspec, keywords, &string)) {
          node* n = PyParser_SimpleParseString(string,
!                                              (type == PyST_EXPR)
                                               ? eval_input : file_input);
  
          if (n != 0)
!             res = parser_newstobject(n, type);
          else
              err_string("could not parse string");
***************
*** 524,544 ****
   */
  static PyObject*
! parser_expr(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     return (parser_do_parse(args, kw, "s:expr", PyAST_EXPR));
  }
  
  
  static PyObject*
! parser_suite(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     return (parser_do_parse(args, kw, "s:suite", PyAST_SUITE));
  }
  
  
  
! /*  This is the messy part of the code.  Conversion from a tuple to an AST
   *  object requires that the input tuple be valid without having to rely on
   *  catching an exception from the compiler.  This is done to allow the
--- 520,540 ----
   */
  static PyObject*
! parser_expr(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     return (parser_do_parse(args, kw, "s:expr", PyST_EXPR));
  }
  
  
  static PyObject*
! parser_suite(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     return (parser_do_parse(args, kw, "s:suite", PyST_SUITE));
  }
  
  
  
! /*  This is the messy part of the code.  Conversion from a tuple to an ST
   *  object requires that the input tuple be valid without having to rely on
   *  catching an exception from the compiler.  This is done to allow the
***************
*** 550,555 ****
   *  Two aspects can be broken out in this code:  creating a node tree from
   *  the tuple passed in, and verifying that it is indeed valid.  It may be
!  *  advantageous to expand the number of AST types to include funcdefs and
!  *  lambdadefs to take advantage of the optimizer, recognizing those ASTs
   *  here.  They are not necessary, and not quite as useful in a raw form.
   *  For now, let's get expressions and suites working reliably.
--- 546,551 ----
   *  Two aspects can be broken out in this code:  creating a node tree from
   *  the tuple passed in, and verifying that it is indeed valid.  It may be
!  *  advantageous to expand the number of ST types to include funcdefs and
!  *  lambdadefs to take advantage of the optimizer, recognizing those STs
   *  here.  They are not necessary, and not quite as useful in a raw form.
   *  For now, let's get expressions and suites working reliably.
***************
*** 562,569 ****
  
  
! /*  PyObject* parser_tuple2ast(PyObject* self, PyObject* args)
   *
   *  This is the public function, called from the Python code.  It receives a
!  *  single tuple object from the caller, and creates an AST object if the
   *  tuple can be validated.  It does this by checking the first code of the
   *  tuple, and, if acceptable, builds the internal representation.  If this
--- 558,565 ----
  
  
! /*  PyObject* parser_tuple2st(PyObject* self, PyObject* args)
   *
   *  This is the public function, called from the Python code.  It receives a
!  *  single tuple object from the caller, and creates an ST object if the
   *  tuple can be validated.  It does this by checking the first code of the
   *  tuple, and, if acceptable, builds the internal representation.  If this
***************
*** 571,583 ****
   *  possible with the various validate_*() routines defined below.
   *
!  *  This function must be changed if support is to be added for PyAST_FRAGMENT
!  *  AST objects.
   *
   */
  static PyObject*
! parser_tuple2ast(PyAST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     PyObject *ast = 0;
      PyObject *tuple;
      node *tree;
--- 567,579 ----
   *  possible with the various validate_*() routines defined below.
   *
!  *  This function must be changed if support is to be added for PyST_FRAGMENT
!  *  ST objects.
   *
   */
  static PyObject*
! parser_tuple2st(PyST_Object *self, PyObject *args, PyObject *kw)
  {
      NOTE(ARGUNUSED(self))
!     PyObject *st = 0;
      PyObject *tuple;
      node *tree;
***************
*** 585,594 ****
      static char *keywords[] = {"sequence", NULL};
  
!     if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2ast", keywords,
                                       &tuple))
          return (0);
      if (!PySequence_Check(tuple)) {
          PyErr_SetString(PyExc_ValueError,
!                         "sequence2ast() requires a single sequence argument");
          return (0);
      }
--- 581,590 ----
      static char *keywords[] = {"sequence", NULL};
  
!     if (!PyArg_ParseTupleAndKeywords(args, kw, "O:sequence2st", keywords,
                                       &tuple))
          return (0);
      if (!PySequence_Check(tuple)) {
          PyErr_SetString(PyExc_ValueError,
!                         "sequence2st() requires a single sequence argument");
          return (0);
      }
***************
*** 602,611 ****
              /*  Might be an eval form.  */
              if (validate_expr_tree(tree))
!                 ast = parser_newastobject(tree, PyAST_EXPR);
          }
          else if (start_sym == file_input) {
              /*  This looks like an exec form so far.  */
              if (validate_file_input(tree))
!                 ast = parser_newastobject(tree, PyAST_SUITE);
          }
          else {
--- 598,607 ----
              /*  Might be an eval form.  */
              if (validate_expr_tree(tree))
!                 st = parser_newstobject(tree, PyST_EXPR);
          }
          else if (start_sym == file_input) {
              /*  This looks like an exec form so far.  */
              if (validate_file_input(tree))
!                 st = parser_newstobject(tree, PyST_SUITE);
          }
          else {
***************
*** 618,625 ****
       *  get this, but we'd do well to be sure something is done.
       */
!     if ((ast == 0) && !PyErr_Occurred())
!         err_string("unspecified AST error occurred");
  
!     return (ast);
  }
  
--- 614,621 ----
       *  get this, but we'd do well to be sure something is done.
       */
!     if (st == NULL && !PyErr_Occurred())
!         err_string("unspecified ST error occurred");
  
!     return st;
  }
  
***************
*** 753,757 ****
           */
          tuple = Py_BuildValue("os", tuple,
!                       "Illegal ast tuple; cannot start with terminal symbol.");
          PyErr_SetObject(parser_error, tuple);
      }
--- 749,753 ----
           */
          tuple = Py_BuildValue("os", tuple,
!                     "Illegal syntax-tree; cannot start with terminal symbol.");
          PyErr_SetObject(parser_error, tuple);
      }
***************
*** 2727,2736 ****
  validate_file_input(node *tree)
  {
!     int j   = 0;
      int nch = NCH(tree) - 1;
      int res = ((nch >= 0)
                 && validate_ntype(CHILD(tree, nch), ENDMARKER));
  
!     for ( ; res && (j < nch); ++j) {
          if (TYPE(CHILD(tree, j)) == stmt)
              res = validate_stmt(CHILD(tree, j));
--- 2723,2732 ----
  validate_file_input(node *tree)
  {
!     int j;
      int nch = NCH(tree) - 1;
      int res = ((nch >= 0)
                 && validate_ntype(CHILD(tree, nch), ENDMARKER));
  
!     for (j = 0; res && (j < nch); ++j) {
          if (TYPE(CHILD(tree, j)) == stmt)
              res = validate_stmt(CHILD(tree, j));
***************
*** 2758,2765 ****
      NOTE(ARGUNUSED(self))
      PyObject *result = NULL;
!     PyObject *ast = NULL;
      PyObject *empty_dict = NULL;
  
!     if (PyArg_ParseTuple(args, "O!:_pickler", &PyAST_Type, &ast)) {
          PyObject *newargs;
          PyObject *tuple;
--- 2754,2761 ----
      NOTE(ARGUNUSED(self))
      PyObject *result = NULL;
!     PyObject *st = NULL;
      PyObject *empty_dict = NULL;
  
!     if (PyArg_ParseTuple(args, "O!:_pickler", &PyST_Type, &st)) {
          PyObject *newargs;
          PyObject *tuple;
***************
*** 2767,2773 ****
          if ((empty_dict = PyDict_New()) == NULL)
              goto finally;
!         if ((newargs = Py_BuildValue("Oi", ast, 1)) == NULL)
              goto finally;
!         tuple = parser_ast2tuple((PyAST_Object*)NULL, newargs, empty_dict);
          if (tuple != NULL) {
              result = Py_BuildValue("O(O)", pickle_constructor, tuple);
--- 2763,2769 ----
          if ((empty_dict = PyDict_New()) == NULL)
              goto finally;
!         if ((newargs = Py_BuildValue("Oi", st, 1)) == NULL)
              goto finally;
!         tuple = parser_st2tuple((PyST_Object*)NULL, newargs, empty_dict);
          if (tuple != NULL) {
              result = Py_BuildValue("O(O)", pickle_constructor, tuple);
***************
*** 2785,2789 ****
  
  /*  Functions exported by this module.  Most of this should probably
!  *  be converted into an AST object with methods, but that is better
   *  done directly in Python, allowing subclasses to be created directly.
   *  We'd really have to write a wrapper around it all anyway to allow
--- 2781,2785 ----
  
  /*  Functions exported by this module.  Most of this should probably
!  *  be converted into an ST object with methods, but that is better
   *  done directly in Python, allowing subclasses to be created directly.
   *  We'd really have to write a wrapper around it all anyway to allow
***************
*** 2791,2816 ****
   */
  static PyMethodDef parser_functions[] =  {
!     {"ast2tuple",       (PyCFunction)parser_ast2tuple,  PUBLIC_METHOD_TYPE,
!         "Creates a tuple-tree representation of an AST."},
!     {"ast2list",        (PyCFunction)parser_ast2list,   PUBLIC_METHOD_TYPE,
!         "Creates a list-tree representation of an AST."},
!     {"compileast",      (PyCFunction)parser_compileast, PUBLIC_METHOD_TYPE,
!         "Compiles an AST object into a code object."},
!     {"expr",            (PyCFunction)parser_expr,       PUBLIC_METHOD_TYPE,
!         "Creates an AST object from an expression."},
!     {"isexpr",          (PyCFunction)parser_isexpr,     PUBLIC_METHOD_TYPE,
!         "Determines if an AST object was created from an expression."},
!     {"issuite",         (PyCFunction)parser_issuite,    PUBLIC_METHOD_TYPE,
!         "Determines if an AST object was created from a suite."},
!     {"suite",           (PyCFunction)parser_suite,      PUBLIC_METHOD_TYPE,
!         "Creates an AST object from a suite."},
!     {"sequence2ast",    (PyCFunction)parser_tuple2ast,  PUBLIC_METHOD_TYPE,
!         "Creates an AST object from a tree representation."},
!     {"tuple2ast",       (PyCFunction)parser_tuple2ast,  PUBLIC_METHOD_TYPE,
!         "Creates an AST object from a tree representation."},
  
      /* private stuff: support pickle module */
      {"_pickler",        (PyCFunction)parser__pickler,   METH_VARARGS,
!         "Returns the pickle magic to allow ast objects to be pickled."},
  
      {NULL, NULL, 0, NULL}
--- 2787,2822 ----
   */
  static PyMethodDef parser_functions[] =  {
!     {"ast2tuple",       (PyCFunction)parser_st2tuple,  PUBLIC_METHOD_TYPE,
!         "Creates a tuple-tree representation of an ST."},
!     {"ast2list",        (PyCFunction)parser_st2list,   PUBLIC_METHOD_TYPE,
!         "Creates a list-tree representation of an ST."},
!     {"compileast",      (PyCFunction)parser_compilest, PUBLIC_METHOD_TYPE,
!         "Compiles an ST object into a code object."},
!     {"compilest",      (PyCFunction)parser_compilest,  PUBLIC_METHOD_TYPE,
!         "Compiles an ST object into a code object."},
!     {"expr",            (PyCFunction)parser_expr,      PUBLIC_METHOD_TYPE,
!         "Creates an ST object from an expression."},
!     {"isexpr",          (PyCFunction)parser_isexpr,    PUBLIC_METHOD_TYPE,
!         "Determines if an ST object was created from an expression."},
!     {"issuite",         (PyCFunction)parser_issuite,   PUBLIC_METHOD_TYPE,
!         "Determines if an ST object was created from a suite."},
!     {"suite",           (PyCFunction)parser_suite,     PUBLIC_METHOD_TYPE,
!         "Creates an ST object from a suite."},
!     {"sequence2ast",    (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
!         "Creates an ST object from a tree representation."},
!     {"sequence2st",     (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
!         "Creates an ST object from a tree representation."},
!     {"st2tuple",        (PyCFunction)parser_st2tuple,  PUBLIC_METHOD_TYPE,
!         "Creates a tuple-tree representation of an ST."},
!     {"st2list",         (PyCFunction)parser_st2list,   PUBLIC_METHOD_TYPE,
!         "Creates a list-tree representation of an ST."},
!     {"tuple2ast",       (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
!         "Creates an ST object from a tree representation."},
!     {"tuple2st",        (PyCFunction)parser_tuple2st,  PUBLIC_METHOD_TYPE,
!         "Creates an ST object from a tree representation."},
  
      /* private stuff: support pickle module */
      {"_pickler",        (PyCFunction)parser__pickler,   METH_VARARGS,
!         "Returns the pickle magic to allow ST objects to be pickled."},
  
      {NULL, NULL, 0, NULL}
***************
*** 2825,2830 ****
      PyObject* module;
      PyObject* dict;
!         
!     PyAST_Type.ob_type = &PyType_Type;
      module = Py_InitModule("parser", parser_functions);
      dict = PyModule_GetDict(module);
--- 2831,2836 ----
      PyObject* module;
      PyObject* dict;
! 
!     PyST_Type.ob_type = &PyType_Type;
      module = Py_InitModule("parser", parser_functions);
      dict = PyModule_GetDict(module);
***************
*** 2834,2847 ****
  
      if ((parser_error == 0)
!         || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0))
!     {
! 	    /* caller will check PyErr_Occurred() */
! 	    return;
!     }
!     /*
!      *  Nice to have, but don't cry if we fail.
!      */
!     Py_INCREF(&PyAST_Type);
!     PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyAST_Type);
  
      PyDict_SetItemString(dict, "__copyright__",
--- 2840,2851 ----
  
      if ((parser_error == 0)
!         || (PyDict_SetItemString(dict, "ParserError", parser_error) != 0)) {
!         /* caller will check PyErr_Occurred() */
!         return;
!     }
!     Py_INCREF(&PyST_Type);
!     PyDict_SetItemString(dict, "ASTType", (PyObject*)&PyST_Type);
!     Py_INCREF(&PyST_Type);
!     PyDict_SetItemString(dict, "STType", (PyObject*)&PyST_Type);
  
      PyDict_SetItemString(dict, "__copyright__",
***************
*** 2858,2862 ****
  
          func = PyObject_GetAttrString(module, "pickle");
!         pickle_constructor = PyDict_GetItemString(dict, "sequence2ast");
          pickler = PyDict_GetItemString(dict, "_pickler");
          Py_XINCREF(pickle_constructor);
--- 2862,2866 ----
  
          func = PyObject_GetAttrString(module, "pickle");
!         pickle_constructor = PyDict_GetItemString(dict, "sequence2st");
          pickler = PyDict_GetItemString(dict, "_pickler");
          Py_XINCREF(pickle_constructor);
***************
*** 2865,2870 ****
              PyObject *res;
  
!             res = PyObject_CallFunction(
!                     func, "OOO", &PyAST_Type, pickler, pickle_constructor);
              Py_XDECREF(res);
          }
--- 2869,2874 ----
              PyObject *res;
  
!             res = PyObject_CallFunction(func, "OOO", &PyST_Type, pickler,
!                                         pickle_constructor);
              Py_XDECREF(res);
          }