[pypy-svn] r14067 - in pypy/dist/pypy/translator/llvm2: . test

rxe at codespeak.net rxe at codespeak.net
Fri Jul 1 20:58:56 CEST 2005


Author: rxe
Date: Fri Jul  1 20:58:54 2005
New Revision: 14067

Added:
   pypy/dist/pypy/translator/llvm2/arraynode.py
Modified:
   pypy/dist/pypy/translator/llvm2/codewriter.py
   pypy/dist/pypy/translator/llvm2/database.py
   pypy/dist/pypy/translator/llvm2/funcnode.py
   pypy/dist/pypy/translator/llvm2/genllvm.py
   pypy/dist/pypy/translator/llvm2/pyxwrapper.py
   pypy/dist/pypy/translator/llvm2/structnode.py
   pypy/dist/pypy/translator/llvm2/test/test_genllvm.py
Log:
A WIP progress of variable length sturcts.  Including globals and function
pointers.
Sorry for big checkin. :-(




Added: pypy/dist/pypy/translator/llvm2/arraynode.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm2/arraynode.py	Fri Jul  1 20:58:54 2005
@@ -0,0 +1,25 @@
+import py
+from pypy.translator.llvm2.log import log 
+log = log.structnode 
+
+class ArrayNode(object):
+    _issetup = False 
+    array_counter = 0
+
+    def __init__(self, db, array): 
+        self.db = db
+        self.array = array
+        self.ref = "%%array.%s.%s" % (array.OF, ArrayNode.array_counter)
+        ArrayNode.array_counter += 1
+        
+    def __str__(self):
+        return "<ArrayNode %r>" % self.ref    
+
+    def setup(self):
+        self._issetup = True
+
+    # ______________________________________________________________________
+    # entry points from genllvm 
+    #
+    def writedatatypedecl(self, codewriter):
+        codewriter.arraydef(self.ref, self.db.repr_arg_type(self.array.OF))

Modified: pypy/dist/pypy/translator/llvm2/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm2/codewriter.py	Fri Jul  1 20:58:54 2005
@@ -11,6 +11,9 @@
         self._lines.append(line) 
         log(line) 
 
+    def comment(self, line):
+        self.append(";; " + line) 
+
     def indent(self, line): 
         self.append("        " + line) 
 
@@ -20,6 +23,9 @@
     def structdef(self, name, typereprs):
         self.append("%s = type { %s }" %(name, ", ".join(typereprs)))
 
+    def arraydef(self, name, typerepr):
+        self.append("%s = type { int, [0 x %s] }" % (name, typerepr))
+
     def declare(self, decl):
         self.append("declare %s" %(decl,))
 
@@ -64,12 +70,17 @@
         self.indent("%(targetvar)s = cast %(fromtype)s "
                         "%(fromvar)s to %(targettype)s" % locals())
 
-    def malloc(self, targetvar, type):
-        self.indent("%(targetvar)s = malloc %(type)s" % locals())
-
-    def getelementptr(self, targetvar, type, typevar, index):
-        self.indent("%(targetvar)s = getelementptr "
-                    "%(type)s %(typevar)s, int 0, uint %(index)s" % locals())
+    def malloc(self, targetvar, type, sizetype=None, size=None):
+        if size is None:
+            assert sizetype is None
+            self.indent("%(targetvar)s = malloc %(type)s" % locals())
+        else:
+            self.indent("%(targetvar)s = malloc %(type)s, %(sizetype)s %(size)s" % locals())
+
+    def getelementptr(self, targetvar, type, typevar, *indices):
+        res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, int 0, " % locals()
+        res += ", ".join(["%s %s" % (t, i) for t, i in indices])
+        self.indent(res)
 
     def load(self, targetvar, targettype, ptr):
         self.indent("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals())

Modified: pypy/dist/pypy/translator/llvm2/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/database.py	(original)
+++ pypy/dist/pypy/translator/llvm2/database.py	Fri Jul  1 20:58:54 2005
@@ -1,12 +1,15 @@
 from pypy.translator.llvm2.log import log 
-from pypy.translator.llvm2.funcnode import FuncNode
-from pypy.translator.llvm2.structnode import StructNode 
+from pypy.translator.llvm2.funcnode import FuncNode, FuncSig
+from pypy.translator.llvm2.structnode import StructNode, StructInstance
+from pypy.translator.llvm2.arraynode import ArrayNode
+ArrayNode
 from pypy.rpython import lltype
 from pypy.objspace.flow.model import Block, Constant, Variable
 
 log = log.database 
 
 PRIMITIVES_TO_LLVM = {lltype.Signed: "int",
+                      lltype.Char: "sbyte",
                       lltype.Unsigned: "uint",
                       lltype.Bool: "bool",
                       lltype.Float: "double" }
@@ -17,7 +20,7 @@
         self.obj2node = {}
         self._pendingsetup = []
         self._tmpcount = 1
-
+        
     def addpending(self, key, node): 
         assert key not in self.obj2node, (
             "node with key %r already known!" %(key,))
@@ -32,11 +35,25 @@
         if const_or_var in self.obj2node:
             return
         if isinstance(const_or_var, Constant):
-            if isinstance(const_or_var.concretetype, lltype.Primitive):
-                pass
-                #log.prepare(const_or_var, "(is primitive)") 
+            
+            ct = const_or_var.concretetype
+            while isinstance(ct, lltype.Ptr):
+                ct = ct.TO
+            
+            if isinstance(ct, lltype.FuncType):
+                self.addpending(const_or_var, FuncNode(self, const_or_var))
             else:
-                self.addpending(const_or_var, FuncNode(self, const_or_var)) 
+                #value = const_or_var.value
+                #while hasattr(value, "_obj"):
+                #    value = value._obj
+                
+                if isinstance(ct, lltype.Struct):
+                    self.addpending(const_or_var, StructInstance(self, value))
+
+                elif isinstance(ct, lltype.Primitive):
+                    log.prepare(const_or_var, "(is primitive)")
+                else:
+                    log.XXX("not sure what to do about %s(%s)" % (ct, const_or_var))
         else:
             log.prepare.ignore(const_or_var) 
 
@@ -47,23 +64,80 @@
             pass
         elif isinstance(type_, lltype.Ptr): 
             self.prepare_repr_arg_type(type_.TO)
+
         elif isinstance(type_, lltype.Struct): 
             self.addpending(type_, StructNode(self, type_))
+
+        elif isinstance(type_, lltype.FuncType): 
+            self.addpending(type_, FuncSig(self, type_))
+
+        elif isinstance(type_, lltype.Array): 
+            self.addpending(type_, ArrayNode(self, type_))
+
         else:     
             log.XXX("need to prepare typerepr", type_)
 
     def prepare_arg(self, const_or_var):
         log.prepare(const_or_var)
-        self.prepare_repr_arg(const_or_var)
         self.prepare_repr_arg_type(const_or_var.concretetype)
-
+        self.prepare_repr_arg(const_or_var)
+            
     def setup_all(self):
         while self._pendingsetup: 
             self._pendingsetup.pop().setup()
 
-    def getobjects(self): 
-        return self.obj2node.values()
-
+    def getobjects(self, subset_types=None):
+        res = []
+        for v in self.obj2node.values():
+            if subset_types is None or isinstance(v, subset_types):
+                res.append(v)
+        res.reverse()
+        return res
+
+    def get_typedecls(self):
+        return self.getobjects((StructNode, ArrayNode))
+
+    def get_globaldata(self):
+        return self.getobjects((StructInstance))
+
+    def get_functions(self):
+        struct_nodes = [n for n in self.getobjects(StructNode) if n.inline_struct]
+        return struct_nodes + self.getobjects(FuncNode)
+
+    def dump(self):
+
+        # get and reverse the order in which seen objs
+        all_objs = self.obj2node.items()
+        all_objs.reverse()
+
+        log.dump_db("*** type declarations ***")
+        for k,v in all_objs:
+            if isinstance(v, (StructNode, ArrayNode)):
+                log.dump_db("%s ---> %s" % (k, v))            
+
+        log.dump_db("*** global data ***")
+        for k,v in all_objs:
+            if isinstance(v, (StructInstance)):
+                log.dump_db("%s ---> %s" % (k, v))
+
+        log.dump_db("*** function protos ***")
+        for k,v in all_objs:
+            if isinstance(v, (FuncNode)):
+                log.dump_db("%s ---> %s" % (k, v))
+
+        log.dump_db("*** function implementations ***")
+        for k,v in all_objs:
+            if isinstance(v, (FuncNode)):
+                log.dump_db("%s ---> %s" % (k, v))
+                
+        log.dump_db("*** unknown ***")
+        for k,v in all_objs:
+            if isinstance(v, (FuncSig)):
+                log.dump_db("%s ---> %s" % (k, v))
+        
+    # __________________________________________________________
+    # Getters
+    
     def repr_arg(self, arg):
         if (isinstance(arg, Constant) and 
             isinstance(arg.concretetype, lltype.Primitive)):
@@ -95,5 +169,3 @@
         count = self._tmpcount 
         self._tmpcount += 1
         return "%tmp." + str(count) 
-        
- 

Modified: pypy/dist/pypy/translator/llvm2/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/funcnode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/funcnode.py	Fri Jul  1 20:58:54 2005
@@ -6,6 +6,24 @@
 from pypy.translator.llvm2.log import log 
 log = log.funcnode
 
+class FuncSig(object):
+    """ XXX Not sure about this - should be combined with FuncNode?
+    Abstract function signature. """
+    def __init__(self, db, typ):
+        self.db = db
+        self.typ = typ
+        # Hack around some debug statements
+        self.ref = "pending setup!"
+        
+    def __str__(self):
+        return "<FuncSig %r>" % self.ref
+
+    def setup(self):
+        returntype = self.db.repr_arg_type(self.typ.RESULT)
+        inputargtypes = self.db.repr_arg_type_multi(self.typ.ARGS)
+        self.ref = "%s (%s)" % (returntype, ", ".join(inputargtypes))
+
+
 class FuncNode(object):
     _issetup = False 
 
@@ -14,7 +32,6 @@
         self.ref = "%" + const_ptr_func.value._obj._name
         self.graph = prepare_graph(const_ptr_func.value._obj.graph,
                                    db._translator)
-
     def __str__(self):
         return "<FuncNode %r>" %(self.ref,)
     
@@ -30,19 +47,6 @@
                     self.db.prepare_arg(op.result)
         traverse(visit, self.graph)
         self._issetup = True
-
-    def getdecl(self):
-        assert self._issetup 
-        startblock = self.graph.startblock
-        returnblock = self.graph.returnblock
-        inputargs = self.db.repr_arg_multi(startblock.inputargs)
-        inputargtypes = self.db.repr_arg_type_multi(startblock.inputargs)
-        returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0])
-        result = "%s %s" % (returntype, self.ref)
-        args = ["%s %s" % item for item in zip(inputargtypes, inputargs)]
-        result += "(%s)" % ", ".join(args)
-        return result 
-
     # ______________________________________________________________________
     # main entry points from genllvm 
     def writedecl(self, codewriter): 
