[pypy-svn] r45058 - in pypy/branch/flex-backend: bin translator translator/flex translator/flex/bin translator/flex/examples translator/flex/examples/bnb translator/flex/examples/bnb/data translator/flex/examples/bnb/data/images translator/flex/examples/console translator/flex/examples/console/data translator/flex/examples/console/test translator/flex/examples/data translator/flex/examples/djangoping translator/flex/examples/djangoping/templates translator/flex/examples/djangoping/test translator/flex/examples/test translator/flex/jssrc translator/flex/lib translator/flex/lib/test translator/flex/modules translator/flex/modules/pygame translator/flex/modules/test translator/flex/modules/test/html translator/flex/sandbox translator/flex/sandbox/py translator/flex/sandbox/py/pygame translator/flex/test translator/flex/tutorial

alecu at codespeak.net alecu at codespeak.net
Sat Jul 14 11:58:11 CEST 2007


Author: alecu
Date: Sat Jul 14 11:58:08 2007
New Revision: 45058

Added:
   pypy/branch/flex-backend/bin/flexcompile.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/
   pypy/branch/flex-backend/translator/flex/__init__.py
   pypy/branch/flex-backend/translator/flex/_class.py
   pypy/branch/flex-backend/translator/flex/asmgen.py
   pypy/branch/flex-backend/translator/flex/autopath.py
   pypy/branch/flex-backend/translator/flex/bin/
   pypy/branch/flex-backend/translator/flex/commproxy.py
   pypy/branch/flex-backend/translator/flex/conftest.py
   pypy/branch/flex-backend/translator/flex/database.py
   pypy/branch/flex-backend/translator/flex/examples/
   pypy/branch/flex-backend/translator/flex/examples/__init__.py
   pypy/branch/flex-backend/translator/flex/examples/autopath.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/
   pypy/branch/flex-backend/translator/flex/examples/bnb/__init__.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/autopath.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/bnb.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/data/
   pypy/branch/flex-backend/translator/flex/examples/bnb/data/bnb.html
   pypy/branch/flex-backend/translator/flex/examples/bnb/data/images/
   pypy/branch/flex-backend/translator/flex/examples/bnb/msgstruct.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/servermessage.py
   pypy/branch/flex-backend/translator/flex/examples/bnb/start_bnb.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/console/
   pypy/branch/flex-backend/translator/flex/examples/console/__init__.py
   pypy/branch/flex-backend/translator/flex/examples/console/client.py
   pypy/branch/flex-backend/translator/flex/examples/console/console.py
   pypy/branch/flex-backend/translator/flex/examples/console/data/
   pypy/branch/flex-backend/translator/flex/examples/console/data/console.html
   pypy/branch/flex-backend/translator/flex/examples/console/docloader.py
   pypy/branch/flex-backend/translator/flex/examples/console/ideas.txt
   pypy/branch/flex-backend/translator/flex/examples/console/play1_snippets.py
   pypy/branch/flex-backend/translator/flex/examples/console/session.py
   pypy/branch/flex-backend/translator/flex/examples/console/test/
   pypy/branch/flex-backend/translator/flex/examples/console/test/test_console.py
   pypy/branch/flex-backend/translator/flex/examples/console/test/test_docloader.py
   pypy/branch/flex-backend/translator/flex/examples/console/test/test_session.py
   pypy/branch/flex-backend/translator/flex/examples/console/test/test_snippets.py
   pypy/branch/flex-backend/translator/flex/examples/data/
   pypy/branch/flex-backend/translator/flex/examples/data/error.html
   pypy/branch/flex-backend/translator/flex/examples/data/index.html
   pypy/branch/flex-backend/translator/flex/examples/data/launcher.html
   pypy/branch/flex-backend/translator/flex/examples/data/py-web1.png   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/data/style.css
   pypy/branch/flex-backend/translator/flex/examples/djangoping/
   pypy/branch/flex-backend/translator/flex/examples/djangoping/__init__.py
   pypy/branch/flex-backend/translator/flex/examples/djangoping/client.py
   pypy/branch/flex-backend/translator/flex/examples/djangoping/manage.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/djangoping/settings.py
   pypy/branch/flex-backend/translator/flex/examples/djangoping/templates/
   pypy/branch/flex-backend/translator/flex/examples/djangoping/templates/index.html
   pypy/branch/flex-backend/translator/flex/examples/djangoping/test/
   pypy/branch/flex-backend/translator/flex/examples/djangoping/test/test_build.py
   pypy/branch/flex-backend/translator/flex/examples/djangoping/urls.py
   pypy/branch/flex-backend/translator/flex/examples/djangoping/views.py
   pypy/branch/flex-backend/translator/flex/examples/guestbook.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/guestbook_client.py
   pypy/branch/flex-backend/translator/flex/examples/over_client.py
   pypy/branch/flex-backend/translator/flex/examples/overmind.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/pythonconsole.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/examples/serialise.py
   pypy/branch/flex-backend/translator/flex/examples/test/
   pypy/branch/flex-backend/translator/flex/examples/test/__init__.py
   pypy/branch/flex-backend/translator/flex/examples/test/test_examples.py
   pypy/branch/flex-backend/translator/flex/function.py
   pypy/branch/flex-backend/translator/flex/helper.py
   pypy/branch/flex-backend/translator/flex/js.py
   pypy/branch/flex-backend/translator/flex/jsbuiltin.py
   pypy/branch/flex-backend/translator/flex/json.py
   pypy/branch/flex-backend/translator/flex/jssrc/
   pypy/branch/flex-backend/translator/flex/jssrc/flex.mxml
   pypy/branch/flex-backend/translator/flex/jssrc/misc.as
   pypy/branch/flex-backend/translator/flex/jssrc/misc.js
   pypy/branch/flex-backend/translator/flex/jts.py
   pypy/branch/flex-backend/translator/flex/lib/
   pypy/branch/flex-backend/translator/flex/lib/__init__.py
   pypy/branch/flex-backend/translator/flex/lib/server.py
   pypy/branch/flex-backend/translator/flex/lib/support.py
   pypy/branch/flex-backend/translator/flex/lib/test/
   pypy/branch/flex-backend/translator/flex/lib/test/__init__.py
   pypy/branch/flex-backend/translator/flex/lib/test/test_server.py
   pypy/branch/flex-backend/translator/flex/lib/test/test_server_g.py
   pypy/branch/flex-backend/translator/flex/lib/test/test_support.py
   pypy/branch/flex-backend/translator/flex/lib/test/test_url.py
   pypy/branch/flex-backend/translator/flex/lib/url.py
   pypy/branch/flex-backend/translator/flex/log.py
   pypy/branch/flex-backend/translator/flex/main.py
   pypy/branch/flex-backend/translator/flex/metavm.py
   pypy/branch/flex-backend/translator/flex/modules/
   pypy/branch/flex-backend/translator/flex/modules/__init__.py
   pypy/branch/flex-backend/translator/flex/modules/dom.py
   pypy/branch/flex-backend/translator/flex/modules/flex.py
   pypy/branch/flex-backend/translator/flex/modules/mochikit.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/
   pypy/branch/flex-backend/translator/flex/modules/pygame/__init__.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/event.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/font.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/image.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/locals.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/mixer.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/pygame.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/sprite.py
   pypy/branch/flex-backend/translator/flex/modules/pygame/time.py
   pypy/branch/flex-backend/translator/flex/modules/test/
   pypy/branch/flex-backend/translator/flex/modules/test/__init__.py
   pypy/branch/flex-backend/translator/flex/modules/test/html/
   pypy/branch/flex-backend/translator/flex/modules/test/html/anim.html
   pypy/branch/flex-backend/translator/flex/modules/test/html/test.html
   pypy/branch/flex-backend/translator/flex/modules/test/test_dom.py
   pypy/branch/flex-backend/translator/flex/modules/test/test_mochikit.py
   pypy/branch/flex-backend/translator/flex/opcodes.py
   pypy/branch/flex-backend/translator/flex/sandbox/
   pypy/branch/flex-backend/translator/flex/sandbox/MyFirst.html
   pypy/branch/flex-backend/translator/flex/sandbox/MyFirst.mxml
   pypy/branch/flex-backend/translator/flex/sandbox/chimp.py
   pypy/branch/flex-backend/translator/flex/sandbox/fun.py
   pypy/branch/flex-backend/translator/flex/sandbox/misc.as
   pypy/branch/flex-backend/translator/flex/sandbox/output.mxml
   pypy/branch/flex-backend/translator/flex/sandbox/output2.mxml
   pypy/branch/flex-backend/translator/flex/sandbox/py/
   pypy/branch/flex-backend/translator/flex/sandbox/py/DictIter.as
   pypy/branch/flex-backend/translator/flex/sandbox/py/StringBuilder.as
   pypy/branch/flex-backend/translator/flex/sandbox/py/pygame/
   pypy/branch/flex-backend/translator/flex/sandbox/py/pygame/Rect.as
   pypy/branch/flex-backend/translator/flex/support.py
   pypy/branch/flex-backend/translator/flex/test/
   pypy/branch/flex-backend/translator/flex/test/__init__.py
   pypy/branch/flex-backend/translator/flex/test/browsertest.py
   pypy/branch/flex-backend/translator/flex/test/runtest.py
   pypy/branch/flex-backend/translator/flex/test/test_basicexternal.py
   pypy/branch/flex-backend/translator/flex/test/test_bltn.py
   pypy/branch/flex-backend/translator/flex/test/test_class.py
   pypy/branch/flex-backend/translator/flex/test/test_exc_operation.py
   pypy/branch/flex-backend/translator/flex/test/test_exception.py
   pypy/branch/flex-backend/translator/flex/test/test_extfunc.py
   pypy/branch/flex-backend/translator/flex/test/test_loops.py
   pypy/branch/flex-backend/translator/flex/test/test_main.py
   pypy/branch/flex-backend/translator/flex/test/test_rclass.py
   pypy/branch/flex-backend/translator/flex/test/test_rdict.py
   pypy/branch/flex-backend/translator/flex/test/test_rfloat.py
   pypy/branch/flex-backend/translator/flex/test/test_rlist.py
   pypy/branch/flex-backend/translator/flex/test/test_rpbc.py
   pypy/branch/flex-backend/translator/flex/test/test_rsnippet.py
   pypy/branch/flex-backend/translator/flex/test/test_rsnippet1.py
   pypy/branch/flex-backend/translator/flex/test/test_runtest.py
   pypy/branch/flex-backend/translator/flex/test/test_seq.py
   pypy/branch/flex-backend/translator/flex/test/test_snippet.py
   pypy/branch/flex-backend/translator/flex/test/test_str.py
   pypy/branch/flex-backend/translator/flex/test/test_typed.py
   pypy/branch/flex-backend/translator/flex/test/tgtest.py
   pypy/branch/flex-backend/translator/flex/tester.py
   pypy/branch/flex-backend/translator/flex/tutorial/
   pypy/branch/flex-backend/translator/flex/tutorial/__init__.py
   pypy/branch/flex-backend/translator/flex/tutorial/step1.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/tutorial/step2.py   (contents, props changed)
   pypy/branch/flex-backend/translator/flex/tutorial/step3.py   (contents, props changed)
Modified:
   pypy/branch/flex-backend/translator/driver.py
Log:
moving the prototype from googlecode to codespeak svn

Added: pypy/branch/flex-backend/bin/flexcompile.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/bin/flexcompile.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+""" RPython to javascript compiler
+Usage: jscompile module_to_compile [list of functions to export]
+
+- or -
+jscompile --help to show list of options
+"""
+
+import autopath
+import sys, os
+
+from pypy.translator.flex.main import rpython2javascript_main, js_optiondescr
+
+from pypy.config.config import Config, to_optparse
+
+def process_options():
+    jsconfig = Config(js_optiondescr)
+    parser = to_optparse(jsconfig, parserkwargs={"usage": __doc__})
+    parser.disable_interspersed_args()
+    options, args = parser.parse_args()
+    return args, jsconfig
+
+if __name__ == '__main__':
+    args, jsconfig = process_options()
+    curdir = os.getcwd()
+    if curdir not in sys.path:
+        sys.path.insert(0, curdir)
+    rpython2javascript_main(args, jsconfig)

Modified: pypy/branch/flex-backend/translator/driver.py
==============================================================================
--- pypy/branch/flex-backend/translator/driver.py	(original)
+++ pypy/branch/flex-backend/translator/driver.py	Sat Jul 14 11:58:08 2007
@@ -627,6 +627,27 @@
     task_run_js = taskdef(task_run_js, ['compile_js'],
                               'Please manually run the generated code')
 
+
+    def task_source_flex(self):
+        from pypy.translator.flex.js import JS
+        self.gen = JS(self.translator, functions=[self.entry_point],
+                      stackless=self.config.translation.stackless)
+        filename = self.gen.write_source()
+        self.log.info("Wrote %s" % (filename,))
+    task_source_flex = taskdef(task_source_flex, 
+                        [OOTYPE],
+                        'Generating Flex source')
+
+    def task_compile_flex(self):
+        pass
+    task_compile_flex = taskdef(task_compile_flex, ['source_flex'],
+                              'Skipping Javascript compilation')
+
+    def task_run_flex(self):
+        pass
+    task_run_flex = taskdef(task_run_flex, ['compile_flex'],
+                              'Please manually run the generated code')
+
     def task_source_cli(self):
         from pypy.translator.cli.gencli import GenCli
         from pypy.translator.cli.entrypoint import get_entrypoint

Added: pypy/branch/flex-backend/translator/flex/__init__.py
==============================================================================

