[Python-checkins] r42579 - in python/trunk: Include/Python-ast.h Include/pythonrun.h Lib/test/test_ast.py Misc/NEWS Parser/asdl_c.py Python/Python-ast.c Python/bltinmodule.c Python/pythonrun.c

martin.v.loewis python-checkins at python.org
Sun Feb 26 20:42:32 CET 2006


Author: martin.v.loewis
Date: Sun Feb 26 20:42:26 2006
New Revision: 42579

Added:
   python/trunk/Lib/test/test_ast.py
Modified:
   python/trunk/Include/Python-ast.h
   python/trunk/Include/pythonrun.h
   python/trunk/Misc/NEWS
   python/trunk/Parser/asdl_c.py
   python/trunk/Python/Python-ast.c
   python/trunk/Python/bltinmodule.c
   python/trunk/Python/pythonrun.c
Log:
Generate code to recursively copy an AST into
a tree of Python objects. Expose this through compile().


Modified: python/trunk/Include/Python-ast.h
==============================================================================
--- python/trunk/Include/Python-ast.h	(original)
+++ python/trunk/Include/Python-ast.h	Sun Feb 26 20:42:26 2006
@@ -404,3 +404,4 @@
 keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena);
 alias_ty alias(identifier name, identifier asname, PyArena *arena);
 
+PyObject* PyAST_mod2obj(mod_ty t);

Modified: python/trunk/Include/pythonrun.h
==============================================================================
--- python/trunk/Include/pythonrun.h	(original)
+++ python/trunk/Include/pythonrun.h	Sun Feb 26 20:42:26 2006
@@ -11,6 +11,7 @@
 #define PyCF_MASK_OBSOLETE (CO_NESTED)
 #define PyCF_SOURCE_IS_UTF8  0x0100
 #define PyCF_DONT_IMPLY_DEDENT 0x0200