@@ -72,6 +76,18 @@
     # ______________________________________________________________________
     # writing helpers for entry points
 
+    def getdecl(self):
+        assert self._issetup 
+        startblock = self.graph.startblock
+        returnblock = self.graph.returnblock
+        inputargs = self.db.repr_arg_multi(startblock.inputargs)
+        inputargtypes = self.db.repr_arg_type_multi(startblock.inputargs)
+        returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0])
+        result = "%s %s" % (returntype, self.ref)
+        args = ["%s %s" % item for item in zip(inputargtypes, inputargs)]
+        result += "(%s)" % ", ".join(args)
+        return result 
+
     def write_block(self, codewriter, block):
         self.write_block_phi_nodes(codewriter, block)
         self.write_block_operations(codewriter, block)
@@ -101,7 +117,6 @@
         opwriter = OpWriter(self.db, codewriter)
         for op in block.operations:
             opwriter.write_operation(op)
-
     def write_startblock(self, codewriter, block):
         self.write_block_operations(codewriter, block)
         self.write_block_branches(codewriter, block)
@@ -218,17 +233,36 @@
         type = self.db.obj2node[arg.value].ref
         self.codewriter.malloc(targetvar, type) 
 
+    def malloc_varsize(self, op):
+        targetvar = self.db.repr_arg(op.result)
+        arg_type = op.args[0]
+        assert (isinstance(arg_type, Constant) and 
+                isinstance(arg_type.value, lltype.Struct))
+        struct_type = self.db.obj2node[arg_type.value].ref
+        struct_cons = self.db.obj2node[arg_type.value].new_var_name
+        argrefs = self.db.repr_arg_multi(op.args[1:])
+        argtypes = self.db.repr_arg_type_multi(op.args[1:])
+        self.codewriter.call(targetvar, struct_type + " *",
+                             struct_cons, argrefs, argtypes)
+
     def getfield(self, op): 
         tmpvar = self.db.repr_tmpvar()