Added: pypy/branch/flex-backend/translator/flex/_class.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/_class.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,103 @@
+
+""" genjs class definition
+"""
+
+from pypy.translator.cli.node import Node
+from pypy.translator.cli.cts import CTS
+
+import pypy.translator.flex.asmgen as asmgen
+
+class Class(Node):
+    def __init__(self, db, classdef):
+        self.db = db
+        self.cts = db.genoo.TypeSystem(db)
+        self.classdef = classdef
+        self.name = classdef._name.replace('.', '_')#[-1]
+        self.real_name = classdef._name
+
+        if not self.is_root(classdef):
+            self.parent = self.db.pending_class(classdef._superclass)
+            self.order = self.parent.order + 1
+        else:
+            self.order = 0
+
+    def __hash__(self):
+        return hash(self.classdef)
+
+    def __eq__(self, other):
+        return self.classdef == other.classdef
+    
+    def __cmp__(self, other):
+        return cmp(self.order, other.order)
+
+    def is_root(classdef):
+        return classdef._superclass is None
+    is_root = staticmethod(is_root)
+
+    def get_name(self):
+        return self.name
+
+    def render(self, ilasm):
+        if self.is_root(self.classdef) or self.name == 'Object':
+            return
+
+        if self.db.class_name(self.classdef) is not None:
+            return # already rendered
+
+        self.ilasm = ilasm
+        
+        old_codegenerator =  ilasm.codegenerator
+        ilasm.codegenerator = asmgen.CodeGenerator(open("py/%s.as"%self.name, "w"))
+        if not self.is_root(self.classdef):
+            basename = self.basename(self.classdef._superclass._name)
+            if basename != 'Root':
+                ilasm.begin_class(self.name, basename)
+            else:
+                ilasm.begin_class(self.name)
+        else:
+            ilasm.begin_class(self.name)
+            
+        ilasm.begin_function(self.name, [])
+        # we need to copy here all the arguments
+        self.copy_class_attributes(ilasm)
+        ilasm.end_function()
+        
+        # begin to_String method
+        ilasm.begin_method("toString", self.name, [])
+        ilasm.load_str("'<%s object>'" % self.real_name)
+        ilasm.ret()
+        ilasm.end_function()
+
+        #for f_name, (f_type, f_default) in self.classdef._fields.iteritems():
+        #    cts_type = self.cts.lltype_to_cts(f_type)
+            #if cts_type != 'void':
+        #    ilasm.field(f_name, cts_type)
+
+        
+        
+        for m_name, m_meth in self.classdef._methods.iteritems():
+            graph = getattr(m_meth, 'graph', None)
+            if graph:
+                f = self.db.genoo.Function(self.db, graph, m_name, is_method = True, _class = self.name)
+                f.render(ilasm)
+            else:
+                pass
+                # XXX: We want to implement an abstract method here
+                self.db.pending_abstract_function(m_name)
+        
+        self.db.record_class(self.classdef, self.name)
+        
+        ilasm.end_class()
+        ilasm.codegenerator._out.close()
+        ilasm.codegenerator = old_codegenerator
+    
+    def copy_class_attributes(self, ilasm):
+        default_values = self.classdef._fields.copy()
+        default_values.update(self.classdef._overridden_defaults)
+        for field_name, (field_type, field_value) in default_values.iteritems():
+            ilasm.load_str("this")
+            self.db.load_const(field_type, field_value, ilasm)
+            ilasm.set_field(None, field_name)
+    
+    def basename(self, name):
+        return name.replace('.', '_')#[-1]

Added: pypy/branch/flex-backend/translator/flex/asmgen.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/asmgen.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,317 @@
+
+""" backend generator routines
+"""
+
+from pypy.translator.flex.log import log
+
+from pypy.objspace.flow.model import Variable
+
+from StringIO import StringIO
+
+class CodeGenerator(object):
+    def __init__(self, out, indentstep = 4, startblock = '{', endblock = '}'):
+        self._out = out
+        self._indent = 0
+        self._bol = True # begin of line
+        self._indentstep = indentstep
+        self._startblock = startblock
+        self._endblock = endblock
+    
+    def write(self, s, indent = 0):
+        indent = self._indent + (indent * self._indentstep)
+        
+        if self._bol:
+            self._out.write(' ' * indent)
+
+        self._out.write(s)
+        self._bol = (s and s[-1] == '\n')
+
+    def writeline(self, s=''):
+        self.write(s)
+        self.write('\n')
+
+    def openblock(self):
+        self.writeline(self._startblock)
+        self._indent += self._indentstep
+
+    def closeblock(self):
+        self._indent -= self._indentstep
+        self.writeline(self._endblock)
+
+class Queue(object):
+    def __init__(self, l, subst_table):
+        self.l = l[:]
+        self.subst_table = subst_table
+    
+    def pop(self):
+        el = self.l.pop()
+        return self.subst_table.get(el, el)
+    
+    def __getattr__(self,attr):
+        return getattr(self.l, attr)
+    
+    def __len__(self):
+        return len(self.l)
+
+    def __nonzero__(self):
+        return len(self.l) > 0
+
+    def empty(self):
+        self.l = []
+
+    def __repr__(self):
+        return "<Queue %s>" % (repr(self.l),)
+
+class AsmGen(object):
+    """ JS 'assembler' generator routines
+    """
+    def __init__(self, outfile, name):
+        self.outfile = outfile
+        self.name = name
+        self.subst_table = {}
+        self.right_hand = Queue([], self.subst_table)
+        self.codegenerator = CodeGenerator(outfile)
+
+    def close(self):
+        self.outfile.close()
+    
+    def begin_function(self, name, arglist):
+        args = ",".join([i[1] for i in arglist])
+        self.codegenerator.write("function %s (%s) "%(name, args))
+        self.codegenerator.openblock()
+    
+    def begin_method(self, name, _class, arglist):
+        args = ",".join(arglist)
+        self.codegenerator.write("%s.prototype.%s = function (%s)"%(_class, name, args))
+        self.codegenerator.openblock()
+    
+    def end_function(self):
+        self.codegenerator.closeblock()
+        self.codegenerator.writeline("")
+        
+    def begin_class(self, name, base="Object"):
+        self.codegenerator.write("package py ")
+        self.codegenerator.openblock()
+
+        self.codegenerator.write("dynamic public class %s extends %s "%(name, base))
+        self.codegenerator.openblock()
+
+    def end_class(self):
+        self.codegenerator.closeblock()
+        self.codegenerator.closeblock()
+        self.codegenerator.writeline("")
+        
+    def load_arg(self, v):
+        self.right_hand.append(v.name)
+    
+    def store_local(self, v):
+        self.store_name(v.name)
+    
+    def store_name(self, name):
+        name = self.subst_table.get(name, name)
+        element = self.right_hand.pop()
+        if element != name:
+            self.codegenerator.writeline("%s = %s;"%(name, element))
+    
+    def load_local(self, v):
+        self.right_hand.append(v.name)
+    
+    def load_const(self, v):
+        self.right_hand.append(v)
+
+    def ret(self):
+        self.codegenerator.writeline("return ( %s );"%self.right_hand.pop())
+    
+    def emit(self, opcode, *args):
+        v1 = self.right_hand.pop()
+        v2 = self.right_hand.pop()
+        self.right_hand.append("(%s%s%s)"%(v2, opcode, v1))
+
+    def call(self, func):
+        func_name, args = func
+        l = [self.right_hand.pop() for i in xrange(len(args))]
+        l.reverse()
+        real_args = ",".join(l)
+        self.right_hand.append("%s ( %s )" % (func_name, real_args))
+
+    def branch_if(self, exitcase):
+        def mapping(exitc):
+            if exitc in ['True', 'False']:
+                return exitc.lower()
+            return exitc
+
+        arg = self.right_hand.pop()
+        if hasattr(arg,'name'):
+            arg_name = self.subst_table.get(arg.name, arg.name)
+        else:
+            arg_name = arg
+        self.branch_if_string("%s == %s"%(arg_name, mapping(str(exitcase))))
+        
+    def branch_if_string(self, arg):
+        self.codegenerator.writeline("if (%s)"%arg)
+        self.codegenerator.openblock()
+    
+    def branch_elsif_string(self, arg):
+        self.codegenerator.closeblock()
+        self.codegenerator.writeline("else if (%s)"%arg)
+        self.codegenerator.openblock()
+    
+    def branch_elsif(self, arg, exitcase):
+        self.codegenerator.closeblock()
+        self.branch_if(arg, exitcase, "else if")
+    
+    def branch_while(self, arg, exitcase):
+        def mapping(exitc):
+            if exitc in ['True', 'False']:
+                return exitc.lower()
+            return exitc
+        
+        arg_name = self.subst_table.get(arg.name, arg.name)
+        self.codegenerator.write("while ( %s == %s )"%(arg_name, mapping(str(exitcase))))
+        self.codegenerator.openblock()
+    
+    def branch_while_true(self):
+        self.codegenerator.write("while (true)")
+        self.codegenerator.openblock()
+    
+    def branch_else(self):
+        self.right_hand.pop()
+        self.codegenerator.closeblock()
+        self.codegenerator.write("else")
+        self.codegenerator.openblock()
+    
+    def close_branch(self):
+        self.codegenerator.closeblock()
+
+    def label(self, *args):
+        self.codegenerator.openblock()
+
+    def change_name(self, from_name, to_name):
+        if isinstance(from_name,Variable) and isinstance(to_name,Variable):
+            self.subst_table[from_name.name] = to_name.name
+    
+    def cast_function(self, name, num):
+        # FIXME: redundancy with call
+        args = [self.right_hand.pop() for i in xrange(num)]
+        args.reverse()
+        arg_list = ",".join(args)
+        self.right_hand.append("%s ( %s )"%(name, arg_list))
+    
+    def prefix_op(self, st):
+        self.right_hand.append("%s%s"%(st, self.right_hand.pop()))
+    
+    #def field(self, f_name, cts_type):
+    #    pass
+
+    def set_locals(self, loc_string):
+        if loc_string != '':
+            self.codegenerator.writeline("var %s;"%loc_string)
+
+    def set_static_field(self, _type, namespace, _class, varname):
+        self.codegenerator.writeline("%s.prototype.%s = %s;"%(_class, varname, self.right_hand.pop()))
+    
+    def set_field(self, useless_parameter, name):
+        v = self.right_hand.pop()
+        self.codegenerator.writeline("%s.%s = %s;"%(self.right_hand.pop(), name, v))
+        #self.right_hand.append(None)
+    
+    def call_method(self, obj, name, signature):
+        l = [self.right_hand.pop() for i in signature]
+        l.reverse()
+        args = ",".join(l)
+        self.right_hand.append("%s.%s(%s)"%(self.right_hand.pop(), name, args))
+    
+    def get_field(self, name):
+        self.right_hand.append("%s.%s"%(self.right_hand.pop(), name))
+    
+    def new(self, obj):
+        #log("New: %r"%obj)
+        self.right_hand.append("new %s()"%obj)
+    
+    def runtimenew(self):
+        self.right_hand.append("new %s()" % self.right_hand.pop())
+    
+    def load_self(self):
+        self.right_hand.append("this")
+    
+    def store_void(self):
+        if not len(self.right_hand):
+            return
+        v = self.right_hand.pop()
+        if v is not None and v.find('('):
+            self.codegenerator.writeline(v+";")
+    
+    def begin_consts(self, name):
+        # load consts, maybe more try to use stack-based features?
+        self.codegenerator.writeline("var %s = {}"%name)
+        self.codegenerator.writeline("function __load_consts_flex() ")
+        self.codegenerator.openblock()
+
+    def end_consts(self):
+        self.codegenerator.closeblock()
+        
+    def new_obj(self):
+        self.right_hand.append("{}")
+    
+    def new_list(self):
+        self.right_hand.append("[]")
+    
+    # FIXME: will refactor later
+    load_str = load_const
+    
+    def list_setitem(self):
+        item = self.right_hand.pop()
+        value = self.right_hand.pop()
+        lst = self.right_hand.pop()
+        self.right_hand.append("%s[%s]=%s"%(lst, item, value))
+    
+    def list_getitem(self):
+        item = self.right_hand.pop()
+        lst = self.right_hand.pop()
+        self.right_hand.append("%s[%s]"%(lst, item))
+    
+    def load_void(self):
+        self.right_hand.append("undefined")
+
+    def load_void_obj(self):
+        self.right_hand.append("{}")
+    
+    def begin_try(self):
+        self.codegenerator.write("try ")
+        self.codegenerator.openblock()
+    
+    def catch(self):
+        self.codegenerator.closeblock()
+        self.codegenerator.write("catch (exc)")
+        self.codegenerator.openblock()
+    
+    def begin_for(self):
+        self.codegenerator.writeline("var block = 0;")
+        self.codegenerator.write("for(;;)")
+        self.codegenerator.openblock()
+        self.codegenerator.write("switch(block)")
+        self.codegenerator.openblock()
+    
+    def write_case(self, num):
+        self.codegenerator.writeline("case %d:"%num)
+    
+    def jump_block(self, num):
+        self.codegenerator.writeline("block = %d;"%num)
+        self.codegenerator.writeline("break;")
+    
+    def end_for(self):
+        self.codegenerator.closeblock()
+        self.codegenerator.closeblock()
+    
+    def inherits(self, subclass_name, parent_name):
+        self.codegenerator.writeline("inherits(%s,%s);"%(subclass_name, parent_name))
+    
+    def throw(self, var):
+        self.throw_real(var.name)
+    
+    def throw_real(self, s):
+        # use throwit wrapper function... because of compiler weirdness with flex compiler.
+        self.codegenerator.writeline("throwit(%s);"%s)
+
+    def clean_stack(self):
+        self.right_hand.empty()