+#define PyCF_ONLY_AST 0x0400
 
 typedef struct {
 	int cf_flags;  /* bitmask of CO_xxx flags relevant to future */

Added: python/trunk/Lib/test/test_ast.py
==============================================================================
--- (empty file)
+++ python/trunk/Lib/test/test_ast.py	Sun Feb 26 20:42:26 2006
@@ -0,0 +1,179 @@
+import sys, itertools
+
+def to_tuple(t):
+    if t is None or isinstance(t, (str, int, long)):
+        return t
+    elif isinstance(t, list):
+        return [to_tuple(e) for e in t]
+    result = [t.__class__.__name__]
+    if t._fields is None:
+        return tuple(result)
+    for f in t._fields:
+        result.append(to_tuple(getattr(t, f)))
+    return tuple(result)
+    
+# These tests are compiled through "exec"
+# There should be atleast one test per statement
+exec_tests = [
+    # FunctionDef
+    "def f(): pass",
+    # ClassDef
+    "class C:pass",
+    # Return
+    "def f():return 1",
+    # Delete
+    "del v",
+    # Assign
+    "v = 1",
+    # AugAssign
+    "v += 1",
+    # Print
+    "print >>f, 1, ",
+    # For
+    "for v in v:pass",
+    # While
+    "while v:pass",
+    # If
+    "if v:pass",
+    # Raise
+    "raise Exception, 'string'",
+    # TryExcept
+    "try:\n  pass\nexcept Exception:\n  pass",
+    # TryFinally
+    "try:\n  pass\nfinally:\n  pass",
+    # Assert
+    "assert v",
+    # Import
+    "import sys",
+    # ImportFrom
+    "from sys import v",
+    # Exec
+    "exec 'v'",
+    # Global
+    "global v",
+    # Expr
+    "1",
+    # Pass,
+    "pass",
+    # Break
+    "break",
+    # Continue
+    "continue",
+]
+
+# These are compiled through "single"
+# because of overlap with "eval", it just tests what
+# can't be tested with "eval"
+single_tests = [
+    "1+2"
+]
+
+# These are compiled through "eval"
+# It should test all expressions
+eval_tests = [
+  # BoolOp
+  "a and b",
+  # BinOp
+  "a + b",
+  # UnaryOp
+  "not v",
+  # Lambda
+  "lambda:None",
+  # Dict
+  "{ 1:2 }",
+  # ListComp
+  "[a for b in c if d]",
+  # GeneratorExp
+  "(a for b in c if d)",
+  # Yield
+  #"def f():yield 3",
+  # Compare
+  "1 < 2 < 3",
+  # Call
+  "f(1,2,c=3,*d,**e)",
+  # Repr
+  "`v`",
+  # Num
+  "10L",
+  # Str
+  "'string'",
+  # Attribute
+  "a.b",
+  # Subscript
+  "a[b:c]",
+  # Name
+  "v",
+  # List
+  "[1,2,3]",
+  # Tuple
+  "1,2,3"
+]
+
+# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
+# excepthandler, arguments, keywords, alias
+
+if __name__=='__main__' and sys.argv[1:] == ['-g']:
+    for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")):
+        print kind+"_results = ["
+        for s in statements:
+            print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
+        print "]"
+    print "run_tests()"
+    raise SystemExit
+
+def run_tests():
+    for input, output, kind in ((exec_tests, exec_results, "exec"), 
+                                        (single_tests, single_results, "single"), 
+                                        (eval_tests, eval_results, "eval")):
+        for i, o in itertools.izip(input, output):
+            assert to_tuple(compile(i, "?", kind, 0x400)) == o
+
+#### EVERYTHING BELOW IS GENERATED ##### 
+exec_results = [
+('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]),
+('Module', [('ClassDef', 'C', [], [('Pass',)])]),
+('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]),
+('Module', [('Delete', [('Name', 'v', ('Del',))])]),
+('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]),
+('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]),
+('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]),
+('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]),
+('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]),
+('Module', [('TryFinally', [('Pass',)], [('Pass',)])]),
+('Module', [('Assert', ('Name', 'v', ('Load',)), None)]),
+('Module', [('Import', [('alias', 'sys', None)])]),
+('Module', [('ImportFrom', 'sys', [('alias', 'v', None)])]),
+('Module', [('Exec', ('Str', 'v'), None, None)]),
+('Module', [('Global', ['v'])]),
+('Module', [('Expr', ('Num', 1))]),
+('Module', [('Pass',)]),
+('Module', [('Break',)]),
+('Module', [('Continue',)]),
+]
+single_results = [
+('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]),
+]
+eval_results = [
+('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])),
+('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))),
+('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))),
+('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))),
+('Expression', ('Dict', [('Num', 1)], [('Num', 2)])),
+('Expression', ('ListComp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
+('Expression', ('GeneratorExp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
+('Expression', ('Compare', ('Num', 1), [('Lt',), ('Lt',)], [('Num', 2), ('Num', 3)])),
+('Expression', ('Call', ('Name', 'f', ('Load',)), [('Num', 1), ('Num', 2)], [('keyword', 'c', ('Num', 3))], ('Name', 'd', ('Load',)), ('Name', 'e', ('Load',)))),
+('Expression', ('Repr', ('Name', 'v', ('Load',)))),
+('Expression', ('Num', 10L)),
+('Expression', ('Str', 'string')),
+('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))),
+('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))),
+('Expression', ('Name', 'v', ('Load',))),
+('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
+('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
+]
+run_tests()
+

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Sun Feb 26 20:42:26 2006
@@ -74,7 +74,9 @@
 
 - Speed up some Unicode operations.
 
-- A new AST parser implementation was completed.
+- A new AST parser implementation was completed. The abstract
+  syntax tree is available for read-only (non-compile) access
+  to Python code.
 
 - SF bug #1167751: fix incorrect code being for generator expressions.
   The following code now raises a SyntaxError:  foo(a = i for i in range(10))

Modified: python/trunk/Parser/asdl_c.py
==============================================================================
--- python/trunk/Parser/asdl_c.py	(original)
+++ python/trunk/Parser/asdl_c.py	Sun Feb 26 20:42:26 2006
@@ -344,13 +344,127 @@
 
     visitProduct = visitSum = prototype
 
-class FreePrototypeVisitor(PickleVisitor):
+class PyTypesDeclareVisitor(PickleVisitor):
 
     def prototype(self, sum, name):
         ctype = get_c_type(name)
         self.emit("void free_%s(%s);" % (name, ctype), 0)
 
-    visitProduct = visitSum = prototype
+    def visitProduct(self, prod, name):
+        self.emit("PyTypeObject *%s_type;" % name, 0)
+        self.emit("static PyObject* ast2obj_%s(void*);" % name, 0)
+        self.emit("char *%s_fields[]={" % name,0)
+        for f in prod.fields:
+            self.emit('"%s",' % f.name, 1)
+        self.emit("};", 0)
+        
+    def visitSum(self, sum, name):
+        self.emit("PyTypeObject *%s_type;" % name, 0)
+        ptype = "void*"
+        if is_simple(sum):
+            ptype = get_c_type(name)
+            tnames = []
+            for t in sum.types:
+                tnames.append(str(t.name)+"_singleton")
+            tnames = ", *".join(tnames)
+            self.emit("static PyObject *%s;" % tnames, 0)
+        self.emit("static PyObject* ast2obj_%s(%s);" % (name, ptype), 0)
+        for t in sum.types:
+            self.visitConstructor(t, name)
+            
+    def visitConstructor(self, cons, name):
+        self.emit("PyTypeObject *%s_type;" % cons.name, 0)
+        self.emit("char *%s_fields[]={" % cons.name, 0)
+        for t in cons.fields:
+            self.emit('"%s",' % t.name, 1)
+        self.emit("};",0)
+
+class PyTypesVisitor(PickleVisitor):
+
+    def visitModule(self, mod):
+        self.emit("""
+static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
+{
+    PyObject *fnames, *result;
+    int i;
+    if (num_fields) {
+        fnames = PyTuple_New(num_fields);
+        if (!fnames) return NULL;
+    } else {
+        fnames = Py_None;
+        Py_INCREF(Py_None);
+    }
+    for(i=0; i < num_fields; i++) {
+        PyObject *field = PyString_FromString(fields[i]);
+        if (!field) {
+            Py_DECREF(fnames);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(fnames, i, field);
+    }
+    result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sO}", type, base, "_fields", fnames);
+    Py_DECREF(fnames);
+    return (PyTypeObject*)result;
+}
+
+static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
+{
+    int i, n = asdl_seq_LEN(seq);
+    PyObject *result = PyList_New(n);
+    PyObject *value;
+    if (!result)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        value = func(asdl_seq_GET(seq, i));
+        if (!value) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        PyList_SET_ITEM(result, i, value);
+    }
+    return result;
+}
+
+static PyObject* ast2obj_object(void *o)
+{
+    if (!o)
+        o = Py_None;
+    Py_INCREF((PyObject*)o);
+    return (PyObject*)o;
+}
+#define ast2obj_identifier ast2obj_object
+#define ast2obj_string ast2obj_object
+static PyObject* ast2obj_bool(bool b)
+{
+    return PyBool_FromLong(b);
+}
+""", 0, reflow=False)
+
+        self.emit("static int initialized;", 0)
+        self.emit("static int init_types(void)",0)
+        self.emit("{", 0)
+        self.emit("if (initialized) return 1;", 1)
+        for dfn in mod.dfns:
+            self.visit(dfn)
+        self.emit("return 1;", 0);
+        self.emit("}", 0)
+
+    def visitProduct(self, prod, name):
+        self.emit('%s_type = make_type("%s", &PyBaseObject_Type, %s_fields, %d);' % 
+                        (name, name, name, len(prod.fields)), 1)
+        
+    def visitSum(self, sum, name):
+        self.emit('%s_type = make_type("%s", &PyBaseObject_Type, NULL, 0);' % (name, name), 1)
+        simple = is_simple(sum)
+        for t in sum.types:
+            self.visitConstructor(t, name, simple)
+            
+    def visitConstructor(self, cons, name, simple):
+        self.emit('%s_type = make_type("%s", %s_type, %s_fields, %d);' % 
+                            (cons.name, cons.name, name, cons.name, len(cons.fields)), 1)
+        if simple:
+            self.emit("%s_singleton = PyType_GenericNew(%s_type, NULL, NULL);" %
+                             (cons.name, cons.name), 1)
 
 _SPECIALIZED_SEQUENCES = ('stmt', 'expr')
 
@@ -400,48 +514,70 @@
 }
 '''
 
-class FreeVisitor(PickleVisitor):
+class ObjVisitor(PickleVisitor):
 
     def func_begin(self, name, has_seq):
         ctype = get_c_type(name)
-        self.emit("void", 0)
-        self.emit("free_%s(%s o)" % (name, ctype), 0)
+        self.emit("PyObject*", 0)
+        self.emit("ast2obj_%s(void* _o)" % (name), 0)
         self.emit("{", 0)
-        if has_seq:
-            self.emit("int i, n;", 1)
-            self.emit("asdl_seq *seq;", 1)
-            self.emit('', 0)
-        self.emit('if (!o)', 1)
-        self.emit('return;', 2)
+        self.emit("%s o = (%s)_o;" % (ctype, ctype), 1)
+        self.emit("PyObject *result = NULL, *value = NULL;", 1)
+        self.emit('if (!o) {', 1)
+        self.emit("Py_INCREF(Py_None);", 2)
+        self.emit('return Py_None;', 2)
+        self.emit("}", 1)
         self.emit('', 0)
 
-    def func_end(self):
+    def func_end(self, has_seq):
+        self.emit("return result;", 1)
+        self.emit("failed:", 0)
+        self.emit("Py_XDECREF(value);", 1)
+        self.emit("Py_XDECREF(result);", 1)
+        self.emit("return NULL;", 1)
         self.emit("}", 0)
         self.emit("", 0)
 
     def visitSum(self, sum, name):
-        has_seq = has_sequence(sum.types, True)
+        if is_simple(sum):
+            self.simpleSum(sum, name)
+            return
+        has_seq = has_sequence(sum.types, False)
         self.func_begin(name, has_seq)
-        if not is_simple(sum):
-            self.emit("switch (o->kind) {", 1)
-            for i in range(len(sum.types)):
-                t = sum.types[i]
-                self.visitConstructor(t, i + 1, name)
-            self.emit("}", 1)
-            self.emit("", 0)
-            self.emit("free(o);", 1)
-        self.func_end()
+        self.emit("switch (o->kind) {", 1)
+        for i in range(len(sum.types)):
+            t = sum.types[i]
+            self.visitConstructor(t, i + 1, name)
+        self.emit("}", 1)
+        self.emit("", 0)
+        self.func_end(has_seq)
+        
+    def simpleSum(self, sum, name):
+        self.emit("PyObject* ast2obj_%s(%s_ty o)" % (name, name), 0)
+        self.emit("{", 0)
+        self.emit("switch(o) {", 1)
+        for t in sum.types:
+            self.emit("case %s:" % t.name, 2)
+            self.emit("Py_INCREF(%s_singleton);" % t.name, 3)
+            self.emit("return %s_singleton;" % t.name, 3)
+        self.emit("}", 1)
+        self.emit("return NULL; /* cannot happen */", 1)
+        self.emit("}", 0)
 
     def visitProduct(self, prod, name):
-        self.func_begin(name, find_sequence(prod.fields, True))
+        has_seq = find_sequence(prod.fields, False)
+        self.func_begin(name, has_seq)
+        self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % name, 1);
+        self.emit("if (!result) return NULL;", 1)
         for field in prod.fields:
             self.visitField(field, name, 1, True)
         self.emit("", 0)
-        self.emit("free(o);", 1)
-        self.func_end()
+        self.func_end(has_seq)
 
     def visitConstructor(self, cons, enum, name):
         self.emit("case %s_kind:" % cons.name, 1)
+        self.emit("result = PyType_GenericNew(%s_type, NULL, NULL);" % cons.name, 2);
+        self.emit("if (!result) goto failed;", 2)
         for f in cons.fields:
             self.visitField(f, cons.name, 2, False)
         self.emit("break;", 2)
@@ -453,40 +589,36 @@
             value = "o->%s" % field.name
         else:
             value = "o->v.%s.%s" % (name, field.name)
-        if field.seq:
-            self.emitSeq(field, value, depth, emit)
-
-        # XXX need to know the simple types in advance, so that we
-        # don't call free_TYPE() for them.
-
-        elif field.opt:
-            emit("if (%s) {" % value, 0)
-            self.free(field, value, depth + 1)
-            emit("}", 0)
-        else:
-            self.free(field, value, depth)
+        self.set(field, value, depth)
+        emit("if (!value) goto failed;", 0)
+        emit('if (PyObject_SetAttrString(result, "%s", value) == -1)' % field.name, 0)
+        emit("goto failed;", 1)
+        emit("Py_DECREF(value);", 0)
 
     def emitSeq(self, field, value, depth, emit):
-        # specialize for freeing sequences of statements and expressions
-        if str(field.type) in _SPECIALIZED_SEQUENCES:
-            c_code = "free_seq_%ss(%s);" % (field.type, value)
-            emit(c_code, 0)
-        else:
-            emit("seq = %s;" % value, 0)
-            emit("n = asdl_seq_LEN(seq);", 0)
-            emit("for (i = 0; i < n; i++)", 0)
-            self.free(field, "asdl_seq_GET(seq, i)", depth + 1)
-            emit("asdl_seq_free(seq);", 0)
+        emit("seq = %s;" % value, 0)
+        emit("n = asdl_seq_LEN(seq);", 0)
+        emit("value = PyList_New(n);", 0)
+        emit("if (!value) goto failed;", 0)
+        emit("for (i = 0; i < n; i++) {", 0)
+        self.set("value", field, "asdl_seq_GET(seq, i)", depth + 1)
+        emit("if (!value1) goto failed;", 1)
+        emit("PyList_SET_ITEM(value, i, value1);", 1)
+        emit("value1 = NULL;", 1)
+        emit("}", 0)
 
-    def free(self, field, value, depth):
-        if str(field.type) in ("identifier", "string", "object"):
-            ctype = get_c_type(field.type)
-            self.emit("Py_DECREF((%s)%s);" % (ctype, value), depth)
-        elif str(field.type) == "bool":
-            return
+    def set(self, field, value, depth):
+        if field.seq:
+            if field.type.value == "cmpop":
+                # XXX check that this cast is safe, i.e. works independent on whether
+                # sizeof(cmpop_ty) != sizeof(void*)
+                cast = "(PyObject*(*)(void*))"
+            else:
+                cast = ""
+            self.emit("value = ast2obj_list(%s, %sast2obj_%s);" % (value, cast, field.type), depth)
         else:
             ctype = get_c_type(field.type)
-            self.emit("free_%s((%s)%s);" % (field.type, ctype, value), depth)
+            self.emit("value = ast2obj_%s(%s);" % (field.type, value), depth, reflow=False)
 
 
 class MarshalUtilVisitor(StaticVisitor):
@@ -632,6 +764,16 @@
             emit("}", 0)
         else:
             emit("marshal_write_%s(buf, off, %s);" % (field.type, value), 0)
+            
+class PartingShots(StaticVisitor):
+
+    CODE = """
+PyObject* PyAST_mod2obj(mod_ty t)
+{
+    init_types();
+    return ast2obj_mod(t);
+}
+"""
 
 class ChainOfVisitors:
     def __init__(self, *visitors):
@@ -663,6 +805,7 @@
 ##                        FreePrototypeVisitor(f),
                         )
     c.visit(mod)
+    print >>f, "PyObject* PyAST_mod2obj(mod_ty t);"
     f.close()
 
     if SRC_DIR:
@@ -674,12 +817,16 @@
     print >> f, '#include "Python.h"'
     print >> f, '#include "%s-ast.h"' % mod.name
     print >> f
-    v = ChainOfVisitors(MarshalPrototypeVisitor(f),
+    v = ChainOfVisitors(
+                        # MarshalPrototypeVisitor(f),
+                        PyTypesDeclareVisitor(f),
+                        PyTypesVisitor(f),
                         FunctionVisitor(f),
 ##                        FreeUtilVisitor(f),
-##                        FreeVisitor(f),
-                        MarshalUtilVisitor(f),
-                        MarshalFunctionVisitor(f),
+                        ObjVisitor(f),
+                        #MarshalUtilVisitor(f),
+                        #MarshalFunctionVisitor(f),
+                        PartingShots(f),
                         )
     v.visit(mod)
     f.close()

Modified: python/trunk/Python/Python-ast.c
==============================================================================
--- python/trunk/Python/Python-ast.c	(original)
+++ python/trunk/Python/Python-ast.c	Sun Feb 26 20:42:26 2006
@@ -3,20 +3,617 @@
 #include "Python.h"
 #include "Python-ast.h"
 
-static int marshal_write_mod(PyObject **, int *, mod_ty);
-static int marshal_write_stmt(PyObject **, int *, stmt_ty);
-static int marshal_write_expr(PyObject **, int *, expr_ty);
-static int marshal_write_expr_context(PyObject **, int *, expr_context_ty);
-static int marshal_write_slice(PyObject **, int *, slice_ty);
-static int marshal_write_boolop(PyObject **, int *, boolop_ty);
-static int marshal_write_operator(PyObject **, int *, operator_ty);
-static int marshal_write_unaryop(PyObject **, int *, unaryop_ty);
-static int marshal_write_cmpop(PyObject **, int *, cmpop_ty);
-static int marshal_write_comprehension(PyObject **, int *, comprehension_ty);
-static int marshal_write_excepthandler(PyObject **, int *, excepthandler_ty);
-static int marshal_write_arguments(PyObject **, int *, arguments_ty);
-static int marshal_write_keyword(PyObject **, int *, keyword_ty);
-static int marshal_write_alias(PyObject **, int *, alias_ty);
+PyTypeObject *mod_type;
+static PyObject* ast2obj_mod(void*);
+PyTypeObject *Module_type;
+char *Module_fields[]={
+        "body",
+};
+PyTypeObject *Interactive_type;
+char *Interactive_fields[]={
+        "body",
+};
+PyTypeObject *Expression_type;
+char *Expression_fields[]={
+        "body",
+};
+PyTypeObject *Suite_type;
+char *Suite_fields[]={
+        "body",
+};
+PyTypeObject *stmt_type;
+static PyObject* ast2obj_stmt(void*);
+PyTypeObject *FunctionDef_type;
+char *FunctionDef_fields[]={
+        "name",
+        "args",
+        "body",
+        "decorators",
+};
+PyTypeObject *ClassDef_type;
+char *ClassDef_fields[]={
+        "name",
+        "bases",
+        "body",
+};
+PyTypeObject *Return_type;
+char *Return_fields[]={
+        "value",
+};
+PyTypeObject *Delete_type;
+char *Delete_fields[]={
+        "targets",
+};
+PyTypeObject *Assign_type;
+char *Assign_fields[]={
+        "targets",
+        "value",
+};
+PyTypeObject *AugAssign_type;
+char *AugAssign_fields[]={
+        "target",
+        "op",
+        "value",
+};
+PyTypeObject *Print_type;
+char *Print_fields[]={
+        "dest",
+        "values",
+        "nl",
+};
+PyTypeObject *For_type;
+char *For_fields[]={
+        "target",
+        "iter",
+        "body",
+        "orelse",
+};
+PyTypeObject *While_type;
+char *While_fields[]={
+        "test",
+        "body",
+        "orelse",
+};
+PyTypeObject *If_type;
+char *If_fields[]={
+        "test",
+        "body",
+        "orelse",
+};
+PyTypeObject *Raise_type;
+char *Raise_fields[]={
+        "type",
+        "inst",
+        "tback",
+};
+PyTypeObject *TryExcept_type;
+char *TryExcept_fields[]={
+        "body",
+        "handlers",
+        "orelse",
+};
+PyTypeObject *TryFinally_type;
+char *TryFinally_fields[]={
+        "body",
+        "finalbody",
+};
+PyTypeObject *Assert_type;
+char *Assert_fields[]={
+        "test",
+        "msg",
+};
+PyTypeObject *Import_type;
+char *Import_fields[]={
+        "names",
+};
+PyTypeObject *ImportFrom_type;
+char *ImportFrom_fields[]={
+        "module",
+        "names",
+};
+PyTypeObject *Exec_type;
+char *Exec_fields[]={
+        "body",
+        "globals",
+        "locals",
+};
+PyTypeObject *Global_type;
+char *Global_fields[]={
+        "names",
+};
+PyTypeObject *Expr_type;
+char *Expr_fields[]={
+        "value",
+};
+PyTypeObject *Pass_type;
+char *Pass_fields[]={
+};
+PyTypeObject *Break_type;
+char *Break_fields[]={
+};
+PyTypeObject *Continue_type;
+char *Continue_fields[]={
+};
+PyTypeObject *expr_type;
+static PyObject* ast2obj_expr(void*);
+PyTypeObject *BoolOp_type;
+char *BoolOp_fields[]={
+        "op",
+        "values",
+};
+PyTypeObject *BinOp_type;
+char *BinOp_fields[]={
+        "left",
+        "op",
+        "right",
+};
+PyTypeObject *UnaryOp_type;
+char *UnaryOp_fields[]={
+        "op",
+        "operand",
+};
+PyTypeObject *Lambda_type;
+char *Lambda_fields[]={
+        "args",
+        "body",
+};
+PyTypeObject *Dict_type;
+char *Dict_fields[]={
+        "keys",
+        "values",
+};
+PyTypeObject *ListComp_type;
+char *ListComp_fields[]={
+        "elt",
+        "generators",
+};
+PyTypeObject *GeneratorExp_type;
+char *GeneratorExp_fields[]={
+        "elt",
+        "generators",
+};
+PyTypeObject *Yield_type;
+char *Yield_fields[]={
+        "value",
+};
+PyTypeObject *Compare_type;
+char *Compare_fields[]={
+        "left",
+        "ops",
+        "comparators",
+};
+PyTypeObject *Call_type;
+char *Call_fields[]={
+        "func",
+        "args",
+        "keywords",
+        "starargs",
+        "kwargs",
+};
+PyTypeObject *Repr_type;
+char *Repr_fields[]={
+        "value",
+};
+PyTypeObject *Num_type;
+char *Num_fields[]={
+        "n",
+};
+PyTypeObject *Str_type;
+char *Str_fields[]={
+        "s",
+};
+PyTypeObject *Attribute_type;
+char *Attribute_fields[]={
+        "value",
+        "attr",
+        "ctx",
+};
+PyTypeObject *Subscript_type;
+char *Subscript_fields[]={
+        "value",
+        "slice",
+        "ctx",
+};
+PyTypeObject *Name_type;
+char *Name_fields[]={
+        "id",
+        "ctx",
+};
+PyTypeObject *List_type;
+char *List_fields[]={
+        "elts",
+        "ctx",
+};
+PyTypeObject *Tuple_type;
+char *Tuple_fields[]={
+        "elts",
+        "ctx",
+};
+PyTypeObject *expr_context_type;
+static PyObject *Load_singleton, *Store_singleton, *Del_singleton,
+*AugLoad_singleton, *AugStore_singleton, *Param_singleton;
+static PyObject* ast2obj_expr_context(expr_context_ty);
+PyTypeObject *Load_type;
+char *Load_fields[]={
+};
+PyTypeObject *Store_type;
+char *Store_fields[]={
+};
+PyTypeObject *Del_type;
+char *Del_fields[]={
+};
+PyTypeObject *AugLoad_type;
+char *AugLoad_fields[]={
+};
+PyTypeObject *AugStore_type;
+char *AugStore_fields[]={
+};
+PyTypeObject *Param_type;
+char *Param_fields[]={
+};
+PyTypeObject *slice_type;
+static PyObject* ast2obj_slice(void*);
+PyTypeObject *Ellipsis_type;
+char *Ellipsis_fields[]={
+};
+PyTypeObject *Slice_type;
+char *Slice_fields[]={
+        "lower",
+        "upper",
+        "step",
+};
+PyTypeObject *ExtSlice_type;
+char *ExtSlice_fields[]={
+        "dims",
+};
+PyTypeObject *Index_type;
+char *Index_fields[]={
+        "value",
+};
+PyTypeObject *boolop_type;
+static PyObject *And_singleton, *Or_singleton;
+static PyObject* ast2obj_boolop(boolop_ty);
+PyTypeObject *And_type;
+char *And_fields[]={
+};
+PyTypeObject *Or_type;
+char *Or_fields[]={
+};
+PyTypeObject *operator_type;
+static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton,
+*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton,
+*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton,
+*FloorDiv_singleton;
+static PyObject* ast2obj_operator(operator_ty);
+PyTypeObject *Add_type;
+char *Add_fields[]={
+};
+PyTypeObject *Sub_type;
+char *Sub_fields[]={
+};
+PyTypeObject *Mult_type;
+char *Mult_fields[]={
+};
+PyTypeObject *Div_type;
+char *Div_fields[]={
+};
+PyTypeObject *Mod_type;
+char *Mod_fields[]={
+};
+PyTypeObject *Pow_type;
+char *Pow_fields[]={
+};
+PyTypeObject *LShift_type;
+char *LShift_fields[]={
+};
+PyTypeObject *RShift_type;
+char *RShift_fields[]={
+};
+PyTypeObject *BitOr_type;
+char *BitOr_fields[]={
+};
+PyTypeObject *BitXor_type;
+char *BitXor_fields[]={
+};
+PyTypeObject *BitAnd_type;
+char *BitAnd_fields[]={
+};
+PyTypeObject *FloorDiv_type;
+char *FloorDiv_fields[]={
+};
+PyTypeObject *unaryop_type;
+static PyObject *Invert_singleton, *Not_singleton, *UAdd_singleton,
+*USub_singleton;
+static PyObject* ast2obj_unaryop(unaryop_ty);
+PyTypeObject *Invert_type;
+char *Invert_fields[]={
+};
+PyTypeObject *Not_type;
+char *Not_fields[]={
+};
+PyTypeObject *UAdd_type;
+char *UAdd_fields[]={
+};
+PyTypeObject *USub_type;
+char *USub_fields[]={
+};
+PyTypeObject *cmpop_type;
+static PyObject *Eq_singleton, *NotEq_singleton, *Lt_singleton, *LtE_singleton,
+*Gt_singleton, *GtE_singleton, *Is_singleton, *IsNot_singleton, *In_singleton,
+*NotIn_singleton;
+static PyObject* ast2obj_cmpop(cmpop_ty);
+PyTypeObject *Eq_type;
+char *Eq_fields[]={
+};
+PyTypeObject *NotEq_type;
+char *NotEq_fields[]={
+};
+PyTypeObject *Lt_type;
+char *Lt_fields[]={
+};
+PyTypeObject *LtE_type;
+char *LtE_fields[]={
+};
+PyTypeObject *Gt_type;
+char *Gt_fields[]={
+};
+PyTypeObject *GtE_type;
+char *GtE_fields[]={
+};
+PyTypeObject *Is_type;
+char *Is_fields[]={
+};
+PyTypeObject *IsNot_type;
+char *IsNot_fields[]={
+};
+PyTypeObject *In_type;
+char *In_fields[]={
+};
+PyTypeObject *NotIn_type;
+char *NotIn_fields[]={
+};
+PyTypeObject *comprehension_type;
+static PyObject* ast2obj_comprehension(void*);
+char *comprehension_fields[]={
+        "target",
+        "iter",
+        "ifs",
+};
+PyTypeObject *excepthandler_type;
+static PyObject* ast2obj_excepthandler(void*);
+char *excepthandler_fields[]={
+        "type",
+        "name",
+        "body",
+};
+PyTypeObject *arguments_type;
+static PyObject* ast2obj_arguments(void*);
+char *arguments_fields[]={
+        "args",
+        "vararg",
+        "kwarg",
+        "defaults",
+};
+PyTypeObject *keyword_type;
+static PyObject* ast2obj_keyword(void*);
+char *keyword_fields[]={
+        "arg",
+        "value",
+};
+PyTypeObject *alias_type;
+static PyObject* ast2obj_alias(void*);
+char *alias_fields[]={
+        "name",
+        "asname",
+};
+
+
+static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
+{
+    PyObject *fnames, *result;
+    int i;
+    if (num_fields) {
+        fnames = PyTuple_New(num_fields);
+        if (!fnames) return NULL;
+    } else {
+        fnames = Py_None;
+        Py_INCREF(Py_None);
+    }
+    for(i=0; i < num_fields; i++) {
+        PyObject *field = PyString_FromString(fields[i]);
+        if (!field) {
+            Py_DECREF(fnames);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(fnames, i, field);
+    }
+    result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sO}", type, base, "_fields", fnames);
+    Py_DECREF(fnames);
+    return (PyTypeObject*)result;
+}
+
+static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
+{
+    int i, n = asdl_seq_LEN(seq);
+    PyObject *result = PyList_New(n);
+    PyObject *value;
+    if (!result)
+        return NULL;
+    for (i = 0; i < n; i++) {
+        value = func(asdl_seq_GET(seq, i));
+        if (!value) {
+            Py_DECREF(result);
+            return NULL;
+        }
+        PyList_SET_ITEM(result, i, value);
+    }
+    return result;
+}
+
+static PyObject* ast2obj_object(void *o)
+{
+    if (!o)
+        o = Py_None;
+    Py_INCREF((PyObject*)o);
+    return (PyObject*)o;
+}
+#define ast2obj_identifier ast2obj_object
+#define ast2obj_string ast2obj_object
+static PyObject* ast2obj_bool(bool b)
+{
+    return PyBool_FromLong(b);
+}
+
+static int initialized;
+static int init_types(void)
+{
+        if (initialized) return 1;
+        mod_type = make_type("mod", &PyBaseObject_Type, NULL, 0);
+        Module_type = make_type("Module", mod_type, Module_fields, 1);
+        Interactive_type = make_type("Interactive", mod_type,
+                                     Interactive_fields, 1);
+        Expression_type = make_type("Expression", mod_type, Expression_fields,
+                                    1);
+        Suite_type = make_type("Suite", mod_type, Suite_fields, 1);
+        stmt_type = make_type("stmt", &PyBaseObject_Type, NULL, 0);
+        FunctionDef_type = make_type("FunctionDef", stmt_type,
+                                     FunctionDef_fields, 4);
+        ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 3);
+        Return_type = make_type("Return", stmt_type, Return_fields, 1);
+        Delete_type = make_type("Delete", stmt_type, Delete_fields, 1);
+        Assign_type = make_type("Assign", stmt_type, Assign_fields, 2);
+        AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3);
+        Print_type = make_type("Print", stmt_type, Print_fields, 3);
+        For_type = make_type("For", stmt_type, For_fields, 4);
+        While_type = make_type("While", stmt_type, While_fields, 3);
+        If_type = make_type("If", stmt_type, If_fields, 3);
+        Raise_type = make_type("Raise", stmt_type, Raise_fields, 3);
+        TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
+        TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
+                                    2);
+        Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
+        Import_type = make_type("Import", stmt_type, Import_fields, 1);
+        ImportFrom_type = make_type("ImportFrom", stmt_type, ImportFrom_fields,
+                                    2);
+        Exec_type = make_type("Exec", stmt_type, Exec_fields, 3);
+        Global_type = make_type("Global", stmt_type, Global_fields, 1);
+        Expr_type = make_type("Expr", stmt_type, Expr_fields, 1);
+        Pass_type = make_type("Pass", stmt_type, Pass_fields, 0);
+        Break_type = make_type("Break", stmt_type, Break_fields, 0);
+        Continue_type = make_type("Continue", stmt_type, Continue_fields, 0);
+        expr_type = make_type("expr", &PyBaseObject_Type, NULL, 0);
+        BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2);
+        BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3);
+        UnaryOp_type = make_type("UnaryOp", expr_type, UnaryOp_fields, 2);
+        Lambda_type = make_type("Lambda", expr_type, Lambda_fields, 2);
+        Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
+        ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
+        GeneratorExp_type = make_type("GeneratorExp", expr_type,
+                                      GeneratorExp_fields, 2);
+        Yield_type = make_type("Yield", expr_type, Yield_fields, 1);
+        Compare_type = make_type("Compare", expr_type, Compare_fields, 3);
+        Call_type = make_type("Call", expr_type, Call_fields, 5);
+        Repr_type = make_type("Repr", expr_type, Repr_fields, 1);
+        Num_type = make_type("Num", expr_type, Num_fields, 1);
+        Str_type = make_type("Str", expr_type, Str_fields, 1);
+        Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
+        Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
+        Name_type = make_type("Name", expr_type, Name_fields, 2);
+        List_type = make_type("List", expr_type, List_fields, 2);
+        Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2);
+        expr_context_type = make_type("expr_context", &PyBaseObject_Type, NULL,
+                                      0);
+        Load_type = make_type("Load", expr_context_type, Load_fields, 0);
+        Load_singleton = PyType_GenericNew(Load_type, NULL, NULL);
+        Store_type = make_type("Store", expr_context_type, Store_fields, 0);
+        Store_singleton = PyType_GenericNew(Store_type, NULL, NULL);
+        Del_type = make_type("Del", expr_context_type, Del_fields, 0);
+        Del_singleton = PyType_GenericNew(Del_type, NULL, NULL);
+        AugLoad_type = make_type("AugLoad", expr_context_type, AugLoad_fields,
+                                 0);
+        AugLoad_singleton = PyType_GenericNew(AugLoad_type, NULL, NULL);
+        AugStore_type = make_type("AugStore", expr_context_type,
+                                  AugStore_fields, 0);
+        AugStore_singleton = PyType_GenericNew(AugStore_type, NULL, NULL);
+        Param_type = make_type("Param", expr_context_type, Param_fields, 0);
+        Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
+        slice_type = make_type("slice", &PyBaseObject_Type, NULL, 0);
+        Ellipsis_type = make_type("Ellipsis", slice_type, Ellipsis_fields, 0);
+        Slice_type = make_type("Slice", slice_type, Slice_fields, 3);
+        ExtSlice_type = make_type("ExtSlice", slice_type, ExtSlice_fields, 1);
+        Index_type = make_type("Index", slice_type, Index_fields, 1);
+        boolop_type = make_type("boolop", &PyBaseObject_Type, NULL, 0);
+        And_type = make_type("And", boolop_type, And_fields, 0);
+        And_singleton = PyType_GenericNew(And_type, NULL, NULL);
+        Or_type = make_type("Or", boolop_type, Or_fields, 0);
+        Or_singleton = PyType_GenericNew(Or_type, NULL, NULL);
+        operator_type = make_type("operator", &PyBaseObject_Type, NULL, 0);
+        Add_type = make_type("Add", operator_type, Add_fields, 0);
+        Add_singleton = PyType_GenericNew(Add_type, NULL, NULL);
+        Sub_type = make_type("Sub", operator_type, Sub_fields, 0);
+        Sub_singleton = PyType_GenericNew(Sub_type, NULL, NULL);
+        Mult_type = make_type("Mult", operator_type, Mult_fields, 0);
+        Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL);
+        Div_type = make_type("Div", operator_type, Div_fields, 0);
+        Div_singleton = PyType_GenericNew(Div_type, NULL, NULL);
+        Mod_type = make_type("Mod", operator_type, Mod_fields, 0);
+        Mod_singleton = PyType_GenericNew(Mod_type, NULL, NULL);
+        Pow_type = make_type("Pow", operator_type, Pow_fields, 0);
+        Pow_singleton = PyType_GenericNew(Pow_type, NULL, NULL);
+        LShift_type = make_type("LShift", operator_type, LShift_fields, 0);
+        LShift_singleton = PyType_GenericNew(LShift_type, NULL, NULL);
+        RShift_type = make_type("RShift", operator_type, RShift_fields, 0);
+        RShift_singleton = PyType_GenericNew(RShift_type, NULL, NULL);
+        BitOr_type = make_type("BitOr", operator_type, BitOr_fields, 0);
+        BitOr_singleton = PyType_GenericNew(BitOr_type, NULL, NULL);
+        BitXor_type = make_type("BitXor", operator_type, BitXor_fields, 0);
+        BitXor_singleton = PyType_GenericNew(BitXor_type, NULL, NULL);
+        BitAnd_type = make_type("BitAnd", operator_type, BitAnd_fields, 0);
+        BitAnd_singleton = PyType_GenericNew(BitAnd_type, NULL, NULL);
+        FloorDiv_type = make_type("FloorDiv", operator_type, FloorDiv_fields,
+                                  0);
+        FloorDiv_singleton = PyType_GenericNew(FloorDiv_type, NULL, NULL);
+        unaryop_type = make_type("unaryop", &PyBaseObject_Type, NULL, 0);
+        Invert_type = make_type("Invert", unaryop_type, Invert_fields, 0);
+        Invert_singleton = PyType_GenericNew(Invert_type, NULL, NULL);
+        Not_type = make_type("Not", unaryop_type, Not_fields, 0);
+        Not_singleton = PyType_GenericNew(Not_type, NULL, NULL);
+        UAdd_type = make_type("UAdd", unaryop_type, UAdd_fields, 0);
+        UAdd_singleton = PyType_GenericNew(UAdd_type, NULL, NULL);
+        USub_type = make_type("USub", unaryop_type, USub_fields, 0);
+        USub_singleton = PyType_GenericNew(USub_type, NULL, NULL);
+        cmpop_type = make_type("cmpop", &PyBaseObject_Type, NULL, 0);
+        Eq_type = make_type("Eq", cmpop_type, Eq_fields, 0);
+        Eq_singleton = PyType_GenericNew(Eq_type, NULL, NULL);
+        NotEq_type = make_type("NotEq", cmpop_type, NotEq_fields, 0);
+        NotEq_singleton = PyType_GenericNew(NotEq_type, NULL, NULL);
+        Lt_type = make_type("Lt", cmpop_type, Lt_fields, 0);
+        Lt_singleton = PyType_GenericNew(Lt_type, NULL, NULL);
+        LtE_type = make_type("LtE", cmpop_type, LtE_fields, 0);
+        LtE_singleton = PyType_GenericNew(LtE_type, NULL, NULL);
+        Gt_type = make_type("Gt", cmpop_type, Gt_fields, 0);
+        Gt_singleton = PyType_GenericNew(Gt_type, NULL, NULL);
+        GtE_type = make_type("GtE", cmpop_type, GtE_fields, 0);
+        GtE_singleton = PyType_GenericNew(GtE_type, NULL, NULL);
+        Is_type = make_type("Is", cmpop_type, Is_fields, 0);
+        Is_singleton = PyType_GenericNew(Is_type, NULL, NULL);
+        IsNot_type = make_type("IsNot", cmpop_type, IsNot_fields, 0);
+        IsNot_singleton = PyType_GenericNew(IsNot_type, NULL, NULL);
+        In_type = make_type("In", cmpop_type, In_fields, 0);
+        In_singleton = PyType_GenericNew(In_type, NULL, NULL);
+        NotIn_type = make_type("NotIn", cmpop_type, NotIn_fields, 0);
+        NotIn_singleton = PyType_GenericNew(NotIn_type, NULL, NULL);
+        comprehension_type = make_type("comprehension", &PyBaseObject_Type,
+                                       comprehension_fields, 3);
+        excepthandler_type = make_type("excepthandler", &PyBaseObject_Type,
+                                       excepthandler_fields, 3);
+        arguments_type = make_type("arguments", &PyBaseObject_Type,
+                                   arguments_fields, 4);
+        keyword_type = make_type("keyword", &PyBaseObject_Type, keyword_fields,
+                                 2);
+        alias_type = make_type("alias", &PyBaseObject_Type, alias_fields, 2);
+return 1;
+}
 
 mod_ty
 Module(asdl_seq * body, PyArena *arena)
@@ -1096,826 +1693,1055 @@
 }
 
 
-
-#define CHECKSIZE(BUF, OFF, MIN) { \
-        int need = *(OFF) + MIN; \
-        if (need >= PyString_GET_SIZE(*(BUF))) { \
-                int newsize = PyString_GET_SIZE(*(BUF)) * 2; \
-                if (newsize < need) \
-                        newsize = need; \
-                if (_PyString_Resize((BUF), newsize) < 0) \
-                        return 0; \
-        } \
-}
-
-static int
-marshal_write_int(PyObject **buf, int *offset, int x)
-{
-        char *s;
-
-        CHECKSIZE(buf, offset, 4)
-        s = PyString_AS_STRING(*buf) + (*offset);
-        s[0] = (x & 0xff);
-        s[1] = (x >> 8) & 0xff;
-        s[2] = (x >> 16) & 0xff;
-        s[3] = (x >> 24) & 0xff;
-        *offset += 4;
-        return 1;
-}
-
-static int
-marshal_write_bool(PyObject **buf, int *offset, bool b)
-{
-        if (b)
-                marshal_write_int(buf, offset, 1);
-        else
-                marshal_write_int(buf, offset, 0);
-        return 1;
-}
-
-static int
-marshal_write_identifier(PyObject **buf, int *offset, identifier id)
-{
-        int l = PyString_GET_SIZE(id);
-        marshal_write_int(buf, offset, l);
-        CHECKSIZE(buf, offset, l);
-        memcpy(PyString_AS_STRING(*buf) + *offset,
-               PyString_AS_STRING(id), l);
-        *offset += l;
-        return 1;
-}
-
-static int
-marshal_write_string(PyObject **buf, int *offset, string s)
+PyObject*
+ast2obj_mod(void* _o)
 {
-        int len = PyString_GET_SIZE(s);
-        marshal_write_int(buf, offset, len);
-        CHECKSIZE(buf, offset, len);
-        memcpy(PyString_AS_STRING(*buf) + *offset,
-               PyString_AS_STRING(s), len);
-        *offset += len;
-        return 1;
-}
-
-static int
-marshal_write_object(PyObject **buf, int *offset, object s)
-{
-        /* XXX */
-        return 0;
-}
-
+        mod_ty o = (mod_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
 
-static int
-marshal_write_mod(PyObject **buf, int *off, mod_ty o)
-{
-        int i;
         switch (o->kind) {
         case Module_kind:
-                marshal_write_int(buf, off, 1);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Module.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.Module.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.Module.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(Module_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Module.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Interactive_kind:
-                marshal_write_int(buf, off, 2);
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.Interactive.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.Interactive.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.Interactive.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(Interactive_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Interactive.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Expression_kind:
-                marshal_write_int(buf, off, 3);
-                marshal_write_expr(buf, off, o->v.Expression.body);
+                result = PyType_GenericNew(Expression_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Expression.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Suite_kind:
-                marshal_write_int(buf, off, 4);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Suite.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.Suite.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.Suite.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(Suite_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Suite.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         }
-        return 1;
-}
 
-static int
-marshal_write_stmt(PyObject **buf, int *off, stmt_ty o)
-{
-        int i;
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_stmt(void* _o)
+{
+        stmt_ty o = (stmt_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
         switch (o->kind) {
         case FunctionDef_kind:
-                marshal_write_int(buf, off, 1);
-                marshal_write_identifier(buf, off, o->v.FunctionDef.name);
-                marshal_write_arguments(buf, off, o->v.FunctionDef.args);
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.FunctionDef.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.FunctionDef.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.FunctionDef.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.FunctionDef.decorators));
-                for (i = 0; i < asdl_seq_LEN(o->v.FunctionDef.decorators); i++)
-                     {
-                        void *elt = asdl_seq_GET(o->v.FunctionDef.decorators,
-                                                 i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
+                result = PyType_GenericNew(FunctionDef_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.FunctionDef.name);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "name", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_arguments(o->v.FunctionDef.args);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.FunctionDef.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.FunctionDef.decorators, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "decorators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case ClassDef_kind:
-                marshal_write_int(buf, off, 2);
-                marshal_write_identifier(buf, off, o->v.ClassDef.name);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.ClassDef.bases));
-                for (i = 0; i < asdl_seq_LEN(o->v.ClassDef.bases); i++) {
-                        void *elt = asdl_seq_GET(o->v.ClassDef.bases, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.ClassDef.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.ClassDef.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.ClassDef.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(ClassDef_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.ClassDef.name);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "name", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ClassDef.bases, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "bases", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Return_kind:
-                marshal_write_int(buf, off, 3);
-                if (o->v.Return.value) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Return.value);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Return_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Return.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Delete_kind:
-                marshal_write_int(buf, off, 4);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Delete.targets));
-                for (i = 0; i < asdl_seq_LEN(o->v.Delete.targets); i++) {
-                        void *elt = asdl_seq_GET(o->v.Delete.targets, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
+                result = PyType_GenericNew(Delete_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Delete.targets, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "targets", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Assign_kind:
-                marshal_write_int(buf, off, 5);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Assign.targets));
-                for (i = 0; i < asdl_seq_LEN(o->v.Assign.targets); i++) {
-                        void *elt = asdl_seq_GET(o->v.Assign.targets, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_expr(buf, off, o->v.Assign.value);
+                result = PyType_GenericNew(Assign_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Assign.targets, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "targets", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Assign.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case AugAssign_kind:
-                marshal_write_int(buf, off, 6);
-                marshal_write_expr(buf, off, o->v.AugAssign.target);
-                marshal_write_operator(buf, off, o->v.AugAssign.op);
-                marshal_write_expr(buf, off, o->v.AugAssign.value);
+                result = PyType_GenericNew(AugAssign_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.AugAssign.target);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "target", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_operator(o->v.AugAssign.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.AugAssign.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Print_kind:
-                marshal_write_int(buf, off, 7);
-                if (o->v.Print.dest) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Print.dest);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Print.values));
-                for (i = 0; i < asdl_seq_LEN(o->v.Print.values); i++) {
-                        void *elt = asdl_seq_GET(o->v.Print.values, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_bool(buf, off, o->v.Print.nl);
+                result = PyType_GenericNew(Print_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Print.dest);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "dest", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Print.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_bool(o->v.Print.nl);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "nl", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case For_kind:
-                marshal_write_int(buf, off, 8);
-                marshal_write_expr(buf, off, o->v.For.target);
-                marshal_write_expr(buf, off, o->v.For.iter);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.For.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.For.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.For.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.For.orelse));
-                for (i = 0; i < asdl_seq_LEN(o->v.For.orelse); i++) {
-                        void *elt = asdl_seq_GET(o->v.For.orelse, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(For_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.For.target);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "target", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.For.iter);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "iter", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.For.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.For.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case While_kind:
-                marshal_write_int(buf, off, 9);
-                marshal_write_expr(buf, off, o->v.While.test);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.While.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.While.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.While.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.While.orelse));
-                for (i = 0; i < asdl_seq_LEN(o->v.While.orelse); i++) {
-                        void *elt = asdl_seq_GET(o->v.While.orelse, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(While_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.While.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.While.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.While.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case If_kind:
-                marshal_write_int(buf, off, 10);
-                marshal_write_expr(buf, off, o->v.If.test);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.If.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.If.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.If.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.If.orelse));
-                for (i = 0; i < asdl_seq_LEN(o->v.If.orelse); i++) {
-                        void *elt = asdl_seq_GET(o->v.If.orelse, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(If_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.If.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.If.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.If.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Raise_kind:
-                marshal_write_int(buf, off, 11);
-                if (o->v.Raise.type) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Raise.type);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Raise.inst) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Raise.inst);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Raise.tback) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Raise.tback);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Raise_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Raise.type);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "type", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Raise.inst);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "inst", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Raise.tback);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "tback", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case TryExcept_kind:
-                marshal_write_int(buf, off, 12);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.TryExcept.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.TryExcept.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.TryExcept.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.TryExcept.handlers));
-                for (i = 0; i < asdl_seq_LEN(o->v.TryExcept.handlers); i++) {
-                        void *elt = asdl_seq_GET(o->v.TryExcept.handlers, i);
-                        marshal_write_excepthandler(buf, off,
-                                                    (excepthandler_ty)elt);
-                }
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.TryExcept.orelse));
-                for (i = 0; i < asdl_seq_LEN(o->v.TryExcept.orelse); i++) {
-                        void *elt = asdl_seq_GET(o->v.TryExcept.orelse, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(TryExcept_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryExcept.handlers,
+                                     ast2obj_excepthandler);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "handlers", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "orelse", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case TryFinally_kind:
-                marshal_write_int(buf, off, 13);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.TryFinally.body));
-                for (i = 0; i < asdl_seq_LEN(o->v.TryFinally.body); i++) {
-                        void *elt = asdl_seq_GET(o->v.TryFinally.body, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.TryFinally.finalbody));
-                for (i = 0; i < asdl_seq_LEN(o->v.TryFinally.finalbody); i++) {
-                        void *elt = asdl_seq_GET(o->v.TryFinally.finalbody, i);
-                        marshal_write_stmt(buf, off, (stmt_ty)elt);
-                }
+                result = PyType_GenericNew(TryFinally_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "finalbody", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Assert_kind:
-                marshal_write_int(buf, off, 14);
-                marshal_write_expr(buf, off, o->v.Assert.test);
-                if (o->v.Assert.msg) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Assert.msg);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Assert_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Assert.test);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "test", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Assert.msg);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "msg", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Import_kind:
-                marshal_write_int(buf, off, 15);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Import.names));
-                for (i = 0; i < asdl_seq_LEN(o->v.Import.names); i++) {
-                        void *elt = asdl_seq_GET(o->v.Import.names, i);
-                        marshal_write_alias(buf, off, (alias_ty)elt);
-                }
+                result = PyType_GenericNew(Import_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Import.names, ast2obj_alias);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case ImportFrom_kind:
-                marshal_write_int(buf, off, 16);
-                marshal_write_identifier(buf, off, o->v.ImportFrom.module);
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.ImportFrom.names));
-                for (i = 0; i < asdl_seq_LEN(o->v.ImportFrom.names); i++) {
-                        void *elt = asdl_seq_GET(o->v.ImportFrom.names, i);
-                        marshal_write_alias(buf, off, (alias_ty)elt);
-                }
+                result = PyType_GenericNew(ImportFrom_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.ImportFrom.module);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "module", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ImportFrom.names, ast2obj_alias);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Exec_kind:
-                marshal_write_int(buf, off, 17);
-                marshal_write_expr(buf, off, o->v.Exec.body);
-                if (o->v.Exec.globals) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Exec.globals);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Exec.locals) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Exec.locals);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Exec_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Exec.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Exec.globals);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "globals", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Exec.locals);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "locals", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Global_kind:
-                marshal_write_int(buf, off, 18);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Global.names));
-                for (i = 0; i < asdl_seq_LEN(o->v.Global.names); i++) {
-                        void *elt = asdl_seq_GET(o->v.Global.names, i);
-                        marshal_write_identifier(buf, off, (identifier)elt);
-                }
+                result = PyType_GenericNew(Global_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Global.names, ast2obj_identifier);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "names", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Expr_kind:
-                marshal_write_int(buf, off, 19);
-                marshal_write_expr(buf, off, o->v.Expr.value);
+                result = PyType_GenericNew(Expr_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Expr.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Pass_kind:
-                marshal_write_int(buf, off, 20);
+                result = PyType_GenericNew(Pass_type, NULL, NULL);
+                if (!result) goto failed;
                 break;
         case Break_kind:
-                marshal_write_int(buf, off, 21);
+                result = PyType_GenericNew(Break_type, NULL, NULL);
+                if (!result) goto failed;
                 break;
         case Continue_kind:
-                marshal_write_int(buf, off, 22);
+                result = PyType_GenericNew(Continue_type, NULL, NULL);
+                if (!result) goto failed;
                 break;
         }
-        return 1;
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
 }
 
-static int
-marshal_write_expr(PyObject **buf, int *off, expr_ty o)
+PyObject*
+ast2obj_expr(void* _o)
 {
-        int i;
+        expr_ty o = (expr_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
         switch (o->kind) {
         case BoolOp_kind:
-                marshal_write_int(buf, off, 1);
-                marshal_write_boolop(buf, off, o->v.BoolOp.op);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.BoolOp.values));
-                for (i = 0; i < asdl_seq_LEN(o->v.BoolOp.values); i++) {
-                        void *elt = asdl_seq_GET(o->v.BoolOp.values, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
+                result = PyType_GenericNew(BoolOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_boolop(o->v.BoolOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.BoolOp.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case BinOp_kind:
-                marshal_write_int(buf, off, 2);
-                marshal_write_expr(buf, off, o->v.BinOp.left);
-                marshal_write_operator(buf, off, o->v.BinOp.op);
-                marshal_write_expr(buf, off, o->v.BinOp.right);
+                result = PyType_GenericNew(BinOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.BinOp.left);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "left", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_operator(o->v.BinOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.BinOp.right);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "right", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case UnaryOp_kind:
-                marshal_write_int(buf, off, 3);
-                marshal_write_unaryop(buf, off, o->v.UnaryOp.op);
-                marshal_write_expr(buf, off, o->v.UnaryOp.operand);
+                result = PyType_GenericNew(UnaryOp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_unaryop(o->v.UnaryOp.op);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "op", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.UnaryOp.operand);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "operand", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Lambda_kind:
-                marshal_write_int(buf, off, 4);
-                marshal_write_arguments(buf, off, o->v.Lambda.args);
-                marshal_write_expr(buf, off, o->v.Lambda.body);
+                result = PyType_GenericNew(Lambda_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_arguments(o->v.Lambda.args);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Lambda.body);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "body", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Dict_kind:
-                marshal_write_int(buf, off, 5);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Dict.keys));
-                for (i = 0; i < asdl_seq_LEN(o->v.Dict.keys); i++) {
-                        void *elt = asdl_seq_GET(o->v.Dict.keys, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Dict.values));
-                for (i = 0; i < asdl_seq_LEN(o->v.Dict.values); i++) {
-                        void *elt = asdl_seq_GET(o->v.Dict.values, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
+                result = PyType_GenericNew(Dict_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Dict.keys, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "keys", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Dict.values, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "values", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case ListComp_kind:
-                marshal_write_int(buf, off, 6);
-                marshal_write_expr(buf, off, o->v.ListComp.elt);
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.ListComp.generators));
-                for (i = 0; i < asdl_seq_LEN(o->v.ListComp.generators); i++) {
-                        void *elt = asdl_seq_GET(o->v.ListComp.generators, i);
-                        marshal_write_comprehension(buf, off,
-                                                    (comprehension_ty)elt);
-                }
+                result = PyType_GenericNew(ListComp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.ListComp.elt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elt", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.ListComp.generators,
+                                     ast2obj_comprehension);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "generators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case GeneratorExp_kind:
-                marshal_write_int(buf, off, 7);
-                marshal_write_expr(buf, off, o->v.GeneratorExp.elt);
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.GeneratorExp.generators));
-                for (i = 0; i < asdl_seq_LEN(o->v.GeneratorExp.generators);
-                     i++) {
-                        void *elt = asdl_seq_GET(o->v.GeneratorExp.generators,
-                                                 i);
-                        marshal_write_comprehension(buf, off,
-                                                    (comprehension_ty)elt);
-                }
+                result = PyType_GenericNew(GeneratorExp_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.GeneratorExp.elt);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elt", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.GeneratorExp.generators,
+                                     ast2obj_comprehension);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "generators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Yield_kind:
-                marshal_write_int(buf, off, 8);
-                if (o->v.Yield.value) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Yield.value);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Yield_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Yield.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Compare_kind:
-                marshal_write_int(buf, off, 9);
-                marshal_write_expr(buf, off, o->v.Compare.left);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Compare.ops));
-                for (i = 0; i < asdl_seq_LEN(o->v.Compare.ops); i++) {
-                        void *elt = asdl_seq_GET(o->v.Compare.ops, i);
-                        marshal_write_cmpop(buf, off, (cmpop_ty)elt);
-                }
-                marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.Compare.comparators));
-                for (i = 0; i < asdl_seq_LEN(o->v.Compare.comparators); i++) {
-                        void *elt = asdl_seq_GET(o->v.Compare.comparators, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
+                result = PyType_GenericNew(Compare_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Compare.left);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "left", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Compare.ops,
+                                     (PyObject*(*)(void*))ast2obj_cmpop);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ops", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Compare.comparators, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "comparators", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Call_kind:
-                marshal_write_int(buf, off, 10);
-                marshal_write_expr(buf, off, o->v.Call.func);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Call.args));
-                for (i = 0; i < asdl_seq_LEN(o->v.Call.args); i++) {
-                        void *elt = asdl_seq_GET(o->v.Call.args, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Call.keywords));
-                for (i = 0; i < asdl_seq_LEN(o->v.Call.keywords); i++) {
-                        void *elt = asdl_seq_GET(o->v.Call.keywords, i);
-                        marshal_write_keyword(buf, off, (keyword_ty)elt);
-                }
-                if (o->v.Call.starargs) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Call.starargs);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Call.kwargs) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Call.kwargs);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Call_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Call.func);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "func", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Call.args, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "args", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_list(o->v.Call.keywords, ast2obj_keyword);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "keywords", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Call.starargs);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "starargs", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Call.kwargs);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "kwargs", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Repr_kind:
-                marshal_write_int(buf, off, 11);
-                marshal_write_expr(buf, off, o->v.Repr.value);
+                result = PyType_GenericNew(Repr_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Repr.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Num_kind:
-                marshal_write_int(buf, off, 12);
-                marshal_write_object(buf, off, o->v.Num.n);
+                result = PyType_GenericNew(Num_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_object(o->v.Num.n);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "n", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Str_kind:
-                marshal_write_int(buf, off, 13);
-                marshal_write_string(buf, off, o->v.Str.s);
+                result = PyType_GenericNew(Str_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_string(o->v.Str.s);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "s", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Attribute_kind:
-                marshal_write_int(buf, off, 14);
-                marshal_write_expr(buf, off, o->v.Attribute.value);
-                marshal_write_identifier(buf, off, o->v.Attribute.attr);
-                marshal_write_expr_context(buf, off, o->v.Attribute.ctx);
+                result = PyType_GenericNew(Attribute_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Attribute.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_identifier(o->v.Attribute.attr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "attr", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Attribute.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Subscript_kind:
-                marshal_write_int(buf, off, 15);
-                marshal_write_expr(buf, off, o->v.Subscript.value);
-                marshal_write_slice(buf, off, o->v.Subscript.slice);
-                marshal_write_expr_context(buf, off, o->v.Subscript.ctx);
+                result = PyType_GenericNew(Subscript_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Subscript.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_slice(o->v.Subscript.slice);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "slice", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Subscript.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Name_kind:
-                marshal_write_int(buf, off, 16);
-                marshal_write_identifier(buf, off, o->v.Name.id);
-                marshal_write_expr_context(buf, off, o->v.Name.ctx);
+                result = PyType_GenericNew(Name_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_identifier(o->v.Name.id);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "id", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Name.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case List_kind:
-                marshal_write_int(buf, off, 17);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.List.elts));
-                for (i = 0; i < asdl_seq_LEN(o->v.List.elts); i++) {
-                        void *elt = asdl_seq_GET(o->v.List.elts, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_expr_context(buf, off, o->v.List.ctx);
+                result = PyType_GenericNew(List_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.List.elts, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elts", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.List.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Tuple_kind:
-                marshal_write_int(buf, off, 18);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.Tuple.elts));
-                for (i = 0; i < asdl_seq_LEN(o->v.Tuple.elts); i++) {
-                        void *elt = asdl_seq_GET(o->v.Tuple.elts, i);
-                        marshal_write_expr(buf, off, (expr_ty)elt);
-                }
-                marshal_write_expr_context(buf, off, o->v.Tuple.ctx);
+                result = PyType_GenericNew(Tuple_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.Tuple.elts, ast2obj_expr);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "elts", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr_context(o->v.Tuple.ctx);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "ctx", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         }
-        return 1;
-}
 
-static int
-marshal_write_expr_context(PyObject **buf, int *off, expr_context_ty o)
-{
-        switch (o) {
-        case Load:
-                marshal_write_int(buf, off, 1);
-                break;
-        case Store:
-                marshal_write_int(buf, off, 2);
-                break;
-        case Del:
-                marshal_write_int(buf, off, 3);
-                break;
-        case AugLoad:
-                marshal_write_int(buf, off, 4);
-                break;
-        case AugStore:
-                marshal_write_int(buf, off, 5);
-                break;
-        case Param:
-                marshal_write_int(buf, off, 6);
-                break;
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject* ast2obj_expr_context(expr_context_ty o)
+{
+        switch(o) {
+                case Load:
+                        Py_INCREF(Load_singleton);
+                        return Load_singleton;
+                case Store:
+                        Py_INCREF(Store_singleton);
+                        return Store_singleton;
+                case Del:
+                        Py_INCREF(Del_singleton);
+                        return Del_singleton;
+                case AugLoad:
+                        Py_INCREF(AugLoad_singleton);
+                        return AugLoad_singleton;
+                case AugStore:
+                        Py_INCREF(AugStore_singleton);
+                        return AugStore_singleton;
+                case Param:
+                        Py_INCREF(Param_singleton);
+                        return Param_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject*
+ast2obj_slice(void* _o)
+{
+        slice_ty o = (slice_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
         }
-        return 1;
-}
 
-static int
-marshal_write_slice(PyObject **buf, int *off, slice_ty o)
-{
-        int i;
         switch (o->kind) {
         case Ellipsis_kind:
-                marshal_write_int(buf, off, 1);
+                result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
+                if (!result) goto failed;
                 break;
         case Slice_kind:
-                marshal_write_int(buf, off, 2);
-                if (o->v.Slice.lower) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Slice.lower);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Slice.upper) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Slice.upper);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
-                if (o->v.Slice.step) {
-                        marshal_write_int(buf, off, 1);
-                        marshal_write_expr(buf, off, o->v.Slice.step);
-                }
-                else {
-                        marshal_write_int(buf, off, 0);
-                }
+                result = PyType_GenericNew(Slice_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Slice.lower);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "lower", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Slice.upper);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "upper", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                value = ast2obj_expr(o->v.Slice.step);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "step", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case ExtSlice_kind:
-                marshal_write_int(buf, off, 3);
-                marshal_write_int(buf, off, asdl_seq_LEN(o->v.ExtSlice.dims));
-                for (i = 0; i < asdl_seq_LEN(o->v.ExtSlice.dims); i++) {
-                        void *elt = asdl_seq_GET(o->v.ExtSlice.dims, i);
-                        marshal_write_slice(buf, off, (slice_ty)elt);
-                }
+                result = PyType_GenericNew(ExtSlice_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "dims", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Index_kind:
-                marshal_write_int(buf, off, 4);
-                marshal_write_expr(buf, off, o->v.Index.value);
-                break;
-        }
-        return 1;
-}
-
-static int
-marshal_write_boolop(PyObject **buf, int *off, boolop_ty o)
-{
-        switch (o) {
-        case And:
-                marshal_write_int(buf, off, 1);
-                break;
-        case Or:
-                marshal_write_int(buf, off, 2);
-                break;
-        }
-        return 1;
-}
-
-static int
-marshal_write_operator(PyObject **buf, int *off, operator_ty o)
-{
-        switch (o) {
-        case Add:
-                marshal_write_int(buf, off, 1);
-                break;
-        case Sub:
-                marshal_write_int(buf, off, 2);
-                break;
-        case Mult:
-                marshal_write_int(buf, off, 3);
-                break;
-        case Div:
-                marshal_write_int(buf, off, 4);
-                break;
-        case Mod:
-                marshal_write_int(buf, off, 5);
-                break;
-        case Pow:
-                marshal_write_int(buf, off, 6);
-                break;
-        case LShift:
-                marshal_write_int(buf, off, 7);
-                break;
-        case RShift:
-                marshal_write_int(buf, off, 8);
-                break;
-        case BitOr:
-                marshal_write_int(buf, off, 9);
-                break;
-        case BitXor:
-                marshal_write_int(buf, off, 10);
-                break;
-        case BitAnd:
-                marshal_write_int(buf, off, 11);
-                break;
-        case FloorDiv:
-                marshal_write_int(buf, off, 12);
-                break;
-        }
-        return 1;
+                result = PyType_GenericNew(Index_type, NULL, NULL);
+                if (!result) goto failed;
+                value = ast2obj_expr(o->v.Index.value);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "value", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
+                break;
+        }
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject* ast2obj_boolop(boolop_ty o)
+{
+        switch(o) {
+                case And:
+                        Py_INCREF(And_singleton);
+                        return And_singleton;
+                case Or:
+                        Py_INCREF(Or_singleton);
+                        return Or_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_operator(operator_ty o)
+{
+        switch(o) {
+                case Add:
+                        Py_INCREF(Add_singleton);
+                        return Add_singleton;
+                case Sub:
+                        Py_INCREF(Sub_singleton);
+                        return Sub_singleton;
+                case Mult:
+                        Py_INCREF(Mult_singleton);
+                        return Mult_singleton;
+                case Div:
+                        Py_INCREF(Div_singleton);
+                        return Div_singleton;
+                case Mod:
+                        Py_INCREF(Mod_singleton);
+                        return Mod_singleton;
+                case Pow:
+                        Py_INCREF(Pow_singleton);
+                        return Pow_singleton;
+                case LShift:
+                        Py_INCREF(LShift_singleton);
+                        return LShift_singleton;
+                case RShift:
+                        Py_INCREF(RShift_singleton);
+                        return RShift_singleton;
+                case BitOr:
+                        Py_INCREF(BitOr_singleton);
+                        return BitOr_singleton;
+                case BitXor:
+                        Py_INCREF(BitXor_singleton);
+                        return BitXor_singleton;
+                case BitAnd:
+                        Py_INCREF(BitAnd_singleton);
+                        return BitAnd_singleton;
+                case FloorDiv:
+                        Py_INCREF(FloorDiv_singleton);
+                        return FloorDiv_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_unaryop(unaryop_ty o)
+{
+        switch(o) {
+                case Invert:
+                        Py_INCREF(Invert_singleton);
+                        return Invert_singleton;
+                case Not:
+                        Py_INCREF(Not_singleton);
+                        return Not_singleton;
+                case UAdd:
+                        Py_INCREF(UAdd_singleton);
+                        return UAdd_singleton;
+                case USub:
+                        Py_INCREF(USub_singleton);
+                        return USub_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject* ast2obj_cmpop(cmpop_ty o)
+{
+        switch(o) {
+                case Eq:
+                        Py_INCREF(Eq_singleton);
+                        return Eq_singleton;
+                case NotEq:
+                        Py_INCREF(NotEq_singleton);
+                        return NotEq_singleton;
+                case Lt:
+                        Py_INCREF(Lt_singleton);
+                        return Lt_singleton;
+                case LtE:
+                        Py_INCREF(LtE_singleton);
+                        return LtE_singleton;
+                case Gt:
+                        Py_INCREF(Gt_singleton);
+                        return Gt_singleton;
+                case GtE:
+                        Py_INCREF(GtE_singleton);
+                        return GtE_singleton;
+                case Is:
+                        Py_INCREF(Is_singleton);
+                        return Is_singleton;
+                case IsNot:
+                        Py_INCREF(IsNot_singleton);
+                        return IsNot_singleton;
+                case In:
+                        Py_INCREF(In_singleton);
+                        return In_singleton;
+                case NotIn:
+                        Py_INCREF(NotIn_singleton);
+                        return NotIn_singleton;
+        }
+        return NULL; /* cannot happen */
+}
+PyObject*
+ast2obj_comprehension(void* _o)
+{
+        comprehension_ty o = (comprehension_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(comprehension_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_expr(o->target);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "target", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->iter);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "iter", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->ifs, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "ifs", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_excepthandler(void* _o)
+{
+        excepthandler_ty o = (excepthandler_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(excepthandler_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_expr(o->type);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "type", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->name);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "name", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->body, ast2obj_stmt);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "body", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_arguments(void* _o)
+{
+        arguments_ty o = (arguments_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(arguments_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_list(o->args, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "args", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->vararg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "vararg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->kwarg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "kwarg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(o->defaults, ast2obj_expr);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "defaults", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_keyword(void* _o)
+{
+        keyword_ty o = (keyword_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(keyword_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_identifier(o->arg);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "arg", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(o->value);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "value", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
+}
+
+PyObject*
+ast2obj_alias(void* _o)
+{
+        alias_ty o = (alias_ty)_o;
+        PyObject *result = NULL, *value = NULL;
+        if (!o) {
+                Py_INCREF(Py_None);
+                return Py_None;
+        }
+
+        result = PyType_GenericNew(alias_type, NULL, NULL);
+        if (!result) return NULL;
+        value = ast2obj_identifier(o->name);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "name", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+        value = ast2obj_identifier(o->asname);
+        if (!value) goto failed;
+        if (PyObject_SetAttrString(result, "asname", value) == -1)
+                goto failed;
+        Py_DECREF(value);
+
+        return result;
+failed:
+        Py_XDECREF(value);
+        Py_XDECREF(result);
+        return NULL;
 }
 
-static int
-marshal_write_unaryop(PyObject **buf, int *off, unaryop_ty o)
-{
-        switch (o) {
-        case Invert:
-                marshal_write_int(buf, off, 1);
-                break;
-        case Not:
-                marshal_write_int(buf, off, 2);
-                break;
-        case UAdd:
-                marshal_write_int(buf, off, 3);
-                break;
-        case USub:
-                marshal_write_int(buf, off, 4);
-                break;
-        }
-        return 1;
-}
 
-static int
-marshal_write_cmpop(PyObject **buf, int *off, cmpop_ty o)
-{
-        switch (o) {
-        case Eq:
-                marshal_write_int(buf, off, 1);
-                break;
-        case NotEq:
-                marshal_write_int(buf, off, 2);
-                break;
-        case Lt:
-                marshal_write_int(buf, off, 3);
-                break;
-        case LtE:
-                marshal_write_int(buf, off, 4);
-                break;
-        case Gt:
-                marshal_write_int(buf, off, 5);
-                break;
-        case GtE:
-                marshal_write_int(buf, off, 6);
-                break;
-        case Is:
-                marshal_write_int(buf, off, 7);
-                break;
-        case IsNot:
-                marshal_write_int(buf, off, 8);
-                break;
-        case In:
-                marshal_write_int(buf, off, 9);
-                break;
-        case NotIn:
-                marshal_write_int(buf, off, 10);
-                break;
-        }
-        return 1;
-}
-
-static int
-marshal_write_comprehension(PyObject **buf, int *off, comprehension_ty o)
-{
-        int i;
-        marshal_write_expr(buf, off, o->target);
-        marshal_write_expr(buf, off, o->iter);
-        marshal_write_int(buf, off, asdl_seq_LEN(o->ifs));
-        for (i = 0; i < asdl_seq_LEN(o->ifs); i++) {
-                void *elt = asdl_seq_GET(o->ifs, i);
-                marshal_write_expr(buf, off, (expr_ty)elt);
-        }
-        return 1;
-}
-
-static int
-marshal_write_excepthandler(PyObject **buf, int *off, excepthandler_ty o)
-{
-        int i;
-        if (o->type) {
-                marshal_write_int(buf, off, 1);
-                marshal_write_expr(buf, off, o->type);
-        }
-        else {
-                marshal_write_int(buf, off, 0);
-        }
-        if (o->name) {
-                marshal_write_int(buf, off, 1);
-                marshal_write_expr(buf, off, o->name);
-        }
-        else {
-                marshal_write_int(buf, off, 0);
-        }
-        marshal_write_int(buf, off, asdl_seq_LEN(o->body));
-        for (i = 0; i < asdl_seq_LEN(o->body); i++) {
-                void *elt = asdl_seq_GET(o->body, i);
-                marshal_write_stmt(buf, off, (stmt_ty)elt);
-        }
-        return 1;
-}
 
-static int
-marshal_write_arguments(PyObject **buf, int *off, arguments_ty o)
+PyObject* PyAST_mod2obj(mod_ty t)
 {
-        int i;
-        marshal_write_int(buf, off, asdl_seq_LEN(o->args));
-        for (i = 0; i < asdl_seq_LEN(o->args); i++) {
-                void *elt = asdl_seq_GET(o->args, i);
-                marshal_write_expr(buf, off, (expr_ty)elt);
-        }
-        if (o->vararg) {
-                marshal_write_int(buf, off, 1);
-                marshal_write_identifier(buf, off, o->vararg);
-        }
-        else {
-                marshal_write_int(buf, off, 0);
-        }
-        if (o->kwarg) {
-                marshal_write_int(buf, off, 1);
-                marshal_write_identifier(buf, off, o->kwarg);
-        }
-        else {
-                marshal_write_int(buf, off, 0);
-        }
-        marshal_write_int(buf, off, asdl_seq_LEN(o->defaults));
-        for (i = 0; i < asdl_seq_LEN(o->defaults); i++) {
-                void *elt = asdl_seq_GET(o->defaults, i);
-                marshal_write_expr(buf, off, (expr_ty)elt);
-        }
-        return 1;
-}
-
-static int
-marshal_write_keyword(PyObject **buf, int *off, keyword_ty o)
-{
-        marshal_write_identifier(buf, off, o->arg);
-        marshal_write_expr(buf, off, o->value);
-        return 1;
-}
-
-static int
-marshal_write_alias(PyObject **buf, int *off, alias_ty o)
-{
-        marshal_write_identifier(buf, off, o->name);
-        if (o->asname) {
-                marshal_write_int(buf, off, 1);
-                marshal_write_identifier(buf, off, o->asname);
-        }
-        else {
-                marshal_write_int(buf, off, 0);
-        }
-        return 1;
+    init_types();
+    return ast2obj_mod(t);
 }
 
 

Modified: python/trunk/Python/bltinmodule.c
==============================================================================
--- python/trunk/Python/bltinmodule.c	(original)
+++ python/trunk/Python/bltinmodule.c	Sun Feb 26 20:42:26 2006
@@ -443,7 +443,7 @@
 	}
 
 	if (supplied_flags &
-	    ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT))
+	    ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST))
 	{
 		PyErr_SetString(PyExc_ValueError,
 				"compile(): unrecognised flags");

Modified: python/trunk/Python/pythonrun.c
==============================================================================
--- python/trunk/Python/pythonrun.c	(original)
+++ python/trunk/Python/pythonrun.c	Sun Feb 26 20:42:26 2006
@@ -1254,6 +1254,11 @@
                 PyArena_Free(arena);
 		return NULL;
         }
+	if (flags->cf_flags & PyCF_ONLY_AST) {
+		PyObject *result = PyAST_mod2obj(mod);
+		PyArena_Free(arena);
+		return result;
+	}
 	co = PyAST_Compile(mod, filename, flags, arena);
         PyArena_Free(arena);
 	return (PyObject *)co;


More information about the Python-checkins mailing list