-        type = self.db.repr_arg_type(op.args[0]) 
-        typevar = self.db.repr_arg(op.args[0]) 
+        typ = self.db.repr_arg_type(op.args[0]) 
+        typevar = self.db.repr_arg(op.args[0])
         fieldnames = list(op.args[0].concretetype.TO._names)
         index = fieldnames.index(op.args[1].value)
-        self.codewriter.getelementptr(tmpvar, type, typevar, index)
-
+        self.codewriter.getelementptr(tmpvar, typ, typevar, ("uint", index))
+        
         targetvar = self.db.repr_arg(op.result)
         targettype = self.db.repr_arg_type(op.result)
-        self.codewriter.load(targetvar, targettype, tmpvar)
+        #XXX This doesnt work - yet
+        #if isinstance(op.result.concretetype, lltype.Ptr):        
+        #    self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
+        #else:
+            # Moving to correct result variable
+            #self.codewriter.load(targetvar, targettype, tmpvar)
+        self.codewriter.load(targetvar, targettype, tmpvar)    
+    getsubstruct = getfield
 
     def setfield(self, op): 
         tmpvar = self.db.repr_tmpvar()
@@ -236,8 +270,51 @@
         typevar = self.db.repr_arg(op.args[0]) 
         fieldnames = list(op.args[0].concretetype.TO._names)
         index = fieldnames.index(op.args[1].value)