Added: pypy/branch/flex-backend/translator/flex/autopath.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/autopath.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,114 @@
+"""
+self cloning, automatic path configuration 
+
+copy this into any subdirectory of pypy from which scripts need 
+to be run, typically all of the test subdirs. 
+The idea is that any such script simply issues
+
+    import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path. 
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py) 
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory. 
+
+This module always provides these attributes:
+
+    pypydir    pypy root directory path 
+    this_dir   directory where this autopath.py resides 
+
+"""
+
+
+def __dirinfo(part):
+    """ return (partdir, this_dir) and insert parent of partdir
+    into sys.path.  If the parent directories don't have the part
+    an EnvironmentError is raised."""
+
+    import sys, os
+    try:
+        head = this_dir = os.path.realpath(os.path.dirname(__file__))
+    except NameError:
+        head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+    while head:
+        partdir = head
+        head, tail = os.path.split(head)
+        if tail == part:
+            break
+    else:
+        raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+    
+    pypy_root = os.path.join(head, '')
+    try:
+        sys.path.remove(head)
+    except ValueError:
+        pass
+    sys.path.insert(0, head)
+
+    munged = {}
+    for name, mod in sys.modules.items():
+        if '.' in name:
+            continue
+        fn = getattr(mod, '__file__', None)
+        if not isinstance(fn, str):
+            continue
+        newname = os.path.splitext(os.path.basename(fn))[0]
+        if not newname.startswith(part + '.'):
+            continue
+        path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+        if path.startswith(pypy_root) and newname != part:
+            modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+            if newname != '__init__':
+                modpaths.append(newname)
+            modpath = '.'.join(modpaths)
+            if modpath not in sys.modules:
+                munged[modpath] = mod
+
+    for name, mod in munged.iteritems():
+        if name not in sys.modules:
+            sys.modules[name] = mod
+        if '.' in name:
+            prename = name[:name.rfind('.')]
+            postname = name[len(prename)+1:]
+            if prename not in sys.modules:
+                __import__(prename)
+                if not hasattr(sys.modules[prename], postname):
+                    setattr(sys.modules[prename], postname, mod)
+
+    return partdir, this_dir
+
+def __clone():
+    """ clone master version of autopath.py into all subdirs """
+    from os.path import join, walk
+    if not this_dir.endswith(join('pypy','tool')):
+        raise EnvironmentError("can only clone master version "
+                               "'%s'" % join(pypydir, 'tool',_myname))
+
+
+    def sync_walker(arg, dirname, fnames):
+        if _myname in fnames:
+            fn = join(dirname, _myname)
+            f = open(fn, 'rwb+')
+            try:
+                if f.read() == arg:
+                    print "checkok", fn
+                else:
+                    print "syncing", fn
+                    f = open(fn, 'w')
+                    f.write(arg)
+            finally:
+                f.close()
+    s = open(join(pypydir, 'tool', _myname), 'rb').read()
+    walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+    __clone()

Added: pypy/branch/flex-backend/translator/flex/commproxy.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/commproxy.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,148 @@
+
+""" Communication proxy rendering
+"""
+
+
+from pypy.objspace.flow.model import Variable, Constant
+from pypy.rpython.ootypesystem.bltregistry import ArgDesc
+
+GET_METHOD_BODY = """
+%(class)s.prototype.%(method)s = function ( %(args)s ) {
+    var data,str;
+    var x = new XMLHttpRequest();
+    data = %(data)s;
+    str = ""
+    for(i in data) {
+        if (data[i]) {
+            if (str.length == 0) {
+                str += "?";
+            } else {
+                str += "&";
+            }
+            str += escape(i) + "=" + escape(data[i].toString());
+        }
+    }
+    //logDebug('%(call)s'+str);
+    x.open("GET", '%(call)s' + str, true);
+    x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+    x.onreadystatechange = function () { %(real_callback)s(x, callback) };
+    //x.setRequestHeader("Connection", "close");
+    //x.send(data);
+    x.send(null);
+}
+"""
+
+POST_METHOD_BODY = """
+%(class)s.prototype.%(method)s = function ( %(args)s ) {
+    var data,str;
+    var x = new XMLHttpRequest();
+    data = %(data)s;
+    str = ""
+    for(i in data) {
+        if (data[i]) {
+            if (str.length != 0) {
+                str += "&";
+            }
+            str += escape(i) + "=" + escape(data[i].toString());
+        }
+    }
+    //logDebug('%(call)s'+str);
+    x.open("POST", '%(call)s', true);
+    //x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+    x.onreadystatechange = function () { %(real_callback)s(x, callback) };
+    //x.setRequestHeader("Connection", "close");
+    //logDebug(str);
+    x.send(str);
+    //x.send(null);
+}
+"""
+
+CALLBACK_BODY = """
+function %(real_callback)s (x, cb) {
+   var d;
+   if (x.readyState == 4) {
+      if (x.responseText) {
+         eval ( "d = " + x.responseText );
+         cb(d);
+      } else {
+         cb({});
+      }
+   }
+}
+"""
+
+CALLBACK_XML_BODY = """
+function %(real_callback)s (x, cb) {
+   if (x.readyState == 4) {
+     if (x.responseXML) {
+       cb(x.responseXML.documentElement);
+     } else {
+       cb(null);
+     }
+   }
+}
+"""
+
+MOCHIKIT_BODY = """
+%(class)s.prototype.%(method)s = function ( %(args)s ) {
+    var data,str;
+    data = %(data)s;
+    loadJSONDoc('%(call)s', data).addCallback(callback);
+}
+"""
+
+USE_MOCHIKIT = True # FIXME: some option?
+
+class XmlHttp(object):
+    """ Class for rendering xmlhttp request communication
+    over normal js code
+    """
+    def __init__(self, ext_obj, name, use_xml=False, base_url="", method="GET"):
+        self.ext_obj = ext_obj
+        self.name = name
+        self.use_xml = use_xml
+        self.base_url = base_url
+        obj = self.ext_obj._TYPE._class_
+        if not base_url and hasattr(obj, '_render_base_path'):
+            self.base_url = obj._render_base_path
+        self.method = method
+    
+    def render(self, ilasm):
+        self.render_body(ilasm)
+        for method_name, method in self.ext_obj._TYPE._class_._methods.iteritems():
+            self.render_method(method_name, method, ilasm)
+    
+    def render_body(self, ilasm):
+        ilasm.begin_function(self.name, [])
+        ilasm.end_function()
+    
+    def render_method(self, method_name, method, ilasm):
+        args, retval = method.args, method.retval.name
+        if len(args) == 0 or args[-1].name != 'callback':
+            args.append(ArgDesc('callback', lambda : None))
+        real_args = list(arg.name for arg in args)
+        # FIXME: dirty JS here
+        data = "{%s}" % ",".join(["'%s':%s" % (i,i) for i in real_args if i != 'callback'])
+        real_callback = Variable("callback").name
+        if len(self.base_url) > 0 and not self.base_url.endswith("/"):
+            url = self.base_url + "/" +method_name
+        else:
+            url = self.base_url + method_name
+        
+        METHOD_BODY = globals()[self.method + "_METHOD_BODY"]
+        if USE_MOCHIKIT and self.use_xml:
+            assert 0, "Cannot use mochikit and xml requests at the same time"
+        if USE_MOCHIKIT and self.method == "POST":
+            assert 0, "Cannot use mochikit with POST method"
+        if USE_MOCHIKIT:
+            ilasm.codegenerator.write(MOCHIKIT_BODY % {'class':self.name, 'method':method_name,\
+                'args':','.join(real_args), 'data':data, 'call':url})
+        else:
+            if not self.use_xml:
+                callback_body = CALLBACK_BODY
+            else:
+                callback_body = CALLBACK_XML_BODY
+            ilasm.codegenerator.write(callback_body % {'real_callback':real_callback})
+            ilasm.codegenerator.write(METHOD_BODY % {'class':self.name, 'method':method_name,\
+                'args':",".join(real_args), 'data':data, 'call':url,\
+                'real_callback':real_callback})

Added: pypy/branch/flex-backend/translator/flex/conftest.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/conftest.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,11 @@
+import py
+
+Option = py.test.config.Option
+
+option = py.test.config.addoptions("pypy-ojs options", 
+        Option('--use-browser', action="store", dest="browser", type="string",
+               default="", help="run Javascript tests in your default browser"),
+        
+        Option('--tg', action="store_true", dest="tg", default=False,
+            help="Use TurboGears machinery for testing")
+    )

