[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>
+ >>> <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