-        self.codewriter.getelementptr(tmpvar, type, typevar, index)
+        self.codewriter.getelementptr(tmpvar, type, typevar, ("uint", index))
+
+        valuevar = self.db.repr_arg(op.args[2]) 
+        valuetype = self.db.repr_arg_type(op.args[2])
+        self.codewriter.store(valuetype, valuevar, tmpvar) 
+
+    def getarrayitem(self, op):
+        var = self.db.repr_arg(op.args[0])
+        vartype = self.db.repr_arg_type(op.args[0])
+        index = self.db.repr_arg(op.args[1])
+        indextype = self.db.repr_arg_type(op.args[1])
+
+        tmpvar = self.db.repr_tmpvar()
+        self.codewriter.getelementptr(tmpvar, vartype, var,
+                                      ("uint", 1), (indextype, index))
+
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+
+        # Ditto see getfield
+        if not isinstance(op.result.concretetype, lltype.Ptr):        
+            self.codewriter.load(targetvar, targettype, tmpvar)
+        else:
+            # XXX noop
+            self.codewriter.cast(targetvar, targettype, tmpvar, targettype)
+
+    def setarrayitem(self, op):
+        array = self.db.repr_arg(op.args[0])
+        arraytype = self.db.repr_arg_type(op.args[0])
+        index = self.db.repr_arg(op.args[1])
+        indextype = self.db.repr_arg_type(op.args[1])
+
+        tmpvar = self.db.repr_tmpvar()
+        self.codewriter.getelementptr(tmpvar, arraytype, array,
+                                      ("uint", 1), (indextype, index))
 
         valuevar = self.db.repr_arg(op.args[2]) 
         valuetype = self.db.repr_arg_type(op.args[2])
         self.codewriter.store(valuetype, valuevar, tmpvar) 
+
+    def getarraysize(self, op):
+        var = self.db.repr_arg(op.args[0])
+        vartype = self.db.repr_arg_type(op.args[0])
+        tmpvar = self.db.repr_tmpvar()
+        self.codewriter.getelementptr(tmpvar, vartype, var, ("uint", 0))
+        targetvar = self.db.repr_arg(op.result)
+        targettype = self.db.repr_arg_type(op.result)
+        self.codewriter.load(targetvar, targettype, tmpvar)