Added: pypy/branch/flex-backend/translator/flex/database.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/database.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,504 @@
+
+""" genjs constant database module
+"""
+
+from pypy.rpython.ootypesystem import ootype
+from pypy.translator.flex.opcodes import opcodes
+from pypy.translator.flex.function import Function
+from pypy.translator.flex.log import log
+from pypy.translator.flex._class import Class
+from pypy.translator.flex.support import JavascriptNameManager
+
+from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Void, Bool, Float
+from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong, typeOf
+from pypy.rpython.lltypesystem.lltype import Char, UniChar
+from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.ootypesystem import bltregistry
+
+from pypy.objspace.flow.model import Variable, Constant
+from pypy.translator.flex.modules import dom
+from pypy.translator.flex.commproxy import XmlHttp
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+class LowLevelDatabase(object):
+    def __init__(self, genoo):
+        self._pending_nodes = set()
+        self.genoo = genoo
+        self._rendered_nodes = set()
+        self.classes = {} # classdef --> class_name
+        self.functions = {} # graph --> function_name
+        self.function_names = {} # graph --> real_name
+        self.methods = {} # graph --> method_name
+        self.consts = {}  # value --> const_name
+        self.reverse_consts = {}
+        self.const_names = set()
+        self.rendered = set()
+        self.const_var = Variable("__consts")
+        self.name_manager = JavascriptNameManager(self)
+        self.pending_consts = []
+        self.cts = self.genoo.TypeSystem(self)
+        self.proxies = []
+    
+    def is_primitive(self, type_):
+        if type_ in [Void, Bool, Float, Signed, Unsigned, SignedLongLong, UnsignedLongLong, Char, UniChar, ootype.StringBuilder] or \
+            isinstance(type_,ootype.StaticMethod):
+            return True
+        return False
+
+    def pending_function(self, graph):
+        self.pending_node(self.genoo.Function(self, graph))
+
+    def pending_abstract_function(self, name):
+        pass
+        # XXX we want to implement it at some point (maybe...)
+
+    def pending_class(self, classdef):
+        c = Class(self, classdef)
+        self.pending_node(c)
+        return c
+
+    def pending_record(self, record):
+        r = Record(self, record)
+        self.pending_node(r)
+        return r.get_name()
+
+    def pending_node(self, node):
+        if node in self._pending_nodes or node in self._rendered_nodes:
+            return
+        self._pending_nodes.add(node)
+
+    def record_function(self, graph, name):
+        self.functions[graph] = name
+    
+    def get_uniquename(self, graph, name):
+        try:
+            return self.function_names[graph]
+        except KeyError:
+            real_name = self.name_manager.uniquename(name, lenmax=1111111)
+            self.function_names[graph] = real_name
+            return real_name
+
+    def record_class(self, classdef, name):
+        self.classes[classdef] = name
+    
+    def register_comm_proxy(self, proxy_const, *args):
+        """ Register external object which should be rendered as
+        method call
+        """
+        self.proxies.append(XmlHttp(proxy_const, *args))
+
+    def graph_name(self, graph):
+        return self.functions.get(graph, None)
+
+    def class_name(self, classdef):
+        return self.classes.get(classdef, None)
+
+    def record_const(self, value, type_ = None, retval='name'):
+        if type_ is None:
+            type_ = typeOf(value)
+        if self.is_primitive(type_):
+            return None
+        const = AbstractConst.make(self, value)
+        if not const:
+            return None
+        try:
+            if retval == 'name':
+                return self.consts[const]
+            else:
+                self.consts[const]
+                return self.reverse_consts[self.consts[const]]
+        except KeyError:
+            if self.genoo.config.translation.verbose:
+                log("New const:%r"%value)
+                if isinstance(value, ootype._string):
+                    log(value._str)
+            else:
+                log.dot()
+            name = const.get_name()
+            if name in self.const_names:
+                name += '__%d' % len(self.consts)
+            self.consts[const] = name
+            self.reverse_consts[name] = const
+            self.const_names.add(name)
+            self.pending_consts.append((const,name))
+        if retval == 'name':
+            return name
+        else:
+            return const
+
+    def gen_constants(self, ilasm, pending):
+        try:
+            while True:
+                const,name = self.pending_consts.pop()
+                const.record_fields()
+        except IndexError:
+            pass
+
+        if pending:
+            return
+
+        if not self.rendered:
+            ilasm.begin_consts(self.const_var.name)
+        
+        def generate_constants(consts):
+            all_c = [const for const,name in consts.iteritems()]
+            dep_ok = set()
+            while len(all_c) > 0:
+                const = all_c.pop()
+                if const not in self.rendered:
+                    to_render = True
+                    if hasattr(const, 'depends_on') and const.depends_on:
+                        for i in const.depends_on:
+                            if i not in self.rendered and i not in dep_ok:
+                                assert i.depends is None or const in i.depends
+                                to_render = False
+                                continue
+                    
+                    if to_render and (not hasattr(const, 'depends')) or (not const.depends) or const in dep_ok:
+                        yield const,consts[const]
+                        self.rendered.add(const)
+                    else:
+                        all_c.append(const)
+                        for i in const.depends:
+                            all_c.append(i)
+                        dep_ok.add(const)
+
+        # We need to keep track of fields to make sure
+        # our items appear earlier than us
+        to_init = []
+        for const, name in generate_constants(self.consts):
+            if self.genoo.config.translation.verbose:
+                log("Recording %r %r"%(const,name))
+            else:
+                log.dot()
+            ilasm.load_local(self.const_var)
+            const.init(ilasm)
+            ilasm.set_field(None, name)
+            ilasm.store_void()
+            to_init.append((const, name))
+            #ilasm.field(name, const.get_type(), static=True)
+        for const, name in to_init:
+            const.init_fields(ilasm, self.const_var, name)
+        
+        
+
+    def load_const(self, type_, value, ilasm):
+        if self.is_primitive(type_):
+            ilasm.load_const(self.cts.primitive_repr(type_, value))
+        else:
+            try:
+                return self.consts[BuiltinConst(value)]
+            except KeyError:
+                name = self.record_const(value)
+                ilasm.load_local(self.const_var)
+                ilasm.get_field(name)
+            #assert False, 'Unknown constant %s' % const
+
+
+class AbstractConst(object):
+    def __init__(self, db, const):
+        self.db = db
+        self.const = const
+        self.cts = db.genoo.TypeSystem(db)
+        self.depends = set()
+        self.depends_on = set()
+
+    def __hash__(self):
+        return hash(self.get_key())
+
+    def __eq__(self, other):
+        return (other.__class__ is self.__class__ and
+                other.get_key() == self.get_key())
+
+    def __ne__(self, other):
+        return not (self == other)
+    
+    def make(db, const):
+        if isinstance(const, ootype._view):
+            static_type = const._TYPE
+            const = const._inst
+        else:
+            static_type = None
+
+        if isinstance(const, ootype._instance):
+            return InstanceConst(db, const, static_type)
+        elif isinstance(const, ootype._list):
+            return ListConst(db, const)
+        elif isinstance(const, ootype._record):
+            return RecordConst(db, const)
+        elif isinstance(const, ootype._string):
+            return StringConst(db, const)
+        elif isinstance(const, ootype._dict):
+            return DictConst(db, const)
+        elif isinstance(const, bltregistry._external_inst):
+            return ExtObject(db, const)
+        elif isinstance(const, ootype._class):
+            if const._INSTANCE:
+                return ClassConst(db, const)
+            else:
+                return None
+        else:
+            assert False, 'Unknown constant: %s %r' % (const, typeOf(const))
+    make = staticmethod(make)
+
+    def get_name(self):
+        pass
+
+    def get_type(self):
+        pass
+
+    def init(self, ilasm):
+        pass
+    
+    def init_fields(self, ilasm, const_var, name):
+        pass
+    
+    def record_fields(self):
+        pass
+
+class InstanceConst(AbstractConst):
+    def __init__(self, db, obj, static_type):
+        self.depends = set()
+        self.depends_on = set()
+        self.db = db
+        self.cts = db.genoo.TypeSystem(db)
+        self.obj = obj
+        if static_type is None:
+            self.static_type = obj._TYPE
+        else:
+            self.static_type = static_type
+            self.cts.lltype_to_cts(obj._TYPE) # force scheduling of obj's class
+
+    def get_key(self):
+        return self.obj
+
+    def get_name(self):
+        return self.obj._TYPE._name.replace('.', '_')
+
+    def get_type(self):
+        return self.cts.lltype_to_cts(self.static_type)
+
+    def init(self, ilasm):
+        if not self.obj:
+            ilasm.load_void()
+            return
+        
+        classdef = self.obj._TYPE
+        try:
+            classdef._hints['_suggested_external']
+            ilasm.new(classdef._name.split(".")[-1])
+        except KeyError:
+            ilasm.new(classdef._name.replace(".", "_"))
+    
+    def record_fields(self):
+        if not self.obj:
+            return
+        INSTANCE = self.obj._TYPE
+        #while INSTANCE:
+        for i, (_type, val) in INSTANCE._allfields().items():
+            if _type is not ootype.Void:
+                name = self.db.record_const(getattr(self.obj, i), _type, 'const')
+                if name is not None:
+                    self.depends.add(name)
+                    name.depends_on.add(self)
+        
+    def init_fields(self, ilasm, const_var, name):
+        if not self.obj:
+            return
+        
+        INSTANCE = self.obj._TYPE
+        #while INSTANCE:
+        for i, (_type, el) in INSTANCE._allfields().items():
+            if _type is not ootype.Void:
+                ilasm.load_local(const_var)
+                self.db.load_const(_type, getattr(self.obj, i), ilasm)
+                ilasm.set_field(None, "%s.%s"%(name, i))
+                ilasm.store_void()
+
+class RecordConst(AbstractConst):
+    def get_name(self):
+        return "const_tuple"
+    
+    def init(self, ilasm):
+        if not self.const:
+            ilasm.load_void()
+        else:
+            ilasm.new_obj()
+    
+    def record_fields(self):
+        if not self.const:
+            return
+        
+        for i in self.const._items:
+            name = self.db.record_const(self.const._items[i], None, 'const')
+            if name is not None:
+                self.depends.add(name)
+                name.depends_on.add(self)
+    
+    def get_key(self):
+        return self.const
+
+    def init_fields(self, ilasm, const_var, name):
+        if not self.const:
+            return
+        
+        #for i in self.const.__dict__["_items"]:
+        for i in self.const._items:
+            ilasm.load_local(const_var)
+            el = self.const._items[i]
+            self.db.load_const(typeOf(el), el, ilasm)
+            ilasm.set_field(None, "%s.%s"%(name, i))
+            ilasm.store_void()
+
+class ListConst(AbstractConst):
+    
+    def get_name(self):
+        return "const_list"
+    
+    def init(self, ilasm):
+        if not self.const:
+            ilasm.load_void()
+        else:
+            ilasm.new_list()
+    
+    def record_fields(self):
+        if not self.const:
+            return
+        
+        for i in self.const._list:
+            name = self.db.record_const(i, None, 'const')
+            if name is not None:
+                self.depends.add(name)
+                name.depends_on.add(self)
+        
+    def get_key(self):
+        return self.const
+
+    def init_fields(self, ilasm, const_var, name):
+        if not self.const:
+            return
+        
+        for i in xrange(len(self.const._list)):
+            ilasm.load_str("%s.%s"%(const_var.name, name))
+            el = self.const._list[i]
+            self.db.load_const(typeOf(el), el, ilasm)
+            self.db.load_const(typeOf(i), i, ilasm)
+            ilasm.list_setitem()
+            ilasm.store_void()
+
+class StringConst(AbstractConst):
+    def get_name(self):
+        return "const_str"
+
+    def get_key(self):
+        return self.const._str
+
+    def init(self, ilasm):
+        if self.const:
+            s = self.const._str
+        # do some escaping
+        #s = s.replace("\n", "\\n").replace('"', '\"')
+        #s = repr(s).replace("\"", "\\\"")
+            ilasm.load_str("%s" % repr(s))
+        else:
+            ilasm.load_str("undefined")
+    
+    def init_fields(self, ilasm, const_var, name):
+        pass
+
+class ClassConst(AbstractConst):
+    def __init__(self, db, const):
+        super(ClassConst, self).__init__(db, const)
+        self.cts.lltype_to_cts(const._INSTANCE) # force scheduling of class
+    
+    def get_name(self):
+        return "const_class"
+    
+    def get_key(self):
+        return self.get_name()
+    
+    def get_name(self):
+        return self.const._INSTANCE._name.replace(".", "_")
+    
+    def init(self, ilasm):
+        ilasm.load_const("%s" % self.get_name())
+    
+    #def init_fields(self, ilasm, const_var, name):
+    #    pass
+
+class BuiltinConst(AbstractConst):
+    def __init__(self, name):
+        self.name = name
+    
+    def get_key(self):
+        return self.name
+    
+    def get_name(self):
+        return self.name
+    
+    def init_fields(self, *args):
+        pass
+    
+    def init(self, ilasm):
+        ilasm.load_str(self.name)
+
+class DictConst(RecordConst):
+    def record_const(self, co):
+        name = self.db.record_const(co, None, 'const')
+        if name is not None:
+            self.depends.add(name)
+            name.depends_on.add(self)
+    
+    def record_fields(self):
+        if not self.const:
+            return
+        
+        for i in self.const._dict:
+            self.record_const(i)
+            self.record_const(self.const._dict[i])
+
+    def init_fields(self, ilasm, const_var, name):
+        if not self.const:
+            return
+        
+        for i in self.const._dict:
+            ilasm.load_str("%s.%s"%(const_var.name, name))
+            el = self.const._dict[i]
+            self.db.load_const(typeOf(el), el, ilasm)
+            self.db.load_const(typeOf(i), i, ilasm)
+            ilasm.list_setitem()
+            ilasm.store_void()
+
+class ExtObject(AbstractConst):
+    def __init__(self, db, const):
+        self.db = db
+        self.const = const
+        self.name = self.get_name()
+        self.depends = set()
+        self.depends_on = set()
+    
+    def get_key(self):
+        return self.name
+    
+    def get_name(self):
+        return self.const._TYPE._name.split('.')[-1][:-2]
+    
+    def init(self, ilasm):
+        _class = self.const._TYPE._class_
+        if getattr(_class, '_render_xmlhttp', False):
+            use_xml = getattr(_class, '_use_xml', False)
+            base_url = getattr(_class, '_base_url', "") # XXX: should be
+            method = getattr(_class, '_use_method', 'GET')
+                # on per-method basis
+            self.db.register_comm_proxy(self.const, self.name, use_xml, base_url, method)
+            ilasm.new(self.get_name())
+        else:
+            # Otherwise they just exist, or it's not implemented
+            if not hasattr(self.const.value, '_render_name'):
+                raise ValueError("Prebuilt constant %s has no attribute _render_name,"
+                                  "don't know how to render" % self.const.value)
+            ilasm.load_str(self.const.value._render_name)

Added: pypy/branch/flex-backend/translator/flex/examples/__init__.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/__init__.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1 @@
+#
\ No newline at end of file

Added: pypy/branch/flex-backend/translator/flex/examples/autopath.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/autopath.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,114 @@
+"""
+self cloning, automatic path configuration 
+
+copy this into any subdirectory of pypy from which scripts need 
+to be run, typically all of the test subdirs. 
+The idea is that any such script simply issues
+
+    import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path. 
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py) 
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory. 
+
+This module always provides these attributes:
+
+    pypydir    pypy root directory path 
+    this_dir   directory where this autopath.py resides 
+
+"""
+
+
+def __dirinfo(part):
+    """ return (partdir, this_dir) and insert parent of partdir
+    into sys.path.  If the parent directories don't have the part
+    an EnvironmentError is raised."""
+
+    import sys, os
+    try:
+        head = this_dir = os.path.realpath(os.path.dirname(__file__))
+    except NameError:
+        head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+    while head:
+        partdir = head
+        head, tail = os.path.split(head)
+        if tail == part:
+            break
+    else:
+        raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+    
+    pypy_root = os.path.join(head, '')
+    try:
+        sys.path.remove(head)
+    except ValueError:
+        pass
+    sys.path.insert(0, head)
+
+    munged = {}
+    for name, mod in sys.modules.items():
+        if '.' in name:
+            continue
+        fn = getattr(mod, '__file__', None)
+        if not isinstance(fn, str):
+            continue
+        newname = os.path.splitext(os.path.basename(fn))[0]
+        if not newname.startswith(part + '.'):
+            continue
+        path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+        if path.startswith(pypy_root) and newname != part:
+            modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+            if newname != '__init__':
+                modpaths.append(newname)
+            modpath = '.'.join(modpaths)
+            if modpath not in sys.modules:
+                munged[modpath] = mod
+
+    for name, mod in munged.iteritems():
+        if name not in sys.modules:
+            sys.modules[name] = mod
+        if '.' in name:
+            prename = name[:name.rfind('.')]
+            postname = name[len(prename)+1:]
+            if prename not in sys.modules:
+                __import__(prename)
+                if not hasattr(sys.modules[prename], postname):
+                    setattr(sys.modules[prename], postname, mod)
+
+    return partdir, this_dir
+
+def __clone():
+    """ clone master version of autopath.py into all subdirs """
+    from os.path import join, walk
+    if not this_dir.endswith(join('pypy','tool')):
+        raise EnvironmentError("can only clone master version "
+                               "'%s'" % join(pypydir, 'tool',_myname))
+
+
+    def sync_walker(arg, dirname, fnames):
+        if _myname in fnames:
+            fn = join(dirname, _myname)
+            f = open(fn, 'rwb+')
+            try:
+                if f.read() == arg:
+                    print "checkok", fn
+                else:
+                    print "syncing", fn
+                    f = open(fn, 'w')
+                    f.write(arg)
+            finally:
+                f.close()
+    s = open(join(pypydir, 'tool', _myname), 'rb').read()
+    walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+    __clone()

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/__init__.py
==============================================================================

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/autopath.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/autopath.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,114 @@
+"""
+self cloning, automatic path configuration 
+
+copy this into any subdirectory of pypy from which scripts need 
+to be run, typically all of the test subdirs. 
+The idea is that any such script simply issues
+
+    import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path. 
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py) 
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory. 
+
+This module always provides these attributes:
+
+    pypydir    pypy root directory path 
+    this_dir   directory where this autopath.py resides 
+
+"""
+
+
+def __dirinfo(part):
+    """ return (partdir, this_dir) and insert parent of partdir
+    into sys.path.  If the parent directories don't have the part
+    an EnvironmentError is raised."""
+
+    import sys, os
+    try:
+        head = this_dir = os.path.realpath(os.path.dirname(__file__))
+    except NameError:
+        head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+    while head:
+        partdir = head
+        head, tail = os.path.split(head)
+        if tail == part:
+            break
+    else:
+        raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir)
+    
+    pypy_root = os.path.join(head, '')
+    try:
+        sys.path.remove(head)
+    except ValueError:
+        pass
+    sys.path.insert(0, head)
+
+    munged = {}
+    for name, mod in sys.modules.items():
+        if '.' in name:
+            continue
+        fn = getattr(mod, '__file__', None)
+        if not isinstance(fn, str):
+            continue
+        newname = os.path.splitext(os.path.basename(fn))[0]
+        if not newname.startswith(part + '.'):
+            continue
+        path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+        if path.startswith(pypy_root) and newname != part:
+            modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+            if newname != '__init__':
+                modpaths.append(newname)
+            modpath = '.'.join(modpaths)
+            if modpath not in sys.modules:
+                munged[modpath] = mod
+
+    for name, mod in munged.iteritems():
+        if name not in sys.modules:
+            sys.modules[name] = mod
+        if '.' in name:
+            prename = name[:name.rfind('.')]
+            postname = name[len(prename)+1:]
+            if prename not in sys.modules:
+                __import__(prename)
+                if not hasattr(sys.modules[prename], postname):
+                    setattr(sys.modules[prename], postname, mod)
+
+    return partdir, this_dir
+
+def __clone():
+    """ clone master version of autopath.py into all subdirs """
+    from os.path import join, walk
+    if not this_dir.endswith(join('pypy','tool')):
+        raise EnvironmentError("can only clone master version "
+                               "'%s'" % join(pypydir, 'tool',_myname))
+
+
+    def sync_walker(arg, dirname, fnames):
+        if _myname in fnames:
+            fn = join(dirname, _myname)
+            f = open(fn, 'rwb+')
+            try:
+                if f.read() == arg:
+                    print "checkok", fn
+                else:
+                    print "syncing", fn
+                    f = open(fn, 'w')
+                    f.write(arg)
+            finally:
+                f.close()
+    s = open(join(pypydir, 'tool', _myname), 'rb').read()
+    walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+    __clone()

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/bnb.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/bnb.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,267 @@
+
+""" xmlhttp controllers, usefull for testing
+"""
+
+import py
+from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
+
+from pypy.translator.js.examples.bnb.servermessage import log, ServerMessage,\
+    PMSG_INLINE_FRAME, PMSG_DEF_ICON
+from pypy.translator.js.examples.bnb.msgstruct import *
+from pypy.translator.js.lib.support import callback
+from pypy.translator.js.lib import server
+
+import re, time, sys, os, urllib, socket, copy, md5, random
+
+class SpriteManager(object):
+    def __init__(self):
+        self.sprite_sets = {}
+        self.positions = {}
+        self.num = 0
+        self.next_pos = {}
+        self.last_seen = set()
+        self.seen = set()
+        self.num_frame = 0
+        self.z_index = {}
+    
+    def def_icon(self, icon_code):
+        self.sprite_sets[icon_code] = []
+    
+    def get_frame_number(self):
+        self.num_frame += 1
+    
+    def get_sprite(self, icon_code, x, y):
+        try:
+            to_ret = self.positions[(icon_code, x, y)]
+            del self.positions[(icon_code, x, y)]
+            self.next_pos[(icon_code, x, y)] = to_ret
+            self.seen.add((icon_code, to_ret))
+            return "still", to_ret
+        except KeyError:
+            try:
+                try:
+                    to_ret = self.sprite_sets[icon_code].pop()
+                except KeyError:
+                    self.def_icon(icon_code)
+                    raise IndexError
+                self.next_pos[(icon_code, x, y)] = to_ret
+                self.seen.add((icon_code, to_ret))
+                return "move", to_ret
+            except IndexError:
+                next = self.num
+                self.num += 1
+                self.next_pos[(icon_code, x, y)] = next
+                self.seen.add((icon_code, next))
+                return "new", next
+    
+    def end_frame(self):
+        self.positions = copy.deepcopy(self.next_pos)
+        self.next_pos = {}
+        to_ret = []
+        for ic, i in self.last_seen - self.seen:
+            self.sprite_sets[ic].append(i)
+            to_ret.append(i)
+        self.last_seen = self.seen
+        self.seen = set()
+        return to_ret
+
+class ExportedMethods(server.ExportedMethods):
+    _serverMessage = {}
+    _spriteManagers = {}
+
+    host = 'localhost'
+    try:
+        port = re.findall('value=".*"', urllib.urlopen('http://%s:8000' % host).read())[0]
+        port = int(port[7:-1])
+    except IOError:
+        log("ERROR: Can't connect to BnB server on %s:8000" % host)
+#        sys.exit()
+    except IndexError:
+        log("ERROR: Connected to BnB server but unable to detect a running game")
+#        sys.exit()
+
+    #def _close(self, sessionid):
+    #    if sessionid in self._serverMessage:
+    #        sm = self.serverMessage()
+    #        if sm.socket is not None:
+    #            sm.socket.close()
+    #        del self._serverMessage[sessionid]
+    def get_sprite_manager(self, sessionid):
+        return self._spriteManagers[sessionid]
+
+    def sessionSocket(self, sessionid, close=False):
+        sm = self.serverMessage(sessionid)
+        if sm.socket is None:
+            player_id = 0 #XXX hardcoded for now
+            sm.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            sm.socket.connect((self.host, self.port))
+            sm.socket.send(message(CMSG_PROTO_VERSION, 2))  #, version a kuku
+            sm.socket.send(message(CMSG_ENABLE_SOUND, 0))   #, has_sound
+            sm.socket.send(message(CMSG_ENABLE_MUSIC, 0))   #, has_music
+            sm.socket.send(message(CMSG_UDP_PORT, "\\"))    #, port
+            sm.socket.send(message(CMSG_PING))              #so server starts sending data
+        return sm.socket
+
+    def _closeIdleConnections(self):
+        t = time.time() - 20.0 #20 seconds until considered idle
+        for sessionid, sm in self._serverMessage.items():
+            if sm.last_active < t:
+                log("Close connection with sessionid %s because it was idle for %.1f seconds" % (
+                    sessionid, time.time() - sm.last_active))
+                if sm.socket is not None:
+                    sm.socket.close()
+                del self._serverMessage[sessionid]
+
+    def serverMessage(self, sessionid):
+        self._closeIdleConnections()
+        if sessionid not in self._serverMessage:
+            self._serverMessage[sessionid] = ServerMessage('data/images')
+        return self._serverMessage[sessionid]
+
+    @callback(retval=None)
+    def player_name(self, player_id=0, name="", sessionid=""):
+        log("Changing player #%s name to %s" % (player_id, name))
+        socket = self.sessionSocket(sessionid)
+        socket.send(message(CMSG_PLAYER_NAME, int(player_id), name))
+
+    @callback(retval=None)
+    def add_player(self, player_id=0, sessionid=""):
+        log("Adding player " + player_id)
+        socket = self.sessionSocket(sessionid)
+        socket.send(message(CMSG_ADD_PLAYER, int(player_id)))
+
+    @callback(retval=None)
+    def remove_player(self, player_id=0, sessionid=""):
+        log("Remove player " + player_id)
+        socket = self.sessionSocket(sessionid)
+        socket.send(message(CMSG_REMOVE_PLAYER, int(player_id)))
+
+    @callback(retval=str)
+    def initialize_session(self):
+        sessionid = md5.md5(str(random.random())).hexdigest()
+        self._create_session(sessionid)
+        return sessionid
+
+    def _create_session(self, sessionid):
+        sm = ServerMessage('data/images/')
+        self._serverMessage[sessionid] = sm
+        self._spriteManagers[sessionid] = SpriteManager()
+        return sessionid
+
+    @callback(retval={str:[{str:str}]})
+    def get_message(self, sessionid="", player_id=0, keys=""):
+        """ This one is long, ugly and obscure
+        """
+        #XXX hangs if not first sending CMSG_PING!
+        try:
+            sm   = self.serverMessage(sessionid)
+        except KeyError:
+            self._create_session(sessionid)
+            sm   = self.serverMessage(sessionid)           
+        data = sm.data
+        sock = self.sessionSocket(sessionid)
+        while True:
+            try:
+                data += sock.recv(4096, socket.MSG_DONTWAIT)
+            except:    
+                break
+        while sm.n_header_lines > 0 and '\n' in data:
+            sm.n_header_lines -= 1
+            header_line, data = data.split('\n',1)
+            #log('RECEIVED HEADER LINE: %s' % header_line)
+
+        #log('RECEIVED DATA CONTAINS %d BYTES' % len(data))
+        messages = []
+        while data:
+            values, data = decodemessage(data)
+            if not values:
+                break  # incomplete message
+            messageOutput = sm.dispatch(*values)
+            if messageOutput:
+                if type(messageOutput) is type([]):
+                    messages += messageOutput
+                else:
+                    messages.append(messageOutput)
+        sm.data = data
+
+        len_before = len(messages)
+        inline_frames = [i for i,msg in enumerate(messages) if msg['type'] == PMSG_INLINE_FRAME]
+        for i in reversed(inline_frames[:-1]):
+            del messages[i]
+
+        to_append = []
+        sprite_manager = self.get_sprite_manager(sessionid)
+
+        sm_restart = 0
+        if player_id != -1:
+            if keys:
+                for i in keys.split(":"):
+                    self.sessionSocket(sessionid).\
+                         send(message(CMSG_KEY, int(player_id), int(i)))
+                
+        def get_partial_frame(next, z_num):
+            new_sprite, s_num = sprite_manager.get_sprite(*next)
+            if new_sprite == 'new':
+                to_append.append({'type':'ns', 's':s_num, 'icon_code':str(next[0]), 'x':str(next[1]), 'y':str(next[2]), 'z':z_num})
+                sprite_manager.z_index[s_num] = z_num
+            elif new_sprite == 'move':
+                to_append.append({'type':'sm', 's':str(s_num), 'x':str(next[1]), 'y':str(next[2]), 'z':z_num})
+                sprite_manager.z_index[s_num] = z_num
+            else:
+                if sprite_manager.z_index[s_num] != z_num:
+                    to_append.append({'type':'zindex', 's':s_num, 'z':z_num})
+                    sprite_manager.z_index[s_num] = z_num
+            return s_num
+        
+        z_num = 0
+        for i, msg in enumerate(messages):
+            if msg['type'] == PMSG_INLINE_FRAME:
+                for next in msg['sprites']:
+                    s_num = get_partial_frame(next, z_num)
+                    z_num += 1
+                del messages[i]
+
+        empty_frame = False
+        if sprite_manager.seen == set([]):
+            empty_frame = True
+        
+        if not empty_frame:
+            for i in sprite_manager.end_frame():
+                to_append.append({'type':'ds', 's':str(i)})
+        messages += to_append
+        return dict(messages=messages, add_data=[{'n':sm.count(), 'sm_restart':sm_restart}])
+
+exported_methods = ExportedMethods()
+
+class BnbHandler(server.Collection):
+    """ BnB server handler
+    """
+    exported_methods = exported_methods
+    static_dir = py.path.local(__file__).dirpath().join("data")
+    
+    index = server.Static(static_dir.join("bnb.html"))
+    images = server.StaticDir("data/images", type="image/png")
+
+    def source_js(self):
+        return "text/javascript", self.server.source
+    source_js.exposed = True
+
+    MochiKit = server.StaticDir('MochiKit')
+    
+    #@turbogears.expose(format='json')
+
+    #@turbogears.expose(format='json')
+
+##    @turbogears.expose(format='json')
+##    def key(self, player_id, keynum):
+##        self.sessionSocket().send(message(CMSG_KEY, int(player_id), int(keynum)))
+##        return dict()
+
+    #@turbogears.expose(format='json')
+    def close(self):
+        self._close()
+        return dict()
+
+class BnbRoot(server.NewHandler):
+    application = BnbHandler()
+

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/data/bnb.html
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/data/bnb.html	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+    <meta content="text/html; charset=UTF-8" http-equiv="content-type"/>
+    <title>Bub'n'bros</title>
+    <script type="text/javascript" src="source.js"></script>
+    <script src="http://mochikit.com/MochiKit/MochiKit.js" type="text/javascript"></script>
+</head>
+<body onload="bnb()">
+</body>
+</html>

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/msgstruct.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/msgstruct.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,78 @@
+from struct import pack, unpack, calcsize
+
+try:
+    from localmsg import PORTS
+except ImportError:
+    PORTS = {}
+try:
+    from localmsg import HOSTNAME
+except ImportError:
+    from socket import gethostname
+    HOSTNAME = gethostname()
+
+
+MSG_WELCOME = "Welcome to gamesrv.py(3) !\n"
+MSG_BROADCAST_PORT= "*"
+MSG_DEF_PLAYFIELD = "p"
+MSG_DEF_KEY       = "k"
+MSG_DEF_ICON      = "r"
+MSG_DEF_BITMAP    = "m"
+MSG_DEF_SAMPLE    = "w"
+MSG_DEF_MUSIC     = "z"
+MSG_PLAY_MUSIC    = "Z"
+MSG_FADEOUT       = "f"
+MSG_PLAYER_JOIN   = "+"
+MSG_PLAYER_KILL   = "-"
+MSG_PLAYER_ICON   = "i"
+MSG_PING          = "g"
+MSG_PONG          = "G"
+MSG_INLINE_FRAME  = "\\"
+MSG_PATCH_FILE    = MSG_DEF_MUSIC
+MSG_ZPATCH_FILE   = "P"
+MSG_MD5_FILE      = "M"
+MSG_RECORDED      = "\x00"
+
+CMSG_PROTO_VERSION= "v"
+CMSG_KEY          = "k"
+CMSG_ADD_PLAYER   = "+"
+CMSG_REMOVE_PLAYER= "-"
+CMSG_UDP_PORT     = "<"
+CMSG_ENABLE_SOUND = "s"
+CMSG_ENABLE_MUSIC = "m"
+CMSG_PING         = "g"
+CMSG_PONG         = "G"
+CMSG_DATA_REQUEST = "M"
+CMSG_PLAYER_NAME  = "n"
+
+BROADCAST_MESSAGE = "game!"   # less than 6 bytes
+
+
+def message(tp, *values):
+    strtype = type('')
+    typecodes = ['']
+    for v in values:
+        if type(v) is strtype:
+            typecodes.append('%ds' % len(v))
+        elif 0 <= v < 256:
+            typecodes.append('B')
+        else:
+            typecodes.append('l')
+    typecodes = ''.join(typecodes)
+    assert len(typecodes) < 256
+    return pack(("!B%dsc" % len(typecodes)) + typecodes,
+                len(typecodes), typecodes, tp, *values)
+
+def decodemessage(data):
+    if data:
+        limit = ord(data[0]) + 1
+        if len(data) >= limit:
+            typecodes = "!c" + data[1:limit]
+            try:
+                end = limit + calcsize(typecodes)
+            except TypeError:
+                return None, ''
+            if len(data) >= end:
+                return unpack(typecodes, data[limit:end]), data[end:]
+            elif end > 1000000:
+                raise OverflowError
+    return None, data

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/servermessage.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/servermessage.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,289 @@
+from msgstruct import *
+from zlib import decompressobj, decompress
+from urllib import quote
+from os.path import exists
+from struct import unpack
+from time import time
+import md5
+
+
+debug = True
+def log(msg):
+    if debug:
+        print msg
+
+
+class BitmapCreationException(Exception):
+    pass
+
+
+#proxy messages
+#PMSG_PING          = "ping"    #server wants to hear from client
+#PMSG_PONG          = "pong"    #server responds to client's ping
+PMSG_DEF_PLAYFIELD = "def_playfield"
+PMSG_DEF_ICON      = "def_icon"
+PMSG_PLAYER_ICON   = "player_icon"
+PMSG_PLAYER_JOIN   = "player_join"
+PMSG_PLAYER_KILL   = "player_kill"
+PMSG_DEF_KEY       = "def_key"
+PMSG_INLINE_FRAME  = "inline_frame"
+
+
+# convert server messages to proxy messages in json format
+class ServerMessage:
+
+    _md5_file       = {}
+    _bitmap2hexdigits={}
+    _def_icon_queue = {}
+    base_gfx_dir = 'data/images/'
+    base_gfx_url = '/images/'
+    gfx_extension = 'png'
+
+    def __init__(self, base_gfx_dir = None):
+        if base_gfx_dir:
+            self.base_gfx_dir = base_gfx_dir
+            if not self.base_gfx_dir.endswith('/'):
+                self.base_gfx_dir += '/'
+        self.socket = None
+        self.data   = ''
+        self.n_header_lines = 2
+        self.gfx_dir = self.base_gfx_dir    #gets overwritten depending on playfield FnDesc
+        self.gfx_url = self.base_gfx_url
+        self.decompressobj = decompressobj().decompress
+        self.last_active = time()
+        self._count = 0
+
+    def count(self):
+        self._count += 1
+        return self._count
+
+    def dispatch(self, *values):
+        #log('RECEIVED:%s(%d)' % (values[0], len(values[1:])))
+        self.last_active = time()
+        fn = self.MESSAGES.get(values[0])
+        if fn:
+            try:
+                return fn(self, *values[1:])
+            except BitmapCreationException, e:
+                log(str(e))
+                return dict()
+        else:
+            log("UNKNOWN:%s" % str(values))
+            return dict(type='unknown', values=values)
+
+    #server message handlers...
+    def ignore(self, *values):
+        #log('ignore %s' % str(values))
+        return
+
+    def def_playfield(self, width, height, backcolor, FnDesc):
+        #log('def_playfield width=%s, height=%s, backcolor=%s, FnDesc=%s' % (\
+        #    width, height, backcolor, FnDesc))
+        self.gfx_dir = self.base_gfx_dir
+        self.gfx_url = self.base_gfx_url
+        return dict(type=PMSG_DEF_PLAYFIELD, width=width, height=height,
+                    backcolor=backcolor, FnDesc=FnDesc)
+
+    def def_bitmap(self, bitmap_code, data_or_fileid, *rest):
+        if type(data_or_fileid) is type(0):
+            fn = self.def_bitmap2
+        else:
+            fn = self.def_bitmap1
+        return fn(bitmap_code, data_or_fileid, *rest)
+
+    def def_bitmap1(self, bitmap_code, data, *rest):
+        import PIL.Image
+        if len(rest) == 0:
+            colorkey = None
+        else:
+            c = rest[0]
+            colorkey = (c & 255, (c >> 8) & 255, (c >> 16) & 255)
+        #log('def_bitmap1 bitmap_code=%d, data=%d bytes, colorkey=%s' % (
+        #    bitmap_code, len(data), colorkey))
+
+        try:
+            decompressed_data = decompress(data)
+        except Exception, e:
+            raise BitmapCreationException('ERROR UNCOMPRESSING DATA FOR %s (%s)' % (
+                bitmap_filename, str(e)))
+        hexdigits = md5.new(decompressed_data).hexdigest()
+        self._bitmap2hexdigits[bitmap_code] = hexdigits
+
+        gfx_bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension)
+        if exists(gfx_bitmap_filename):
+            #log('CACHED:%s' % gfx_bitmap_filename)
+            pass
+        else:
+            bitmap_filename = '%s%s.ppm' % (self.gfx_dir, hexdigits)
+            f = open(bitmap_filename, 'wb')
+            f.write(decompressed_data)
+            f.close()
+            #TODO: use in memory (don't save ppm first)
+            try:
+                bitmap = PIL.Image.open(bitmap_filename)
+            except IOError, e:
+                raise BitmapCreationException('ERROR LOADING %s (%s)' % (
+                    bitmap_filename, str(e)))
+
+            #create alpha layer (PIL export this correctly with png but not with gif)
+            if colorkey is not None:
+                bitmap = bitmap.convert("RGBA")
+                data   = bitmap.getdata()
+                c      = (colorkey[0], colorkey[1], colorkey[2], 255)
+                width, height = bitmap.size
+                for y in range(height): #this is slowish but gfx are cached, so...
+                    for x in range(width):
+                        p = data.getpixel((x,y))
+                        if p == c:
+                            data.putpixel((x,y), (0,0,0,0))
+
+            try:
+                bitmap.save(gfx_bitmap_filename)
+                log('SAVED:%s' % gfx_bitmap_filename)
+            except IOError:
+                raise BitmapCreationException('ERROR SAVING %s (%s)' % (
+                    gfx_bitmap_filename, str(e)))
+
+    def def_bitmap2(self, bitmap_code, fileid, *rest):
+        #log('def_bitmap2: bitmap_code=%d, fileid=%d, colorkey=%s' % (bitmap_code, fileid, rest))
+        hexdigits = self._md5_file[fileid]['hexdigits']
+        self._bitmap2hexdigits[bitmap_code] = hexdigits
+        gfx_bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension)
+        if exists(gfx_bitmap_filename):
+            #log('SKIP DATA_REQUEST:%s' % gfx_bitmap_filename)
+            pass
+        else:
+            self._md5_file[fileid]['bitmap_code'] = bitmap_code
+            self._md5_file[fileid]['colorkey'] = rest
+            position = self._md5_file[fileid]['offset']
+            size     = self._md5_file[fileid]['len_data']
+            msg      = message(CMSG_DATA_REQUEST, fileid, position, size)
+            self.socket.send(msg)
+            log('DATA_REQUEST:fileid=%d(pos=%d,size=%d):%s' % (
+                fileid, position, size, gfx_bitmap_filename))
+
+    def def_icon(self, bitmap_code, icon_code, x,y,w,h, *rest):
+        import PIL.Image
+
+        #log('def_icon bitmap_code=%s, icon_code=%s, x=%s, y=%s, w=%s, h=%s, alpha=%s' %\
+        #    (bitmap_code, icon_code, x,y,w,h, rest) #ignore alpha (bubbles)
+
+        hexdigits = self._bitmap2hexdigits[bitmap_code]
+        bitmap_filename = '%s%s.%s' % (self.gfx_dir, hexdigits, self.gfx_extension)
+        icon_filename = '%s%s_%d_%d_%d_%d.%s' % (
+            self.gfx_dir, hexdigits, x, y, w, h, self.gfx_extension)
+        if exists(icon_filename):
+            #log('CACHED:%s' % icon_filename)
+            pass
+        elif exists(bitmap_filename):
+            #TODO: use in memory (don't save ppm first)
+            icon    = PIL.Image.open(bitmap_filename)
+            box     = (x, y, x+w, y+h)
+            region  = icon.crop(box)
+            region.save(icon_filename)
+            log('SAVED:%s' % icon_filename)
+        else:   #bitmap is not available yet (protocol 2)
+            #log('%s NOT AVAILABLE FOR %s' % (bitmap_filename, icon_filename))
+            if bitmap_code not in self._def_icon_queue:
+                self._def_icon_queue[bitmap_code] = []
+            self._def_icon_queue[bitmap_code].append((icon_code, x, y, w, h, rest))
+            return
+
+        filename = '%s%s_%d_%d_%d_%d.%s' % (
+            self.gfx_url, hexdigits, x, y, w, h, self.gfx_extension)
+        return dict(type=PMSG_DEF_ICON, icon_code=icon_code, filename=filename, width=w, height=h)
+
+    def zpatch_file(self, fileid, position, data): #response to CMSG_DATA_REQUEST
+        #log('zpatch_file fileid=%d, position=%d, len(data)=%d' % (fileid, position, len(data)))
+
+        bitmap_code = self._md5_file[fileid]['bitmap_code']
+        colorkey    = self._md5_file[fileid]['colorkey']
+        try:
+            t = self.def_bitmap(bitmap_code, data, *colorkey)
+        except BitmapCreationException, e:
+            log(str(e))
+            return #i.e. not attempting to create icons 
+        messages = []
+        if bitmap_code in self._def_icon_queue:
+            #log('%d icons queued for bitmap %d' % (
+            #    len(self._def_icon_queue[bitmap_code]), bitmap_code))
+            for t in self._def_icon_queue[bitmap_code]:
+                icon_code, x, y, w, h, rest = t
+                messages.append(self.def_icon(bitmap_code, icon_code, x, y, w, h, *rest))
+            del self._def_icon_queue[bitmap_code]
+        return messages
+    
+    def player_icon(self, player_id, icon_code):
+        #log('player_icon player_id=%d, icon_code=%d' % (player_id, icon_code))
+        return dict(type=PMSG_PLAYER_ICON, player_id=player_id, icon_code=icon_code)
+
+    def player_join(self, player_id, client_is_self):
+        #log('player_join player_id=%d, client_is_self=%d' % (player_id, client_is_self))
+        return dict(type=PMSG_PLAYER_JOIN, player_id=player_id, client_is_self=client_is_self)
+
+    def player_kill(self, player_id):
+        #log('player_kill player_id=%d' % player_id)
+        return dict(type=PMSG_PLAYER_KILL, player_id=player_id)
+
+    def def_key(self, keyname, num, *icon_codes):
+        #log('def_key keyname=%s, num=%d, icon_codes=%s' % (keyname, num, str(icon_codes)))
+        return dict(type=PMSG_DEF_KEY, keyname=keyname, num=num, icon_codes=icon_codes)
+
+    def md5_file(self, fileid, protofilepath, offset, len_data, checksum):
+        hd = '0123456789abcdef'
+        hexdigits = ''
+        for c in checksum:
+            i = ord(c)
+            hexdigits = hexdigits + hd[i >> 4] + hd[i & 15]
+        #log('md5_file fileid=%d, protofilepath=%s, offset=%d, len_data=%d, hexdigits=%s' % (
+        #    fileid, protofilepath, offset, len_data, hexdigits))
+        self._md5_file[fileid] = {
+            'protofilepath' : protofilepath,
+            'offset'        : offset,
+            'len_data'      : len_data,
+            'checksum'      : checksum,
+            'hexdigits'     : hexdigits,
+            }
+
+    def inline_frame(self, data):
+        decompressed_data = d = self.decompressobj(data)
+        #log('inline_frame len(data)=%d, len(decompressed_data)=%d' % (
+        #    len(data), len(d)))
+
+        return_raw_data = False
+        if return_raw_data:
+            return dict(type=PMSG_INLINE_FRAME, data=decompressed_data)
+
+        #note: we are not returning the raw data here but we could let the Javascript
+        #      handle it. If this is working we can convert this to RPython and move it
+        #      to the client instead. (based on BnB update_sprites in display/pclient.py)
+        sounds, sprites = [], []
+
+        base = 0
+        while d[base+4:base+6] == '\xFF\xFF':
+            key, lvol, rvol = struct.unpack("!hBB", udpdata[base:base+4])
+            sounds.append((key, lvol, rvol))
+            base += 6
+
+        for j in range(base, len(d)-5, 6):
+            info = d[j:j+6]
+            x, y, icon_code = unpack("!hhh", info[:6])
+            sprites.append((icon_code, x, y))
+
+        return dict(type=PMSG_INLINE_FRAME, sounds=sounds, sprites=sprites)
+
+    MESSAGES = {
+        MSG_BROADCAST_PORT : ignore,
+        MSG_PING           : ignore,
+        MSG_PONG           : ignore,
+        MSG_DEF_PLAYFIELD  : def_playfield,
+        MSG_DEF_BITMAP     : def_bitmap,
+        MSG_ZPATCH_FILE    : zpatch_file,
+        MSG_DEF_ICON       : def_icon,
+        MSG_PLAYER_ICON    : player_icon,
+        MSG_PLAYER_JOIN    : player_join,
+        MSG_PLAYER_KILL    : player_kill,
+        MSG_DEF_KEY        : def_key,
+        MSG_MD5_FILE       : md5_file,
+        MSG_INLINE_FRAME   : inline_frame,
+        }