Modified: pypy/dist/pypy/translator/llvm2/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm2/genllvm.py	Fri Jul  1 20:58:54 2005
@@ -20,14 +20,27 @@
     db.setup_all()
     entrynode = db.obj2node[c]
     codewriter = CodeWriter()
-    dbobjects =  db.getobjects()
-    log.debug(dbobjects)
-    log.debug(db.obj2node)
-    for node in dbobjects:
-        node.writedecl(codewriter) 
-    codewriter.startimpl() 
-    for node in dbobjects:
-        node.writeimpl(codewriter)
+    comment = codewriter.comment
+    nl = lambda: codewriter.append("")
+    
+    nl(); comment("Type Declarations"); nl()
+    for typ_decl in db.get_typedecls():
+        typ_decl.writedatatypedecl(codewriter)
+
+    nl(); comment("Global Data") ; nl()
+    for typ_decl in db.get_globaldata():
+        typ_decl.writedata(codewriter)
+
+    nl(); comment("Function Prototypes") ; nl()
+    for typ_decl in db.get_functions():
+        typ_decl.writedecl(codewriter)
+
+    nl(); comment("Function Implementation") 
+    codewriter.startimpl()
+    for typ_decl in db.get_functions():
+        typ_decl.writeimpl(codewriter)
+
+    comment("End of file") ; nl()
     
     targetdir = udir
     llvmsource = targetdir.join(func.func_name).new(ext='.ll')

Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/pyxwrapper.py	(original)
+++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py	Fri Jul  1 20:58:54 2005
@@ -6,6 +6,7 @@
                    lltype.Unsigned: "unsigned int",
                    lltype.Bool: "char",
                    lltype.Float: "double",
+                   lltype.Char: "char",
                    }
 
 def write_pyx_wrapper(funcgen, targetpath): 

Modified: pypy/dist/pypy/translator/llvm2/structnode.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/structnode.py	(original)
+++ pypy/dist/pypy/translator/llvm2/structnode.py	Fri Jul  1 20:58:54 2005
@@ -1,6 +1,7 @@
 import py
 from pypy.objspace.flow.model import Block, Constant, Variable, Link
 from pypy.translator.llvm2.log import log 
+from pypy.rpython import lltype
 log = log.structnode 
 
 class StructNode(object):
@@ -8,22 +9,39 @@
     struct_counter = 0
 
     def __init__(self, db, struct): 
+        assert isinstance(struct, lltype.Struct)
+
         self.db = db
-        self.struct = struct 
-        self.ref = "%%st.%s.%s" % (struct._name, StructNode.struct_counter)
+        self.struct = struct
+        
+        self.name = "%s.%s" % (self.struct._name, StructNode.struct_counter)
+        self.ref = "%%st.%s" % self.name
+        self.inline_struct = self.struct._arrayfld
+        
         StructNode.struct_counter += 1
         
     def __str__(self):
         return "<StructNode %r>" %(self.ref,)
     
     def setup(self):
-        log.XXX("setup", self)
+        # Recurse
+        for fieldname in self.struct._names:
+            field_type = getattr(self.struct, fieldname)
+            self.db.prepare_repr_arg_type(field_type)
+
+        if self.inline_struct:
+            log.XXX("Register me", self)
+
         self._issetup = True
 
+    def get_decl_for_varsize(self):
+        self.new_var_name = "%%new.st.%s" % self.name
+        return "%s * %s(int %%len)" % (self.ref, self.new_var_name)
+
     # ______________________________________________________________________
-    # entry points from genllvm 
-    #
-    def writedecl(self, codewriter): 
+    # main entry points from genllvm 
+
+    def writedatatypedecl(self, codewriter):
         assert self._issetup 
         struct = self.struct
         l = []
@@ -32,5 +50,81 @@
             l.append(self.db.repr_arg_type(type_))
         codewriter.structdef(self.ref, l) 
 