Added: pypy/branch/flex-backend/translator/flex/examples/bnb/start_bnb.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/bnb/start_bnb.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,283 @@
+#!/usr/bin/env python
+""" bub-n-bros testing utility
+"""
+
+import autopath
+
+import py
+
+from pypy.translator.js.main import rpython2javascript
+from pypy.translator.js.modules.dom import document, window
+from pypy.translator.js.modules.mochikit import log, logWarning,\
+     createLoggingPane, logDebug, connect
+from pypy.translator.js.examples.bnb.bnb import exported_methods
+from pypy.translator.js import commproxy
+
+commproxy.USE_MOCHIKIT = True
+
+import time
+import os
+import sys
+
+def logKey(msg):
+    pass
+
+class Stats(object):
+    """ Class containing some statistics
+    """
+    def __init__(self):
+        self.n_received_inline_frames = 0
+        self.n_rendered_inline_frames = 0
+        self.n_rendered_dynamic_sprites = 0
+        self.fps = 0
+        self.starttime = 0.0
+        self.n_sprites = 0
+    
+    def register_frame(self):
+        self.n_rendered_inline_frames += 1
+        if self.n_rendered_inline_frames >= 10:
+            next_time = time.time()
+            self.fps = 10000/(next_time - self.starttime)
+            self.n_rendered_inline_frames = 0
+            self.starttime = next_time
+
+stats = Stats()
+
+class Player(object):
+    def __init__(self):
+        self.id = -1
+        self.prev_count = 0
+        self.sessionid = ""
+
+player = Player()
+
+class SpriteManager(object):
+    def __init__(self):
+        self.sprites = {}
+        self.filenames = {}
+        self.all_sprites = {}
+        self.frames = []
+
+    def add_icon(self, icon_code, filename):
+        self.filenames[icon_code] = filename
+        #self.sprite_queues[icon_code] = []
+        #self.used[icon_code] = []
+        # FIXME: Need to write down DictIterator once...
+        #self.icon_codes.append(icon_code)
+
+    def add_sprite(self, s, icon_code, x, y):
+        #try:
+        #    img = self.sprite_queues[icon_code].pop()
+        #except IndexError:
+        stats.n_sprites += 1
+        img = document.createElement("img")
+        img.src = self.filenames[icon_code]
+        img.style.position = 'absolute'
+        img.style.left = x + 'px'
+        img.style.top = y + 'px'
+        img.style.visibility = 'visible'
+        document.getElementById("playfield").appendChild(img)
+        try:
+            self.sprites[s].style.visibility = "hidden"
+            # FIXME: We should delete it
+        except KeyError:
+            self.sprites[s] = img
+        return img
+
+    def move_sprite(self, s, x, y):
+        i = self.sprites[s]
+        i.style.top = y + 'px'
+        i.style.left = x + 'px'
+        i.style.visibility = 'visible'
+
+    def hide_sprite(self, s):
+        i = self.sprites[s]
+        i.style.visibility = "hidden"
+    
+    def start_clean_sprites(self):
+        self.all_sprites = {}
+    
+    def show_sprite(self, s, icon_code, x, y):
+        self.all_sprites[s] = 1
+        try:
+            self.move_sprite(s, x, y)
+        except KeyError:
+            self.add_sprite(s, icon_code, x, y)
+    
+    def end_clean_sprites(self):
+        for i in self.sprites:
+            try:
+                self.all_sprites[i]
+            except KeyError:
+                self.hide_sprite(i)
+    
+    def set_z_index(self, s_num, z):
+        self.sprites[s_num].style.zIndex = z
+    
+    #def show_sprite(self, s):
+    #    i = self.sprites[s]
+    #    i.style.visibility = "visible"
+
+sm = SpriteManager()
+
+class KeyManager(object):
+    def __init__(self):
+        self.keymappings = {ord('D'):'right', ord('S'):'fire', ord('A'):'left', ord('W'):'up'}
+        self.key_to_bnb_down = {'right':0, 'left':1, 'fire':3, 'up':2}
+        self.key_to_bnb_up = {'right':4, 'left':5, 'fire':7, 'up':6}
+        self.queue = []
+            
+    def add_key_up(self, key):
+        self.queue.append(self.key_to_bnb_up[key])
+    
+    def add_key_down(self, key):
+        self.queue.append(self.key_to_bnb_down[key])
+
+    def get_keys(self):
+        retval = self.queue
+        self.queue = []
+        return retval
+    
+km = KeyManager()
+
+def appendPlayfield(msg):
+    body = document.getElementsByTagName('body')[0]
+    bgcolor = '#000'
+    body.style.backgroundColor = bgcolor
+    div = document.createElement("div")
+    div.id = 'playfield'
+    div.style.width = msg['width']
+    div.style.height = msg['height']
+    div.style.position = 'absolute'
+    div.style.top = '0px'
+    div.style.left = '0px'
+    div.appendChild(document.createTextNode('foobar?'))
+
+    #document.body.childNodes.insert(0, div)
+    body.appendChild(div)
+
+def appendPlayfieldXXX():
+    bgcolor = '#000000'
+    document.body.setAttribute('bgcolor', bgcolor)
+    div = document.createElement("div")
+    div.id = 'playfield'
+    div.style.width = 500
+    div.style.height = 250
+    div.style.position = 'absolute'
+    div.style.top = '0px'
+    div.style.left = '0px'
+    document.body.appendChild(div)
+
+def process_message(msg):
+    if msg['type'] == 'def_playfield':
+        appendPlayfield(msg)
+    elif msg['type'] == 'def_icon':
+        sm.add_icon(msg['icon_code'], msg['filename'])
+    elif msg['type'] == 'ns':
+        sm.add_sprite(msg['s'], msg['icon_code'], msg['x'], msg['y'])
+        sm.set_z_index(msg['s'], msg['z'])
+    elif msg['type'] == 'sm':
+        sm.move_sprite(msg['s'], msg['x'], msg['y'])
+        sm.set_z_index(msg['s'], msg['z'])
+    elif msg['type'] == 'ds':
+        sm.hide_sprite(msg['s'])
+    elif msg['type'] == 'begin_clean_sprites':
+        sm.start_clean_sprites()
+    elif msg['type'] == 'clean_sprites':
+        sm.end_clean_sprites()
+    elif msg['type'] == 'show_sprite':
+        sm.show_sprite(msg['s'], msg['icon_code'], msg['x'], msg['y'])
+    elif msg['type'] == 'zindex':
+        sm.set_z_index(msg['s'], msg['z'])
+    #elif msg['type'] == 'ss':
+    #    sm.show_sprite(msg['s'])
+    elif msg['type'] == 'player_icon' or msg['type'] == 'def_key' or \
+         msg['type'] == 'player_join' or msg['type'] == 'player_kill':
+        pass #ignore
+    else:
+        logWarning('unknown message type: ' + msg['type'])
+
+
+def ignore(arg):
+    pass
+ignore._annspecialcase_ = 'specialize:argtype(0)'
+
+def addPlayer(player_id):
+    name  = "player no. " + str(player_id)
+    #name  = "player no. %d" % player_id
+    #File "/Users/eric/projects/pypy-dist/pypy/translator/js/jts.py", line 52, in lltype_to_cts
+    #    raise NotImplementedError("Type %r" % (t,))
+    #    NotImplementedError: Type <StringBuilder>
+    prev_player_id = player.id
+    if player.id >= 0:
+        exported_methods.remove_player(player.id, player.sessionid, ignore)
+        player.id = -1
+    if player_id != prev_player_id:
+        exported_methods.player_name(player_id, name, player.sessionid, ignore)
+        exported_methods.add_player(player_id, player.sessionid, ignore)
+        player.id = player_id
+
+
+def keydown(key):
+    #c = chr(int(key.keyCode)).lower()
+    #c = int(key.keyCode)
+    key = key._event
+    try:
+        c = key.keyCode
+        if c > ord('0') and c < ord('9'):
+            addPlayer(int(chr(c)))
+        #for i in km.keymappings:
+        #    log(str(i))
+        if c in km.keymappings:
+            km.add_key_down(km.keymappings[c])
+        #else:
+    except Exception, e:
+        log(str(e))
+
+def keyup(key):
+    key = key._event
+    c = key.keyCode
+    if c > ord('0') and c < ord('9'):
+        pass    #don't print warning
+    elif c in km.keymappings:
+        km.add_key_up(km.keymappings[c])
+    else:
+        logWarning('unknown keyup: ' + str(c))
+    
+#def ignore_dispatcher(msgs):
+#    pass
+
+def bnb_dispatcher(msgs):
+    s = ":".join([str(i) for i in km.get_keys()])
+    exported_methods.get_message(player.sessionid, player.id, s,
+                                 bnb_dispatcher)
+    render_frame(msgs)
+
+def render_frame(msgs):
+    for msg in msgs['messages']:
+        process_message(msg)
+    stats.register_frame()
+    document.title = str(stats.n_sprites) + " sprites " + str(stats.fps)
+
+def session_dispatcher(sessionid):
+    player.sessionid = sessionid
+    connect(document, 'onkeydown', keydown)
+    connect(document, 'onkeyup', keyup)
+    exported_methods.get_message(player.sessionid, player.id, "",
+                                 bnb_dispatcher)
+
+def bnb():
+    createLoggingPane(True)
+    log("keys: [0-9] to select player, [wsad] to walk around")
+    exported_methods.initialize_session(session_dispatcher)
+
+def run_bnb():    
+    from pypy.translator.js.examples.bnb.bnb import BnbRoot
+    from pypy.translator.js.lib import server
+    addr = ('', 7070)
+    httpd = server.create_server(handler=BnbRoot, server_address=addr)
+    httpd.source = rpython2javascript(sys.modules[__name__], ['bnb'])
+    httpd.serve_forever()
+
+if __name__ == '__main__':
+    run_bnb()

Added: pypy/branch/flex-backend/translator/flex/examples/console/__init__.py
==============================================================================

Added: pypy/branch/flex-backend/translator/flex/examples/console/client.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/client.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,154 @@
+
+from pypy.translator.js.modules import dom
+from pypy.translator.js.modules.mochikit import log, createLoggingPane
+from pypy.translator.js.examples.console.console import exported_methods
+
+class Glob(object):
+    def __init__(self):
+        self.console_running = False
+        self.next_console = ""
+        self.text_to_show = []
+        self.pss = []
+
+glob = Glob()
+
+def add_text_to_dom(txt):
+    data_elem = dom.document.getElementById("data")
+    if data_elem.childNodes:
+        data = data_elem.childNodes[0].nodeValue + txt
+    else:
+        data = txt
+    while data_elem.childNodes:
+        data_elem.removeChild(data_elem.childNodes[0])
+    data_elem.appendChild(dom.document.createTextNode(data))
+
+
+def add_text(txt, server_flag, fn=add_text_to_dom):
+    if not server_flag:
+        if txt.find("\n") != len(txt) - 1:
+            if txt[-1] == '\n':
+                txt = txt[:-1]
+            lst = txt.split("\n")
+            add_text_to_dom(lst[0] + "\n")
+            glob.text_to_show += lst[1:]
+        else:
+            add_text_to_dom(txt)
+    else:
+        for ps in glob.pss:
+            if glob.text_to_show:
+                num = txt.find(ps)
+                if txt.startswith(ps):
+                    txt = txt[len(ps):]
+                    add_text_to_dom(ps + glob.text_to_show.pop(0) + "\n")
+                    add_text(txt, True)
+                    return
+                if txt.startswith("\n" + ps):
+                    txt = txt[len(ps) + 1:]
+                    add_text_to_dom(ps + glob.text_to_show.pop(0) + "\n")
+                    add_text(txt, True)
+                    return
+        add_text_to_dom(txt)
+
+def create_text(txt):
+    return dom.document.createTextNode(txt)
+
+def set_text(txt):
+    data_elem = dom.document.getElementById("data")
+    while data_elem.childNodes:
+        data_elem.removeChild(data_elem.childNodes[0])
+    data_elem.appendChild(dom.document.createTextNode(txt))    
+
+def refresh_console(msg):
+    inp_elem = dom.document.getElementById("inp")
+    #inp_elem.disabled = False
+    if msg[0] == "refresh":
+        data = msg[1]
+        if data:
+            inp_elem.scrollIntoView()
+        inp_elem.focus()
+        exported_methods.refresh_empty(glob.sess_id, refresh_console)
+        add_text(data, True)
+    elif msg[0] == 'disconnected':
+        inp_elem.disabled = True
+        name_bar = dom.document.getElementById("namebar")
+        name_bar.style.color = "red"
+        text = name_bar.lastChild.nodeValue
+        name_bar.removeChild(name_bar.lastChild)
+        name_bar.appendChild(create_text(text + " [DEFUNCT]"))
+        glob.console_running = False
+        if glob.next_console:
+            next = glob.next_console
+            glob.next_console = ""
+            load_console(next)
+
+def set_sessid(data):
+    sessid = int(data[0])
+    help_msg = data[1]
+    glob.pss = data[2:]
+    glob.sess_id = sessid
+    inp_elem = dom.document.getElementById("inp")
+    inp_elem.disabled = False 
+    name_bar = dom.document.getElementById("namebar")
+    name_bar.style.color = "black"
+    name_bar.removeChild(name_bar.lastChild)
+    name_bar.appendChild(create_text("Python console"))
+    dom.document.getElementById("helpcontents").innerHTML = help_msg
+    exported_methods.refresh_empty(sessid, refresh_console)
+
+def empty_callback(msg):
+    inp_elem = dom.document.getElementById("inp")
+    #inp_elem.disabled = False
+    inp_elem.scrollIntoView()
+
+def keypressed(key):
+    kc = key.keyCode
+    if kc == ord("\r"):
+        inp_elem = dom.document.getElementById("inp")
+        cmd = inp_elem.value
+        inp_elem.value = ''
+        add_text(cmd + "\n", False)
+        #if not cmd:
+        #    exported_methods.refresh(glob.sess_id, cmd, empty_callback)
+        #else:
+        exported_methods.refresh(glob.sess_id, cmd + "\n", refresh_console)
+
+def nothing(msg):
+    pass
+
+def nothing2(msg):
+    pass
+
+def cleanup_console():
+    inp_elem = dom.document.getElementById("inp")
+    inp_elem.disabled = True
+    set_text("")
+    glob.text_to_show = [] # better safe than sorry
+    exported_methods.kill_console(glob.sess_id, nothing2)
+
+def load_console(python="python"):
+    if glob.console_running:
+        cleanup_console()
+        glob.next_console = python
+        return
+    inp_elem = dom.document.getElementById("inp")
+    main = dom.document.getElementById("main")
+    main.style.visibility = "visible"
+    inp_elem.disabled = False
+    inp_elem.focus()
+    glob.console_running = True
+    exported_methods.get_console(python, set_sessid)
+
+def add_snippet(snippet):
+    add_text(snippet, False)
+    exported_methods.refresh(glob.sess_id, snippet, refresh_console)
+
+def execute_snippet(name='python', number=3):
+    exported_methods.execute_snippet(name, number, add_snippet)
+
+def console_onload():
+    #createLoggingPane(True)
+    #inp_elem = dom.document.getElementById("inp")
+    #inp_elem.focus()
+    dom.document.onkeypress = keypressed
+    #exported_methods.get_console("python", set_sessid)
+