+    def writedecl(self, codewriter): 
+        # declaration for constructor
+        if self.inline_struct:
+            # XXX Not well thought out - hack / better to modify the graph
+            codewriter.declare(self.get_decl_for_varsize())
+
     def writeimpl(self, codewriter):
-        assert self._issetup 
+
+        if self.inline_struct:
+            log.writeimpl(self.ref)
+            codewriter.openfunc(self.get_decl_for_varsize())
+            codewriter.label("block0")
+            
+            # XXX TODO
+            arraytype = "sbyte"
+            indices_to_array = [("uint", 1)]
+            
+            # Into array and length            
+            indices = indices_to_array + [("uint", 1), ("int", "%len")]
+            codewriter.getelementptr("%size", self.ref + "*",
+                                     "null", *indices)
+            
+            #XXX is this ok for 64bit?
+            codewriter.cast("%sizeu", arraytype + "*", "%size", "uint")
+            codewriter.malloc("%resulttmp", "sbyte", "uint", "%sizeu")
+            codewriter.cast("%result", "sbyte*", "%resulttmp", self.ref + "*")
+
+            # remember the allocated length for later use.
+            indices = indices_to_array + [("uint", 0)]
+            codewriter.getelementptr("%size_ptr", self.ref + "*",
+                                     "%result", *indices)
+
+            codewriter.cast("%signedsize", "uint", "%sizeu", "int")
+            codewriter.store("int", "%signedsize", "%size_ptr")
+
+            codewriter.ret(self.ref + "*", "%result")
+            codewriter.closefunc()
+
+
+class StructInstance(object):
+    _issetup = False 
+    struct_counter = 0
+
+    def __init__(self, db, value):
+        self.db = db
+        self.name = "%s.%s" % (value._TYPE._name, StructInstance.struct_counter)
+        self.ref = "%%stinstance.%s" % self.name
+        self.value = value
+        StructInstance.struct_counter += 1
+
+    def __str__(self):
+        return "<StructInstance %r>" %(self.ref,)
+
+    def setup(self):
+        # Recurse fields (XXX Messy!)
+        for name in self.value._TYPE._names:
+            T = self.value._TYPE._flds[name]
+            self.db.prepare_repr_arg_type(T)
+            if not isinstance(T, lltype.Primitive):
+                value = getattr(self.value, name)
+                self.db.prepare_repr_arg(value)
+                
+        self._issetup = True
+
+#     def struct_repr(self):
+#         typ = repr_arg_type(self.value)
+#         self.value._TYPE._names
+#         typevaluepairs = ["%s %s" % for t, v in 
+#         typevaluepairsstr = ", ".join(typevaluepairs)
+#         return "%s { %s }" % (typ, typevaluepairsstr)
+
+    def writedata(self, codewriter):
+        log.XXXXXXXXXX("ooops TODO should write - ", self.ref)
+        for name in self.value._TYPE._names:
+            log.XXXXXXXXXX("ooops ", getattr(self.value, name))
+        typ = self.db.repr_arg_type(self.value._TYPE)
+        # XXX constant you say?
+        codewriter.append("%s = internal constant %s* null" % (self.ref, typ))

Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py	Fri Jul  1 20:58:54 2005
@@ -168,7 +168,31 @@
         l = (1,(1,2,i),i)
         return l[1][2]
     f = compile_function(nested_tuple, [int])
-    assert f(4) == 4 
+    assert f(4) == 4
+
+def test_pbc_fns(): 
+    def f2(x):
+         return x+1
+    def f3(x):
+         return x+2
+    def g(y):
+        if y < 0:
+            f = f2
+        else:
+            f = f3
+        return f(y+3)
+    f = compile_function(g, [int])
+    assert f(-1) == 3
+    assert f(0) == 5
+
+def DONOT_test_simple_chars():
+     def char_constant2(s):
+         s = s + s + s
+         return len(s + '.')
+     def char_constant():
+         return char_constant2("kk")    
+     f = compile_function(char_constant, [])
+     assert f() == 7
 
 def DONOTtest_string_getitem():
     def string_test(i): 
@@ -192,4 +216,3 @@
         except TestException:
             return 0
     f = compile_function(catch, [int])
-    



More information about the Pypy-commit mailing list