Added: pypy/branch/flex-backend/translator/flex/examples/console/console.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/console.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,155 @@
+import py
+
+from pypy.translator.js.lib import server
+from pypy.translator.js.main import rpython2javascript
+from pypy.translator.js.lib.support import callback
+from pypy.translator.js import commproxy
+from pypy.translator.js.examples.console.session import Interpreter, Killed
+from pypy.translator.js.examples.console.docloader import DocLoader
+from py.__.green.server.httpserver import GreenHTTPServer
+from py.__.green.greensock2 import ConnexionClosed
+
+commproxy.USE_MOCHIKIT = True
+
+FUNCTION_LIST = ["load_console", "console_onload", "execute_snippet"]
+
+class Ignore(Exception):
+    pass
+
+def js_source():
+    import client
+    return rpython2javascript(client, FUNCTION_LIST)
+
+def line_split(ret, max_len):
+    to_ret = []
+    for line in ret.split("\n"):
+        if len(line) > max_len:
+            to_ret += [line[i*max_len:(i+1)*max_len] for i in
+                       range(len(line)/max_len)]
+            i = len(line)/max_len
+        else:
+            i = 0
+        to_ret.append(line[i*max_len:])
+    return "\n".join(to_ret)
+
+
+STATIC_DIR = py.path.local(__file__)
+for x in range(6):
+    STATIC_DIR = STATIC_DIR.dirpath()
+STATIC_DIR = STATIC_DIR.join("compiled")
+DOCDIR = STATIC_DIR.dirpath().join("pypy", "doc", "play1")
+CONSOLES = ['python', 'pypy-c', 'pypy-c-thunk', 'pypy-c-taint', 'pypy-cli', 'pyrolog-c', 'pypy-c-jit']
+
+class Sessions(object):
+    def __init__(self):
+        self.sessions = {}
+        self.updating = {}
+        testfile = py.path.local(__file__).dirpath().join("play1_snippets.py")
+        self.docloader = DocLoader(docdir=DOCDIR, consoles=CONSOLES,
+                                   testfile=testfile)
+
+    def new_session(self, python="python"):
+        if not py.path.local().sysfind(python):
+            python = str(STATIC_DIR.join(python))
+        ip = Interpreter(python)
+        self.sessions[ip.pid] = ip
+        self.updating[ip.pid] = False
+        return ip.pid
+
+    def update_session(self, pid, to_write=None):
+        ip = self.sessions[pid]
+        if self.updating[pid]:
+            ip.write_only(to_write)
+            raise Ignore()
+        self.updating[pid] = True
+        ret = ip.interact(to_write)
+        self.updating[pid] = False
+        if not ret:
+            return ""
+        MAX_LEN = 80
+        return line_split(ret, MAX_LEN)
+
+    def kill_session(self, pid):
+        ip = self.sessions[pid]
+        ip.pipe.stdin.close()
+        del self.sessions[pid]
+        del self.updating[pid]
+
+    def get_ps(self, python):
+        if python == 'python':
+            return ['>>> ', '... ']
+        if python.startswith('pypy'):
+            return ['>>>> ', '.... ']
+        if python == 'pyrolog-c':
+            return ['>?-']
+        return []
+
+# We hack here, cause in exposed methods we don't have global 'server'
+# state
+sessions = Sessions()
+
+class ExportedMethods(server.ExportedMethods):
+    @callback(retval=[str])
+    def get_console(self, python="python"):
+        retval = sessions.new_session(python)
+        return [str(retval), sessions.docloader.get_html(python)] +\
+               sessions.get_ps(python)
+
+    def _refresh(self, pid, to_write):
+        try:
+            return ["refresh", sessions.update_session(int(pid), to_write)]
+        except (KeyError, IOError, Killed, ConnexionClosed):
+            return ["disconnected"]
+        except Ignore:
+            return ["ignore"]        
+
+    @callback(retval=[str])
+    def refresh(self, pid=0, to_write=""):
+        return self._refresh(pid, to_write)
+
+    @callback(retval=[str])
+    def refresh_empty(self, pid=0):
+        #print "Empty refresh %d" % int(pid)
+        return self._refresh(pid, None)
+
+    @callback(retval=str)
+    def execute_snippet(self, name='aaa', number=3):
+        return sessions.docloader.get_snippet(name, int(number)) + "\n"
+
+    @callback()
+    def kill_console(self, pid=0):
+        try:
+            sessions.kill_session(int(pid))
+        except KeyError:
+            pass
+
+exported_methods = ExportedMethods()
+
+static_dir = py.path.local(__file__).dirpath().join("data")
+
+class Root(server.Collection):
+    exported_methods = exported_methods
+    index = server.FsFile(static_dir.join("console.html"))
+    style_css = server.FsFile(static_dir.dirpath().dirpath().join("data").
+                              join("style.css"))
+    MochiKit = server.StaticDir('MochiKit')
+
+    def source_js(self):
+        if hasattr(self.server, 'source_console'):
+            source = self.server.source_console
+        else:
+            source = js_source()
+            self.server.source_console = source
+        return "text/javascript", source
+    source_js.exposed = True
+
+class Handler(server.NewHandler):
+    application = Root()
+    application.some = Root()
+    application.other = Root()
+
+if __name__ == '__main__':
+    addr = ('', 8007)
+    httpd = server.create_server(server_address=addr, handler=Handler,
+                                 server=GreenHTTPServer)
+    httpd.serve_forever()

Added: pypy/branch/flex-backend/translator/flex/examples/console/data/console.html
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/data/console.html	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,43 @@
+<html>
+<head>
+   <script type="text/javascript" src="source.js"></script>
+   <script src="http://mochikit.com/MochiKit/MochiKit.js" type="text/javascript"></script>
+   <script src="source.js"></script>
+   <link href="style.css" media="screen" rel="stylesheet" type="text/css"/>
+   <title>Console</title>
+</head>
+<body onload="console_onload()">
+  <a id="mainlink" href="http://codespeak.net/pypy/"><img alt="PyPy" height="110" id="pyimg" src="/py_web1.png" width="149"/></a>
+  <div id="metaspace">
+    <h1 class="title">PyPy[consoles]</h1>
+    <div class="menubar">
+      <a href="/console">Python consoles</a> - <a href="http://play1.codespeak.net:8058/">ANSI terminal</a> - <a href="/bnb">Bub'n'Bros JavaScript version</a>
+    </div>
+  </div>
+  <div id="contents">
+     <ul>
+       <li><a href="javascript:load_console('python')">Plain CPython console</a></li>
+       <li><a href="javascript:load_console('pypy-c')">pypy-c with stackless and transparent proxy</a></li>
+       <li><a href="javascript:load_console('pypy-c-thunk')">pypy-c with thunk objspace</a></li>
+       <li><a href="javascript:load_console('pypy-c-taint')">pypy-c with taint objspace</a></li>
+       <li><a href="javascript:load_console('pypy-c-jit')">pypy-c with jit</a></li>
+       <li><a href="javascript:load_console('pypy-cli')">pypy-cli</a></li>
+       <li><a href="javascript:load_console('pyrolog-c')">pyrolog-c</a></li>
+       <li><b><a href="javascript:cleanup_console()">kill console</a></b></li>
+     </ul>
+  </div>
+  <div style="visibility:hidden" id="main">
+     <fieldset>
+       <legend><b id="namebar">Python console</b></legend>
+       <pre id="data"></pre>
+       &gt;&gt;&gt; <input id="inp" size="80" type="text" autocomplete="off"/>
+     </fieldset>
+     <fieldset id="help">
+       <legend><b>Help box</b></legend> 
+       <p id="helpcontents">
+       </p>
+     </fieldset>
+     <p id="error"></p>
+  </div>
+</body>
+</html>

Added: pypy/branch/flex-backend/translator/flex/examples/console/docloader.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/docloader.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,43 @@
+
+""" Simple module for loading documentation of various
+pypy-cs from doc directory
+"""
+
+import py
+
+class DocLoader(object):
+    def __init__(self, consoles, docdir, testfile):
+        self.consoles = consoles
+        self.docdir = py.path.local(docdir)
+        assert self.docdir.check(dir=1)
+        self.testfile = testfile
+        assert self.testfile.check()
+        self.htmls = {}
+        self.snippets = {}
+        self.load()
+
+    def get_html(self, console):
+        return self.htmls[console]
+
+    def get_snippet(self, console, num):
+        return str(self.snippets[console][num])
+
+    def load(self):
+        def mangle_name(name):
+            return name.replace("-", "_").replace(".", "_")
+
+        def mangle(source):
+            source = source.strip()
+            del source.lines[0]
+            return source.deindent()
+        
+        testmod = self.testfile.pyimport()
+        for console in self.consoles:
+            html = self.docdir.join(console + '.html').read()
+            snip_class = getattr(testmod, 'AppTest_' + mangle_name(console))
+            snippets = [mangle(py.code.Source(getattr(snip_class, name)))
+                        for name in
+                        dir(snip_class) if name.startswith("test_snippet")]
+            self.snippets[console] = snippets
+            self.htmls[console] = html % tuple([str(i) for i in snippets])
+

Added: pypy/branch/flex-backend/translator/flex/examples/console/ideas.txt
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/ideas.txt	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,11 @@
+* Thunk objspace - lazy evaluation in demo/fibonacci2 or sth
+
+* Taint objspace - examples in the documentation
+
+* Transparent proxy
+
+* Stackless - examples in a docs of stackless/WP7
+
+* __pypy__.internal_repr - --faassen, ropes
+
+* changing grammar at the runtime

Added: pypy/branch/flex-backend/translator/flex/examples/console/play1_snippets.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/play1_snippets.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,82 @@
+from pypy.conftest import gettestobjspace
+
+class AppTest_pypy_c(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
+            "usemodules":("_stackless",)})
+        
+    def test_snippet_1(self):
+        from tputil import make_proxy
+        history = []
+        def recorder(operation):
+            history.append(operation) 
+            return operation.delegate()
+
+        l = make_proxy(recorder, obj=[])
+
+class AppTest_pypy_c_thunk(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{"objspace.name": 'thunk'})
+
+    def test_snippet_1(self):
+        from __pypy__ import thunk
+        def f():
+            print 'computing...'
+            return 6*7
+
+        x = thunk(f)
+
+class AppTest_pypy_c_taint(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{'objspace.name': 'taint'})
+
+    def test_snippet_1(self):
+        from __pypy__ import taint
+        x = taint(6)
+
+class AppTest_pypy_cli(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{'usemodules': 'clr'})
+
+    def test_snippet_1(self):
+        import clr
+        ArrayList = clr.load_cli_class('System.Collections', 'ArrayList')
+        obj = ArrayList()
+        obj.Add(1)
+
+class AppTest_pyrolog_c(object):
+    pass
+
+class AppTest_python(object):
+    pass
+
+class AppTest_pypy_c_jit(object):
+    def setup_class(cls):
+        cls.space = gettestobjspace(**{'usemodules':('pypyjit',)})
+
+    def test_snippet_1(self):
+        import time
+        
+        def f1(n):
+            "Arbitrary test function."
+            i = 0
+            x = 1
+            while i<n:
+                j = 0
+                while j<=i:
+                    j = j + 1
+                    x = x + (i&j)
+                i = i + 1
+            return x
+
+        def test_f1():
+            res = f1(211)
+            print "running..."
+            N = 5
+            start = time.time()
+            for i in range(N):
+                assert f1(211) == res
+            end = time.time()
+            print '%d iterations, time per iteration: %s' % (N, (end-start)/N)
+
+        import pypyjit

Added: pypy/branch/flex-backend/translator/flex/examples/console/session.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/session.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,101 @@
+
+""" In this file we define all necessary stuff
+build around subprocess to run python console in it
+"""
+
+KILL_TIMEOUT = 300
+TIMEOUT = 10
+
+""" The idea behind is that we create xmlhttprequest immediataly
+and reply with new data (if available) or reply anyway
+after TIMEOUT
+"""
+
+import py
+import subprocess
+from Queue import Queue
+from py.__.green.greensock2 import autogreenlet, Timer, Interrupted,\
+     meetingpoint
+from py.__.green.pipe.fd import FDInput
+from py.magic import greenlet
+import time
+
+class Killed(Exception):
+    pass
+
+class Interpreter(object):
+    def __init__(self, python, timeout=TIMEOUT, kill_timeout=KILL_TIMEOUT):
+        pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE,
+                            stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
+                            close_fds=True, bufsize=0)
+        self.pipe = pipe
+        self.read_fd = FDInput(self.pipe.stdout.fileno(), close=False)
+        self.pid = pipe.pid
+        self.timeout = timeout
+        #self.kill_timeout = kill_timeout
+        self.giver, accepter = meetingpoint()
+        autogreenlet(self.timeout_kill, accepter, kill_timeout)
+        #self.last_activity = time.time()
+
+    def timeout_kill(self, accepter, timeout):
+        while 1:
+            try:
+                self.kill_timer = Timer(timeout)
+                accepter.accept()
+                self.kill_timer.stop()
+            except Interrupted:
+                self.close()
+                return
+
+    def timeout_read(self, fd, timeout):
+        timer = Timer(timeout)
+        try:
+            data = fd.recv(10024)
+        except Interrupted:
+            data = None
+        else:
+            timer.stop()
+        return data
+
+    def write_only(self, to_write):
+        if to_write is not None:
+            self.giver.give(42)
+            self.pipe.stdin.write(to_write)
+
+    def interact(self, to_write=None):
+        self.write_only(to_write)
+        return self.timeout_read(self.read_fd, self.timeout)
+
+    def close(self):
+        self.pipe.stdin.close()
+        # XXX: some sane way of doing wait here? (note that wait
+        #      is blocking, which means it eats all our clean interface)
+        self.pipe.wait()
+
+    __del__ = close
+
+class InterpreterManager(object):
+    pass
+
+#class Sessions(object):
+#    def __init__(self):
+#        self.sessions = {}
+
+#    def new_session(self, python="python"):
+#        pipe = run_console(python)
+#        self.sessions[pipe.pid] = pipe
+#        return pipe.pid
+
+#    def update_session(self, pid, to_write=None):
+#        pipe = self.sessions[pid]
+#        return interact(pipe, to_write)
+
+
+#def interact(pipe, to_write=None):
+#    if to_write is not None:
+#        pipe.stdin.write(to_write + "\n")
+#    try:
+#        return pipe.stdout.read()
+#    except IOError:
+#        time.sleep(.1)
+#        return ""

Added: pypy/branch/flex-backend/translator/flex/examples/console/test/test_console.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-backend/translator/flex/examples/console/test/test_console.py	Sat Jul 14 11:58:08 2007
@@ -0,0 +1,26 @@
+
+import py
+
+def test_line_skip():
+    from pypy.translator.js.examples.console.console import line_split
+    assert line_split("asdf", 80) == "asdf"
+    assert line_split("a b c d", 3) == "a b\n c \nd"
+    assert line_split("a b c d e f g h i j", 3) == "a b\n c \nd e\n f \ng h\n i \nj"
+
+def test_run_console():
+    """ Check if we can read anything
+    """
+    import py
+    py.test.skip("XXX")
+
+    from pypy.translator.js.examples.console import console
+    pipe = console.run_console("python")
+    pipe.stdin.close()
+    t = False
+    while not t:
+        try:
+            d = pipe.stdout.read()
+            t = True
+        except IOError:
+            import time
+            time.sleep(.1)

Added: pypy/branch/flex-backend/translator/flex/examples/console/test/test_docloader.py
==============================================================================
--- (empty file)
+++ pypy/branch/flex-b