diff --git a/README.md b/README.md index 27f64f7..db3e43f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,37 @@ Introduction ------------ -PythonJS is a transpiler written in Python that converts Python into fast JavaScript. It can be run with regular Python, or fully self-hosted within NodeJS using Empythoned. PythonJS has been designed with speed and easy integration with existing JavaScript code in mind. +PythonJS is a transpiler written in Python that converts a python like language into fast +JavaScript. It also includes experimental backends that translate to: Dart, Lua, CoffeeScript, and Go. -Installing +[Syntax Documentation](https://github.com/PythonJS/PythonJS/blob/master/doc/syntax.md) + + +Go backend +---------- +The Go backend uses a fully typed subset of Python, mixed with extra syntax inspired by Golang to output Go programs that can be compiled to native executeables, or translated to JavaScript using GopherJS. + +[Syntax Documentation](https://github.com/PythonJS/PythonJS/blob/master/doc/go_syntax.md) + + +Getting Started +=============== +PythonJS can be run with regular Python, or fully self-hosted within +NodeJS using Empythoned. + +To get started, you have two options: +1. install NodeJS, python-js package, and write a build script. +2. or install Python2 and use translator.py from this repo directly. + + +1. Installing NodeJS Package ------------- - npm install python-js +You can quickly get started with the stable version of PythonJS by installing the NodeJS package, +and writing a build script in javascript to compile your python scripts to javascript. +(Python2.7 is not required) + +``` +npm install python-js +``` NodeJS Quick Example -------------- @@ -17,28 +44,45 @@ eval( pythonjs.runtime.javascript + jscode ); ``` -JavaScript API ----------- -``` -var pythonjs, output; -pythonjs = require('python-js'); -output = pythonjs.translator.to_javascript( input ); -output = pythonjs.translator.to_javascript_module( input ); -output = pythonjs.translator.to_dart( input ); -output = pythonjs.translator.to_coffee( input ); -output = pythonjs.translator.to_lua( input ); - -pythonjs.runtime.javascript // runtime required by translator output - -``` Example Projects ---------------- +The example projects below, require the NodeJS python-js package. + [https://github.com/PythonJS/pythonjs-demo-server-nodejs](https://github.com/PythonJS/pythonjs-demo-server-nodejs) [https://github.com/PythonJS/pypubjs](https://github.com/PythonJS/pypubjs) + +2. translator.py +-------------------------------------- +If you want to run the latest version of the translator, you will need to install +Python2.7 and git clone this repo. (the NodeJS package above is not required) +Then, to translate your python script, directly run the `translator.py` script in the "pythonjs" directory. You can give it a list of python files to translate at once. +It will output the translation to stdout. The default output type is JavaScript. +An html file can also be used as input, python code inside a script tag: `') + if script is True: + self._html_tail.extend( o ) + else: + for y in o: + writer.write(y) + + else: + writer.write(line) + + elif line.strip() == '': + if type(script) is list and len(script): + source = '\n'.join(script) + script = True + self._html_tail.append( '') + else: + writer.write( line ) + + elif isinstance( script, list ): + script.append( line ) + + elif script is True: + self._html_tail.append( line ) + + else: + writer.write( line ) source = typedpython.transform_source( source ) - super(PythonToPythonJS, self).__init__() self.setup_inliner( writer ) - self._direct_operators = set() ## optimize "+" operator + self._in_catch_exception = False + + self._line = None + self._line_number = 0 + self._stack = [] ## current path to the root + + self._direct_operators = set() ## optimize "+" and "*" operator self._with_ll = False ## lowlevel - self._with_lua = lua - self._with_coffee = coffee - self._with_dart = dart - self._with_js = False + self._with_js = True self._in_lambda = False self._in_while_test = False self._use_threading = False @@ -144,6 +211,11 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._with_webworker = False self._with_rpc = None self._with_rpc_name = None + self._with_direct_keys = False + + self._with_glsl = False + self._in_gpu_main = False + self._gpu_return_types = set() ## 'array' or float32, or array of 'vec4' float32's. self._source = source.splitlines() self._classes = dict() ## class name : [method names] @@ -152,15 +224,19 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._class_attributes = dict() self._catch_attributes = None self._typedef_vars = dict() + #self._names = set() ## not used? + ## inferred class instances, TODO regtests to confirm that this never breaks ## self._instances = dict() ## instance name : class name + self._decorator_properties = dict() self._decorator_class_props = dict() self._function_return_types = dict() self._return_type = None - self._module = module - self._module_path = module_path ## DEPRECATED - self._typedefs = dict() ## class name : typedef (not pickled) + + + self._module = module ## DEPRECATED + self._typedefs = dict() ## class name : typedef (deprecated - part of the old static type finder) self._globals = dict() self._global_nodes = dict() @@ -173,7 +249,7 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._js_classes = dict() self._in_js_class = False self._in_assign_target = False - self._with_runtime_exceptions = True + self._with_runtime_exceptions = True ## this is only used in full python mode. self._iter_ids = 0 self._addop_ids = 0 @@ -183,6 +259,9 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._comprehensions = [] self._generator_functions = set() + self._in_loop_with_else = False + self._introspective_functions = False + self._custom_operators = {} self._injector = [] ## advanced meta-programming hacks self._in_class = None @@ -220,8 +299,14 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe self._source = source.splitlines() + if '--debug--' in sys.argv: + try: + tree = ast.parse( source ) + except SyntaxError: + raise SyntaxError(source) + else: + tree = ast.parse( source ) - tree = parse( source ) ## ast.parse self._generator_function_nodes = collect_generator_functions( tree ) for node in tree.body: @@ -231,6 +316,20 @@ def __init__(self, source=None, module=None, module_path=None, dart=False, coffe else: self.visit(node) + if self._html_tail: + for line in self._html_tail: + writer.write(line) + + def visit(self, node): + """Visit a node.""" + ## modified code of visit() method from Python 2.7 stdlib + self._stack.append(node) + method = 'visit_' + node.__class__.__name__ + visitor = getattr(self, method, self.generic_visit) + res = visitor(node) + self._stack.pop() + return res + def has_webworkers(self): return len(self._webworker_functions.keys()) @@ -287,9 +386,10 @@ def get_typedef(self, instance=None, class_name=None): if class_name: #assert class_name in self._classes if class_name not in self._classes: - log('ERROR: class name not in self._classes: %s'%class_name) - log('self._classes: %s'%self._classes) - raise RuntimeError('class name: %s - not found in self._classes - node:%s '%(class_name, instance)) + #log('ERROR: class name not in self._classes: %s'%class_name) + #log('self._classes: %s'%self._classes) + #raise RuntimeError('class name: %s - not found in self._classes - node:%s '%(class_name, instance)) + return None ## TODO hook into self._typedef_vars if class_name not in self._typedefs: self._typedefs[ class_name ] = Typedef( @@ -324,7 +424,9 @@ def visit_Import(self, node): tornado = ['tornado', 'tornado.web', 'tornado.ioloop'] for alias in node.names: - if alias.name in tornado: + if self._with_go: + writer.write('import %s' %alias.name) + elif alias.name in tornado: pass ## pythonjs/fakelibs/tornado.py elif alias.name == 'tempfile': pass ## pythonjs/fakelibs/tempfile.py @@ -332,6 +434,8 @@ def visit_Import(self, node): pass ## pythonjs/fakelibs/sys.py elif alias.name == 'subprocess': pass ## pythonjs/fakelibs/subprocess.py + elif alias.name == 'numpy': + pass elif alias.name == 'json' or alias.name == 'os': pass ## part of builtins.py @@ -346,12 +450,14 @@ def visit_Import(self, node): writer.write( 'if __NODEJS__==True and typeof(Worker)=="undefined": Worker = require("workerjs")') elif alias.asname: - writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.asname, alias.name) ) + #writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.asname, alias.name) ) + writer.write( '''inline("var %s = require('%s')")''' %(alias.asname, alias.name.replace('__DASH__', '-')) ) elif '.' in alias.name: raise NotImplementedError('import with dot not yet supported: line %s' % node.lineno) else: - writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.name, alias.name) ) + #writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.name, alias.name) ) + writer.write( '''inline("var %s = require('%s')")''' %(alias.name, alias.name) ) def visit_ImportFrom(self, node): if self._with_dart: @@ -361,11 +467,18 @@ def visit_ImportFrom(self, node): else: lib = ministdlib.JS + path = os.path.join( self._module_path, node.module+'.py') + if node.module == 'time' and node.names[0].name == 'sleep': self._use_sleep = True elif node.module == 'array' and node.names[0].name == 'array': self._use_array = True ## this is just a hint that calls to array call the builtin array + elif node.module == 'bisect' and node.names[0].name == 'bisect': + ## bisect library is part of the stdlib, + ## in pythonjs it is a builtin function defined in builtins.py + pass + elif node.module in lib: imported = False for n in node.names: @@ -379,12 +492,21 @@ def visit_ImportFrom(self, node): if n.name not in self._builtin_functions: self._builtin_functions[ n.name ] = n.name + '()' - elif node.module.startswith('nodejs.'): ## TODO - DEPRECATE - ## this import syntax is now used to import NodeJS bindings see: PythonJS/nodejs/bindings - ## the helper script (nodejs.py) checks for these import statements, and loads the binding, - pass + elif os.path.isfile(path): + ## user import `from mymodule import *` TODO support files from other folders + ## this creates a sub-translator, because they share the same `writer` object (a global), + ## there is no need to call `writer.write` here. + ## note: the current pythonjs.configure mode here maybe different from the subcontext. + data = open(path, 'rb').read() + subtrans = PythonToPythonJS( + data, + module_path=self._module_path + ) + self._js_classes.update( subtrans._js_classes ) ## TODO - what other typedef info needs to be copied here? + else: - raise SyntaxError( 'invalid import - %s' %node.module ) + msg = 'invalid import - file not found: %s/%s.py'%(self._module_path,node.module) + raise SyntaxError( self.format_error(msg) ) def visit_Assert(self, node): ## hijacking "assert isinstance(a,A)" as a type system ## @@ -402,23 +524,23 @@ def visit_Dict(self, node): if isinstance(v, ast.Lambda): v.keep_as_lambda = True v = self.visit( v ) - if self._with_js: - a.append( '[%s,%s]'%(k,v) ) - elif self._with_dart or self._with_ll: + if self._with_dart or self._with_ll or self._with_go: a.append( '%s:%s'%(k,v) ) #if isinstance(node.keys[i], ast.Str): # a.append( '%s:%s'%(k,v) ) #else: # a.append( '"%s":%s'%(k,v) ) + elif self._with_js: + a.append( '[%s,%s]'%(k,v) ) else: a.append( 'JSObject(key=%s, value=%s)'%(k,v) ) ## this allows non-string keys - if self._with_js: - b = ','.join( a ) - return '__jsdict( [%s] )' %b - elif self._with_dart or self._with_ll: + if self._with_dart or self._with_ll or self._with_go: b = ','.join( a ) return '{%s}' %b + elif self._with_js: + b = ','.join( a ) + return '__jsdict( [%s] )' %b else: b = '[%s]' %', '.join(a) return '__get__(dict, "__call__")([], {"js_object":%s})' %b @@ -484,7 +606,11 @@ def visit_ListComp(self, node): a = ['get%s'%i for i in range(length)] writer.write('var( %s )' %','.join(a) ) - writer.write('%s = JSArray()'%cname) + if self._with_go: + assert node.go_listcomp_type + writer.write('%s = __go__array__(%s)' %(cname, node.go_listcomp_type)) + else: + writer.write('%s = JSArray()'%cname) generators = list( node.generators ) generators.reverse() @@ -541,6 +667,8 @@ def _gen_comp(self, generators, node): writer.write('%s.add( %s )' %(cname,self.visit(node.elt)) ) elif self._with_lua: writer.write('table.insert(%s, %s )' %(cname,self.visit(node.elt)) ) + elif self._with_go: + writer.write('%s = append(%s, %s )' %(cname, cname,self.visit(node.elt)) ) else: writer.write('%s.push( %s )' %(cname,self.visit(node.elt)) ) writer.pull() @@ -550,6 +678,8 @@ def _gen_comp(self, generators, node): writer.write('%s.add( %s )' %(cname,self.visit(node.elt)) ) elif self._with_lua: writer.write('table.insert(%s, %s )' %(cname,self.visit(node.elt)) ) + elif self._with_go: + writer.write('%s = append(%s, %s )' %(cname, cname,self.visit(node.elt)) ) else: writer.write('%s.push( %s )' %(cname,self.visit(node.elt)) ) if self._with_lua: @@ -570,6 +700,11 @@ def visit_NotIn(self, node): #return ' not in ' raise RuntimeError('"not in" is only allowed in if-test: see method - visit_Compare') + ## TODO check if the default visit_Compare always works ## + #def visit_Compare(self, node): + # raise NotImplementedError( node ) + + def visit_AugAssign(self, node): self._in_assign_target = True target = self.visit( node.target ) @@ -658,9 +793,13 @@ def visit_AugAssign(self, node): raise NotImplementedError b = '%s %s %s' %(target, op, self.visit(node.value)) - ## dart2js is smart enough to optimize this if/else away ## - writer.write('if instanceof(%s, Number) or instanceof(%s, String): %s' %(target,target,b) ) - writer.write('else: %s' %a) + if isinstance( node.target, ast.Name ) and node.target.id in self._typedef_vars and self._typedef_vars[node.target.id] in typedpython.native_number_types+typedpython.vector_types: + writer.write(b) + + else: + ## dart2js is smart enough to optimize this if/else away ## + writer.write('if instanceof(%s, Number) or instanceof(%s, String): %s' %(target,target,b) ) + writer.write('else: %s' %a) elif self._with_js: ## no operator overloading in with-js mode a = '%s %s %s' %(target, op, self.visit(node.value)) @@ -680,8 +819,21 @@ def visit_AugAssign(self, node): # writer.write(a %(name, slice, op, self.visit(node.value))) #else: op = self.visit(node.op) - a = '__get__(%s, "__setitem__")( [%s, __get__(%s, "__getitem__")([%s], {}) %s (%s)], {} )' - writer.write(a %(name, slice, name, slice, op, self.visit(node.value))) + value = self.visit(node.value) + #a = '__get__(%s, "__setitem__")( [%s, __get__(%s, "__getitem__")([%s], {}) %s (%s)], {} )' + fallback = '__get__(%s, "__setitem__")( [%s, __get__(%s, "__getitem__")([%s], {}) %s (%s)], {} )'%(name, slice, name, slice, op, value) + if isinstance(node.target.value, ast.Name): + ## TODO also check for arr.remote (RPC) if defined then __setitem__ can not be bypassed + + ## the overhead of checking if target is an array, + ## and calling __setitem__ directly bypassing a single __get__, + ## is greather than simply calling the fallback + #writer.write('if instanceof(%s, Array): %s.__setitem__([%s, %s[%s] %s (%s) ], __NULL_OBJECT__)' %(name, name, slice, name,slice, op, value)) + + writer.write('if instanceof(%s, Array): %s[%s] %s= %s' %(name, name,slice, op, value)) + writer.write('else: %s' %fallback) + else: + writer.write(fallback) else: ## TODO extra checks to make sure the operator type is valid in this context @@ -709,6 +861,8 @@ def _visit_dart_classdef(self, node): methods = {} method_list = [] ## getter/setters can have the same name props = set() + struct_types = dict() + for item in node.body: if isinstance(item, FunctionDef): methods[ item.name ] = item @@ -726,7 +880,18 @@ def _visit_dart_classdef(self, node): if n.id == 'self': n.id = 'this' - if props: + elif isinstance(item, ast.Expr) and isinstance(item.value, ast.Dict): + sdef = [] + for i in range( len(item.value.keys) ): + k = self.visit( item.value.keys[ i ] ) + v = self.visit( item.value.values[i] ) + sdef.append( '%s=%s'%(k,v) ) + + writer.write('@__struct__(%s)' %','.join(sdef)) + + if self._with_go: + pass + elif props: writer.write('@properties(%s)'%','.join(props)) for dec in node.decorator_list: writer.write('@%s'%self.visit(dec)) @@ -749,7 +914,8 @@ def _visit_dart_classdef(self, node): ## constructor if init: methods.pop( '__init__' ) - init.name = node.name + if not self._with_go: + init.name = node.name self.visit(init) ## methods @@ -767,22 +933,45 @@ def _visit_dart_classdef(self, node): writer.pull() + def is_gpu_method(self, n): + for dec in n.decorator_list: + if isinstance(dec, Attribute) and isinstance(dec.value, Name) and dec.value.id == 'gpu': + if dec.attr == 'method': + return True + + def _visit_js_classdef(self, node): name = node.name - log('JavaScript-ClassDef: %s'%name) self._js_classes[ name ] = node self._in_js_class = True + class_decorators = [] + gpu_object = False + + for decorator in node.decorator_list: ## class decorators + if isinstance(decorator, Attribute) and isinstance(decorator.value, Name) and decorator.value.id == 'gpu': + if decorator.attr == 'object': + gpu_object = True + else: + raise SyntaxError( self.format_error('invalid gpu class decorator') ) + else: + class_decorators.append( decorator ) + method_names = [] ## write back in order (required by GLSL) methods = {} class_vars = [] + for item in node.body: if isinstance(item, FunctionDef): + method_names.append(item.name) methods[ item.name ] = item - item.args.args = item.args.args[1:] ## remove self - finfo = inspect_function( item ) - for n in finfo['name_nodes']: - if n.id == 'self': - n.id = 'this' + if self.is_gpu_method( item ): + item.args.args[0].id = name ## change self to the class name, pythonjs.py changes it to 'ClassName self' + else: + item.args.args = item.args.args[1:] ## remove self + finfo = inspect_function( item ) + for n in finfo['name_nodes']: + if n.id == 'self': + n.id = 'this' elif isinstance(item, ast.Expr) and isinstance(item.value, Str): ## skip doc strings pass else: @@ -794,6 +983,8 @@ def _visit_js_classdef(self, node): if init: args = [self.visit(arg) for arg in init.args.args] node._cached_init = init + if init.args.kwarg: + args.append( init.args.kwarg ) else: args = [] @@ -805,6 +996,11 @@ def _visit_js_classdef(self, node): writer.write('def %s(%s):' %(name,','.join(args))) writer.push() if init: + tail = '' + if gpu_object: + tail = 'this.__struct_name__="%s"' %name + + #for b in init.body: # line = self.visit(b) # if line: writer.write( line ) @@ -812,10 +1008,10 @@ def _visit_js_classdef(self, node): if hasattr(init, '_code'): ## cached ## code = init._code elif args: - code = '%s.__init__(this, %s)'%(name, ','.join(args)) + code = '%s.__init__(this, %s); %s'%(name, ','.join(args), tail) init._code = code else: - code = '%s.__init__(this)'%name + code = '%s.__init__(this); %s'%(name, tail) init._code = code writer.write(code) @@ -835,16 +1031,31 @@ def _visit_js_classdef(self, node): writer.write('%s.__uid__ = "" + _PythonJS_UID' %name) writer.write('_PythonJS_UID += 1') - keys = methods.keys() - keys.sort() - for mname in keys: + #keys = methods.keys() + #keys.sort() + for mname in method_names: method = methods[mname] - writer.write('@%s.prototype'%name) - line = self.visit(method) - if line: writer.write( line ) - #writer.write('%s.prototype.%s = %s'%(name,mname,mname)) - f = 'function () { return %s.prototype.%s.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }' %(name, mname) - writer.write('%s.%s = JS("%s")'%(name,mname,f)) + gpu_method = False + for dec in method.decorator_list: + if isinstance(dec, Attribute) and isinstance(dec.value, Name) and dec.value.id == 'gpu': + if dec.attr == 'method': + gpu_method = True + + if gpu_method: + method.name = '%s_%s' %(name, method.name) + self._in_gpu_method = name ## name of class + line = self.visit(method) + if line: writer.write( line ) + self._in_gpu_method = None + + else: + + writer.write('@%s.prototype'%name) + line = self.visit(method) + if line: writer.write( line ) + #writer.write('%s.prototype.%s = %s'%(name,mname,mname)) + f = 'function () { return %s.prototype.%s.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }' %(name, mname) + writer.write('%s.%s = JS("%s")'%(name,mname,f)) for base in node.bases: base = self.visit(base) @@ -866,6 +1077,9 @@ def _visit_js_classdef(self, node): self.visit(item) # this will output the code for the assign writer.write('%s.prototype.%s = %s' % (name, item_name, item.targets[0].id)) + if gpu_object: + ## TODO check class variables ## + writer.write('%s.prototype.__struct_name__ = "%s"' %(name,name)) ## TODO support property decorators in javascript-mode ## writer.write('%s.prototype.__properties__ = {}' %name) @@ -875,7 +1089,7 @@ def _visit_js_classdef(self, node): self._in_js_class = False def visit_ClassDef(self, node): - if self._with_dart: + if self._with_dart or self._with_go: self._visit_dart_classdef(node) return elif self._with_js: @@ -883,7 +1097,6 @@ def visit_ClassDef(self, node): return name = node.name - log('ClassDef: %s'%name) self._in_class = name self._classes[ name ] = list() ## method names self._class_parents[ name ] = set() @@ -893,19 +1106,17 @@ def visit_ClassDef(self, node): self._decorator_class_props[ name ] = self._decorator_properties self._instances[ 'self' ] = name + self._injector = [] ## DEPRECATED class_decorators = [] - self._injector = [] + gpu_object = False + for decorator in node.decorator_list: ## class decorators - if isinstance(decorator, Attribute) and isinstance(decorator.value, Name) and decorator.value.id == 'pythonjs': - if decorator.attr == 'property_callbacks': - self._injector.append('set') - elif decorator.attr == 'init_callbacks': - self._injector.append('init') + if isinstance(decorator, Attribute) and isinstance(decorator.value, Name) and decorator.value.id == 'gpu': + if decorator.attr == 'object': + gpu_object = True else: - raise SyntaxError( 'unsupported pythonjs class decorator' ) - + raise SyntaxError( self.format_error('invalid gpu class decorator') ) else: - #raise SyntaxError( 'unsupported class decorator' ) class_decorators.append( decorator ) ## always catch attributes ## @@ -934,11 +1145,15 @@ def visit_ClassDef(self, node): self._classes[ name ].append( item.name ) item_name = item.name item.original_name = item.name - item.name = '__%s_%s' % (name, item_name) + + if self.is_gpu_method( item ): + item.name = '%s_%s' % (name, item_name) + else: + item.name = '__%s_%s' % (name, item_name) self.visit(item) # this will output the code for the function - if item_name in self._decorator_properties: + if item_name in self._decorator_properties or self.is_gpu_method( item ): pass else: writer.write('__%s_attrs.%s = %s' % (name, item_name, item.name)) @@ -985,9 +1200,11 @@ def visit_ClassDef(self, node): self._in_class = False writer.write('%s = __create_class__("%s", __%s_parents, __%s_attrs, __%s_properties)' % (name, name, name, name, name)) - if 'init' in self._injector: - writer.write('%s.init_callbacks = JSArray()' %name) - self._injector = [] + + ## DEPRECATED + #if 'init' in self._injector: + # writer.write('%s.init_callbacks = JSArray()' %name) + #self._injector = [] for dec in class_decorators: writer.write('%s = __get__(%s,"__call__")( [%s], JSObject() )' % (name, self.visit(dec), name)) @@ -1000,11 +1217,12 @@ def visit_Or(self, node): def visit_BoolOp(self, node): op = self.visit(node.op) - return op.join( [self.visit(v) for v in node.values] ) + #raise SyntaxError(op) + return '('+ op.join( [self.visit(v) for v in node.values] ) + ')' def visit_If(self, node): if self._with_dart and writer.is_at_global_level(): - raise SyntaxError('if statements can not be used at module level in dart') + raise SyntaxError( self.format_error('if statements can not be used at module level in dart') ) elif self._with_lua: writer.write('if __test_if_true__(%s):' % self.visit(node.test)) @@ -1017,7 +1235,7 @@ def visit_If(self, node): elif isinstance(node.test, ast.List): writer.write('if %s.length:' % self.visit(node.test)) - elif self._with_ll: + elif self._with_ll or self._with_glsl: writer.write('if %s:' % self.visit(node.test)) elif isinstance(node.test, ast.Compare): writer.write('if %s:' % self.visit(node.test)) @@ -1034,6 +1252,16 @@ def visit_If(self, node): writer.pull() def visit_TryExcept(self, node): + if len(node.handlers)==0: + raise SyntaxError(self.format_error('no except handlers')) + + ## by default in js-mode some expections will not be raised, + ## this allows those cases to throw proper errors. + if node.handlers[0].type: + self._in_catch_exception = self.visit(node.handlers[0].type) + else: + self._in_catch_exception = None + writer.write('try:') writer.push() map(self.visit, node.body) @@ -1050,7 +1278,7 @@ def visit_Raise(self, node): elif isinstance(node.type, ast.Call): if len(node.type.args) > 1: - raise SyntaxError('error to raise can have at most a single argument') + raise SyntaxError( self.format_error('raise Error(x) can only have a single argument') ) if node.type.args: writer.write( 'raise %s(%s)' %(self.visit(node.type.func), self.visit(node.type.args[0])) ) else: @@ -1094,15 +1322,39 @@ def visit_Return(self, node): elif isinstance(node.value, Name) and node.value.id == 'self' and 'self' in self._instances: self._return_type = self._instances['self'] - ## cached property is DEPRECATED - #if self._cached_property: - # writer.write('self["__dict__"]["%s"] = %s' %(self._cached_property, self.visit(node.value)) ) - # writer.write('return self["__dict__"]["%s"]' %self._cached_property) - #else: - if self._inline: + + if self._with_glsl and self._in_gpu_main: + ## _id_ is inserted into all function headers by pythonjs.py for glsl functions. + if not self._gpu_return_types: + raise SyntaxError( self.format_error('function return type unknown - required decorator `@returns(array/vec4=[w,h])`') ) + + ## only one return type is allowed ## + if 'array' in self._gpu_return_types: + writer.write('out_float = %s' %self.visit(node.value)) + elif 'vec4' in self._gpu_return_types: + writer.write('out_float4 = %s' %self.visit(node.value)) + elif 'mat4' in self._gpu_return_types: + nv = self.visit(node.value) + writer.write('inline("mat4 _res_ = %s; int _row = matrix_row();")' %nv) + + r0 = 'vec4(_res_[0][0],_res_[0][1],_res_[0][2],_res_[0][3])' + r1 = 'vec4(_res_[1][0],_res_[1][1],_res_[1][2],_res_[1][3])' + r2 = 'vec4(_res_[2][0],_res_[2][1],_res_[2][2],_res_[2][3])' + r3 = 'vec4(_res_[3][0],_res_[3][1],_res_[3][2],_res_[3][3])' + + writer.write('if _row==0: out_float4 = %s' % r0) + writer.write('elif _row==1: out_float4 = %s'%r1) + writer.write('elif _row==2: out_float4 = %s'%r2) + writer.write('else: out_float4 = %s'%r3) + + else: + raise SyntaxError( self.format_error('invalid GPU return type: %s' %self._gpu_return_types) ) + + elif self._inline: writer.write('__returns__%s = %s' %(self._inline[-1], self.visit(node.value)) ) if self._inline_breakout: writer.write('break') + elif isinstance(node.value, ast.Lambda): self.visit( node.value ) writer.write( 'return __lambda__' ) @@ -1123,9 +1375,27 @@ def visit_Return(self, node): def visit_BinOp(self, node): left = self.visit(node.left) op = self.visit(node.op) + + is_go_listcomp = False + if self._with_go: + if op == '<<': + if isinstance(node.left, ast.Call) and isinstance(node.left.func, ast.Name) and node.left.func.id=='__go__array__': + if isinstance(node.right, ast.GeneratorExp): + is_go_listcomp = True + node.right.go_listcomp_type = node.left.args[0].id + + right = self.visit(node.right) - if op == '|': + if self._with_glsl: + return '(%s %s %s)' % (left, op, right) + elif self._with_go: + if is_go_listcomp: + return right + else: + return '(%s %s %s)' % (left, op, right) + + elif op == '|': if isinstance(node.right, Str): self._custom_op_hack = (node.right.s, left) return '' @@ -1157,9 +1427,10 @@ def visit_BinOp(self, node): if node.right.id in self._global_nodes: n = self._global_nodes[ node.right.id ].n else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) else: - raise SyntaxError + #raise SyntaxError( self.format_error(node) ) + return '__mul_op(%s,%s)'%(left, right) elts = [ self.visit(e) for e in node.left.elts ] expanded = [] @@ -1192,6 +1463,15 @@ def visit_BinOp(self, node): power = POWER_OF_TWO.index( node.right.n ) return '%s >> %s'%(left, power) + elif not self._with_dart and op == '*' and '*' in self._direct_operators: + return '(%s * %s)'%(left, right) + + elif not self._with_dart and not self._with_js and op == '*': + if left in self._typedef_vars and self._typedef_vars[left] in typedpython.native_number_types: + return '(%s * %s)'%(left, right) + else: + return '__mul_op(%s,%s)'%(left, right) + elif op == '//': if self._with_dart: return '(%s/%s).floor()' %(left, right) @@ -1288,8 +1568,7 @@ def visit_Compare(self, node): left = self.visit(node.left) comp = [ left ] for i in range( len(node.ops) ): - if i==0 and isinstance(node.left, ast.Name) and node.left.id in self._typedef_vars: - #raise RuntimeError(node) + if i==0 and isinstance(node.left, ast.Name) and node.left.id in self._typedef_vars and self._typedef_vars[node.left.id] == 'long': if isinstance(node.ops[i], ast.Eq): comp = ['%s.equals(%s)' %(left, self.visit(node.comparators[i]))] elif isinstance(node.ops[i], ast.Lt): @@ -1361,7 +1640,8 @@ def visit_USub(self, node): def visit_Attribute(self, node): - ## in some cases the translator knows what type a node is and what attribute's it has, in those cases the call to `__get__` can be optimized away, + + ## TODO check if this is always safe. if isinstance(node.value, Name): typedef = self.get_typedef( instance=node.value ) elif hasattr(node.value, 'returns_type'): @@ -1371,21 +1651,24 @@ def visit_Attribute(self, node): node_value = self.visit(node.value) - - if self._with_dart or self._with_ll: + if self._with_glsl: + #if node_value not in self._typedef_vars: ## dynamic var DEPRECATED + # return 'glsl_inline(%s.%s)' %(node_value, node.attr) + #else: return '%s.%s' %(node_value, node.attr) - elif self._with_js: + elif self._with_dart or self._with_ll or self._with_go: return '%s.%s' %(node_value, node.attr) - ## TODO pythonjs.configure to allow this - #if self._in_assign_target or not isinstance(node.attr, str): - # return '%s.%s' %(node_value, node.attr) - #else: - # return '__ternary_operator__(%s.%s is not undefined, %s.%s, __getattr__(%s, "%s"))' %(node_value, node.attr, node_value, node.attr, node_value, node.attr) + + elif self._with_js: + if self._in_catch_exception == 'AttributeError': + return '__getfast__(%s, "%s")' % (node_value, node.attr) + else: + return '%s.%s' %(node_value, node.attr) elif self._with_lua and self._in_assign_target: ## this is required because lua has no support for inplace assignment ops like "+=" return '%s.%s' %(node_value, node.attr) - elif typedef and node.attr in typedef.attributes: + elif typedef and node.attr in typedef.attributes: ## optimize away `__get__` return '%s.%s' %(node_value, node.attr) elif hasattr(node, 'lineno'): @@ -1407,8 +1690,8 @@ def visit_Subscript(self, node): #return '%s["$wrapped"]' %name return '%s[...]' %name - elif self._with_ll: - return '%s[ %s ]' %(name, self.visit(node.slice)) + elif self._with_ll or self._with_glsl or self._with_go: + return '%s[%s]' %(name, self.visit(node.slice)) elif self._with_js or self._with_dart: if isinstance(node.slice, ast.Slice): ## allow slice on Array @@ -1416,7 +1699,10 @@ def visit_Subscript(self, node): ## this is required because we need to support slices on String ## return '__getslice__(%s, %s)'%(name, self.visit(node.slice)) else: - return '%s.__getslice__(%s)'%(name, self.visit(node.slice)) + if not node.slice.lower and not node.slice.upper and not node.slice.step: + return '%s.copy()' %name + else: + return '%s.__getslice__(%s)'%(name, self.visit(node.slice)) elif isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.Num): @@ -1430,12 +1716,26 @@ def visit_Subscript(self, node): return '%s[ %s ]' %(name, self.visit(node.slice)) - elif isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.BinOp): - return '%s[ %s ]' %(name, self.visit(node.slice)) - else: ## ------------------ javascript mode ------------------------ - s = self.visit(node.slice) - return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) + if self._in_catch_exception == 'KeyError': + value = self.visit(node.value) + slice = self.visit(node.slice) + return '__get__(%s, "__getitem__")([%s], __NULL_OBJECT__)' % (value, slice) + + elif isinstance(node.slice, ast.Index) and isinstance(node.slice.value, ast.BinOp): + ## TODO keep this optimization? in js mode `a[x+y]` is assumed to a direct key, + ## it would be safer to check if one of the operands is a number literal, + ## in that case it is safe to assume that this is a direct key. + return '%s[ %s ]' %(name, self.visit(node.slice)) + + elif self._with_direct_keys: + return '%s[ %s ]' %(name, self.visit(node.slice)) + + else: + s = self.visit(node.slice) + #return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, s) + check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) + return '%s[ __ternary_operator__(%s.__uid__, %s) ]' %(name, s, check_array) elif isinstance(node.slice, ast.Slice): return '__get__(%s, "__getslice__")([%s], __NULL_OBJECT__)' % ( @@ -1463,14 +1763,18 @@ def visit_Subscript(self, node): src = src.replace('"', '\\"') err = 'line %s: %s' %(node.lineno, src.strip()) - return '__get__(%s, "__getitem__", "%s")([%s], __NULL_OBJECT__)' % ( - self.visit(node.value), - err, - self.visit(node.slice) - ) + value = self.visit(node.value) + slice = self.visit(node.slice) + fallback = '__get__(%s, "__getitem__", "%s")([%s], __NULL_OBJECT__)' % (value, err, slice) + if not self._with_lua and isinstance(node.value, ast.Name): + return '__ternary_operator__(instanceof(%s, Array), %s[%s], %s)' %(value, value,slice, fallback) + else: + return fallback def visit_Slice(self, node): - if self._with_dart: + if self._with_go: + lower = upper = step = None + elif self._with_dart: lower = upper = step = 'null' elif self._with_js: lower = upper = step = 'undefined' @@ -1482,13 +1786,27 @@ def visit_Slice(self, node): upper = self.visit(node.upper) if node.step: step = self.visit(node.step) - return "%s, %s, %s" % (lower, upper, step) + + if self._with_go: + if lower and upper: + return '%s:%s' %(lower,upper) + elif upper: + return ':%s' %upper + elif lower: + return '%s:'%lower + else: + return "%s, %s, %s" % (lower, upper, step) def visit_Assign(self, node): - use_runtime_errors = not (self._with_js or self._with_ll or self._with_dart or self._with_coffee or self._with_lua) + use_runtime_errors = not (self._with_js or self._with_ll or self._with_dart or self._with_coffee or self._with_lua or self._with_go) use_runtime_errors = use_runtime_errors and self._with_runtime_exceptions lineno = node.lineno + if node.lineno < len(self._source): + src = self._source[ node.lineno ] + self._line_number = node.lineno + self._line = src + if use_runtime_errors: writer.write('try:') @@ -1509,8 +1827,16 @@ def visit_Assign(self, node): self._typedef_vars[ node.value.id ] = target.id return None else: - raise SyntaxError(targets) + raise SyntaxError( self.format_error(targets) ) + + elif self._with_rpc_name and isinstance(target, Attribute) and isinstance(target.value, Name) and target.value.id == self._with_rpc_name: + writer.write('__rpc_set__(%s, "%s", %s)' %(self._with_rpc, target.attr, self.visit(node.value))) + return None + elif self._with_rpc_name and isinstance(node.value, Attribute) and isinstance(node.value.value, Name) and node.value.value.id == self._with_rpc_name: + writer.write('%s = __rpc_get__(%s, "%s")' %(self.visit(target), self._with_rpc, node.value.attr)) + return None + ############################################# for target in targets: self._visit_assign_helper( node, target ) node = ast.Expr( value=target ) @@ -1539,6 +1865,54 @@ def _visit_assign_helper(self, node, target): self.visit(node.value) ## writes function def writer.write('%s = __lambda__' %self.visit(target)) + elif isinstance(node.value, ast.Dict) and self._with_go: + key_type = None + val_type = None + + for i in range( len(node.value.keys) ): + k = node.value.keys[ i ] + v = node.value.values[i] + if isinstance(k, ast.Str): + key_type = 'string' + elif isinstance(k, ast.Num): + key_type = 'int' + + if isinstance(v, ast.Str): + val_type = 'string' + elif isinstance(v, ast.Num): + if isinstance(v.n, int): + val_type = 'int' + else: + val_type = 'float64' + + if not key_type: + raise SyntaxError( self.format_error('can not determine dict key type') ) + if not val_type: + raise SyntaxError( self.format_error('can not determine dict value type') ) + + t = self.visit(target) + v = self.visit(node.value) + writer.write('%s = __go__map__(%s, %s) << %s' %(t, key_type, val_type, v)) + + + elif isinstance(node.value, ast.List) and self._with_go: + guess_type = None + for elt in node.value.elts: + if isinstance(elt, ast.Num): + if isinstance(elt.n, int): + guess_type = 'int' + else: + guess_type = 'float64' + elif isinstance(elt, ast.Str): + guess_type = 'string' + + if guess_type: + t = self.visit(target) + v = self.visit(node.value) + writer.write('%s = __go__array__(%s) << %s' %(t, guess_type, v)) + else: + raise SyntaxError(self.format_error('can not determine type of array')) + elif isinstance(target, Subscript): name = self.visit(target.value) ## target.value may have "returns_type" after being visited @@ -1546,7 +1920,10 @@ def _visit_assign_helper(self, node, target): #code = '%s["$wrapped"] = %s' %(self.visit(target.value), self.visit(node.value)) code = '%s[...] = %s' %(self.visit(target.value), self.visit(node.value)) - elif self._with_dart or self._with_ll: + elif isinstance(target.slice, ast.Slice): + code = '%s.__setslice__(%s, %s)' %(self.visit(target.value), self.visit(target.slice), self.visit(node.value)) + + elif self._with_dart or self._with_ll or self._with_glsl or self._with_go: code = '%s[ %s ] = %s' code = code % (self.visit(target.value), self.visit(target.slice.value), self.visit(node.value)) @@ -1554,11 +1931,13 @@ def _visit_assign_helper(self, node, target): s = self.visit(target.slice.value) if isinstance(target.slice.value, ast.Num) or isinstance(target.slice.value, ast.BinOp): code = '%s[ %s ] = %s' % (self.visit(target.value), s, self.visit(node.value)) + elif self._with_direct_keys: + code = '%s[ %s ] = %s' % (self.visit(target.value), s, self.visit(node.value)) else: - code = '%s[ __ternary_operator__(%s.__uid__, %s) ] = %s' % (self.visit(target.value), s, s, self.visit(node.value)) + check_array = '__ternary_operator__( instanceof(%s,Array), JSON.stringify(%s), %s )' %(s, s, s) + code = '%s[ __ternary_operator__(%s.__uid__, %s) ] = %s' %(self.visit(target.value), s, check_array, self.visit(node.value)) elif name in self._func_typedefs and self._func_typedefs[name] == 'list': - #code = '%s[...][%s] = %s'%(name, self.visit(target.slice.value), self.visit(node.value)) code = '%s[%s] = %s'%(name, self.visit(target.slice.value), self.visit(node.value)) else: @@ -1581,7 +1960,7 @@ def _visit_assign_helper(self, node, target): ##################################### - if self._with_js or self._with_dart: + if self._with_js or self._with_dart or self._with_go: writer.write( '%s.%s=%s' %(target_value, target.attr, self.visit(node.value)) ) elif typedef and target.attr in typedef.properties and 'set' in typedef.properties[ target.attr ]: setter = typedef.properties[ target.attr ]['set'] @@ -1634,7 +2013,33 @@ def _visit_assign_helper(self, node, target): ) writer.write(code) - elif isinstance(target, Name): + elif isinstance(target, Name) and self._with_glsl: ## assignment to variable + if target.id not in self._typedef_vars: + raise SyntaxError(self.format_error('untyped variable')) + node_value = self.visit( node.value ) ## node.value may have extra attributes after being visited + + if node_value in self._typedef_vars: + writer.write('%s = %s' % (self.visit(target), self.visit(node.value))) + + elif isinstance(node.value, ast.Subscript) and isinstance(node.value.slice, ast.Ellipsis): + writer.write('glsl_inline_assign_from_iterable("%s", "%s", %s)'%(self._typedef_vars[target.id], target.id, self.visit(node.value.value)) ) + + else: + + ## also assign variable in current javascript scope ## + if not isinstance(node.value, (ast.BinOp, ast.Call)): + if isinstance(node.value, ast.Subscript) and isinstance(node.value.slice, ast.Slice): + x = node_value.split('(')[-1].split(')')[0].split('[')[0] + writer.write('glsl_inline_push_js_assign("%s", %s.__getslice__(%s))'%(target.id, x, self.visit(node.value.slice)) ) + else: + writer.write('glsl_inline_push_js_assign("%s", %s)'%(target.id, self.visit(node.value)) ) + else: + writer.write('%s = %s' % (target.id, self.visit(node.value))) + + return None + + + elif isinstance(target, Name): ## assignment to variable node_value = self.visit( node.value ) ## node.value may have extra attributes after being visited if writer.is_at_global_level(): @@ -1723,10 +2128,11 @@ def _visit_assign_helper(self, node, target): elif self._with_js or self._with_dart: writer.write("%s = %s[%s]" % (self.visit(target), r, i)) else: - writer.write("%s = __get__(__get__(%s, '__getitem__'), '__call__')([%s], __NULL_OBJECT__)" % (self.visit(target), r, i)) + fallback = "__get__(__get__(%s, '__getitem__'), '__call__')([%s], __NULL_OBJECT__)" %(r, i) + writer.write("%s = __ternary_operator__(instanceof(%s,Array), %s[%s], %s)" % (self.visit(target), r, r,i, fallback )) def visit_Print(self, node): - writer.write('print %s' % ', '.join(map(self.visit, node.values))) + writer.write('print(%s)' % ', '.join(map(self.visit, node.values))) def visit_Str(self, node): s = node.s.replace('\\','\\\\').replace('\n', '\\n').replace('\r', '\\r').replace('\0', '\\0') @@ -1746,12 +2152,13 @@ def visit_Str(self, node): return '"""%s"""' %s.encode('utf-8') def visit_Expr(self, node): - log('line: %s' %node.lineno ) if node.lineno < len(self._source): src = self._source[ node.lineno ] - log( src ) + ## TODO raise SyntaxErrors with the line number and line source + self._line_number = node.lineno + self._line = src - use_runtime_errors = not (self._with_js or self._with_ll or self._with_dart or self._with_coffee or self._with_lua) + use_runtime_errors = not (self._with_js or self._with_ll or self._with_dart or self._with_coffee or self._with_lua or self._with_go) use_runtime_errors = use_runtime_errors and self._with_runtime_exceptions if use_runtime_errors: @@ -1760,7 +2167,8 @@ def visit_Expr(self, node): line = self.visit(node.value) if line: - writer.write(line) + #writer.write('('+line+')') + writer.write( line ) elif use_runtime_errors: writer.write('pass') @@ -1796,6 +2204,10 @@ def visit_Call(self, node): name = self.visit(node.func) + if name in typedpython.GO_SPECIAL_CALLS: + name = typedpython.GO_SPECIAL_CALLS[ name ] + args = [self.visit(e) for e in node.args ] + return '%s( %s )' %(name, ','.join(args)) if self._with_rpc: if not self._with_rpc_name: @@ -1817,7 +2229,7 @@ def visit_Call(self, node): #return '%s.append( [%s], __NULL_OBJECT__)' %(node.func.value.id, self.visit(node.args[0]) ) return '%s.push( %s )' %(node.func.value.id, self.visit(node.args[0]) ) else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif self._with_webworker and isinstance(node.func, ast.Attribute) and isinstance(node.func.value, Name) and node.func.value.id == 'self' and node.func.attr == 'terminate': @@ -1829,7 +2241,7 @@ def visit_Call(self, node): elif node.func.attr == 'start_webworker': return '__start_new_thread( %s, %s )' %(self.visit(node.args[0]), self.visit(node.args[1])) else: - raise SyntaxError(node.func.attr) + raise SyntaxError( self.format_error(node.func.attr) ) elif self._with_webworker and name in self._global_functions: node.calling_from_worker = True @@ -1842,7 +2254,15 @@ def visit_Call(self, node): return '__js_typed_array(%s)' %','.join(args) ######################################### - if isinstance(node.func, ast.Attribute) and isinstance(node.func.value, Name) and node.func.value.id == 'pythonjs' and node.func.attr == 'configure': + if isinstance(node.func, ast.Attribute) and isinstance(node.func.value, Name) and node.func.value.id == 'numpy' and node.func.attr == 'array': + args = [self.visit(arg) for arg in node.args] + if node.keywords: + kwargs = [ '%s=%s' %(x.arg, self.visit(x.value)) for x in node.keywords] + return 'numpy.array(%s, %s)' %( ','.join(args), ','.join(kwargs) ) + else: + return 'numpy.array(%s)' %','.join(args) + + elif isinstance(node.func, ast.Attribute) and isinstance(node.func.value, Name) and node.func.value.id == 'pythonjs' and node.func.attr == 'configure': for kw in node.keywords: if kw.arg == 'javascript': if kw.value.id == 'True': @@ -1852,7 +2272,7 @@ def visit_Call(self, node): self._with_js = False writer.with_javascript = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'dart': if kw.value.id == 'True': @@ -1860,7 +2280,7 @@ def visit_Call(self, node): elif kw.value.id == 'False': self._with_dart = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'coffee': if kw.value.id == 'True': @@ -1868,7 +2288,7 @@ def visit_Call(self, node): elif kw.value.id == 'False': self._with_coffee = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'lua': if kw.value.id == 'True': @@ -1876,7 +2296,7 @@ def visit_Call(self, node): elif kw.value.id == 'False': self._with_lua = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'inline_functions': if kw.value.id == 'True': @@ -1884,7 +2304,7 @@ def visit_Call(self, node): elif kw.value.id == 'False': self._with_inline = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'runtime_exceptions': if kw.value.id == 'True': @@ -1892,7 +2312,15 @@ def visit_Call(self, node): elif kw.value.id == 'False': self._with_runtime_exceptions = False else: - raise SyntaxError + raise SyntaxError( self.format_error(node) ) + + elif kw.arg == 'direct_keys': + if kw.value.id == 'True': + self._with_direct_keys = True + elif kw.value.id == 'False': + self._with_direct_keys = False + else: + raise SyntaxError( self.format_error(node) ) elif kw.arg == 'direct_operator': if kw.value.s.lower() == 'none': @@ -1901,14 +2329,46 @@ def visit_Call(self, node): self._direct_operators.add( kw.value.s ) else: - raise SyntaxError + raise SyntaxError( self.format_error('invalid keyword option') ) - elif self._with_ll or name == 'inline': + elif self._with_ll or name == 'inline' or self._with_glsl: + F = self.visit(node.func) args = [self.visit(arg) for arg in node.args] + if hasattr(self, '_in_gpu_method') and self._in_gpu_method and isinstance(node.func, ast.Attribute): + fv = self.visit(node.func.value) + if fv == 'self': + clsname = self._in_gpu_method + args.insert(0, 'self') + else: + fvt = fv.split('.')[-1] + clsname = self._typedef_vars[ fvt ] + args.insert(0, fv) + + F = '%s_%s' %(clsname, node.func.attr) + + elif isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name) and node.func.value.id in self._typedef_vars: + #raise RuntimeError(node.func.value.id) + clsname = self._typedef_vars[ node.func.value.id ] + F = '%s_%s' %(clsname, node.func.attr) + args.insert(0, node.func.value.id) + + if node.keywords: args.extend( [self.visit(x.value) for x in node.keywords] ) - return '%s(%s)' %( self.visit(node.func), ','.join(args) ) + return '%s(%s)' %( F, ','.join(args) ) + + else: + return '%s(%s)' %( F, ','.join(args) ) + elif self._with_go: + args = list( map(self.visit, node.args) ) + if node.keywords: + args.extend( ['%s=%s'%(x.arg,self.visit(x.value)) for x in node.keywords] ) + if node.starargs: + args.append('*%s' %self.visit(node.starargs)) + + if isinstance(node.func, Name) and node.func.id in self._js_classes: + return '__new__%s(%s)' %( self.visit(node.func), ','.join(args) ) else: return '%s(%s)' %( self.visit(node.func), ','.join(args) ) @@ -1971,6 +2431,9 @@ def visit_Call(self, node): elif anode.attr == 'split' and not args: return '__split_method(%s)' %self.visit(anode.value) + elif anode.attr == 'sort' and not args: + return '__sort_method(%s)' %self.visit(anode.value) + elif anode.attr == 'replace' and len(node.args)==2: return '__replace_method(%s, %s)' %(self.visit(anode.value), ','.join(args) ) @@ -1982,6 +2445,8 @@ def visit_Call(self, node): if args: if node.starargs: a = ( method, ctx, ','.join(args), self.visit(node.starargs), ','.join(kwargs) ) + ## note: this depends on the fact that [].extend in PythonJS returns self (this), + ## which is different from regular python where list.extend returns None return '%s.apply( %s, [].extend([%s]).extend(%s).append({%s}) )' %a else: return '%s(%s, {%s})' %( method, ','.join(args), ','.join(kwargs) ) @@ -2005,14 +2470,16 @@ def visit_Call(self, node): elif isinstance(node.func, Name) and node.func.id in self._js_classes: if node.keywords: - kwargs = [ '%s=%s'%(x.arg, self.visit(x.value)) for x in node.keywords ] + kwargs = [ '%s:%s'%(x.arg, self.visit(x.value)) for x in node.keywords ] if args: a = ','.join(args) - return 'new( %s(%s, %s) )' %( self.visit(node.func), a, ','.join(kwargs) ) + return 'new( %s(%s, {%s}) )' %( self.visit(node.func), a, ','.join(kwargs) ) else: - return 'new( %s(%s) )' %( self.visit(node.func), ','.join(kwargs) ) - + return 'new( %s({%s}) )' %( self.visit(node.func), ','.join(kwargs) ) else: + if node.kwargs: + args.append( self.visit(node.kwargs) ) + a = ','.join(args) return 'new( %s(%s) )' %( self.visit(node.func), a ) @@ -2062,7 +2529,11 @@ def visit_Call(self, node): a = ( self.visit(node.func),self.visit(node.func), self.visit(node.starargs), ','.join(kwargs) ) return '%s.apply(%s, [].extend(%s).append({%s}) )' %a else: - return '%s({%s})' %( self.visit(node.func), ','.join(kwargs) ) + func_name = self.visit(node.func) + if func_name == 'dict': + return '{%s}' %','.join(kwargs) + else: + return '%s({%s})' %( func_name, ','.join(kwargs) ) else: if node.starargs: @@ -2153,7 +2624,7 @@ def visit_Call(self, node): ####################################### ## special method calls ## - if isinstance(node.func, ast.Attribute) and node.func.attr in ('get', 'keys', 'values', 'pop', 'items', 'split', 'replace') and not self._with_lua: + if isinstance(node.func, ast.Attribute) and node.func.attr in ('get', 'keys', 'values', 'pop', 'items', 'split', 'replace', 'sort') and not self._with_lua: anode = node.func if anode.attr == 'get' and len(node.args) > 0 and len(node.args) <= 2: return '__jsdict_get(%s, %s)' %(self.visit(anode.value), args ) @@ -2173,6 +2644,9 @@ def visit_Call(self, node): else: return '__jsdict_pop(%s)' %self.visit(anode.value) + elif anode.attr == 'sort' and not args: + return '__sort_method(%s)' %self.visit(anode.value) + elif anode.attr == 'split' and len(node.args) <= 1: if not args: return '__split_method(%s)' %self.visit(anode.value) @@ -2194,7 +2668,7 @@ def visit_Call(self, node): elif hasattr(node,'constant') or name in self._builtin_functions: if args and kwargs: - return '%s([%s], {%s})' %(args, kwargs) + return '%s([%s], {%s})' %(name, args, kwargs) elif args: return '%s([%s], __NULL_OBJECT__)' %(name,args) elif kwargs: @@ -2249,10 +2723,11 @@ def visit_Call(self, node): def visit_Lambda(self, node): args = [self.visit(a) for a in node.args.args] - #if self._with_js: ## TODO is it better to return a normal lambda - # return """JS('(function (%s) {return %s})')""" %(','.join(args), self.visit(node.body)) - #else: - if hasattr(node, 'keep_as_lambda'): + + ##'__INLINE_FUNCTION__' from typedpython.py + + if hasattr(node, 'keep_as_lambda') or args and args[0]=='__INLINE_FUNCTION__': + ## TODO lambda keyword args self._in_lambda = True a = '(lambda %s: %s)' %(','.join(args), self.visit(node.body)) self._in_lambda = False @@ -2286,23 +2761,57 @@ def visit_FunctionDef(self, node): with_dart_decorators = [] setter = False return_type = None + return_type_keywords = {} fastdef = False javascript = False inline = False threaded = self._with_webworker jsfile = None + self._typedef_vars = dict() ## clear typed variables: filled in below by @typedef or in visit_Assign + self._gpu_return_types = set() + gpu = False + gpu_main = False + gpu_vectorize = False + gpu_method = False + local_typedefs = [] + typedef_chans = [] + func_expr = None ## deprecated? self._cached_property = None self._func_typedefs = {} - if writer.is_at_global_level() and not self._with_webworker: + if writer.is_at_global_level() and not self._with_webworker and not self._with_glsl: self._global_functions[ node.name ] = node ## save ast-node for decorator in reversed(node.decorator_list): log('@decorator: %s' %decorator) - if isinstance(decorator, Name) and decorator.id == 'inline': + if isinstance(decorator, Name) and decorator.id == 'gpu': + gpu = True + + elif isinstance(decorator, Call) and decorator.func.id == 'expression': + assert len(decorator.args)==1 + func_expr = self.visit(decorator.args[0]) + + elif isinstance(decorator, Call) and decorator.func.id in ('typedef', 'typedef_chan'): + c = decorator + assert len(c.args) == 0 and len(c.keywords) + for kw in c.keywords: + #assert isinstance( kw.value, Name) + kwval = self.visit(kw.value) + self._typedef_vars[ kw.arg ] = kwval + self._instances[ kw.arg ] = kwval + self._func_typedefs[ kw.arg ] = kwval + local_typedefs.append( '%s=%s' %(kw.arg, kwval)) + if decorator.func.id=='typedef_chan': + typedef_chans.append( kw.arg ) + writer.write('@__typedef_chan__(%s=%s)' %(kw.arg, kwval)) + else: + writer.write('@__typedef__(%s=%s)' %(kw.arg, kwval)) + + + elif isinstance(decorator, Name) and decorator.id == 'inline': inline = True self._with_inline = True @@ -2312,6 +2821,31 @@ def visit_FunctionDef(self, node): assert len(decorator.args) == 1 jsfile = decorator.args[0].s + elif isinstance(decorator, Call) and isinstance(decorator.func, ast.Name) and decorator.func.id == 'returns': + if decorator.keywords: + for k in decorator.keywords: + key = k.arg + assert key == 'array' or key == 'vec4' + self._gpu_return_types.add(key) ## used in visit_Return ## + return_type_keywords[ key ] = self.visit(k.value) + + else: + assert len(decorator.args) == 1 + assert isinstance( decorator.args[0], Name) + return_type = decorator.args[0].id + if return_type in typedpython.glsl_types: + self._gpu_return_types.add( return_type ) + + elif isinstance(decorator, Attribute) and isinstance(decorator.value, Name) and decorator.value.id == 'gpu': + gpu = True + if decorator.attr == 'vectorize': + gpu_vectorize = True + elif decorator.attr == 'main': + gpu_main = True + elif decorator.attr == 'method': + gpu_method = True + else: + raise NotImplementedError(decorator) elif self._with_dart: with_dart_decorators.append( self.visit(decorator) ) @@ -2338,7 +2872,7 @@ def visit_FunctionDef(self, node): elif isinstance(decorator, Attribute) and isinstance(decorator.value, Name) and decorator.value.id in self._decorator_properties: if decorator.attr == 'setter': if self._decorator_properties[ decorator.value.id ]['set']: - raise SyntaxError('user error - the same decorator.setter is used more than once!') + raise SyntaxError( self.format_error("decorator.setter is used more than once") ) n = node.name + '__setprop__' self._decorator_properties[ decorator.value.id ]['set'] = n node.name = n @@ -2358,24 +2892,20 @@ def visit_FunctionDef(self, node): raise RuntimeError( op, self._custom_operators ) self._custom_operators[ op ] = node.name - elif isinstance(decorator, Call) and decorator.func.id == 'returns': - assert len(decorator.args) == 1 - assert isinstance( decorator.args[0], Name) - return_type = decorator.args[0].id - - elif isinstance(decorator, Call) and decorator.func.id == 'typedef': - c = decorator - assert len(c.args) == 0 and len(c.keywords) - for kw in c.keywords: - assert isinstance( kw.value, Name) - self._instances[ kw.arg ] = kw.value.id - self._func_typedefs[ kw.arg ] = kw.value.id - log('@typedef - %s : %s'%(kw.arg, kw.value.id)) else: decorators.append( decorator ) + if gpu: + restore_with_glsl = self._with_glsl + self._with_glsl = True + if gpu_main: ## sets float + self._in_gpu_main = True + writer.write('@gpu.main') + + + if threaded: if not jsfile: jsfile = 'worker.js' writer_main.write('%s = "%s"' %(node.name, jsfile)) @@ -2406,11 +2936,73 @@ def visit_FunctionDef(self, node): writer.write('self.onmessage = onmessage' ) + + ## force python variable scope, and pass user type information to second stage of translation. + ## the dart backend can use this extra type information for speed and debugging. + ## the Go and GLSL backends require this extra type information. + vars = [] + local_typedef_names = set() + if not self._with_coffee: + try: + local_vars, global_vars = retrieve_vars(node.body) + except SyntaxError as err: + raise SyntaxError( self.format_error(err) ) + + local_vars = local_vars-global_vars + inlined_long = False + if local_vars: + args_typedefs = [] + args = [ a.id for a in node.args.args ] + + for v in local_vars: + usertype = None + if '=' in v: + t,n = v.split('=') ## unpack type and name + if self._with_dart and t in typedpython.simd_types: + t = t[0].upper() + t[1:] + v = '%s=%s' %(n,t) ## reverse + local_typedef_names.add( n ) + if t == 'long' and inlined_long == False: + inlined_long = True + writer.write('''inline("if (__NODEJS__==true) var long = require('long')")''') ## this is ugly + + if n in args: + args_typedefs.append( v ) + else: + local_typedefs.append( v ) + elif v in args or v in local_typedef_names: pass + else: vars.append( v ) + + if args_typedefs: + writer.write('@__typedef__(%s)' %','.join(args_typedefs)) + + if func_expr: + writer.write('@expression(%s)' %func_expr) + + + if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl: + writer.write('@__pyfunction__') + + if return_type or return_type_keywords: + if return_type_keywords and return_type: + kw = ['%s=%s' %(k,v) for k,v in return_type_keywords.items()] + writer.write('@returns(%s, %s)' %(return_type,','.join(kw)) ) + elif return_type_keywords: + writer.write('@returns(%s)' %','.join( ['%s=%s' %(k,v) for k,v in return_type_keywords.items()] )) + else: + writer.write('@returns(%s)' %return_type) + + if gpu_vectorize: + writer.write('@gpu.vectorize') + if gpu_method: + writer.write('@gpu.method') + + if self._with_dart: ## dart supports optional positional params [x=1, y=2], or optional named {x:1, y:2} ## but not both at the same time. if node.args.kwarg: - raise SyntaxError( 'dart functions can not take variable keyword arguments (**kwargs)' ) + raise SyntaxError( self.format_error('dart functions can not take variable keyword arguments (**kwargs)' ) ) for dec in with_dart_decorators: writer.write('@%s'%dec) @@ -2427,15 +3019,36 @@ def visit_FunctionDef(self, node): if node.args.vararg: if node.args.defaults: - raise SyntaxError( 'dart functions can not use variable arguments (*args) and have keyword arguments' ) + raise SyntaxError( self.format_error('dart functions can not use variable arguments (*args) and have keyword arguments' ) ) args.append('__variable_args__%s' %node.args.vararg) + writer.write( 'def %s( %s ):' % (node.name, ','.join(args)) ) + + elif self._with_go: + + args = [] + offset = len(node.args.args) - len(node.args.defaults) + for i, arg in enumerate(node.args.args): + a = arg.id + dindex = i - offset + if dindex >= 0 and node.args.defaults: + default = self.visit(node.args.defaults[dindex]) + args.append( '%s=%s' %(a, default)) + else: + args.append( a ) + + if node.args.vararg: + args.append( '*%s' %node.args.vararg ) writer.write( 'def %s( %s ):' % (node.name, ','.join(args)) ) - elif self._with_js or javascript or self._with_ll:# or self._with_coffee: + elif self._with_js or javascript or self._with_ll or self._with_glsl or self._with_go: + + if self._with_glsl: + writer.write('@__glsl__') + if node.args.vararg: #raise SyntaxError( 'pure javascript functions can not take variable arguments (*args)' ) writer.write('#WARNING - NOT IMPLEMENTED: javascript-mode functions with (*args)') @@ -2460,28 +3073,22 @@ def visit_FunctionDef(self, node): writer.write( 'def %s( %s ):' % (node.name, ','.join(args)) ) else: - writer.write('def %s(args, kwargs):' % node.name) - writer.push() - - ## the user will almost always want to use Python-style variable scope, - ## this is kept here as an option to be sure we are compatible with the - ## old-style code in runtime/pythonpythonjs.py and runtime/builtins.py - if not GLOBAL_VARIABLE_SCOPE and not self._with_coffee: - local_vars, global_vars = retrieve_vars(node.body) - if local_vars-global_vars: - vars = [] - args = [ a.id for a in node.args.args ] + if len(node.args.defaults) or node.args.kwarg or len(node.args.args) or node.args.vararg: + writer.write('def %s(args, kwargs):' % node.name) + else: + writer.write('def %s():' % node.name) - for v in local_vars-global_vars: - if v in args: pass - elif v == 'long': writer.write('''inline("if (__NODEJS__==true) var long = require('long')")''') ## this is ugly - else: vars.append( v ) + writer.push() - a = ','.join( vars ) - writer.write('var(%s)' %a) + ## write local typedefs and var scope ## + a = ','.join( vars ) + if local_typedefs: + if a: a += ',' + a += ','.join(local_typedefs) + writer.write('var(%s)' %a) ##################################################################### - if self._with_dart: + if self._with_dart or self._with_glsl or self._with_go: pass elif self._with_js or javascript or self._with_ll: @@ -2567,19 +3174,19 @@ def visit_FunctionDef(self, node): # First check the arguments are well formed # ie. that this function is not a callback of javascript code + if not self._with_go: + writer.write("""if instanceof(args,Array) and Object.prototype.toString.call(kwargs) == '[object Object]' and arguments.length==2:""") + writer.push() + writer.write('pass') # do nothing if it's not called from javascript + writer.pull() - writer.write("""if instanceof(args,Array) and Object.prototype.toString.call(kwargs) == '[object Object]' and arguments.length==2:""") - writer.push() - writer.write('pass') # do nothing if it's not called from javascript - writer.pull() - - writer.write('else:') - writer.push() - # If it's the case, move use ``arguments`` to ``args`` - writer.write('args = Array.prototype.slice.call(arguments, 0, __sig__.args.length)') - # This means you can't pass keyword argument from javascript but we already knew that - writer.write('kwargs = JSObject()') - writer.pull() + writer.write('else:') + writer.push() + # If it's the case, move use ``arguments`` to ``args`` + writer.write('args = Array.prototype.slice.call(arguments, 0, __sig__.args.length)') + # This means you can't pass keyword argument from javascript but we already knew that + writer.write('kwargs = JSObject()') + writer.pull() @@ -2729,6 +3336,9 @@ def visit_FunctionDef(self, node): self._function_return_types[ node.name ] = self._return_type self._return_type = None + + ############################################################ + ### DEPRECATED if setter and 'set' in self._injector: ## inject extra code value_name = node.args.args[1].id inject = [ @@ -2748,9 +3358,19 @@ def visit_FunctionDef(self, node): writer.write('callback( [self], JSObject() )') writer.pull() writer.pull() + ############################################################ writer.pull() ## end function body + #if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl: + # writer.write('%s.pythonscript_function=True'%node.name) + + + if gpu: + self._with_glsl = restore_with_glsl + if gpu_main: + self._in_gpu_main = False + self._typedef_vars = dict() ## clear typed variables if inline: @@ -2773,23 +3393,22 @@ def visit_FunctionDef(self, node): if not self._with_dart and not self._with_lua: ## Dart functions can not have extra attributes? - ## note, in javascript function.name is a non-standard readonly attribute, - ## the compiler creates anonymous functions with name set to an empty string. - writer.write('%s.NAME = "%s"' %(node.name,node.name)) + if self._introspective_functions: + ## note, in javascript function.name is a non-standard readonly attribute, + ## the compiler creates anonymous functions with name set to an empty string. + writer.write('%s.NAME = "%s"' %(node.name,node.name)) - writer.write( '%s.args_signature = [%s]' %(node.name, ','.join(['"%s"'%n.id for n in node.args.args])) ) - defaults = ['%s:%s'%(self.visit(x[0]), self.visit(x[1])) for x in zip(node.args.args[-len(node.args.defaults):], node.args.defaults) ] - writer.write( '%s.kwargs_signature = {%s}' %(node.name, ','.join(defaults)) ) - if self._with_fastdef or fastdef: - writer.write('%s.fastdef = True' %node.name) + writer.write( '%s.args_signature = [%s]' %(node.name, ','.join(['"%s"'%n.id for n in node.args.args])) ) + defaults = ['%s:%s'%(self.visit(x[0]), self.visit(x[1])) for x in zip(node.args.args[-len(node.args.defaults):], node.args.defaults) ] + writer.write( '%s.kwargs_signature = {%s}' %(node.name, ','.join(defaults)) ) + if self._with_fastdef or fastdef: + writer.write('%s.fastdef = True' %node.name) - writer.write( '%s.types_signature = {%s}' %(node.name, ','.join(types)) ) + writer.write( '%s.types_signature = {%s}' %(node.name, ','.join(types)) ) - if return_type: - writer.write('%s.return_type = "%s"'%(node.name, return_type)) + if return_type: + writer.write('%s.return_type = "%s"'%(node.name, return_type)) - if not self._with_js and not javascript: - writer.write('%s.pythonscript_function=True'%node.name) if self._with_js and with_js_decorators: @@ -2854,10 +3473,14 @@ def visit_Continue(self, node): return '' def visit_Break(self, node): + if self._in_loop_with_else: + writer.write('__break__ = True') writer.write('break') def visit_For(self, node): - log('for loop:') + if node.orelse: + raise SyntaxError( self.format_error('the syntax for/else is deprecated') ) + if self._cache_for_body_calls: ## TODO add option for this for n in node.body: calls = collect_calls(n) @@ -2871,6 +3494,32 @@ def visit_For(self, node): c.constant = True self._call_ids += 1 + if self._with_glsl or self._with_go: + writer.write( 'for %s in %s:' %(self.visit(node.target), self.visit(node.iter)) ) + writer.push() + map(self.visit, node.body) + writer.pull() + return None + + if self._with_rpc_name and isinstance(node.iter, ast.Attribute) and isinstance(node.iter.value, ast.Name) and node.iter.value.id == self._with_rpc_name: + target = self.visit(node.target) + writer.write('def __rpc_loop__():') + writer.push() + writer.write( '%s = __rpc_iter__(%s, "%s")' %(target, self._with_rpc, node.iter.attr) ) + writer.write( 'if %s == "__STOP_ITERATION__": __continue__()' %target) + writer.write( 'else:') + writer.push() + map( self.visit, node.body ) + writer.write( '__rpc_loop__()') + writer.pull() + writer.pull() + writer.write('__rpc_loop__()') + + writer.write('def __continue__():') ## because this def comes after, it needs to be `hoisted` up by the javascript VM + writer.push() + return None + + iterid = self._iter_ids self._iter_ids += 1 @@ -3065,13 +3714,10 @@ def visit_For(self, node): _call_ids = 0 def visit_While(self, node): - log('while loop:') if self._cache_while_body_calls: ## TODO add option for this for n in node.body: calls = collect_calls(n) for c in calls: - log('--call: %s' %c) - log('------: %s' %c.func) if isinstance(c.func, ast.Name): ## these are constant for sure i = self._call_ids writer.write( '__call__%s = __get__(%s,"__call__")' %(i,self.visit(c.func)) ) @@ -3079,6 +3725,12 @@ def visit_While(self, node): c.constant = True self._call_ids += 1 + if node.orelse: + raise SyntaxError( self.format_error('the syntax while/else is deprecated')) + self._in_loop_with_else = True + writer.write('var(__break__)') + writer.write('__break__ = False') + self._in_while_test = True writer.write('while %s:' % self.visit(node.test)) self._in_while_test = False @@ -3086,10 +3738,34 @@ def visit_While(self, node): map(self.visit, node.body) writer.pull() + if node.orelse: + self._in_loop_with_else = False + writer.write('if __break__ == False:') + writer.push() + map(self.visit, node.orelse) + writer.pull() + def visit_With(self, node): global writer - if isinstance( node.context_expr, ast.Call ) and isinstance(node.context_expr.func, ast.Name) and node.context_expr.func.id == 'rpc': + if isinstance( node.context_expr, Name ) and node.context_expr.id == 'glsl': + if not isinstance(node.optional_vars, ast.Name): + raise SyntaxError( self.format_error('wrapper function name must be given: `with glsl as myfunc:`') ) + main_func = None + writer.inline_glsl = True + self._with_glsl = True + for b in node.body: + if isinstance(b, ast.FunctionDef) and b.name == 'main': + main_func = True + writer.write('@__glsl__.%s' %node.optional_vars.id) + a = self.visit(b) + if a: writer.write(a) + self._with_glsl = False + writer.inline_glsl = False + if not main_func: + raise SyntaxError( self.format_error('a function named `main` must be defined as the entry point for the shader program') ) + + elif isinstance( node.context_expr, ast.Call ) and isinstance(node.context_expr.func, ast.Name) and node.context_expr.func.id == 'rpc': self._with_rpc = self.visit( node.context_expr.args[0] ) if isinstance(node.optional_vars, ast.Name): self._with_rpc_name = node.optional_vars.id @@ -3123,7 +3799,10 @@ def visit_With(self, node): writer.pull() elif isinstance( node.context_expr, Name ) and node.context_expr.id == 'lowlevel': self._with_ll = True - map(self.visit, node.body) + #map(self.visit, node.body) + for b in node.body: + a = self.visit(b) + if a: writer.write(a) self._with_ll = False elif isinstance( node.context_expr, Name ) and node.context_expr.id == 'javascript': self._with_js = True @@ -3151,9 +3830,40 @@ def visit_With(self, node): map(self.visit, node.body) self._with_inline = False + elif isinstance( node.context_expr, Name ) and node.context_expr.id in EXTRA_WITH_TYPES: + writer.write('with %s:' %self.visit(node.context_expr)) + writer.push() + for b in node.body: + a = self.visit(b) + if a: writer.write(a) + writer.pull() + + elif isinstance( node.context_expr, ast.Call ) and isinstance(node.context_expr.func, ast.Name) and node.context_expr.func.id in EXTRA_WITH_TYPES: + + restore = self._with_js + self._with_js = True + if node.context_expr.keywords: + assert len(node.context_expr.keywords)==1 + k = node.context_expr.keywords[0].arg + v = self.visit(node.context_expr.keywords[0].value) + a = 'with %s(%s=%s):' %( self.visit(node.context_expr.func), k,v ) + writer.write(a) + else: + writer.write('with %s:' %self.visit(node.context_expr)) + + + self._with_js = restore + + writer.push() + for b in node.body: + a = self.visit(b) + if a: writer.write(a) + writer.pull() + else: - raise SyntaxError('improper use of "with" statement') + raise SyntaxError('invalid use of "with" statement') +EXTRA_WITH_TYPES = ('__switch__', '__default__', '__case__', '__select__') class GeneratorFunctionTransformer( PythonToPythonJS ): ''' @@ -3167,38 +3877,15 @@ class GeneratorFunctionTransformer( PythonToPythonJS ): ''' def __init__(self, node, compiler=None): - self._with_ll = False - self._with_js = False - self._with_dart = False - self._with_coffee = False - self._with_lua = False - self._with_rpc = None - self._with_rpc_name = None - self._with_inline = False - self._in_while_test = False - self._in_lambda = False + assert '_stack' in dir(compiler) + #self.__dict___ = compiler.__dict__ ## share all state + for name in dir(compiler): + if name not in dir(self): + setattr(self, name, (getattr(compiler, name))) - if compiler._with_dart: ## TODO - self._with_dart = True - elif compiler._with_coffee: - self._with_coffee = True - elif compiler._with_lua: - self._with_lua = True - else: - self._with_js = True - - self._typedef_vars = compiler._typedef_vars - self._direct_operators = compiler._direct_operators - self._builtin_functions = compiler._builtin_functions - self._js_classes = compiler._js_classes - self._global_functions = compiler._global_functions - self._addop_ids = compiler._addop_ids - self._cache_for_body_calls = False - self._source = compiler._source - self._instances = dict() self._head_yield = False self.visit( node ) - compiler._addop_ids = self._addop_ids + compiler._addop_ids = self._addop_ids ## note: need to keep id index insync def visit_Yield(self, node): if self._in_head: @@ -3360,12 +4047,14 @@ def collect_generator_functions(node): -def main(script, dart=False, coffee=False, lua=False): +def main(script, dart=False, coffee=False, lua=False, go=False, module_path=None): translator = PythonToPythonJS( source = script, dart = dart or '--dart' in sys.argv, coffee = coffee, - lua = lua + lua = lua, + go = go, + module_path = module_path ) code = writer.getvalue() @@ -3384,18 +4073,15 @@ def main(script, dart=False, coffee=False, lua=False): return code -def command(): - module = None + +if __name__ == '__main__': + ## if run directly prints source transformed to python-js-subset, this is just for debugging ## scripts = [] if len(sys.argv) > 1: argv = sys.argv[1:] for i,arg in enumerate(argv): if arg.endswith('.py'): scripts.append( arg ) - module = arg.split('.')[0] - elif i > 0: - if argv[i-1] == '--module': - module = arg if len(scripts): a = [] @@ -3408,12 +4094,7 @@ def command(): compiler = PythonToPythonJS( source=data, - module=module, dart='--dart' in sys.argv ) output = writer.getvalue() print( output ) ## pipe to stdout - - -if __name__ == '__main__': - command() diff --git a/pythonjs/pythonjs.js b/pythonjs/pythonjs.js index 0cff487..fa6a00b 100644 --- a/pythonjs/pythonjs.js +++ b/pythonjs/pythonjs.js @@ -2,18 +2,18 @@ __NULL_OBJECT__ = Object.create(null); __WEBWORKER__ = false; __NODEJS__ = false; __BROWSER__ = false; -if (( typeof(process) ) != "undefined") { +if ((!(typeof(process) instanceof Array ? JSON.stringify(typeof(process))==JSON.stringify("undefined") : typeof(process)==="undefined"))) { __NODEJS__ = true; } -if (( typeof(window) ) != "undefined") { +if ((!(typeof(window) instanceof Array ? JSON.stringify(typeof(window))==JSON.stringify("undefined") : typeof(window)==="undefined"))) { __BROWSER__ = true; } -if (( typeof(importScripts) ) == "function") { +if ((typeof(importScripts) instanceof Array ? JSON.stringify(typeof(importScripts))==JSON.stringify("function") : typeof(importScripts)==="function")) { __WEBWORKER__ = true; } -__create_array__ = function() { +var __create_array__ = function() { "Used to fix a bug/feature of Javascript where new Array(number)\n created a array with number of undefined elements which is not\n what we want"; - var i, array; + var i,array; array = []; i = 0; while (( i ) < arguments.length) { @@ -23,7 +23,7 @@ __create_array__ = function() { return array; } -__get__ = function(object, attribute, error_message) { +var __get__ = function(object, attribute, error_message) { "Retrieve an attribute, method, property, or wrapper function.\n\n method are actually functions which are converted to methods by\n prepending their arguments with the current object. Properties are\n not functions!\n\n DOM support:\n http://stackoverflow.com/questions/14202699/document-createelement-not-working\n https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof\n\n Direct JavaScript Calls:\n if an external javascript function is found, and it was not a wrapper that was generated here,\n check the function for a 'cached_wrapper' attribute, if none is found then generate a new\n wrapper, cache it on the function, and return the wrapper.\n "; if (( object ) === null) { if (error_message) { @@ -40,21 +40,21 @@ __get__ = function(object, attribute, error_message) { } } } - if (( attribute ) == "__call__") { - if (object.pythonscript_function || object.is_wrapper) { + if ((attribute instanceof Array ? JSON.stringify(attribute)==JSON.stringify("__call__") : attribute==="__call__")) { + if ((object.pythonscript_function || object.is_wrapper)) { return object; } else { if (object.cached_wrapper) { return object.cached_wrapper; } else { if ({}.toString.call(object) === '[object Function]') { - var wrapper = function(args, kwargs) { - var i, arg, keys; - if (( args ) != null) { + var wrapper = function(args, kwargs) { + var i,arg,keys; + if ((!(args instanceof Array ? JSON.stringify(args)==JSON.stringify(null) : args===null))) { i = 0; while (( i ) < args.length) { arg = args[i]; - if (arg && ( typeof(arg) ) == "object") { + if ((arg && (typeof(arg) instanceof Array ? JSON.stringify(typeof(arg))==JSON.stringify("object") : typeof(arg)==="object"))) { if (arg.jsify) { args[i] = arg.jsify(); } @@ -62,14 +62,14 @@ __get__ = function(object, attribute, error_message) { i += 1; } } - if (( kwargs ) != null) { + if ((!(kwargs instanceof Array ? JSON.stringify(kwargs)==JSON.stringify(null) : kwargs===null))) { keys = __object_keys__(kwargs); - if (( keys.length ) != 0) { + if ((!(keys.length instanceof Array ? JSON.stringify(keys.length)==JSON.stringify(0) : keys.length===0))) { args.push(kwargs); i = 0; while (( i ) < keys.length) { arg = kwargs[keys[i]]; - if (arg && ( typeof(arg) ) == "object") { + if ((arg && (typeof(arg) instanceof Array ? JSON.stringify(typeof(arg))==JSON.stringify("object") : typeof(arg)==="object"))) { if (arg.jsify) { kwargs[keys[i]] = arg.jsify(); } @@ -93,10 +93,10 @@ __get__ = function(object, attribute, error_message) { } var attr; attr = object[attribute]; - if (( __NODEJS__ ) === false && ( __WEBWORKER__ ) === false) { + if ((( __NODEJS__ ) === false && ( __WEBWORKER__ ) === false)) { if (object instanceof HTMLDocument) { if (typeof(attr) === 'function') { - var wrapper = function(args, kwargs) { + var wrapper = function(args, kwargs) { return attr.apply(object, args); } @@ -108,7 +108,7 @@ __get__ = function(object, attribute, error_message) { } else { if (object instanceof HTMLElement) { if (typeof(attr) === 'function') { - var wrapper = function(args, kwargs) { + var wrapper = function(args, kwargs) { return attr.apply(object, args); } @@ -121,18 +121,18 @@ __get__ = function(object, attribute, error_message) { } } if (( attr ) !== undefined) { - if (( typeof(attr) ) == "function") { + if ((typeof(attr) instanceof Array ? JSON.stringify(typeof(attr))==JSON.stringify("function") : typeof(attr)==="function")) { if (attr.pythonscript_function === undefined && attr.is_wrapper === undefined) { - if (attr.prototype instanceof Object && ( Object.keys(attr.prototype).length ) > 0) { + if ((attr.prototype instanceof Object && ( Object.keys(attr.prototype).length ) > 0)) { return attr; } - var wrapper = function(args, kwargs) { - var i, arg, keys; - if (( args ) != null) { + var wrapper = function(args, kwargs) { + var i,arg,keys; + if ((!(args instanceof Array ? JSON.stringify(args)==JSON.stringify(null) : args===null))) { i = 0; while (( i ) < args.length) { arg = args[i]; - if (arg && ( typeof(arg) ) == "object") { + if ((arg && (typeof(arg) instanceof Array ? JSON.stringify(typeof(arg))==JSON.stringify("object") : typeof(arg)==="object"))) { if (arg.jsify) { args[i] = arg.jsify(); } @@ -140,14 +140,14 @@ __get__ = function(object, attribute, error_message) { i += 1; } } - if (( kwargs ) != null) { + if ((!(kwargs instanceof Array ? JSON.stringify(kwargs)==JSON.stringify(null) : kwargs===null))) { keys = __object_keys__(kwargs); - if (( keys.length ) != 0) { + if ((!(keys.length instanceof Array ? JSON.stringify(keys.length)==JSON.stringify(0) : keys.length===0))) { args.push(kwargs); i = 0; while (( i ) < keys.length) { arg = kwargs[keys[i]]; - if (arg && ( typeof(arg) ) == "object") { + if ((arg && (typeof(arg) instanceof Array ? JSON.stringify(typeof(arg))==JSON.stringify("object") : typeof(arg)==="object"))) { if (arg.jsify) { kwargs[keys[i]] = arg.jsify(); } @@ -164,10 +164,10 @@ __get__ = function(object, attribute, error_message) { return wrapper; } else { if (attr.is_classmethod) { - var method = function() { + var method = function() { var args; args = Array.prototype.slice.call(arguments); - if (args[0] instanceof Array && {}.toString.call(args[1]) === '[object Object]' && ( args.length ) == 2) { + if ((args[0] instanceof Array && {}.toString.call(args[1]) === '[object Object]' && (args.length instanceof Array ? JSON.stringify(args.length)==JSON.stringify(2) : args.length===2))) { /*pass*/ } else { args = [args, {}]; @@ -191,7 +191,7 @@ __get__ = function(object, attribute, error_message) { return attr; } } - var __class__, bases; + var __class__,bases; __class__ = object.__class__; if (__class__) { if (( attribute ) in __class__.__properties__) { @@ -200,8 +200,8 @@ __get__ = function(object, attribute, error_message) { if (( attribute ) in __class__.__unbound_methods__) { attr = __class__.__unbound_methods__[attribute]; if (attr.fastdef) { - var method = function(args, kwargs) { - if (arguments && arguments[0]) { + var method = function(args, kwargs) { + if ((arguments && arguments[0])) { arguments[0].splice(0, 0, object); return attr.apply(this, arguments); } else { @@ -210,11 +210,11 @@ __get__ = function(object, attribute, error_message) { } } else { - var method = function(args, kwargs) { - if (( arguments.length ) == 0) { + var method = function(args, kwargs) { + if ((arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(0) : arguments.length===0)) { return attr([object], __NULL_OBJECT__); } else { - if (args instanceof Array && ( typeof(kwargs) ) === "object" && ( arguments.length ) == 2) { + if ((args instanceof Array && ( typeof(kwargs) ) === "object" && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { args.splice(0, 0, object); if (( kwargs ) === undefined) { return attr(args, __NULL_OBJECT__); @@ -242,8 +242,8 @@ __get__ = function(object, attribute, error_message) { return attr; } else { if (attr.fastdef) { - var method = function(args, kwargs) { - if (arguments && arguments[0]) { + var method = function(args, kwargs) { + if ((arguments && arguments[0])) { arguments[0].splice(0, 0, object); return attr.apply(this, arguments); } else { @@ -252,11 +252,11 @@ __get__ = function(object, attribute, error_message) { } } else { - var method = function(args, kwargs) { - if (( arguments.length ) == 0) { + var method = function(args, kwargs) { + if ((arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(0) : arguments.length===0)) { return attr([object], __NULL_OBJECT__); } else { - if (args instanceof Array && ( typeof(kwargs) ) === "object" && ( arguments.length ) == 2) { + if ((args instanceof Array && ( typeof(kwargs) ) === "object" && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { args.splice(0, 0, object); if (( kwargs ) === undefined) { return attr(args, __NULL_OBJECT__); @@ -283,15 +283,15 @@ __get__ = function(object, attribute, error_message) { } bases = __class__.__bases__; var __iter1 = bases; - if (! (__iter1 instanceof Array || typeof __iter1 == "string" || __is_typed_array(__iter1)) ) { __iter1 = __object_keys__(__iter1) } + if (! (__iter1 instanceof Array || typeof __iter1 == "string" || __is_typed_array(__iter1) || __is_some_array(__iter1) )) { __iter1 = __object_keys__(__iter1) } for (var __idx1=0; __idx1 < __iter1.length; __idx1++) { var base = __iter1[ __idx1 ]; attr = _get_upstream_attribute(base, attribute); if (( attr ) !== undefined) { if ({}.toString.call(attr) === '[object Function]') { if (attr.fastdef) { - var method = function(args, kwargs) { - if (arguments && arguments[0]) { + var method = function(args, kwargs) { + if ((arguments && arguments[0])) { arguments[0].splice(0, 0, object); return attr.apply(this, arguments); } else { @@ -300,11 +300,11 @@ __get__ = function(object, attribute, error_message) { } } else { - var method = function(args, kwargs) { - if (( arguments.length ) == 0) { + var method = function(args, kwargs) { + if ((arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(0) : arguments.length===0)) { return attr([object], __NULL_OBJECT__); } else { - if (args instanceof Array && ( typeof(kwargs) ) === "object" && ( arguments.length ) == 2) { + if ((args instanceof Array && ( typeof(kwargs) ) === "object" && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { args.splice(0, 0, object); if (( kwargs ) === undefined) { return attr(args, __NULL_OBJECT__); @@ -330,7 +330,7 @@ __get__ = function(object, attribute, error_message) { } } var __iter2 = bases; - if (! (__iter2 instanceof Array || typeof __iter2 == "string" || __is_typed_array(__iter2)) ) { __iter2 = __object_keys__(__iter2) } + if (! (__iter2 instanceof Array || typeof __iter2 == "string" || __is_typed_array(__iter2) || __is_some_array(__iter2) )) { __iter2 = __object_keys__(__iter2) } for (var __idx2=0; __idx2 < __iter2.length; __idx2++) { var base = __iter2[ __idx2 ]; var prop; @@ -343,7 +343,7 @@ __get__ = function(object, attribute, error_message) { return __class__["__getattr__"]([object, attribute], {}); } var __iter3 = bases; - if (! (__iter3 instanceof Array || typeof __iter3 == "string" || __is_typed_array(__iter3)) ) { __iter3 = __object_keys__(__iter3) } + if (! (__iter3 instanceof Array || typeof __iter3 == "string" || __is_typed_array(__iter3) || __is_some_array(__iter3) )) { __iter3 = __object_keys__(__iter3) } for (var __idx3=0; __idx3 < __iter3.length; __idx3++) { var base = __iter3[ __idx3 ]; var f; @@ -353,16 +353,19 @@ __get__ = function(object, attribute, error_message) { } } } - if (( attribute ) == "__getitem__") { - var wrapper = function(args, kwargs) { - return object[args[0]]; + if ((attribute instanceof Array ? JSON.stringify(attribute)==JSON.stringify("__getitem__") : attribute==="__getitem__")) { + var wrapper = function(args, kwargs) { + v = object[args[0]]; + if (( v ) === undefined) { + throw new KeyError(args[0]); + } } wrapper.is_wrapper = true; return wrapper; } else { - if (( attribute ) == "__setitem__") { - var wrapper = function(args, kwargs) { + if ((attribute instanceof Array ? JSON.stringify(attribute)==JSON.stringify("__setitem__") : attribute==="__setitem__")) { + var wrapper = function(args, kwargs) { object[args[0]] = args[1]; } @@ -370,20 +373,20 @@ __get__ = function(object, attribute, error_message) { return wrapper; } } - if (typeof(object, "function") && object.is_wrapper) { + if ((typeof(object, "function") && object.is_wrapper)) { return object.wrapped[attribute]; } - if (( attribute ) == "__iter__" && object instanceof Object) { - var wrapper = function(args, kwargs) { + if (((attribute instanceof Array ? JSON.stringify(attribute)==JSON.stringify("__iter__") : attribute==="__iter__") && object instanceof Object)) { + var wrapper = function(args, kwargs) { return new __ArrayIterator(Object.keys(object), 0); } wrapper.is_wrapper = true; return wrapper; } - if (( attribute ) == "__contains__" && object instanceof Object) { - var wrapper = function(args, kwargs) { - return ( Object.keys(object).indexOf(args[0]) ) != -1; + if (((attribute instanceof Array ? JSON.stringify(attribute)==JSON.stringify("__contains__") : attribute==="__contains__") && object instanceof Object)) { + var wrapper = function(args, kwargs) { + return (!(Object.keys(object).indexOf(args[0]) instanceof Array ? JSON.stringify(Object.keys(object).indexOf(args[0]))==JSON.stringify(-1) : Object.keys(object).indexOf(args[0])===-1)); } wrapper.is_wrapper = true; @@ -400,33 +403,33 @@ __get__ = function(object, attribute, error_message) { } } -_get_upstream_attribute = function(base, attr) { +var _get_upstream_attribute = function(base, attr) { if (( attr ) in base) { return base[attr]; } var __iter4 = base.__bases__; - if (! (__iter4 instanceof Array || typeof __iter4 == "string" || __is_typed_array(__iter4)) ) { __iter4 = __object_keys__(__iter4) } + if (! (__iter4 instanceof Array || typeof __iter4 == "string" || __is_typed_array(__iter4) || __is_some_array(__iter4) )) { __iter4 = __object_keys__(__iter4) } for (var __idx4=0; __idx4 < __iter4.length; __idx4++) { var parent = __iter4[ __idx4 ]; return _get_upstream_attribute(parent, attr); } } -_get_upstream_property = function(base, attr) { +var _get_upstream_property = function(base, attr) { if (( attr ) in base.__properties__) { return base.__properties__[attr]; } var __iter5 = base.__bases__; - if (! (__iter5 instanceof Array || typeof __iter5 == "string" || __is_typed_array(__iter5)) ) { __iter5 = __object_keys__(__iter5) } + if (! (__iter5 instanceof Array || typeof __iter5 == "string" || __is_typed_array(__iter5) || __is_some_array(__iter5) )) { __iter5 = __object_keys__(__iter5) } for (var __idx5=0; __idx5 < __iter5.length; __idx5++) { var parent = __iter5[ __idx5 ]; return _get_upstream_property(parent, attr); } } -__set__ = function(object, attribute, value) { +var __set__ = function(object, attribute, value) { "\n __setattr__ is always called when an attribute is set,\n unlike __getattr__ that only triggers when an attribute is not found,\n this asymmetry is in fact part of the Python spec.\n note there is no __setattribute__\n\n In normal Python a property setter is not called before __setattr__,\n this is bad language design because the user has been more explicit\n in having the property setter.\n\n In PythonJS, property setters are called instead of __setattr__.\n "; - if (( "__class__" ) in object && ( object.__class__.__setters__.indexOf(attribute) ) != -1) { + if ((( "__class__" ) in object && (!(object.__class__.__setters__.indexOf(attribute) instanceof Array ? JSON.stringify(object.__class__.__setters__.indexOf(attribute))==JSON.stringify(-1) : object.__class__.__setters__.indexOf(attribute)===-1)))) { object[attribute] = value; } else { if (( "__setattr__" ) in object) { @@ -437,7 +440,7 @@ __set__ = function(object, attribute, value) { } } -__getargs__ = function(func_name, signature, args, kwargs) { +var __getargs__ = function(func_name, signature, args, kwargs) { "Based on ``signature`` and ``args``, ``kwargs`` parameters retrieve\n the actual parameters.\n\n This will set default keyword arguments and retrieve positional arguments\n in kwargs if their called as such"; if (( args ) === null) { args = []; @@ -481,56 +484,481 @@ __getargs__ = function(func_name, signature, args, kwargs) { return out; } -try { -/*pass*/ -} catch(__exception__) { -console.trace(); -console.error(__exception__, __exception__.message); -console.error("line 5: pythonjs.configure(runtime_exceptions=False)"); -throw new RuntimeError("line 5: pythonjs.configure(runtime_exceptions=False)"); - -} _PythonJS_UID = 0; IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError"; KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError"; ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError"; AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError"; RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError"; -__getattr__ = function(ob, a) { - if (ob.__getattr__) { - return ob.__getattr__(a); +var __getfast__ = function(ob, attr) { + var v; + v = ob[attr]; + if (( v ) === undefined) { + throw new AttributeError(attr); + } else { + return v; + } +} + +var __wrap_function__ = function(f) { + + f.is_wrapper = true; + return f; +} + +var __gpu_object = function(cls, struct_name, data_name) { + + cls.prototype.__struct_name__ = struct_name; + cls.prototype.__struct_data__ = data_name; +} + +gpu = { "object":__gpu_object }; +var glsljit_runtime = function(header) { + + return new GLSLJITRuntime(header); +} + +var GLSLJITRuntime = function(header) { + GLSLJITRuntime.__init__(this, header); + this.__class__ = GLSLJITRuntime; + this.__uid__ = ("" + _PythonJS_UID); + _PythonJS_UID += 1; +} + +GLSLJITRuntime.__uid__ = ("" + _PythonJS_UID); +_PythonJS_UID += 1; +GLSLJITRuntime.prototype.__init__ = function(header) { + + this.header = header; + this.shader = []; + this.object_packagers = []; + this.struct_types = __jsdict([]); + this.glsltypes = ["vec2", "vec3", "vec4", "mat4"]; + this.matrices = []; +} + +GLSLJITRuntime.__init__ = function () { return GLSLJITRuntime.prototype.__init__.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.compile_header = function() { + var a,b; + a = []; + var __iter1 = this.struct_types; + if (! (__iter1 instanceof Array || typeof __iter1 == "string" || __is_typed_array(__iter1) || __is_some_array(__iter1) )) { __iter1 = __object_keys__(__iter1) } + for (var __idx1=0; __idx1 < __iter1.length; __idx1++) { + var sname = __iter1[ __idx1 ]; + if (__contains__(this.glsltypes, sname)) { + /*pass*/ + } else { + a.push(this.struct_types[sname]["code"]); + } + } + a.push(__sprintf("int matrix_index() { return int(get_global_id().y*%s.0); }", this.matrices.length)); + a.push("int matrix_row() { return int(get_global_id().x*4.0); }"); + a = "\n".join(a); + b = "\n".join(this.header); + return "\n".join([a, b]); +} + +GLSLJITRuntime.compile_header = function () { return GLSLJITRuntime.prototype.compile_header.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.compile_main = function() { + + return "\n".join(this.shader); +} + +GLSLJITRuntime.compile_main = function () { return GLSLJITRuntime.prototype.compile_main.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.push = function(s) { + + this.shader.push(s); +} + +GLSLJITRuntime.push = function () { return GLSLJITRuntime.prototype.push.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.define_structure = function(ob) { + var integers,arr,code,struct_name,struct_type,member_list,subtype,t,members,arrays,structs,floats; + struct_name = null; + if (__test_if_true__(ob.__struct_name__)) { + struct_name = ob.__struct_name__; + if (__contains__(this.struct_types, struct_name)) { + return struct_name; + } + } + arrays = []; + floats = []; + integers = []; + structs = []; + struct_type = []; + if (__test_if_true__((struct_name && __contains__(this.glsltypes, struct_name)))) { + return struct_name; + } + var __iter2 = dir(ob); + if (! (__iter2 instanceof Array || typeof __iter2 == "string" || __is_typed_array(__iter2) || __is_some_array(__iter2) )) { __iter2 = __object_keys__(__iter2) } + for (var __idx2=0; __idx2 < __iter2.length; __idx2++) { + var key = __iter2[ __idx2 ]; + if (__test_if_true__(((key.length instanceof Array ? JSON.stringify(key.length)==JSON.stringify(1) : key.length===1) && __contains__("0123456789", key)))) { + throw new RuntimeError(key); + } + t = typeof(ob[key]); + if (__test_if_true__(((t instanceof Array ? JSON.stringify(t)==JSON.stringify("object") : t==="object") && ob[key] instanceof Array && ob[key].length && (typeof(ob[key][0]) instanceof Array ? JSON.stringify(typeof(ob[key][0]))==JSON.stringify("number") : typeof(ob[key][0])==="number")))) { + struct_type.push(("ARY_" + key)); + arrays.push(key); + } else { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("number") : t==="number")) { + struct_type.push(("NUM_" + key)); + floats.push(key); + } else { + if (__test_if_true__(ob[key] instanceof Int16Array)) { + struct_type.push(("INT_" + key)); + if ((ob[key].length instanceof Array ? JSON.stringify(ob[key].length)==JSON.stringify(1) : ob[key].length===1)) { + integers.push(key); + } else { + /*pass*/ + } + } else { + if (__test_if_true__(((t instanceof Array ? JSON.stringify(t)==JSON.stringify("object") : t==="object") && ob[key].__struct_name__))) { + struct_type.push(("S_" + key)); + structs.push(key); + if (! (__contains__(this.struct_types, ob[key].__struct_name__))) { + if (__contains__(this.glsltypes, ob[key].__struct_name__)) { + /*pass*/ + } else { + this.define_structure(ob[key]); + } + } + } + } + } + } + } + if (( struct_name ) === null) { + struct_name = "".join(struct_type); + ob.__struct_name__ = struct_name; + } + if (! (__contains__(this.struct_types, struct_name))) { + member_list = []; + var __iter3 = integers; + if (! (__iter3 instanceof Array || typeof __iter3 == "string" || __is_typed_array(__iter3) || __is_some_array(__iter3) )) { __iter3 = __object_keys__(__iter3) } + for (var __idx3=0; __idx3 < __iter3.length; __idx3++) { + var key = __iter3[ __idx3 ]; + member_list.append((("int " + key) + ";")); + } + var __iter4 = floats; + if (! (__iter4 instanceof Array || typeof __iter4 == "string" || __is_typed_array(__iter4) || __is_some_array(__iter4) )) { __iter4 = __object_keys__(__iter4) } + for (var __idx4=0; __idx4 < __iter4.length; __idx4++) { + var key = __iter4[ __idx4 ]; + member_list.append((("float " + key) + ";")); + } + var __iter5 = arrays; + if (! (__iter5 instanceof Array || typeof __iter5 == "string" || __is_typed_array(__iter5) || __is_some_array(__iter5) )) { __iter5 = __object_keys__(__iter5) } + for (var __idx5=0; __idx5 < __iter5.length; __idx5++) { + var key = __iter5[ __idx5 ]; + arr = ob[key]; + member_list.append((((("float " + key) + "[") + arr.length) + "];")); + } + var __iter6 = structs; + if (! (__iter6 instanceof Array || typeof __iter6 == "string" || __is_typed_array(__iter6) || __is_some_array(__iter6) )) { __iter6 = __object_keys__(__iter6) } + for (var __idx6=0; __idx6 < __iter6.length; __idx6++) { + var key = __iter6[ __idx6 ]; + subtype = ob[key].__struct_name__; + member_list.append((((subtype + " ") + key) + ";")); + } + if ((len(member_list) instanceof Array ? JSON.stringify(len(member_list))==JSON.stringify(0) : len(member_list)===0)) { + throw new RuntimeError(struct_name); + } + members = "".join(member_list); + code = (((("struct " + struct_name) + " {") + members) + "};"); + this.struct_types[struct_name] = __jsdict([["arrays", arrays], ["floats", floats], ["integers", integers], ["structs", structs], ["code", code]]); + } + return struct_name; +} + +GLSLJITRuntime.define_structure = function () { return GLSLJITRuntime.prototype.define_structure.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.structure = function(ob, name) { + var sname,stype,args,value,has_arrays,o,aname,wrapper; + wrapper = null; + if (__test_if_true__(ob instanceof Object)) { + /*pass*/ + } else { + if (( ob.__class__ ) === dict) { + wrapper = ob; + ob = ob["$wrapped"]; + } + } + sname = this.define_structure(ob); + if (__test_if_true__(wrapper)) { + wrapper.__struct_name__ = sname; + } + args = []; + stype = this.struct_types[sname]; + if (! (__contains__(this.struct_types, sname))) { + if (__contains__(this.glsltypes, sname)) { + if ((sname instanceof Array ? JSON.stringify(sname)==JSON.stringify("mat4") : sname==="mat4")) { + if (__test_if_true__(ob.__struct_data__)) { + o = ob[ob.__struct_data__]; + } else { + o = ob; + } + var i,i__end__; + i = 0; + i__end__ = o.length; + while (( i ) < i__end__) { + value = (o[i] + ""); + if (! (__contains__(value, "."))) { + value += ".0"; + } + args.push(value); + i += 1; + } + } + } else { + throw new RuntimeError(("no method to pack structure: " + sname)); + } + } + has_arrays = false; + if (__test_if_true__(stype)) { + if (( stype["arrays"].length ) > 0) { + has_arrays = true; + } + var __iter7 = stype["integers"]; + if (! (__iter7 instanceof Array || typeof __iter7 == "string" || __is_typed_array(__iter7) || __is_some_array(__iter7) )) { __iter7 = __object_keys__(__iter7) } + for (var __idx7=0; __idx7 < __iter7.length; __idx7++) { + var key = __iter7[ __idx7 ]; + args.push((ob[key][0] + "")); + } + var __iter8 = stype["floats"]; + if (! (__iter8 instanceof Array || typeof __iter8 == "string" || __is_typed_array(__iter8) || __is_some_array(__iter8) )) { __iter8 = __object_keys__(__iter8) } + for (var __idx8=0; __idx8 < __iter8.length; __idx8++) { + var key = __iter8[ __idx8 ]; + value = (ob[key] + ""); + if (! (__contains__(value, "."))) { + value += ".0"; + } + args.push(value); + } + var __iter9 = stype["arrays"]; + if (! (__iter9 instanceof Array || typeof __iter9 == "string" || __is_typed_array(__iter9) || __is_some_array(__iter9) )) { __iter9 = __object_keys__(__iter9) } + for (var __idx9=0; __idx9 < __iter9.length; __idx9++) { + var key = __iter9[ __idx9 ]; + aname = (("_" + key) + name); + this.array(ob[key], aname); + args.push(aname); + } + var __iter10 = stype["structs"]; + if (! (__iter10 instanceof Array || typeof __iter10 == "string" || __is_typed_array(__iter10) || __is_some_array(__iter10) )) { __iter10 = __object_keys__(__iter10) } + for (var __idx10=0; __idx10 < __iter10.length; __idx10++) { + var key = __iter10[ __idx10 ]; + aname = (("_" + key) + name); + this.structure(ob[key], aname); + args.push(aname); + } + } + args = ",".join(args); + if (__test_if_true__(has_arrays)) { + this.shader.push((((((((sname + " ") + name) + "=") + sname) + "(") + args) + ");")); + } else { + this.header.push((((((((("const " + sname) + " ") + name) + "=") + sname) + "(") + args) + ");")); + } + return stype; +} + +GLSLJITRuntime.structure = function () { return GLSLJITRuntime.prototype.structure.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.int16array = function(ob, name) { + var a,i; + a = [(((("int " + name) + "[") + ob.length) + "]")]; + i = 0; + while (( i ) < ob.length) { + a.push((((((";" + name) + "[") + i) + "]=") + ob[i])); + i += 1; + } + this.shader.push("".join(a)); +} + +GLSLJITRuntime.int16array = function () { return GLSLJITRuntime.prototype.int16array.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.array = function(ob, name) { + var a,i,j,subname,subarr,v; + if (__test_if_true__(ob[0] instanceof Array)) { + a = []; + i = 0; + while (( i ) < ob.length) { + subarr = ob[i]; + subname = __sprintf("%s_%s", [name, i]); + if ((a.length instanceof Array ? JSON.stringify(a.length)==JSON.stringify(0) : a.length===0)) { + a.append((((("float " + subname) + "[") + subarr.length) + "]")); + } else { + a.append(((((";float " + subname) + "[") + subarr.length) + "]")); + } + j = 0; + while (( j ) < subarr.length) { + v = (subarr[j] + ""); + if (! (__contains__(v, "."))) { + v += ".0"; + } + a.push((((((";" + subname) + "[") + j) + "]=") + v)); + j += 1; + } + i += 1; + } + this.shader.push("".join(a)); + } else { + if (__test_if_true__((ob[0] instanceof Object || ( ob[0].__class__ ) === dict))) { + i = 0; + while (( i ) < ob.length) { + this.structure(ob[i], ((name + "_") + i)); + i += 1; + } + } else { + a = [(((("float " + name) + "[") + ob.length) + "];")]; + i = 0; + while (( i ) < ob.length) { + a.push((((((name + "[") + i) + "]=") + ob[i]) + ";")); + i += 1; + } + this.shader.push("".join(a)); + } + } +} + +GLSLJITRuntime.array = function () { return GLSLJITRuntime.prototype.array.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.object = function(ob, name) { + var func,cls; + var __iter11 = this.object_packagers; + if (! (__iter11 instanceof Array || typeof __iter11 == "string" || __is_typed_array(__iter11) || __is_some_array(__iter11) )) { __iter11 = __object_keys__(__iter11) } + for (var __idx11=0; __idx11 < __iter11.length; __idx11++) { + var p = __iter11[ __idx11 ]; + var __r_0; + __r_0 = p; + cls = __r_0[0]; + func = __r_0[1]; + if (__test_if_true__(ob instanceof cls)) { + return func(ob); + } + } +} + +GLSLJITRuntime.object = function () { return GLSLJITRuntime.prototype.object.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.unpack_array2d = function(arr, dims) { + var h,rows,w,row; + if ((typeof(dims) instanceof Array ? JSON.stringify(typeof(dims))==JSON.stringify("number") : typeof(dims)==="number")) { + return arr; + } + var __r_1; + __r_1 = dims; + w = __r_1[0]; + h = __r_1[1]; + row = []; + rows = [row]; + var __iter12 = arr; + if (! (__iter12 instanceof Array || typeof __iter12 == "string" || __is_typed_array(__iter12) || __is_some_array(__iter12) )) { __iter12 = __object_keys__(__iter12) } + for (var __idx12=0; __idx12 < __iter12.length; __idx12++) { + var value = __iter12[ __idx12 ]; + row.append(value); + if (( row.length ) >= w) { + row = []; + rows.append(row); + } + } + __jsdict_pop(rows); + if ((!(rows.length instanceof Array ? JSON.stringify(rows.length)==JSON.stringify(h) : rows.length===h))) { + console.log("ERROR: __unpack_array2d, invalid height."); + } + return rows; +} + +GLSLJITRuntime.unpack_array2d = function () { return GLSLJITRuntime.prototype.unpack_array2d.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.unpack_vec4 = function(arr, dims) { + var rows,i,h,vec,w,row; + if ((typeof(dims) instanceof Array ? JSON.stringify(typeof(dims))==JSON.stringify("number") : typeof(dims)==="number")) { + w = dims; + h = 1; + } else { + var __r_2; + __r_2 = dims; + w = __r_2[0]; + h = __r_2[1]; + } + rows = []; + i = 0; + var y,y__end__; + y = 0; + y__end__ = h; + while (( y ) < y__end__) { + row = []; + rows.append(row); + var x,x__end__; + x = 0; + x__end__ = w; + while (( x ) < x__end__) { + vec = []; + var j,j__end__; + j = 0; + j__end__ = 4; + while (( j ) < j__end__) { + vec.append(arr[i]); + i += 1; + j += 1; + } + row.append(vec); + x += 1; + } + y += 1; + } + if ((!(rows.length instanceof Array ? JSON.stringify(rows.length)==JSON.stringify(h) : rows.length===h))) { + console.log("ERROR: __unpack_vec4, invalid height."); + } + return rows; +} + +GLSLJITRuntime.unpack_vec4 = function () { return GLSLJITRuntime.prototype.unpack_vec4.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.unpack_mat4 = function(arr) { + var i; + i = 0; + var __iter13 = this.matrices; + if (! (__iter13 instanceof Array || typeof __iter13 == "string" || __is_typed_array(__iter13) || __is_some_array(__iter13) )) { __iter13 = __object_keys__(__iter13) } + for (var __idx13=0; __idx13 < __iter13.length; __idx13++) { + var mat = __iter13[ __idx13 ]; + var j,j__end__; + j = 0; + j__end__ = 16; + while (( j ) < j__end__) { + mat[j] = arr[i]; + i += 1; + j += 1; + } } + return this.matrices; } -__getattr__.NAME = "__getattr__"; -__getattr__.args_signature = ["ob", "a"]; -__getattr__.kwargs_signature = { }; -__getattr__.types_signature = { }; -__getattr__.pythonscript_function = true; -__test_if_true__ = function(ob) { +GLSLJITRuntime.unpack_mat4 = function () { return GLSLJITRuntime.prototype.unpack_mat4.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; +GLSLJITRuntime.prototype.__properties__ = { }; +GLSLJITRuntime.prototype.__unbound_methods__ = { }; +var __getattr__ = function(ob, a) { + + if (ob.__getattr__) { + return ob.__getattr__(a); + } +};__getattr__.is_wrapper = true; +var __test_if_true__ = function(ob) { + if (( ob ) === true) { return true; } else { if (( ob ) === false) { return false; } else { - if (( typeof(ob) ) == "string") { - return ( ob.length ) != 0; + if ((typeof(ob) instanceof Array ? JSON.stringify(typeof(ob))==JSON.stringify("string") : typeof(ob)==="string")) { + return (!(ob.length instanceof Array ? JSON.stringify(ob.length)==JSON.stringify(0) : ob.length===0)); } else { if (! (ob)) { return false; } else { if (ob instanceof Array) { - return ( ob.length ) != 0; + return (!(ob.length instanceof Array ? JSON.stringify(ob.length)==JSON.stringify(0) : ob.length===0)); } else { - if (( typeof(ob) ) == "function") { + if ((typeof(ob) instanceof Array ? JSON.stringify(typeof(ob))==JSON.stringify("function") : typeof(ob)==="function")) { return true; } else { - if (ob.__class__ && ( ob.__class__ ) === dict) { - return ( Object.keys(ob["$wrapped"]).length ) != 0; + if ((ob.__class__ && ( ob.__class__ ) === dict)) { + return (!(Object.keys(ob["$wrapped"]).length instanceof Array ? JSON.stringify(Object.keys(ob["$wrapped"]).length)==JSON.stringify(0) : Object.keys(ob["$wrapped"]).length===0)); } else { if (ob instanceof Object) { - return ( Object.keys(ob).length ) != 0; + return (!(Object.keys(ob).length instanceof Array ? JSON.stringify(Object.keys(ob).length)==JSON.stringify(0) : Object.keys(ob).length===0)); } else { return true; } @@ -541,28 +969,18 @@ __test_if_true__ = function(ob) { } } } -} - -__test_if_true__.NAME = "__test_if_true__"; -__test_if_true__.args_signature = ["ob"]; -__test_if_true__.kwargs_signature = { }; -__test_if_true__.types_signature = { }; -__test_if_true__.pythonscript_function = true; -__replace_method = function(ob, a, b) { - if (( typeof(ob) ) == "string") { +};__test_if_true__.is_wrapper = true; +var __replace_method = function(ob, a, b) { + + if ((typeof(ob) instanceof Array ? JSON.stringify(typeof(ob))==JSON.stringify("string") : typeof(ob)==="string")) { return ob.split(a).join(b); } else { return ob.replace(a, b); } -} - -__replace_method.NAME = "__replace_method"; -__replace_method.args_signature = ["ob", "a", "b"]; -__replace_method.kwargs_signature = { }; -__replace_method.types_signature = { }; -__replace_method.pythonscript_function = true; -__split_method = function(ob, delim) { - if (( typeof(ob) ) == "string") { +};__replace_method.is_wrapper = true; +var __split_method = function(ob, delim) { + + if ((typeof(ob) instanceof Array ? JSON.stringify(typeof(ob))==JSON.stringify("string") : typeof(ob)==="string")) { if (( delim ) === undefined) { return ob.split(" "); } else { @@ -575,24 +993,50 @@ __split_method = function(ob, delim) { return ob.split(delim); } } +};__split_method.is_wrapper = true; +__dom_array_types__ = []; +if ((typeof(NodeList) instanceof Array ? JSON.stringify(typeof(NodeList))==JSON.stringify("function") : typeof(NodeList)==="function")) { + __dom_array_types__ = [NodeList, FileList, DOMStringList, HTMLCollection, SVGNumberList, SVGTransformList]; + if ((typeof(DataTransferItemList) instanceof Array ? JSON.stringify(typeof(DataTransferItemList))==JSON.stringify("function") : typeof(DataTransferItemList)==="function")) { + __dom_array_types__.push(DataTransferItemList); + } + if ((typeof(HTMLAllCollection) instanceof Array ? JSON.stringify(typeof(HTMLAllCollection))==JSON.stringify("function") : typeof(HTMLAllCollection)==="function")) { + __dom_array_types__.push(HTMLAllCollection); + } + if ((typeof(SVGElementInstanceList) instanceof Array ? JSON.stringify(typeof(SVGElementInstanceList))==JSON.stringify("function") : typeof(SVGElementInstanceList)==="function")) { + __dom_array_types__.push(SVGElementInstanceList); + } + if ((typeof(ClientRectList) instanceof Array ? JSON.stringify(typeof(ClientRectList))==JSON.stringify("function") : typeof(ClientRectList)==="function")) { + __dom_array_types__.push(ClientRectList); + } +} +var __is_some_array = function(ob) { + + if (( __dom_array_types__.length ) > 0) { + var __iter14 = __dom_array_types__; + if (! (__iter14 instanceof Array || typeof __iter14 == "string" || __is_typed_array(__iter14) || __is_some_array(__iter14) )) { __iter14 = __object_keys__(__iter14) } + for (var __idx14=0; __idx14 < __iter14.length; __idx14++) { + var t = __iter14[ __idx14 ]; + if (__test_if_true__(ob instanceof t)) { + return true; + } + } + } + return false; } -__split_method.NAME = "__split_method"; -__split_method.args_signature = ["ob", "delim"]; -__split_method.kwargs_signature = { }; -__split_method.types_signature = { }; -__split_method.pythonscript_function = true; -__is_typed_array = function(ob) { - if (__test_if_true__(ob instanceof Int8Array || ob instanceof Uint8Array)) { +var __is_typed_array = function(ob) { + + if (__test_if_true__((ob instanceof Int8Array || ob instanceof Uint8Array))) { return true; } else { - if (__test_if_true__(ob instanceof Int16Array || ob instanceof Uint16Array)) { + if (__test_if_true__((ob instanceof Int16Array || ob instanceof Uint16Array))) { return true; } else { - if (__test_if_true__(ob instanceof Int32Array || ob instanceof Uint32Array)) { + if (__test_if_true__((ob instanceof Int32Array || ob instanceof Uint32Array))) { return true; } else { - if (__test_if_true__(ob instanceof Float32Array || ob instanceof Float64Array)) { + if (__test_if_true__((ob instanceof Float32Array || ob instanceof Float64Array))) { return true; } else { return false; @@ -602,42 +1046,34 @@ __is_typed_array = function(ob) { } } -__is_typed_array.NAME = "__is_typed_array"; -__is_typed_array.args_signature = ["ob"]; -__is_typed_array.kwargs_signature = { }; -__is_typed_array.types_signature = { }; -__js_typed_array = function(t, a) { +var __js_typed_array = function(t, a) { var arr; - if (( t ) == "i") { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("i") : t==="i")) { arr = new Int32Array(a.length); } arr.set(a); return arr; } -__js_typed_array.NAME = "__js_typed_array"; -__js_typed_array.args_signature = ["t", "a"]; -__js_typed_array.kwargs_signature = { }; -__js_typed_array.types_signature = { }; -__contains__ = function(ob, a) { +var __contains__ = function(ob, a) { var t; t = typeof(ob); - if (( t ) == "string") { - if (( ob.indexOf(a) ) == -1) { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("string") : t==="string")) { + if ((ob.indexOf(a) instanceof Array ? JSON.stringify(ob.indexOf(a))==JSON.stringify(-1) : ob.indexOf(a)===-1)) { return false; } else { return true; } } else { - if (( t ) == "number") { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("number") : t==="number")) { throw new TypeError; } else { if (__test_if_true__(__is_typed_array(ob))) { - var __iter1 = ob; - if (! (__iter1 instanceof Array || typeof __iter1 == "string" || __is_typed_array(__iter1)) ) { __iter1 = __object_keys__(__iter1) } - for (var __idx1=0; __idx1 < __iter1.length; __idx1++) { - var x = __iter1[ __idx1 ]; - if (( x ) == a) { + var __iter15 = ob; + if (! (__iter15 instanceof Array || typeof __iter15 == "string" || __is_typed_array(__iter15) || __is_some_array(__iter15) )) { __iter15 = __object_keys__(__iter15) } + for (var __idx15=0; __idx15 < __iter15.length; __idx15++) { + var x = __iter15[ __idx15 ]; + if ((x instanceof Array ? JSON.stringify(x)==JSON.stringify(a) : x===a)) { return true; } } @@ -646,7 +1082,7 @@ __contains__ = function(ob, a) { if (__test_if_true__(ob.__contains__)) { return ob.__contains__(a); } else { - if (__test_if_true__(ob instanceof Object && Object.hasOwnProperty.call(ob, a))) { + if (__test_if_true__((ob instanceof Object && Object.hasOwnProperty.call(ob, a)))) { return true; } else { return false; @@ -657,14 +1093,10 @@ __contains__ = function(ob, a) { } } -__contains__.NAME = "__contains__"; -__contains__.args_signature = ["ob", "a"]; -__contains__.kwargs_signature = { }; -__contains__.types_signature = { }; -__add_op = function(a, b) { - var c, t; +var __add_op = function(a, b) { + var c,t; t = typeof(a); - if (__test_if_true__(( t ) == "string" || ( t ) == "number")) { + if (__test_if_true__(((t instanceof Array ? JSON.stringify(t)==JSON.stringify("string") : t==="string") || (t instanceof Array ? JSON.stringify(t)==JSON.stringify("number") : t==="number")))) { return a+b; } else { if (__test_if_true__(a instanceof Array)) { @@ -682,34 +1114,72 @@ __add_op = function(a, b) { } } -__add_op.NAME = "__add_op"; -__add_op.args_signature = ["a", "b"]; -__add_op.kwargs_signature = { }; -__add_op.types_signature = { }; -__jsdict = function(items) { - var d, key; +var __mul_op = function(a, b) { + var c,arr,t; + t = typeof(a); + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("number") : t==="number")) { + return a * b; + } else { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("string") : t==="string")) { + arr = []; + var i,i__end__; + i = 0; + i__end__ = b; + while (( i ) < i__end__) { + arr.append(a); + i += 1; + } + return "".join(arr); + } else { + if (__test_if_true__(a instanceof Array)) { + c = []; + + i = 0; + i__end__ = b; + while (( i ) < i__end__) { + c.extend(a); + i += 1; + } + return c; + } else { + if (__test_if_true__(a.__mul__)) { + return a.__mul__(b); + } else { + throw new TypeError("invalid objects for multiplication"); + } + } + } + } +} + +var __jsdict = function(items) { + var d,key; d = {}; - var __iter2 = items; - if (! (__iter2 instanceof Array || typeof __iter2 == "string" || __is_typed_array(__iter2)) ) { __iter2 = __object_keys__(__iter2) } - for (var __idx2=0; __idx2 < __iter2.length; __idx2++) { - var item = __iter2[ __idx2 ]; + var __iter16 = items; + if (! (__iter16 instanceof Array || typeof __iter16 == "string" || __is_typed_array(__iter16) || __is_some_array(__iter16) )) { __iter16 = __object_keys__(__iter16) } + for (var __idx16=0; __idx16 < __iter16.length; __idx16++) { + var item = __iter16[ __idx16 ]; key = item[0]; - if (__test_if_true__(key.__uid__)) { - key = key.__uid__; + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } else { + if (__test_if_true__(key.__uid__)) { + key = key.__uid__; + } } - d[((key.__uid__) ? key.__uid__ : key)] = item[1]; + d[key] = item[1]; } return d; } -__jsdict.NAME = "__jsdict"; -__jsdict.args_signature = ["items"]; -__jsdict.kwargs_signature = { }; -__jsdict.types_signature = { }; -__jsdict_get = function(ob, key, default_value) { +var __jsdict_get = function(ob, key, default_value) { + if (__test_if_true__(ob instanceof Object)) { + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } if (__test_if_true__(key in ob)) { - return ob[((key.__uid__) ? key.__uid__ : key)]; + return ob[key]; } return default_value; } else { @@ -721,23 +1191,20 @@ __jsdict_get = function(ob, key, default_value) { } } -__jsdict_get.NAME = "__jsdict_get"; -__jsdict_get.args_signature = ["ob", "key", "default_value"]; -__jsdict_get.kwargs_signature = { }; -__jsdict_get.types_signature = { }; -__jsdict_set = function(ob, key, value) { +var __jsdict_set = function(ob, key, value) { + if (__test_if_true__(ob instanceof Object)) { - ob[((key.__uid__) ? key.__uid__ : key)] = value; + if (__test_if_true__(key instanceof Array)) { + key = JSON.stringify(key); + } + ob[key] = value; } else { ob.set(key,value); } } -__jsdict_set.NAME = "__jsdict_set"; -__jsdict_set.args_signature = ["ob", "key", "value"]; -__jsdict_set.kwargs_signature = { }; -__jsdict_set.types_signature = { }; -__jsdict_keys = function(ob) { +var __jsdict_keys = function(ob) { + if (__test_if_true__(ob instanceof Object)) { return Object.keys( ob ); } else { @@ -745,20 +1212,16 @@ __jsdict_keys = function(ob) { } } -__jsdict_keys.NAME = "__jsdict_keys"; -__jsdict_keys.args_signature = ["ob"]; -__jsdict_keys.kwargs_signature = { }; -__jsdict_keys.types_signature = { }; -__jsdict_values = function(ob) { - var arr, value; +var __jsdict_values = function(ob) { + var arr,value; if (__test_if_true__(ob instanceof Object)) { arr = []; - var __iter3 = ob; - if (! (__iter3 instanceof Array || typeof __iter3 == "string" || __is_typed_array(__iter3)) ) { __iter3 = __object_keys__(__iter3) } - for (var __idx3=0; __idx3 < __iter3.length; __idx3++) { - var key = __iter3[ __idx3 ]; + var __iter17 = ob; + if (! (__iter17 instanceof Array || typeof __iter17 == "string" || __is_typed_array(__iter17) || __is_some_array(__iter17) )) { __iter17 = __object_keys__(__iter17) } + for (var __idx17=0; __idx17 < __iter17.length; __idx17++) { + var key = __iter17[ __idx17 ]; if (__test_if_true__(ob.hasOwnProperty(key))) { - value = ob[((key.__uid__) ? key.__uid__ : key)]; + value = ob[key]; arr.push(value); } } @@ -768,20 +1231,16 @@ __jsdict_values = function(ob) { } } -__jsdict_values.NAME = "__jsdict_values"; -__jsdict_values.args_signature = ["ob"]; -__jsdict_values.kwargs_signature = { }; -__jsdict_values.types_signature = { }; -__jsdict_items = function(ob) { - var arr, value; - if (__test_if_true__(ob instanceof Object || ( ob.items ) === undefined)) { +var __jsdict_items = function(ob) { + var arr,value; + if (__test_if_true__((ob instanceof Object || ( ob.items ) === undefined))) { arr = []; - var __iter4 = ob; - if (! (__iter4 instanceof Array || typeof __iter4 == "string" || __is_typed_array(__iter4)) ) { __iter4 = __object_keys__(__iter4) } - for (var __idx4=0; __idx4 < __iter4.length; __idx4++) { - var key = __iter4[ __idx4 ]; + var __iter18 = ob; + if (! (__iter18 instanceof Array || typeof __iter18 == "string" || __is_typed_array(__iter18) || __is_some_array(__iter18) )) { __iter18 = __object_keys__(__iter18) } + for (var __idx18=0; __idx18 < __iter18.length; __idx18++) { + var key = __iter18[ __idx18 ]; if (__test_if_true__(Object.hasOwnProperty.call(ob, key))) { - value = ob[((key.__uid__) ? key.__uid__ : key)]; + value = ob[key]; arr.push([key, value]); } } @@ -791,11 +1250,7 @@ __jsdict_items = function(ob) { } } -__jsdict_items.NAME = "__jsdict_items"; -__jsdict_items.args_signature = ["ob"]; -__jsdict_items.kwargs_signature = { }; -__jsdict_items.types_signature = { }; -__jsdict_pop = function(ob, key, _kwargs_) { +var __jsdict_pop = function(ob, key, _kwargs_) { var v; if (!( _kwargs_ instanceof Object )) {; var _kwargs_ = {ob: arguments[0],key: arguments[1],_default: arguments[2]}; @@ -803,14 +1258,18 @@ __jsdict_pop = function(ob, key, _kwargs_) { if (_kwargs_ === undefined || _kwargs_._default === undefined) {var _default = null} else {var _default=_kwargs_._default}; if (__test_if_true__(ob instanceof Array)) { if (__test_if_true__(ob.length)) { - return ob.pop(key); + if (( key ) === undefined) { + return ob.pop(); + } else { + return ob.splice(key, 1)[0]; + } } else { throw new IndexError(key); } } else { if (__test_if_true__(ob instanceof Object)) { if (__test_if_true__(key in ob)) { - v = ob[((key.__uid__) ? key.__uid__ : key)]; + v = ob[key]; delete ob[key]; return v; } else { @@ -826,11 +1285,16 @@ __jsdict_pop = function(ob, key, _kwargs_) { } } -__jsdict_pop.NAME = "__jsdict_pop"; -__jsdict_pop.args_signature = ["ob", "key", "_default"]; -__jsdict_pop.kwargs_signature = { _default:null }; -__jsdict_pop.types_signature = { _default:"None" }; -__object_keys__ = function(ob) { +var dir = function(ob) { + + if (__test_if_true__(ob instanceof Object)) { + return Object.keys( ob ); + } else { + return __object_keys__(ob); + } +} + +var __object_keys__ = function(ob) { var arr; "\n notes:\n . Object.keys(ob) will not work because we create PythonJS objects using `Object.create(null)`\n . this is different from Object.keys because it traverses the prototype chain.\n "; arr = []; @@ -838,94 +1302,71 @@ __object_keys__ = function(ob) { return arr; } -__object_keys__.NAME = "__object_keys__"; -__object_keys__.args_signature = ["ob"]; -__object_keys__.kwargs_signature = { }; -__object_keys__.types_signature = { }; -__bind_property_descriptors__ = function(o, klass) { - var prop, desc; - var __iter5 = klass.__properties__; - if (! (__iter5 instanceof Array || typeof __iter5 == "string" || __is_typed_array(__iter5)) ) { __iter5 = __object_keys__(__iter5) } - for (var __idx5=0; __idx5 < __iter5.length; __idx5++) { - var name = __iter5[ __idx5 ]; +var __bind_property_descriptors__ = function(o, klass) { + var prop,desc; + var __iter19 = klass.__properties__; + if (! (__iter19 instanceof Array || typeof __iter19 == "string" || __is_typed_array(__iter19) || __is_some_array(__iter19) )) { __iter19 = __object_keys__(__iter19) } + for (var __idx19=0; __idx19 < __iter19.length; __idx19++) { + var name = __iter19[ __idx19 ]; desc = __jsdict([["enumerable", true]]); - prop = klass.__properties__[((name.__uid__) ? name.__uid__ : name)]; - if (__test_if_true__(prop[(("get".__uid__) ? "get".__uid__ : "get")])) { - desc[(("get".__uid__) ? "get".__uid__ : "get")] = __generate_getter__(klass, o, name); + prop = klass.__properties__[name]; + if (__test_if_true__(prop["get"])) { + desc["get"] = __generate_getter__(klass, o, name); } - if (__test_if_true__(prop[(("set".__uid__) ? "set".__uid__ : "set")])) { - desc[(("set".__uid__) ? "set".__uid__ : "set")] = __generate_setter__(klass, o, name); + if (__test_if_true__(prop["set"])) { + desc["set"] = __generate_setter__(klass, o, name); } Object.defineProperty(o, name, desc); } - var __iter6 = klass.__bases__; - if (! (__iter6 instanceof Array || typeof __iter6 == "string" || __is_typed_array(__iter6)) ) { __iter6 = __object_keys__(__iter6) } - for (var __idx6=0; __idx6 < __iter6.length; __idx6++) { - var base = __iter6[ __idx6 ]; + var __iter20 = klass.__bases__; + if (! (__iter20 instanceof Array || typeof __iter20 == "string" || __is_typed_array(__iter20) || __is_some_array(__iter20) )) { __iter20 = __object_keys__(__iter20) } + for (var __idx20=0; __idx20 < __iter20.length; __idx20++) { + var base = __iter20[ __idx20 ]; __bind_property_descriptors__(o, base); } } -__bind_property_descriptors__.NAME = "__bind_property_descriptors__"; -__bind_property_descriptors__.args_signature = ["o", "klass"]; -__bind_property_descriptors__.kwargs_signature = { }; -__bind_property_descriptors__.types_signature = { }; -__generate_getter__ = function(klass, o, n) { - var __lambda__ = function() { - return klass.__properties__[((n.__uid__) ? n.__uid__ : n)][(("get".__uid__) ? "get".__uid__ : "get")]([o], __jsdict([])); +var __generate_getter__ = function(klass, o, n) { + + var __lambda__ = function() { + + return klass.__properties__[n]["get"]([o], __jsdict([])); } - __lambda__.NAME = "__lambda__"; - __lambda__.args_signature = []; - __lambda__.kwargs_signature = { }; - __lambda__.types_signature = { }; return __lambda__; } -__generate_getter__.NAME = "__generate_getter__"; -__generate_getter__.args_signature = ["klass", "o", "n"]; -__generate_getter__.kwargs_signature = { }; -__generate_getter__.types_signature = { }; -__generate_setter__ = function(klass, o, n) { - var __lambda__ = function(v) { - return klass.__properties__[((n.__uid__) ? n.__uid__ : n)][(("set".__uid__) ? "set".__uid__ : "set")]([o, v], __jsdict([])); +var __generate_setter__ = function(klass, o, n) { + + var __lambda__ = function(v) { + + return klass.__properties__[n]["set"]([o, v], __jsdict([])); } - __lambda__.NAME = "__lambda__"; - __lambda__.args_signature = ["v"]; - __lambda__.kwargs_signature = { }; - __lambda__.types_signature = { }; return __lambda__; } -__generate_setter__.NAME = "__generate_setter__"; -__generate_setter__.args_signature = ["klass", "o", "n"]; -__generate_setter__.kwargs_signature = { }; -__generate_setter__.types_signature = { }; -__sprintf = function(fmt, args) { - var chunks, item, arr; +var __sprintf = function(fmt, args) { + var chunks,item,arr; if (__test_if_true__(args instanceof Array)) { chunks = fmt.split("%s"); arr = []; var i; i = 0; - var __iter7 = chunks; - if (! (__iter7 instanceof Array || typeof __iter7 == "string" || __is_typed_array(__iter7)) ) { __iter7 = __object_keys__(__iter7) } - for (var __idx7=0; __idx7 < __iter7.length; __idx7++) { - var txt = __iter7[ __idx7 ]; + var __iter21 = chunks; + if (! (__iter21 instanceof Array || typeof __iter21 == "string" || __is_typed_array(__iter21) || __is_some_array(__iter21) )) { __iter21 = __object_keys__(__iter21) } + for (var __idx21=0; __idx21 < __iter21.length; __idx21++) { + var txt = __iter21[ __idx21 ]; arr.append(txt); if (( i ) >= args.length) { break; } - item = args[((i.__uid__) ? i.__uid__ : i)]; - if (( typeof(item) ) == "string") { + item = args[i]; + if ((typeof(item) instanceof Array ? JSON.stringify(typeof(item))==JSON.stringify("string") : typeof(item)==="string")) { arr.append(item); } else { - if (( typeof(item) ) == "number") { - var __left0, __right1; - __left0 = ""; - __right1 = item; - arr.append(((( typeof(__left0) ) == "number") ? (__left0 + __right1) : __add_op(__left0, __right1))); + if ((typeof(item) instanceof Array ? JSON.stringify(typeof(item))==JSON.stringify("number") : typeof(item)==="number")) { + arr.append(("" + item)); } else { arr.append(Object.prototype.toString.call(item)); } @@ -938,12 +1379,8 @@ __sprintf = function(fmt, args) { } } -__sprintf.NAME = "__sprintf"; -__sprintf.args_signature = ["fmt", "args"]; -__sprintf.kwargs_signature = { }; -__sprintf.types_signature = { }; -__create_class__ = function(class_name, parents, attrs, props) { - var f, klass, prop; +var __create_class__ = function(class_name, parents, attrs, props) { + var f,klass,prop; "Create a PythonScript class"; klass = Object.create(null); klass.__bases__ = parents; @@ -952,69 +1389,69 @@ __create_class__ = function(class_name, parents, attrs, props) { klass.__all_method_names__ = []; klass.__properties__ = props; klass.__attributes__ = attrs; - var __iter8 = attrs; - if (! (__iter8 instanceof Array || typeof __iter8 == "string" || __is_typed_array(__iter8)) ) { __iter8 = __object_keys__(__iter8) } - for (var __idx8=0; __idx8 < __iter8.length; __idx8++) { - var key = __iter8[ __idx8 ]; - if (( typeof(attrs[((key.__uid__) ? key.__uid__ : key)]) ) == "function") { + var __iter22 = attrs; + if (! (__iter22 instanceof Array || typeof __iter22 == "string" || __is_typed_array(__iter22) || __is_some_array(__iter22) )) { __iter22 = __object_keys__(__iter22) } + for (var __idx22=0; __idx22 < __iter22.length; __idx22++) { + var key = __iter22[ __idx22 ]; + if ((typeof(attrs[key]) instanceof Array ? JSON.stringify(typeof(attrs[key]))==JSON.stringify("function") : typeof(attrs[key])==="function")) { klass.__all_method_names__.push(key); - f = attrs[((key.__uid__) ? key.__uid__ : key)]; - if (__test_if_true__(hasattr(f, "is_classmethod") && f.is_classmethod)) { + f = attrs[key]; + if (__test_if_true__((hasattr(f, "is_classmethod") && f.is_classmethod))) { /*pass*/ } else { - if (__test_if_true__(hasattr(f, "is_staticmethod") && f.is_staticmethod)) { + if (__test_if_true__((hasattr(f, "is_staticmethod") && f.is_staticmethod))) { /*pass*/ } else { - klass.__unbound_methods__[((key.__uid__) ? key.__uid__ : key)] = attrs[((key.__uid__) ? key.__uid__ : key)]; + klass.__unbound_methods__[key] = attrs[key]; } } } - if (( key ) == "__getattribute__") { + if ((key instanceof Array ? JSON.stringify(key)==JSON.stringify("__getattribute__") : key==="__getattribute__")) { continue } - klass[((key.__uid__) ? key.__uid__ : key)] = attrs[((key.__uid__) ? key.__uid__ : key)]; + klass[key] = attrs[key]; } klass.__setters__ = []; klass.__getters__ = []; - var __iter9 = klass.__properties__; - if (! (__iter9 instanceof Array || typeof __iter9 == "string" || __is_typed_array(__iter9)) ) { __iter9 = __object_keys__(__iter9) } - for (var __idx9=0; __idx9 < __iter9.length; __idx9++) { - var name = __iter9[ __idx9 ]; - prop = klass.__properties__[((name.__uid__) ? name.__uid__ : name)]; + var __iter23 = klass.__properties__; + if (! (__iter23 instanceof Array || typeof __iter23 == "string" || __is_typed_array(__iter23) || __is_some_array(__iter23) )) { __iter23 = __object_keys__(__iter23) } + for (var __idx23=0; __idx23 < __iter23.length; __idx23++) { + var name = __iter23[ __idx23 ]; + prop = klass.__properties__[name]; klass.__getters__.push(name); - if (__test_if_true__(prop[(("set".__uid__) ? "set".__uid__ : "set")])) { + if (__test_if_true__(prop["set"])) { klass.__setters__.push(name); } } - var __iter10 = klass.__bases__; - if (! (__iter10 instanceof Array || typeof __iter10 == "string" || __is_typed_array(__iter10)) ) { __iter10 = __object_keys__(__iter10) } - for (var __idx10=0; __idx10 < __iter10.length; __idx10++) { - var base = __iter10[ __idx10 ]; + var __iter24 = klass.__bases__; + if (! (__iter24 instanceof Array || typeof __iter24 == "string" || __is_typed_array(__iter24) || __is_some_array(__iter24) )) { __iter24 = __object_keys__(__iter24) } + for (var __idx24=0; __idx24 < __iter24.length; __idx24++) { + var base = __iter24[ __idx24 ]; Array.prototype.push.apply(klass.__getters__, base.__getters__); Array.prototype.push.apply(klass.__setters__, base.__setters__); Array.prototype.push.apply(klass.__all_method_names__, base.__all_method_names__); } - var __call__ = function() { - var has_getattr, wrapper, object, has_getattribute; + var __call__ = function() { + var has_getattr,wrapper,object,has_getattribute; "Create a PythonJS object"; object = Object.create(null); object.__class__ = klass; object.__dict__ = object; has_getattribute = false; has_getattr = false; - var __iter11 = klass.__all_method_names__; - if (! (__iter11 instanceof Array || typeof __iter11 == "string" || __is_typed_array(__iter11)) ) { __iter11 = __object_keys__(__iter11) } - for (var __idx11=0; __idx11 < __iter11.length; __idx11++) { - var name = __iter11[ __idx11 ]; - if (( name ) == "__getattribute__") { + var __iter25 = klass.__all_method_names__; + if (! (__iter25 instanceof Array || typeof __iter25 == "string" || __is_typed_array(__iter25) || __is_some_array(__iter25) )) { __iter25 = __object_keys__(__iter25) } + for (var __idx25=0; __idx25 < __iter25.length; __idx25++) { + var name = __iter25[ __idx25 ]; + if ((name instanceof Array ? JSON.stringify(name)==JSON.stringify("__getattribute__") : name==="__getattribute__")) { has_getattribute = true; } else { - if (( name ) == "__getattr__") { + if ((name instanceof Array ? JSON.stringify(name)==JSON.stringify("__getattr__") : name==="__getattr__")) { has_getattr = true; } else { wrapper = __get__(object, name); if (__test_if_true__(! (wrapper.is_wrapper))) { - console.log("RUNTIME ERROR: failed to get wrapper for:", name); + console.log(["RUNTIME ERROR: failed to get wrapper for:", name]); } } } @@ -1032,23 +1469,16 @@ __create_class__ = function(class_name, parents, attrs, props) { return object; } - __call__.NAME = "__call__"; - __call__.args_signature = []; - __call__.kwargs_signature = { }; - __call__.types_signature = { }; - __call__.pythonscript_function = true; + __call__.is_wrapper = true; klass.__call__ = __call__; return klass; } -__create_class__.NAME = "__create_class__"; -__create_class__.args_signature = ["class_name", "parents", "attrs", "props"]; -__create_class__.kwargs_signature = { }; -__create_class__.types_signature = { }; -type = function(args, kwargs) { - var __sig__, __args__; +var type = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{"bases": null, "class_dict": null},args:["ob_or_class_name", "bases", "class_dict"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1058,23 +1488,18 @@ type = function(args, kwargs) { var ob_or_class_name = __args__['ob_or_class_name']; var bases = __args__['bases']; var class_dict = __args__['class_dict']; - "\n type(object) -> the object's type\n type(name, bases, dict) -> a new type ## broken? - TODO test\n "; - if (__test_if_true__(( bases ) === null && ( class_dict ) === null)) { + "\n type(object) -> the object's type\n type(name, bases, dict) -> a __new__>>type ## broken? - TODO test\n "; + if (__test_if_true__((( bases ) === null && ( class_dict ) === null))) { return ob_or_class_name.__class__; } else { return create_class(ob_or_class_name, bases, class_dict); } -} - -type.NAME = "type"; -type.args_signature = ["ob_or_class_name", "bases", "class_dict"]; -type.kwargs_signature = { bases:null,class_dict:null }; -type.types_signature = { bases:"None",class_dict:"None" }; -type.pythonscript_function = true; -hasattr = function(args, kwargs) { - var __sig__, __args__; +};type.is_wrapper = true; +var hasattr = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["ob", "attr"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1084,18 +1509,12 @@ hasattr = function(args, kwargs) { var ob = __args__['ob']; var attr = __args__['attr']; return Object.hasOwnProperty.call(ob, attr); -} - -hasattr.NAME = "hasattr"; -hasattr.args_signature = ["ob", "attr"]; -hasattr.kwargs_signature = { }; -hasattr.types_signature = { }; -hasattr.pythonscript_function = true; -getattr = function(args, kwargs) { +};hasattr.is_wrapper = true; +var getattr = function(args, kwargs) { var prop; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{"property": false},args:["ob", "attr", "property"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1107,26 +1526,20 @@ getattr = function(args, kwargs) { var property = __args__['property']; if (__test_if_true__(property)) { prop = _get_upstream_property(ob.__class__, attr); - if (__test_if_true__(prop && prop[(("get".__uid__) ? "get".__uid__ : "get")])) { - return prop[(("get".__uid__) ? "get".__uid__ : "get")]([ob], __jsdict([])); + if (__test_if_true__((prop && prop["get"]))) { + return prop["get"]([ob], __jsdict([])); } else { - console.log("ERROR: getattr property error", prop); + console.log(["ERROR: getattr property error", prop]); } } else { return __get__(ob, attr); } -} - -getattr.NAME = "getattr"; -getattr.args_signature = ["ob", "attr", "property"]; -getattr.kwargs_signature = { property:false }; -getattr.types_signature = { property:"False" }; -getattr.pythonscript_function = true; -setattr = function(args, kwargs) { +};getattr.is_wrapper = true; +var setattr = function(args, kwargs) { var prop; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{"property": false},args:["ob", "attr", "value", "property"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1139,26 +1552,20 @@ setattr = function(args, kwargs) { var property = __args__['property']; if (__test_if_true__(property)) { prop = _get_upstream_property(ob.__class__, attr); - if (__test_if_true__(prop && prop[(("set".__uid__) ? "set".__uid__ : "set")])) { - prop[(("set".__uid__) ? "set".__uid__ : "set")]([ob, value], __jsdict([])); + if (__test_if_true__((prop && prop["set"]))) { + prop["set"]([ob, value], __jsdict([])); } else { - console.log("ERROR: setattr property error", prop); + console.log(["ERROR: setattr property error", prop]); } } else { __set__(ob, attr, value); } -} - -setattr.NAME = "setattr"; -setattr.args_signature = ["ob", "attr", "value", "property"]; -setattr.kwargs_signature = { property:false }; -setattr.types_signature = { property:"False" }; -setattr.pythonscript_function = true; -issubclass = function(args, kwargs) { - var i, bases; - var __sig__, __args__; +};setattr.is_wrapper = true; +var issubclass = function(args, kwargs) { + var i,bases; + var __sig__,__args__; __sig__ = { kwargs:{},args:["C", "B"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1172,25 +1579,19 @@ issubclass = function(args, kwargs) { } bases = C.__bases__; i = 0; - while (( i ) < __get__(bases, "length", "missing attribute `length` - line 381: while i < bases.length:")) { - if (__test_if_true__(issubclass([__get__(bases, "__getitem__", "line 382: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__), B], __NULL_OBJECT__))) { + while (( i ) < __get__(bases, "length", "missing attribute `length` - line 655: while i < bases.length:")) { + if (__test_if_true__(issubclass([((bases instanceof Array) ? bases[i] : __get__(bases, "__getitem__", "line 656: if issubclass( bases[i], B ):")([i], __NULL_OBJECT__)), B], __NULL_OBJECT__))) { return true; } i += 1; } return false; -} - -issubclass.NAME = "issubclass"; -issubclass.args_signature = ["C", "B"]; -issubclass.kwargs_signature = { }; -issubclass.types_signature = { }; -issubclass.pythonscript_function = true; -isinstance = function(args, kwargs) { +};issubclass.is_wrapper = true; +var isinstance = function(args, kwargs) { var ob_class; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["ob", "klass"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1199,10 +1600,10 @@ isinstance = function(args, kwargs) { __args__ = __getargs__("isinstance", __sig__, args, kwargs); var ob = __args__['ob']; var klass = __args__['klass']; - if (__test_if_true__(( ob ) === undefined || ( ob ) === null)) { + if (__test_if_true__((( ob ) === undefined || ( ob ) === null))) { return false; } else { - if (__test_if_true__(ob instanceof Array && ( klass ) === list)) { + if (__test_if_true__((ob instanceof Array && ( klass ) === list))) { return true; } else { if (__test_if_true__(! (Object.hasOwnProperty.call(ob, "__class__")))) { @@ -1216,18 +1617,12 @@ isinstance = function(args, kwargs) { } else { return issubclass([ob_class, klass], __NULL_OBJECT__); } -} - -isinstance.NAME = "isinstance"; -isinstance.args_signature = ["ob", "klass"]; -isinstance.kwargs_signature = { }; -isinstance.types_signature = { }; -isinstance.pythonscript_function = true; -int = function(args, kwargs) { - ; - var __sig__, __args__; +};isinstance.is_wrapper = true; +var int = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1240,18 +1635,19 @@ int = function(args, kwargs) { throw new ValueError("not a number"); } return a; +};int.is_wrapper = true; +var int16 = function(a) { + var arr; + arr = new Int16Array(1); + arr[0] = a; + return arr; } -int.NAME = "int"; -int.args_signature = ["a"]; -int.kwargs_signature = { }; -int.types_signature = { }; -int.pythonscript_function = true; -float = function(args, kwargs) { - ; - var __sig__, __args__; +var float = function(args, kwargs) { + var b; + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1259,23 +1655,26 @@ float = function(args, kwargs) { } __args__ = __getargs__("float", __sig__, args, kwargs); var a = __args__['a']; - a = Number(a); - if (__test_if_true__(isNaN(a))) { - throw new ValueError("not a number"); + if ((typeof(a) instanceof Array ? JSON.stringify(typeof(a))==JSON.stringify("string") : typeof(a)==="string")) { + if ((a.lower() instanceof Array ? JSON.stringify(a.lower())==JSON.stringify("nan") : a.lower()==="nan")) { + return NaN; + } else { + if ((a.lower() instanceof Array ? JSON.stringify(a.lower())==JSON.stringify("inf") : a.lower()==="inf")) { + return Infinity; + } + } } - return a; -} - -float.NAME = "float"; -float.args_signature = ["a"]; -float.kwargs_signature = { }; -float.types_signature = { }; -float.pythonscript_function = true; -round = function(args, kwargs) { - var y, x, c, b; - var __sig__, __args__; - __sig__ = { kwargs:{},args:["a", "places"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + b = Number(a); + if (__test_if_true__(isNaN(b))) { + throw new ValueError(("can not convert to float: " + a)); + } + return b; +};float.is_wrapper = true; +var round = function(args, kwargs) { + var p,b; + var __sig__,__args__; + __sig__ = { kwargs:{"places": 0},args:["a", "places"] }; + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1284,35 +1683,19 @@ round = function(args, kwargs) { __args__ = __getargs__("round", __sig__, args, kwargs); var a = __args__['a']; var places = __args__['places']; - var __left2, __right3; - __left2 = ""; - __right3 = a; - b = ((( typeof(__left2) ) == "number") ? (__left2 + __right3) : __add_op(__left2, __right3)); - if (( b.indexOf(".") ) == -1) { + b = ("" + a); + if ((b.indexOf(".") instanceof Array ? JSON.stringify(b.indexOf("."))==JSON.stringify(-1) : b.indexOf(".")===-1)) { return a; } else { - c = b.split("."); - x = c[0]; - y = c[1].substring(0, places); - var __left4, __right5; - __left4 = x; - __right5 = "."; - var __left6, __right7; - __left6 = ((( typeof(__left4) ) == "number") ? (__left4 + __right5) : __add_op(__left4, __right5)); - __right7 = y; - return parseFloat(((( typeof(__left6) ) == "number") ? (__left6 + __right7) : __add_op(__left6, __right7))); - } -} - -round.NAME = "round"; -round.args_signature = ["a", "places"]; -round.kwargs_signature = { }; -round.types_signature = { }; -round.pythonscript_function = true; -str = function(args, kwargs) { - var __sig__, __args__; + p = Math.pow(10, places); + return (Math.round((a * p)) / p); + } +};round.is_wrapper = true; +var str = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["s"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1320,148 +1703,100 @@ str = function(args, kwargs) { } __args__ = __getargs__("str", __sig__, args, kwargs); var s = __args__['s']; - var __left8, __right9; - __left8 = ""; - __right9 = s; - return ((( typeof(__left8) ) == "number") ? (__left8 + __right9) : __add_op(__left8, __right9)); -} - -str.NAME = "str"; -str.args_signature = ["s"]; -str.kwargs_signature = { }; -str.types_signature = { }; -str.pythonscript_function = true; -_setup_str_prototype = function(args, kwargs) { + return ("" + s); +};str.is_wrapper = true; +var _setup_str_prototype = function() { + "\n Extend JavaScript String.prototype with methods that implement the Python str API.\n The decorator @String.prototype.[name] assigns the function to the prototype,\n and ensures that the special 'this' variable will work.\n "; - var func = function(a) { - if (( this.indexOf(a) ) == -1) { + var func = function(a) { + + if ((this.indexOf(a) instanceof Array ? JSON.stringify(this.indexOf(a))==JSON.stringify(-1) : this.indexOf(a)===-1)) { return false; } else { return true; } } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "__contains__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(index) { + var func = function(index) { + if (( index ) < 0) { - var __left10, __right11; - __left10 = this.length; - __right11 = index; - return this[((( typeof(__left10) ) == "number") ? (__left10 + __right11) : __add_op(__left10, __right11))]; + return this[(this.length + index)]; } else { - return this[((index.__uid__) ? index.__uid__ : index)]; + return this[index]; } } - func.NAME = "func"; - func.args_signature = ["index"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "get", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(self) { + var func = function(self) { + return __get__(Iterator, "__call__")([this, 0], __NULL_OBJECT__); } - func.NAME = "func"; - func.args_signature = ["self"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "__iter__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(idx) { + var func = function(idx) { + if (( idx ) < 0) { - var __left12, __right13; - __left12 = this.length; - __right13 = idx; - return this[((( typeof(__left12) ) == "number") ? (__left12 + __right13) : __add_op(__left12, __right13))]; + return this[(this.length + idx)]; } else { - return this[((idx.__uid__) ? idx.__uid__ : idx)]; + return this[idx]; } } - func.NAME = "func"; - func.args_signature = ["idx"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "__getitem__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.length; } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "__len__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(start, stop, step) { - ; - if (__test_if_true__(( start ) === undefined && ( stop ) === undefined && ( step ) == -1)) { + var func = function(start, stop, step) { + + if (__test_if_true__((( start ) === undefined && ( stop ) === undefined && (step instanceof Array ? JSON.stringify(step)==JSON.stringify(-1) : step===-1)))) { return this.split("").reverse().join(""); } else { if (( stop ) < 0) { - var __left14, __right15; - __left14 = this.length; - __right15 = stop; - stop = ((( typeof(__left14) ) == "number") ? (__left14 + __right15) : __add_op(__left14, __right15)); + stop = (this.length + stop); } return this.substring(start, stop); } } - func.NAME = "func"; - func.args_signature = ["start", "stop", "step"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "__getslice__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.split("\n"); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "splitlines", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.trim(); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "strip", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { - if (( this.substring(0, a.length) ) == a) { + var func = function(a) { + + if ((this.substring(0, a.length) instanceof Array ? JSON.stringify(this.substring(0, a.length))==JSON.stringify(a) : this.substring(0, a.length)===a)) { return true; } else { return false; } } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "startswith", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { - if (( this.substring((this.length - a.length), this.length) ) == a) { + var func = function(a) { + + if ((this.substring((this.length - a.length), this.length) instanceof Array ? JSON.stringify(this.substring((this.length - a.length), this.length))==JSON.stringify(a) : this.substring((this.length - a.length), this.length)===a)) { return true; } else { return false; } } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "endswith", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { - var i, arr, out; + var func = function(a) { + var i,arr,out; out = ""; if (__test_if_true__(a instanceof Array)) { arr = a; @@ -1469,10 +1804,10 @@ _setup_str_prototype = function(args, kwargs) { arr = a["$wrapped"]; } i = 0; - var __iter12 = arr; - if (! (__iter12 instanceof Array || typeof __iter12 == "string" || __is_typed_array(__iter12)) ) { __iter12 = __object_keys__(__iter12) } - for (var __idx12=0; __idx12 < __iter12.length; __idx12++) { - var value = __iter12[ __idx12 ]; + var __iter26 = arr; + if (! (__iter26 instanceof Array || typeof __iter26 == "string" || __is_typed_array(__iter26) || __is_some_array(__iter26) )) { __iter26 = __object_keys__(__iter26) } + for (var __idx26=0; __idx26 < __iter26.length; __idx26++) { + var value = __iter26[ __idx26 ]; out += value; i += 1; if (( i ) < arr.length) { @@ -1482,62 +1817,42 @@ _setup_str_prototype = function(args, kwargs) { return out; } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "join", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.toUpperCase(); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "upper", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.toLowerCase(); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "lower", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { + var func = function(a) { var i; i = this.indexOf(a); - if (( i ) == -1) { - var __left16, __right17; - __left16 = a; - __right17 = " - not in string"; - throw new ValueError(((( typeof(__left16) ) == "number") ? (__left16 + __right17) : __add_op(__left16, __right17))); + if ((i instanceof Array ? JSON.stringify(i)==JSON.stringify(-1) : i===-1)) { + throw new ValueError((a + " - not in string")); } return i; } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "index", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { + var func = function(a) { + return this.indexOf(a); } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "find", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { var digits; digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; - var __iter13 = this; - if (! (__iter13 instanceof Array || typeof __iter13 == "string" || __is_typed_array(__iter13)) ) { __iter13 = __object_keys__(__iter13) } - for (var __idx13=0; __idx13 < __iter13.length; __idx13++) { - var char = __iter13[ __idx13 ]; + var __iter27 = this; + if (! (__iter27 instanceof Array || typeof __iter27 == "string" || __is_typed_array(__iter27) || __is_some_array(__iter27) )) { __iter27 = __object_keys__(__iter27) } + for (var __idx27=0; __idx27 < __iter27.length; __idx27++) { + var char = __iter27[ __idx27 ]; if (__contains__(digits, char)) { /*pass*/ } else { @@ -1547,65 +1862,85 @@ _setup_str_prototype = function(args, kwargs) { return true; } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "isdigit", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(encoding) { + var func = function() { + var digits; + digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."]; + var __iter28 = this; + if (! (__iter28 instanceof Array || typeof __iter28 == "string" || __is_typed_array(__iter28) || __is_some_array(__iter28) )) { __iter28 = __object_keys__(__iter28) } + for (var __idx28=0; __idx28 < __iter28.length; __idx28++) { + var char = __iter28[ __idx28 ]; + if (__contains__(digits, char)) { + /*pass*/ + } else { + return false; + } + } + return true; + } + + Object.defineProperty(String.prototype, "isnumber", { enumerable:false,value:func,writeable:true,configurable:true }); + var func = function(encoding) { + return this; } - func.NAME = "func"; - func.args_signature = ["encoding"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "decode", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(encoding) { + var func = function(encoding) { + return this; } - func.NAME = "func"; - func.args_signature = ["encoding"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "encode", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(fmt) { - var keys, r; + var func = function(fmt) { + var keys,r; r = this; keys = Object.keys(fmt); - var __iter14 = keys; - if (! (__iter14 instanceof Array || typeof __iter14 == "string" || __is_typed_array(__iter14)) ) { __iter14 = __object_keys__(__iter14) } - for (var __idx14=0; __idx14 < __iter14.length; __idx14++) { - var key = __iter14[ __idx14 ]; - r = r.split(key).join(fmt[((key.__uid__) ? key.__uid__ : key)]); + var __iter29 = keys; + if (! (__iter29 instanceof Array || typeof __iter29 == "string" || __is_typed_array(__iter29) || __is_some_array(__iter29) )) { __iter29 = __object_keys__(__iter29) } + for (var __idx29=0; __idx29 < __iter29.length; __idx29++) { + var key = __iter29[ __idx29 ]; + r = r.split(key).join(fmt[key]); } r = r.split("{").join("").split("}").join(""); return r; } - func.NAME = "func"; - func.args_signature = ["fmt"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(String.prototype, "format", { enumerable:false,value:func,writeable:true,configurable:true }); +};_setup_str_prototype.is_wrapper = true; +_setup_str_prototype(); +var __sort_method = function(ob) { + + if (__test_if_true__(ob instanceof Array)) { + var f = function(a, b) { + + if (( a ) < b) { + return -1; + } else { + if (( a ) > b) { + return 1; + } else { + return 0; + } + } + } + + return ob.sort( f ); + } else { + return ob.sort(); + } } -_setup_str_prototype.NAME = "_setup_str_prototype"; -_setup_str_prototype.args_signature = []; -_setup_str_prototype.kwargs_signature = { }; -_setup_str_prototype.types_signature = { }; -_setup_str_prototype.pythonscript_function = true; -_setup_str_prototype(); -_setup_array_prototype = function(args, kwargs) { - var func = function() { - var i, item; +var _setup_array_prototype = function() { + + var func = function() { + var i,item; i = 0; while (( i ) < this.length) { - item = this[((i.__uid__) ? i.__uid__ : i)]; - if (( typeof(item) ) == "object") { + item = this[i]; + if ((typeof(item) instanceof Array ? JSON.stringify(typeof(item))==JSON.stringify("object") : typeof(item)==="object")) { if (__test_if_true__(item.jsify)) { - this[((i.__uid__) ? i.__uid__ : i)] = item.jsify(); + this[i] = item.jsify(); } } i += 1; @@ -1613,177 +1948,162 @@ _setup_array_prototype = function(args, kwargs) { return this; } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "jsify", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(a) { - if (( this.indexOf(a) ) == -1) { + var func = function(a) { + + if ((this.indexOf(a) instanceof Array ? JSON.stringify(this.indexOf(a))==JSON.stringify(-1) : this.indexOf(a)===-1)) { return false; } else { return true; } } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "__contains__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.length; } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "__len__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(index) { - return this[((index.__uid__) ? index.__uid__ : index)]; + var func = function(index) { + + return this[index]; } - func.NAME = "func"; - func.args_signature = ["index"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "get", { enumerable:false,value:func,writeable:true,configurable:true }); - var __getitem__ = function(index) { - ; + var __getitem__ = function(index) { + if (( index ) < 0) { - var __left18, __right19; - __left18 = this.length; - __right19 = index; - index = ((( typeof(__left18) ) == "number") ? (__left18 + __right19) : __add_op(__left18, __right19)); + index = (this.length + index); } - return this[((index.__uid__) ? index.__uid__ : index)]; + return this[index]; } - __getitem__.NAME = "__getitem__"; - __getitem__.args_signature = ["index"]; - __getitem__.kwargs_signature = { }; - __getitem__.types_signature = { }; Object.defineProperty(Array.prototype, "__getitem__", { enumerable:false,value:__getitem__,writeable:true,configurable:true }); - var __setitem__ = function(index, value) { - ; + var __setitem__ = function(index, value) { + if (( index ) < 0) { - var __left20, __right21; - __left20 = this.length; - __right21 = index; - index = ((( typeof(__left20) ) == "number") ? (__left20 + __right21) : __add_op(__left20, __right21)); + index = (this.length + index); } - this[((index.__uid__) ? index.__uid__ : index)] = value; + this[index] = value; } - __setitem__.NAME = "__setitem__"; - __setitem__.args_signature = ["index", "value"]; - __setitem__.kwargs_signature = { }; - __setitem__.types_signature = { }; Object.defineProperty(Array.prototype, "__setitem__", { enumerable:false,value:__setitem__,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return __get__(Iterator, "__call__")([this, 0], __NULL_OBJECT__); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "__iter__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(start, stop, step) { - var i, arr; - if (__test_if_true__(( start ) === undefined && ( stop ) === undefined)) { - arr = []; - i = 0; - while (( i ) < this.length) { - arr.push(this[((i.__uid__) ? i.__uid__ : i)]); - i += step; + var func = function(start, stop, step) { + var i,arr,n; + arr = []; + start = (start | 0); + if (( stop ) === undefined) { + stop = this.length; + } + if (( start ) < 0) { + start = (this.length + start); + } + if (( stop ) < 0) { + stop = (this.length + stop); + } + if ((typeof(step) instanceof Array ? JSON.stringify(typeof(step))==JSON.stringify("number") : typeof(step)==="number")) { + if (( step ) < 0) { + i = start; + while (( i ) >= 0) { + arr.push(this[i]); + i += step; + } + return arr; + } else { + i = start; + n = stop; + while (( i ) < n) { + arr.push(this[i]); + i += step; + } + return arr; } - return arr; } else { - if (( stop ) < 0) { - var __left22, __right23; - __left22 = this.length; - __right23 = stop; - stop = ((( typeof(__left22) ) == "number") ? (__left22 + __right23) : __add_op(__left22, __right23)); + i = start; + n = stop; + while (( i ) < n) { + arr.push(this[i]); + i += 1; } - return this.slice(start, stop); + return arr; } } - func.NAME = "func"; - func.args_signature = ["start", "stop", "step"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "__getslice__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(item) { + var func = function(start, stop, step, items) { + var arr; + if (( start ) === undefined) { + start = 0; + } + if (( stop ) === undefined) { + stop = this.length; + } + arr = [start, (stop - start)]; + var __iter30 = items; + if (! (__iter30 instanceof Array || typeof __iter30 == "string" || __is_typed_array(__iter30) || __is_some_array(__iter30) )) { __iter30 = __object_keys__(__iter30) } + for (var __idx30=0; __idx30 < __iter30.length; __idx30++) { + var item = __iter30[ __idx30 ]; + arr.push(item); + } + this.splice.apply(this, arr); + } + + Object.defineProperty(Array.prototype, "__setslice__", { enumerable:false,value:func,writeable:true,configurable:true }); + var func = function(item) { + this.push(item); return this; } - func.NAME = "func"; - func.args_signature = ["item"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "append", { enumerable:false,value:func,writeable:true,configurable:true }); - var extend = function(other) { - var __iter15 = other; - if (! (__iter15 instanceof Array || typeof __iter15 == "string" || __is_typed_array(__iter15)) ) { __iter15 = __object_keys__(__iter15) } - for (var __idx15=0; __idx15 < __iter15.length; __idx15++) { - var obj = __iter15[ __idx15 ]; + var extend = function(other) { + + var __iter31 = other; + if (! (__iter31 instanceof Array || typeof __iter31 == "string" || __is_typed_array(__iter31) || __is_some_array(__iter31) )) { __iter31 = __object_keys__(__iter31) } + for (var __idx31=0; __idx31 < __iter31.length; __idx31++) { + var obj = __iter31[ __idx31 ]; this.push(obj); } return this; } - extend.NAME = "extend"; - extend.args_signature = ["other"]; - extend.kwargs_signature = { }; - extend.types_signature = { }; Object.defineProperty(Array.prototype, "extend", { enumerable:false,value:extend,writeable:true,configurable:true }); - var func = function(item) { + var func = function(item) { var index; index = this.indexOf(item); this.splice(index, 1); } - func.NAME = "func"; - func.args_signature = ["item"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "remove", { enumerable:false,value:func,writeable:true,configurable:true }); - var insert = function(index, obj) { - ; + var insert = function(index, obj) { + if (( index ) < 0) { - var __left24, __right25; - __left24 = this.length; - __right25 = index; - index = ((( typeof(__left24) ) == "number") ? (__left24 + __right25) : __add_op(__left24, __right25)); + index = (this.length + index); } this.splice(index, 0, obj); } - insert.NAME = "insert"; - insert.args_signature = ["index", "obj"]; - insert.kwargs_signature = { }; - insert.types_signature = { }; Object.defineProperty(Array.prototype, "insert", { enumerable:false,value:insert,writeable:true,configurable:true }); - var index = function(obj) { + var index = function(obj) { + return this.indexOf(obj); } - index.NAME = "index"; - index.args_signature = ["obj"]; - index.kwargs_signature = { }; - index.types_signature = { }; Object.defineProperty(Array.prototype, "index", { enumerable:false,value:index,writeable:true,configurable:true }); - var count = function(obj) { + var count = function(obj) { var a; a = 0; - var __iter16 = this; - if (! (__iter16 instanceof Array || typeof __iter16 == "string" || __is_typed_array(__iter16)) ) { __iter16 = __object_keys__(__iter16) } - for (var __idx16=0; __idx16 < __iter16.length; __idx16++) { - var item = __iter16[ __idx16 ]; + var __iter32 = this; + if (! (__iter32 instanceof Array || typeof __iter32 == "string" || __is_typed_array(__iter32) || __is_some_array(__iter32) )) { __iter32 = __object_keys__(__iter32) } + for (var __idx32=0; __idx32 < __iter32.length; __idx32++) { + var item = __iter32[ __idx32 ]; if (( item ) === obj) { a += 1; } @@ -1791,13 +2111,9 @@ _setup_array_prototype = function(args, kwargs) { return a; } - count.NAME = "count"; - count.args_signature = ["obj"]; - count.kwargs_signature = { }; - count.types_signature = { }; Object.defineProperty(Array.prototype, "count", { enumerable:false,value:count,writeable:true,configurable:true }); - var func = function(x, low, high) { - var a, mid; + var func = function(x, low, high) { + var a,mid; if (( low ) === undefined) { low = 0; } @@ -1805,187 +2121,133 @@ _setup_array_prototype = function(args, kwargs) { high = this.length; } while (( low ) < high) { - var __left26, __right27; - __left26 = low; - __right27 = high; - a = ((( typeof(__left26) ) == "number") ? (__left26 + __right27) : __add_op(__left26, __right27)); + a = (low + high); mid = Math.floor((a / 2)); - if (( x ) < this[((mid.__uid__) ? mid.__uid__ : mid)]) { + if (( x ) < this[mid]) { high = mid; } else { - var __left28, __right29; - __left28 = mid; - __right29 = 1; - low = ((( typeof(__left28) ) == "number") ? (__left28 + __right29) : __add_op(__left28, __right29)); + low = (mid + 1); } } return low; } - func.NAME = "func"; - func.args_signature = ["x", "low", "high"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "bisect", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(other) { + var func = function(other) { var f; - var __lambda__ = function(i) { - return ( other.indexOf(i) ) == -1; + var __lambda__ = function(i) { + + return (other.indexOf(i) instanceof Array ? JSON.stringify(other.indexOf(i))==JSON.stringify(-1) : other.indexOf(i)===-1); } - __lambda__.NAME = "__lambda__"; - __lambda__.args_signature = ["i"]; - __lambda__.kwargs_signature = { }; - __lambda__.types_signature = { }; f = __lambda__; return this.filter(f); } - func.NAME = "func"; - func.args_signature = ["other"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "difference", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(other) { + var func = function(other) { var f; - var __lambda__ = function(i) { - return ( other.indexOf(i) ) != -1; + var __lambda__ = function(i) { + + return (!(other.indexOf(i) instanceof Array ? JSON.stringify(other.indexOf(i))==JSON.stringify(-1) : other.indexOf(i)===-1)); } - __lambda__.NAME = "__lambda__"; - __lambda__.args_signature = ["i"]; - __lambda__.kwargs_signature = { }; - __lambda__.types_signature = { }; f = __lambda__; return this.filter(f); } - func.NAME = "func"; - func.args_signature = ["other"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "intersection", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(other) { - var __iter17 = this; - if (! (__iter17 instanceof Array || typeof __iter17 == "string" || __is_typed_array(__iter17)) ) { __iter17 = __object_keys__(__iter17) } - for (var __idx17=0; __idx17 < __iter17.length; __idx17++) { - var item = __iter17[ __idx17 ]; - if (( other.indexOf(item) ) == -1) { + var func = function(other) { + + var __iter33 = this; + if (! (__iter33 instanceof Array || typeof __iter33 == "string" || __is_typed_array(__iter33) || __is_some_array(__iter33) )) { __iter33 = __object_keys__(__iter33) } + for (var __idx33=0; __idx33 < __iter33.length; __idx33++) { + var item = __iter33[ __idx33 ]; + if ((other.indexOf(item) instanceof Array ? JSON.stringify(other.indexOf(item))==JSON.stringify(-1) : other.indexOf(item)===-1)) { return false; } } return true; } - func.NAME = "func"; - func.args_signature = ["other"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(Array.prototype, "issubset", { enumerable:false,value:func,writeable:true,configurable:true }); -} + var func = function() { + var i,arr; + arr = []; + i = 0; + while (( i ) < this.length) { + arr.push(this[i]); + i += 1; + } + return arr; + } -_setup_array_prototype.NAME = "_setup_array_prototype"; -_setup_array_prototype.args_signature = []; -_setup_array_prototype.kwargs_signature = { }; -_setup_array_prototype.types_signature = { }; -_setup_array_prototype.pythonscript_function = true; + Object.defineProperty(Array.prototype, "copy", { enumerable:false,value:func,writeable:true,configurable:true }); +};_setup_array_prototype.is_wrapper = true; _setup_array_prototype(); -_setup_nodelist_prototype = function(args, kwargs) { - var func = function(a) { - if (( this.indexOf(a) ) == -1) { +var _setup_nodelist_prototype = function() { + + var func = function(a) { + + if ((this.indexOf(a) instanceof Array ? JSON.stringify(this.indexOf(a))==JSON.stringify(-1) : this.indexOf(a)===-1)) { return false; } else { return true; } } - func.NAME = "func"; - func.args_signature = ["a"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(NodeList.prototype, "__contains__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return this.length; } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(NodeList.prototype, "__len__", { enumerable:false,value:func,writeable:true,configurable:true }); - var func = function(index) { - return this[((index.__uid__) ? index.__uid__ : index)]; + var func = function(index) { + + return this[index]; } - func.NAME = "func"; - func.args_signature = ["index"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(NodeList.prototype, "get", { enumerable:false,value:func,writeable:true,configurable:true }); - var __getitem__ = function(index) { - ; + var __getitem__ = function(index) { + if (( index ) < 0) { - var __left30, __right31; - __left30 = this.length; - __right31 = index; - index = ((( typeof(__left30) ) == "number") ? (__left30 + __right31) : __add_op(__left30, __right31)); + index = (this.length + index); } - return this[((index.__uid__) ? index.__uid__ : index)]; + return this[index]; } - __getitem__.NAME = "__getitem__"; - __getitem__.args_signature = ["index"]; - __getitem__.kwargs_signature = { }; - __getitem__.types_signature = { }; Object.defineProperty(NodeList.prototype, "__getitem__", { enumerable:false,value:__getitem__,writeable:true,configurable:true }); - var __setitem__ = function(index, value) { - ; + var __setitem__ = function(index, value) { + if (( index ) < 0) { - var __left32, __right33; - __left32 = this.length; - __right33 = index; - index = ((( typeof(__left32) ) == "number") ? (__left32 + __right33) : __add_op(__left32, __right33)); + index = (this.length + index); } - this[((index.__uid__) ? index.__uid__ : index)] = value; + this[index] = value; } - __setitem__.NAME = "__setitem__"; - __setitem__.args_signature = ["index", "value"]; - __setitem__.kwargs_signature = { }; - __setitem__.types_signature = { }; Object.defineProperty(NodeList.prototype, "__setitem__", { enumerable:false,value:__setitem__,writeable:true,configurable:true }); - var func = function() { + var func = function() { + return __get__(Iterator, "__call__")([this, 0], __NULL_OBJECT__); } - func.NAME = "func"; - func.args_signature = []; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(NodeList.prototype, "__iter__", { enumerable:false,value:func,writeable:true,configurable:true }); - var index = function(obj) { + var index = function(obj) { + return this.indexOf(obj); } - index.NAME = "index"; - index.args_signature = ["obj"]; - index.kwargs_signature = { }; - index.types_signature = { }; Object.defineProperty(NodeList.prototype, "index", { enumerable:false,value:index,writeable:true,configurable:true }); -} - -_setup_nodelist_prototype.NAME = "_setup_nodelist_prototype"; -_setup_nodelist_prototype.args_signature = []; -_setup_nodelist_prototype.kwargs_signature = { }; -_setup_nodelist_prototype.types_signature = { }; -_setup_nodelist_prototype.pythonscript_function = true; -if (__test_if_true__(( __NODEJS__ ) == false && ( __WEBWORKER__ ) == false)) { +};_setup_nodelist_prototype.is_wrapper = true; +if (__test_if_true__(((__NODEJS__ instanceof Array ? JSON.stringify(__NODEJS__)==JSON.stringify(false) : __NODEJS__===false) && (__WEBWORKER__ instanceof Array ? JSON.stringify(__WEBWORKER__)==JSON.stringify(false) : __WEBWORKER__===false)))) { _setup_nodelist_prototype(); } -bisect = function(args, kwargs) { - var __sig__, __args__; +var bisect = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{"low": null, "high": null},args:["a", "x", "low", "high"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -1996,19 +2258,13 @@ bisect = function(args, kwargs) { var x = __args__['x']; var low = __args__['low']; var high = __args__['high']; - return __get__(__get__(a, "bisect", "missing attribute `bisect` - line 740: return a.bisect(x, low, high)"), "__call__")([x, low, high], __NULL_OBJECT__); -} - -bisect.NAME = "bisect"; -bisect.args_signature = ["a", "x", "low", "high"]; -bisect.kwargs_signature = { low:null,high:null }; -bisect.types_signature = { low:"None",high:"None" }; -bisect.pythonscript_function = true; -range = function(args, kwargs) { - var i, arr; - var __sig__, __args__; + return a.bisect(x, low, high); +};bisect.is_wrapper = true; +var range = function(args, kwargs) { + var i,arr; + var __sig__,__args__; __sig__ = { kwargs:{},args:["num", "stop", "step"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2034,17 +2290,12 @@ range = function(args, kwargs) { i += step; } return arr; -} - -range.NAME = "range"; -range.args_signature = ["num", "stop", "step"]; -range.kwargs_signature = { }; -range.types_signature = { }; -range.pythonscript_function = true; -xrange = function(args, kwargs) { - var __sig__, __args__; +};range.is_wrapper = true; +var xrange = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["num", "stop", "step"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2055,18 +2306,12 @@ xrange = function(args, kwargs) { var stop = __args__['stop']; var step = __args__['step']; return range([num, stop, step], __NULL_OBJECT__); -} - -xrange.NAME = "xrange"; -xrange.args_signature = ["num", "stop", "step"]; -xrange.kwargs_signature = { }; -xrange.types_signature = { }; -xrange.pythonscript_function = true; -sum = function(args, kwargs) { +};xrange.is_wrapper = true; +var sum = function(args, kwargs) { var a; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["arr"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2075,31 +2320,26 @@ sum = function(args, kwargs) { __args__ = __getargs__("sum", __sig__, args, kwargs); var arr = __args__['arr']; a = 0; - var b, __iterator__17; - __iterator__17 = __get__(__get__(arr, "__iter__", "no iterator - line 764: for b in arr:"), "__call__")([], __NULL_OBJECT__); - var __next__17; - __next__17 = __get__(__iterator__17, "next"); - while (( __iterator__17.index ) < __iterator__17.length) { - b = __next__17(); + var b,__iterator__40; + __iterator__40 = __get__(__get__(arr, "__iter__", "no iterator - line 1065: for b in arr:"), "__call__")([], __NULL_OBJECT__); + var __next__40; + __next__40 = __get__(__iterator__40, "next"); + while (( __iterator__40.index ) < __iterator__40.length) { + b = __next__40(); a += b; } return a; -} - -sum.NAME = "sum"; -sum.args_signature = ["arr"]; -sum.kwargs_signature = { }; -sum.types_signature = { }; -sum.pythonscript_function = true; -var StopIteration, __StopIteration_attrs, __StopIteration_parents; +};sum.is_wrapper = true; +var StopIteration,__StopIteration_attrs,__StopIteration_parents; __StopIteration_attrs = {}; __StopIteration_parents = []; __StopIteration_properties = {}; StopIteration = __create_class__("StopIteration", __StopIteration_parents, __StopIteration_attrs, __StopIteration_properties); -len = function(args, kwargs) { - var __sig__, __args__; +var len = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["ob"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2116,25 +2356,20 @@ len = function(args, kwargs) { if (__test_if_true__(ob instanceof ArrayBuffer)) { return ob.byteLength; } else { - if (__test_if_true__(ob instanceof Object)) { - return Object.keys(ob).length; + if (__test_if_true__(ob.__len__)) { + return ob.__len__(); } else { - return __get__(__get__(ob, "__len__", "missing attribute `__len__` - line 784: return ob.__len__()"), "__call__")(); + return Object.keys(ob).length; } } } } -} - -len.NAME = "len"; -len.args_signature = ["ob"]; -len.kwargs_signature = { }; -len.types_signature = { }; -len.pythonscript_function = true; -next = function(args, kwargs) { - var __sig__, __args__; +};len.is_wrapper = true; +var next = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["obj"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2142,19 +2377,13 @@ next = function(args, kwargs) { } __args__ = __getargs__("next", __sig__, args, kwargs); var obj = __args__['obj']; - return __get__(__get__(obj, "next", "missing attribute `next` - line 788: return obj.next()"), "__call__")(); -} - -next.NAME = "next"; -next.args_signature = ["obj"]; -next.kwargs_signature = { }; -next.types_signature = { }; -next.pythonscript_function = true; -map = function(args, kwargs) { - var arr, v; - var __sig__, __args__; + return __get__(__get__(obj, "next", "missing attribute `next` - line 1083: return obj.next()"), "__call__")(); +};next.is_wrapper = true; +var map = function(args, kwargs) { + var arr,v; + var __sig__,__args__; __sig__ = { kwargs:{},args:["func", "objs"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2164,28 +2393,22 @@ map = function(args, kwargs) { var func = __args__['func']; var objs = __args__['objs']; arr = []; - var ob, __iterator__18; - __iterator__18 = __get__(__get__(objs, "__iter__", "no iterator - line 793: for ob in objs:"), "__call__")([], __NULL_OBJECT__); - var __next__18; - __next__18 = __get__(__iterator__18, "next"); - while (( __iterator__18.index ) < __iterator__18.length) { - ob = __next__18(); + var ob,__iterator__41; + __iterator__41 = __get__(__get__(objs, "__iter__", "no iterator - line 1086: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + var __next__41; + __next__41 = __get__(__iterator__41, "next"); + while (( __iterator__41.index ) < __iterator__41.length) { + ob = __next__41(); v = __get__(func, "__call__")([ob], __NULL_OBJECT__); arr.push(v); } return arr; -} - -map.NAME = "map"; -map.args_signature = ["func", "objs"]; -map.kwargs_signature = { }; -map.types_signature = { }; -map.pythonscript_function = true; -filter = function(args, kwargs) { +};map.is_wrapper = true; +var filter = function(args, kwargs) { var arr; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["func", "objs"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2195,29 +2418,23 @@ filter = function(args, kwargs) { var func = __args__['func']; var objs = __args__['objs']; arr = []; - var ob, __iterator__19; - __iterator__19 = __get__(__get__(objs, "__iter__", "no iterator - line 801: for ob in objs:"), "__call__")([], __NULL_OBJECT__); - var __next__19; - __next__19 = __get__(__iterator__19, "next"); - while (( __iterator__19.index ) < __iterator__19.length) { - ob = __next__19(); + var ob,__iterator__42; + __iterator__42 = __get__(__get__(objs, "__iter__", "no iterator - line 1093: for ob in objs:"), "__call__")([], __NULL_OBJECT__); + var __next__42; + __next__42 = __get__(__iterator__42, "next"); + while (( __iterator__42.index ) < __iterator__42.length) { + ob = __next__42(); if (__test_if_true__(__get__(func, "__call__")([ob], __NULL_OBJECT__))) { arr.push(ob); } } return arr; -} - -filter.NAME = "filter"; -filter.args_signature = ["func", "objs"]; -filter.kwargs_signature = { }; -filter.types_signature = { }; -filter.pythonscript_function = true; -min = function(args, kwargs) { +};filter.is_wrapper = true; +var min = function(args, kwargs) { var a; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["lst"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2226,12 +2443,12 @@ min = function(args, kwargs) { __args__ = __getargs__("min", __sig__, args, kwargs); var lst = __args__['lst']; a = null; - var value, __iterator__20; - __iterator__20 = __get__(__get__(lst, "__iter__", "no iterator - line 810: for value in lst:"), "__call__")([], __NULL_OBJECT__); - var __next__20; - __next__20 = __get__(__iterator__20, "next"); - while (( __iterator__20.index ) < __iterator__20.length) { - value = __next__20(); + var value,__iterator__43; + __iterator__43 = __get__(__get__(lst, "__iter__", "no iterator - line 1100: for value in lst:"), "__call__")([], __NULL_OBJECT__); + var __next__43; + __next__43 = __get__(__iterator__43, "next"); + while (( __iterator__43.index ) < __iterator__43.length) { + value = __next__43(); if (( a ) === null) { a = value; } else { @@ -2241,18 +2458,12 @@ min = function(args, kwargs) { } } return a; -} - -min.NAME = "min"; -min.args_signature = ["lst"]; -min.kwargs_signature = { }; -min.types_signature = { }; -min.pythonscript_function = true; -max = function(args, kwargs) { +};min.is_wrapper = true; +var max = function(args, kwargs) { var a; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["lst"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2261,12 +2472,12 @@ max = function(args, kwargs) { __args__ = __getargs__("max", __sig__, args, kwargs); var lst = __args__['lst']; a = null; - var value, __iterator__21; - __iterator__21 = __get__(__get__(lst, "__iter__", "no iterator - line 817: for value in lst:"), "__call__")([], __NULL_OBJECT__); - var __next__21; - __next__21 = __get__(__iterator__21, "next"); - while (( __iterator__21.index ) < __iterator__21.length) { - value = __next__21(); + var value,__iterator__44; + __iterator__44 = __get__(__get__(lst, "__iter__", "no iterator - line 1106: for value in lst:"), "__call__")([], __NULL_OBJECT__); + var __next__44; + __next__44 = __get__(__iterator__44, "next"); + while (( __iterator__44.index ) < __iterator__44.length) { + value = __next__44(); if (( a ) === null) { a = value; } else { @@ -2276,17 +2487,12 @@ max = function(args, kwargs) { } } return a; -} - -max.NAME = "max"; -max.args_signature = ["lst"]; -max.kwargs_signature = { }; -max.types_signature = { }; -max.pythonscript_function = true; -abs = function(args, kwargs) { - var __sig__, __args__; +};max.is_wrapper = true; +var abs = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["num"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2295,17 +2501,12 @@ abs = function(args, kwargs) { __args__ = __getargs__("abs", __sig__, args, kwargs); var num = __args__['num']; return Math.abs(num); -} - -abs.NAME = "abs"; -abs.args_signature = ["num"]; -abs.kwargs_signature = { }; -abs.types_signature = { }; -abs.pythonscript_function = true; -ord = function(args, kwargs) { - var __sig__, __args__; +};abs.is_wrapper = true; +var ord = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["char"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2314,17 +2515,12 @@ ord = function(args, kwargs) { __args__ = __getargs__("ord", __sig__, args, kwargs); var char = __args__['char']; return char.charCodeAt(0); -} - -ord.NAME = "ord"; -ord.args_signature = ["char"]; -ord.kwargs_signature = { }; -ord.types_signature = { }; -ord.pythonscript_function = true; -chr = function(args, kwargs) { - var __sig__, __args__; +};ord.is_wrapper = true; +var chr = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["num"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2333,14 +2529,8 @@ chr = function(args, kwargs) { __args__ = __getargs__("chr", __sig__, args, kwargs); var num = __args__['num']; return String.fromCharCode(num); -} - -chr.NAME = "chr"; -chr.args_signature = ["num"]; -chr.kwargs_signature = { }; -chr.types_signature = { }; -chr.pythonscript_function = true; -__ArrayIterator = function(arr, index) { +};chr.is_wrapper = true; +var __ArrayIterator = function(arr, index) { __ArrayIterator.__init__(this, arr, index); this.__class__ = __ArrayIterator; this.__uid__ = ("" + _PythonJS_UID); @@ -2350,6 +2540,7 @@ __ArrayIterator = function(arr, index) { __ArrayIterator.__uid__ = ("" + _PythonJS_UID); _PythonJS_UID += 1; __ArrayIterator.prototype.__init__ = function(arr, index) { + this.arr = arr; this.index = index; this.length = arr.length; @@ -2357,7 +2548,7 @@ __ArrayIterator.prototype.__init__ = function(arr, index) { __ArrayIterator.__init__ = function () { return __ArrayIterator.prototype.__init__.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; __ArrayIterator.prototype.next = function() { - var index, arr; + var index,arr; index = this.index; this.index += 1; arr = this.arr; @@ -2367,14 +2558,15 @@ __ArrayIterator.prototype.next = function() { __ArrayIterator.next = function () { return __ArrayIterator.prototype.next.apply(arguments[0], Array.prototype.slice.call(arguments,1)) }; __ArrayIterator.prototype.__properties__ = { }; __ArrayIterator.prototype.__unbound_methods__ = { }; -var Iterator, __Iterator_attrs, __Iterator_parents; +var Iterator,__Iterator_attrs,__Iterator_parents; __Iterator_attrs = {}; __Iterator_parents = []; __Iterator_properties = {}; -__Iterator___init__ = function(args, kwargs) { - var __sig__, __args__; +var __Iterator___init__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "obj", "index"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2387,20 +2579,14 @@ __Iterator___init__ = function(args, kwargs) { self.obj = obj; self.index = index; self.length = len([obj], __NULL_OBJECT__); - self.obj_get = __get__(obj, "get", "missing attribute `get` - line 852: self.obj_get = obj.get ## cache this for speed"); -} - -__Iterator___init__.NAME = "__Iterator___init__"; -__Iterator___init__.args_signature = ["self", "obj", "index"]; -__Iterator___init__.kwargs_signature = { }; -__Iterator___init__.types_signature = { }; -__Iterator___init__.pythonscript_function = true; + self.obj_get = __get__(obj, "get", "missing attribute `get` - line 1134: self.obj_get = obj.get ## cache this for speed"); +};__Iterator___init__.is_wrapper = true; __Iterator_attrs.__init__ = __Iterator___init__; -__Iterator_next = function(args, kwargs) { +var __Iterator_next = function(args, kwargs) { var index; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2411,19 +2597,14 @@ __Iterator_next = function(args, kwargs) { index = self.index; self.index += 1; return self.obj_get([index], __jsdict([])); -} - -__Iterator_next.NAME = "__Iterator_next"; -__Iterator_next.args_signature = ["self"]; -__Iterator_next.kwargs_signature = { }; -__Iterator_next.types_signature = { }; -__Iterator_next.pythonscript_function = true; +};__Iterator_next.is_wrapper = true; __Iterator_attrs.next = __Iterator_next; Iterator = __create_class__("Iterator", __Iterator_parents, __Iterator_attrs, __Iterator_properties); -tuple = function(args, kwargs) { - var __sig__, __args__; +var tuple = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2431,13 +2612,13 @@ tuple = function(args, kwargs) { } __args__ = __getargs__("tuple", __sig__, args, kwargs); var a = __args__['a']; - if (( Object.keys(arguments).length ) == 0) { + if ((Object.keys(arguments).length instanceof Array ? JSON.stringify(Object.keys(arguments).length)==JSON.stringify(0) : Object.keys(arguments).length===0)) { return []; } else { if (__test_if_true__(a instanceof Array)) { return a.slice(); } else { - if (( typeof(a) ) == "string") { + if ((typeof(a) instanceof Array ? JSON.stringify(typeof(a))==JSON.stringify("string") : typeof(a)==="string")) { return a.split(""); } else { console.log(a); @@ -2446,17 +2627,12 @@ tuple = function(args, kwargs) { } } } -} - -tuple.NAME = "tuple"; -tuple.args_signature = ["a"]; -tuple.kwargs_signature = { }; -tuple.types_signature = { }; -tuple.pythonscript_function = true; -list = function(args, kwargs) { - var __sig__, __args__; +};tuple.is_wrapper = true; +var list = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2464,13 +2640,13 @@ list = function(args, kwargs) { } __args__ = __getargs__("list", __sig__, args, kwargs); var a = __args__['a']; - if (( Object.keys(arguments).length ) == 0) { + if ((Object.keys(arguments).length instanceof Array ? JSON.stringify(Object.keys(arguments).length)==JSON.stringify(0) : Object.keys(arguments).length===0)) { return []; } else { if (__test_if_true__(a instanceof Array)) { return a.slice(); } else { - if (( typeof(a) ) == "string") { + if ((typeof(a) instanceof Array ? JSON.stringify(typeof(a))==JSON.stringify("string") : typeof(a)==="string")) { return a.split(""); } else { console.log(a); @@ -2479,22 +2655,44 @@ list = function(args, kwargs) { } } } +};list.is_wrapper = true; +var __tuple_key__ = function(arr) { + var i,item,r,t; + r = []; + i = 0; + while (( i ) < arr.length) { + item = arr[i]; + t = typeof(item); + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("string") : t==="string")) { + r.append((("'" + item) + "'")); + } else { + if (__test_if_true__(item instanceof Array)) { + r.append(__tuple_key__(item)); + } else { + if ((t instanceof Array ? JSON.stringify(t)==JSON.stringify("object") : t==="object")) { + if (( item.__uid__ ) === undefined) { + throw new KeyError(item); + } + r.append(item.__uid__); + } else { + r.append(item); + } + } + } + i += 1; + } + return r.join(","); } -list.NAME = "list"; -list.args_signature = ["a"]; -list.kwargs_signature = { }; -list.types_signature = { }; -list.pythonscript_function = true; -var dict, __dict_attrs, __dict_parents; +var dict,__dict_attrs,__dict_parents; __dict_attrs = {}; __dict_parents = []; __dict_properties = {}; -__dict___init__ = function(args, kwargs) { - var ob, value; - var __sig__, __args__; +var __dict___init__ = function(args, kwargs) { + var k,ob,value,v; + var __sig__,__args__; __sig__ = { kwargs:{"js_object": null, "pointer": null},args:["self", "js_object", "pointer"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2511,49 +2709,53 @@ __dict___init__ = function(args, kwargs) { if (__test_if_true__(js_object)) { ob = js_object; if (__test_if_true__(ob instanceof Array)) { - var o, __iterator__22; - __iterator__22 = __get__(__get__(ob, "__iter__", "no iterator - line 907: for o in ob:"), "__call__")([], __NULL_OBJECT__); - var __next__22; - __next__22 = __get__(__iterator__22, "next"); - while (( __iterator__22.index ) < __iterator__22.length) { - o = __next__22(); - if (__test_if_true__(o instanceof Array)) { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 909: self.__setitem__( o[0], o[1] )"), "__call__")([__get__(o, "__getitem__", "line 909: self.__setitem__( o[0], o[1] )")([0], __NULL_OBJECT__), __get__(o, "__getitem__", "line 909: self.__setitem__( o[0], o[1] )")([1], __NULL_OBJECT__)], __NULL_OBJECT__); + var o,__iterator__45; + __iterator__45 = __get__(__get__(ob, "__iter__", "no iterator - line 1196: for o in ob:"), "__call__")([], __NULL_OBJECT__); + var __next__45; + __next__45 = __get__(__iterator__45, "next"); + while (( __iterator__45.index ) < __iterator__45.length) { + o = __next__45(); + if (o instanceof Array) { + k = o[0]; + v = o[1]; } else { - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 911: self.__setitem__( o['key'], o['value'] )"), "__call__")([__get__(o, "__getitem__", "line 911: self.__setitem__( o['key'], o['value'] )")(["key"], __NULL_OBJECT__), __get__(o, "__getitem__", "line 911: self.__setitem__( o['key'], o['value'] )")(["value"], __NULL_OBJECT__)], __NULL_OBJECT__); + k = o["key"]; + v = o["value"]; } + try { +__get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1203: self.__setitem__( k,v )"), "__call__")([k, v], __NULL_OBJECT__); + } catch(__exception__) { +if (__exception__ == KeyError || __exception__ instanceof KeyError) { +throw new KeyError("error in dict init, bad key"); +} + +} } } else { if (__test_if_true__(isinstance([ob, dict], __NULL_OBJECT__))) { - var key, __iterator__23; - __iterator__23 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 913: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); - var __next__23; - __next__23 = __get__(__iterator__23, "next"); - while (( __iterator__23.index ) < __iterator__23.length) { - key = __next__23(); - value = __get__(ob, "__getitem__", "line 914: value = ob[ key ]")([key], __NULL_OBJECT__); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 915: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); + var key,__iterator__46; + __iterator__46 = __get__(__get__(__jsdict_keys(ob), "__iter__", "no iterator - line 1207: for key in ob.keys():"), "__call__")([], __NULL_OBJECT__); + var __next__46; + __next__46 = __get__(__iterator__46, "next"); + while (( __iterator__46.index ) < __iterator__46.length) { + key = __next__46(); + value = ((ob instanceof Array) ? ob[key] : __get__(ob, "__getitem__", "line 1208: value = ob[ key ]")([key], __NULL_OBJECT__)); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1209: self.__setitem__( key, value )"), "__call__")([key, value], __NULL_OBJECT__); } } else { - console.log("ERROR init dict from:", js_object); + console.log(["ERROR init dict from:", js_object]); throw new TypeError; } } } } -} - -__dict___init__.NAME = "__dict___init__"; -__dict___init__.args_signature = ["self", "js_object", "pointer"]; -__dict___init__.kwargs_signature = { js_object:null,pointer:null }; -__dict___init__.types_signature = { js_object:"None",pointer:"None" }; -__dict___init__.pythonscript_function = true; +};__dict___init__.is_wrapper = true; __dict_attrs.__init__ = __dict___init__; -__dict_jsify = function(args, kwargs) { - var keys, value; - var __sig__, __args__; +var __dict_jsify = function(args, kwargs) { + var keys,value; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2562,36 +2764,31 @@ __dict_jsify = function(args, kwargs) { __args__ = __getargs__("__dict_jsify", __sig__, args, kwargs); var self = __args__['self']; keys = __object_keys__([self["$wrapped"]], __NULL_OBJECT__); - var key, __iterator__24; - __iterator__24 = __get__(__get__(keys, "__iter__", "no iterator - line 923: for key in keys:"), "__call__")([], __NULL_OBJECT__); - var __next__24; - __next__24 = __get__(__iterator__24, "next"); - while (( __iterator__24.index ) < __iterator__24.length) { - key = __next__24(); - value = __get__(self["$wrapped"], "__getitem__", "line 924: value = self[...][key]")([key], __NULL_OBJECT__); - if (( typeof(value) ) == "object") { + var key,__iterator__47; + __iterator__47 = __get__(__get__(keys, "__iter__", "no iterator - line 1216: for key in keys:"), "__call__")([], __NULL_OBJECT__); + var __next__47; + __next__47 = __get__(__iterator__47, "next"); + while (( __iterator__47.index ) < __iterator__47.length) { + key = __next__47(); + value = __get__(self["$wrapped"], "__getitem__", "line 1217: value = self[...][key]")([key], __NULL_OBJECT__); + if ((typeof(value) instanceof Array ? JSON.stringify(typeof(value))==JSON.stringify("object") : typeof(value)==="object")) { if (__test_if_true__(hasattr([value, "jsify"], __NULL_OBJECT__))) { - __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 927: self[...][key] = value.jsify()"), "__call__")()], {}); + __get__(__get__(self["$wrapped"], "__setitem__"), "__call__")([key, __get__(__get__(value, "jsify", "missing attribute `jsify` - line 1220: self[...][key] = value.jsify()"), "__call__")()], {}); } } else { - if (( typeof(value) ) == "function") { + if ((typeof(value) instanceof Array ? JSON.stringify(typeof(value))==JSON.stringify("function") : typeof(value)==="function")) { throw new RuntimeError("can not jsify function"); } } } return self["$wrapped"]; -} - -__dict_jsify.NAME = "__dict_jsify"; -__dict_jsify.args_signature = ["self"]; -__dict_jsify.kwargs_signature = { }; -__dict_jsify.types_signature = { }; -__dict_jsify.pythonscript_function = true; +};__dict_jsify.is_wrapper = true; __dict_attrs.jsify = __dict_jsify; -__dict_copy = function(args, kwargs) { - var __sig__, __args__; +var __dict_copy = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2600,19 +2797,13 @@ __dict_copy = function(args, kwargs) { __args__ = __getargs__("__dict_copy", __sig__, args, kwargs); var self = __args__['self']; return __get__(dict, "__call__")([self], __NULL_OBJECT__); -} - -__dict_copy.NAME = "__dict_copy"; -__dict_copy.args_signature = ["self"]; -__dict_copy.kwargs_signature = { }; -__dict_copy.types_signature = { }; -__dict_copy.return_type = "dict"; -__dict_copy.pythonscript_function = true; +};__dict_copy.is_wrapper = true; __dict_attrs.copy = __dict_copy; -__dict_clear = function(args, kwargs) { - var __sig__, __args__; +var __dict_clear = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2621,19 +2812,13 @@ __dict_clear = function(args, kwargs) { __args__ = __getargs__("__dict_clear", __sig__, args, kwargs); var self = __args__['self']; self["$wrapped"] = __jsdict([]); -} - -__dict_clear.NAME = "__dict_clear"; -__dict_clear.args_signature = ["self"]; -__dict_clear.kwargs_signature = { }; -__dict_clear.types_signature = { }; -__dict_clear.pythonscript_function = true; +};__dict_clear.is_wrapper = true; __dict_attrs.clear = __dict_clear; -__dict_has_key = function(args, kwargs) { +var __dict_has_key = function(args, kwargs) { var __dict; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2644,25 +2829,20 @@ __dict_has_key = function(args, kwargs) { var key = __args__['key']; __dict = self["$wrapped"]; if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - key = __get__(key, "__uid__", "missing attribute `__uid__` - line 943: key = key.__uid__"); + key = __get__(key, "__uid__", "missing attribute `__uid__` - line 1233: key = key.__uid__"); } if (__test_if_true__(key in __dict)) { return true; } else { return false; } -} - -__dict_has_key.NAME = "__dict_has_key"; -__dict_has_key.args_signature = ["self", "key"]; -__dict_has_key.kwargs_signature = { }; -__dict_has_key.types_signature = { }; -__dict_has_key.pythonscript_function = true; +};__dict_has_key.is_wrapper = true; __dict_attrs.has_key = __dict_has_key; -__dict_update = function(args, kwargs) { - var __sig__, __args__; +var __dict_update = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "other"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2671,27 +2851,21 @@ __dict_update = function(args, kwargs) { __args__ = __getargs__("__dict_update", __sig__, args, kwargs); var self = __args__['self']; var other = __args__['other']; - var key, __iterator__25; - __iterator__25 = __get__(__get__(other, "__iter__", "no iterator - line 951: for key in other:"), "__call__")([], __NULL_OBJECT__); - var __next__25; - __next__25 = __get__(__iterator__25, "next"); - while (( __iterator__25.index ) < __iterator__25.length) { - key = __next__25(); - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 952: self.__setitem__( key, other[key] )"), "__call__")([key, __get__(other, "__getitem__", "line 952: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__)], __NULL_OBJECT__); - } -} - -__dict_update.NAME = "__dict_update"; -__dict_update.args_signature = ["self", "other"]; -__dict_update.kwargs_signature = { }; -__dict_update.types_signature = { }; -__dict_update.pythonscript_function = true; + var key,__iterator__48; + __iterator__48 = __get__(__get__(other, "__iter__", "no iterator - line 1239: for key in other:"), "__call__")([], __NULL_OBJECT__); + var __next__48; + __next__48 = __get__(__iterator__48, "next"); + while (( __iterator__48.index ) < __iterator__48.length) { + key = __next__48(); + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1240: self.__setitem__( key, other[key] )"), "__call__")([key, ((other instanceof Array) ? other[key] : __get__(other, "__getitem__", "line 1240: self.__setitem__( key, other[key] )")([key], __NULL_OBJECT__))], __NULL_OBJECT__); + } +};__dict_update.is_wrapper = true; __dict_attrs.update = __dict_update; -__dict_items = function(args, kwargs) { +var __dict_items = function(args, kwargs) { var arr; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2700,27 +2874,22 @@ __dict_items = function(args, kwargs) { __args__ = __getargs__("__dict_items", __sig__, args, kwargs); var self = __args__['self']; arr = []; - var key, __iterator__26; - __iterator__26 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 956: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); - var __next__26; - __next__26 = __get__(__iterator__26, "next"); - while (( __iterator__26.index ) < __iterator__26.length) { - key = __next__26(); - __get__(__get__(arr, "append", "missing attribute `append` - line 957: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); + var key,__iterator__49; + __iterator__49 = __get__(__get__(__jsdict_keys(self), "__iter__", "no iterator - line 1243: for key in self.keys():"), "__call__")([], __NULL_OBJECT__); + var __next__49; + __next__49 = __get__(__iterator__49, "next"); + while (( __iterator__49.index ) < __iterator__49.length) { + key = __next__49(); + __get__(__get__(arr, "append", "missing attribute `append` - line 1244: arr.append( [key, self[key]] )"), "__call__")([[key, __get__(self, "__getitem__")([key], __NULL_OBJECT__)]], __NULL_OBJECT__); } return arr; -} - -__dict_items.NAME = "__dict_items"; -__dict_items.args_signature = ["self"]; -__dict_items.kwargs_signature = { }; -__dict_items.types_signature = { }; -__dict_items.pythonscript_function = true; +};__dict_items.is_wrapper = true; __dict_attrs.items = __dict_items; -__dict_get = function(args, kwargs) { - var __sig__, __args__; +var __dict_get = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{"_default": null},args:["self", "key", "_default"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2736,18 +2905,13 @@ return __get__(self, "__getitem__")([key], __NULL_OBJECT__); return _default; } -} - -__dict_get.NAME = "__dict_get"; -__dict_get.args_signature = ["self", "key", "_default"]; -__dict_get.kwargs_signature = { _default:null }; -__dict_get.types_signature = { _default:"None" }; -__dict_get.pythonscript_function = true; +};__dict_get.is_wrapper = true; __dict_attrs.get = __dict_get; -__dict_set = function(args, kwargs) { - var __sig__, __args__; +var __dict_set = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2757,20 +2921,14 @@ __dict_set = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; - __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 967: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); -} - -__dict_set.NAME = "__dict_set"; -__dict_set.args_signature = ["self", "key", "value"]; -__dict_set.kwargs_signature = { }; -__dict_set.types_signature = { }; -__dict_set.pythonscript_function = true; + __get__(__get__(self, "__setitem__", "missing attribute `__setitem__` - line 1252: self.__setitem__(key, value)"), "__call__")([key, value], __NULL_OBJECT__); +};__dict_set.is_wrapper = true; __dict_attrs.set = __dict_set; -__dict___len__ = function(args, kwargs) { +var __dict___len__ = function(args, kwargs) { var __dict; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2780,19 +2938,13 @@ __dict___len__ = function(args, kwargs) { var self = __args__['self']; __dict = self["$wrapped"]; return Object.keys(__dict).length; -} - -__dict___len__.NAME = "__dict___len__"; -__dict___len__.args_signature = ["self"]; -__dict___len__.kwargs_signature = { }; -__dict___len__.types_signature = { }; -__dict___len__.pythonscript_function = true; +};__dict___len__.is_wrapper = true; __dict_attrs.__len__ = __dict___len__; -__dict___getitem__ = function(args, kwargs) { - var __dict; - var __sig__, __args__; +var __dict___getitem__ = function(args, kwargs) { + var __dict,msg,err; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2801,31 +2953,36 @@ __dict___getitem__ = function(args, kwargs) { __args__ = __getargs__("__dict___getitem__", __sig__, args, kwargs); var self = __args__['self']; var key = __args__['key']; - "\n notes:\n . '4' and 4 are the same key\n . it is possible that the translator mistakes a javascript-object for a dict and inlines this function,\n that is why below we return the key in self if __dict is undefined.\n "; + "\n note: `\"4\"` and `4` are the same key in javascript, is there a sane way to workaround this,\n that can remain compatible with external javascript?\n "; __dict = self["$wrapped"]; - if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { - return __dict[key.__uid__]; + err = false; + if (__test_if_true__(key instanceof Array)) { + key = __tuple_key__(key); + } else { + if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { + if (__test_if_true__(key.__uid__ && key.__uid__ in __dict)) { + return __dict[key.__uid__]; + } else { + err = true; + } } - throw new KeyError(key); } - if (__test_if_true__(__dict && key in __dict)) { + if (__test_if_true__((__dict && key in __dict))) { return __dict[key]; + } else { + err = true; } - throw new KeyError(key); -} - -__dict___getitem__.NAME = "__dict___getitem__"; -__dict___getitem__.args_signature = ["self", "key"]; -__dict___getitem__.kwargs_signature = { }; -__dict___getitem__.types_signature = { }; -__dict___getitem__.pythonscript_function = true; + if (__test_if_true__(err)) { + msg = __sprintf("missing key: %s -\n", key); + throw new KeyError(__jsdict_keys(__dict)); + } +};__dict___getitem__.is_wrapper = true; __dict_attrs.__getitem__ = __dict___getitem__; -__dict___setitem__ = function(args, kwargs) { +var __dict___setitem__ = function(args, kwargs) { var __dict; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "key", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2835,27 +2992,36 @@ __dict___setitem__ = function(args, kwargs) { var self = __args__['self']; var key = __args__['key']; var value = __args__['value']; + if (( key ) === undefined) { + throw new KeyError("undefined is invalid key type"); + } + if (( key ) === null) { + throw new KeyError("null is invalid key type"); + } __dict = self["$wrapped"]; - if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { - if (__test_if_true__(key.__uid__ === undefined)) { - key.__uid__ = '' + _PythonJS_UID++; + if (__test_if_true__(key instanceof Array)) { + key = __tuple_key__(key); + if (( key ) === undefined) { + throw new KeyError("undefined is invalid key type (tuple)"); } - __dict[key.__uid__] = value; - } else { __dict[key] = value; + } else { + if (__test_if_true__(typeof(key) === 'object' || typeof(key) === 'function')) { + if (__test_if_true__(key.__uid__ === undefined)) { + key.__uid__ = '' + _PythonJS_UID++; + } + __dict[key.__uid__] = value; + } else { + __dict[key] = value; + } } -} - -__dict___setitem__.NAME = "__dict___setitem__"; -__dict___setitem__.args_signature = ["self", "key", "value"]; -__dict___setitem__.kwargs_signature = { }; -__dict___setitem__.types_signature = { }; -__dict___setitem__.pythonscript_function = true; +};__dict___setitem__.is_wrapper = true; __dict_attrs.__setitem__ = __dict___setitem__; -__dict_keys = function(args, kwargs) { - var __sig__, __args__; +var __dict_keys = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2864,19 +3030,13 @@ __dict_keys = function(args, kwargs) { __args__ = __getargs__("__dict_keys", __sig__, args, kwargs); var self = __args__['self']; return Object.keys(self["$wrapped"]); -} - -__dict_keys.NAME = "__dict_keys"; -__dict_keys.args_signature = ["self"]; -__dict_keys.kwargs_signature = { }; -__dict_keys.types_signature = { }; -__dict_keys.pythonscript_function = true; +};__dict_keys.is_wrapper = true; __dict_attrs.keys = __dict_keys; -__dict_pop = function(args, kwargs) { - var js_object, v; - var __sig__, __args__; +var __dict_pop = function(args, kwargs) { + var js_object,v; + var __sig__,__args__; __sig__ = { kwargs:{"d": null},args:["self", "key", "d"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2894,19 +3054,13 @@ __dict_pop = function(args, kwargs) { delete js_object[key]; return v; } -} - -__dict_pop.NAME = "__dict_pop"; -__dict_pop.args_signature = ["self", "key", "d"]; -__dict_pop.kwargs_signature = { d:null }; -__dict_pop.types_signature = { d:"None" }; -__dict_pop.pythonscript_function = true; +};__dict_pop.is_wrapper = true; __dict_attrs.pop = __dict_pop; -__dict_values = function(args, kwargs) { - var keys, out; - var __sig__, __args__; +var __dict_values = function(args, kwargs) { + var keys,out; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2916,25 +3070,20 @@ __dict_values = function(args, kwargs) { var self = __args__['self']; keys = Object.keys(self["$wrapped"]); out = []; - var __iter18 = keys; - if (! (__iter18 instanceof Array || typeof __iter18 == "string" || __is_typed_array(__iter18)) ) { __iter18 = __object_keys__(__iter18) } - for (var __idx18=0; __idx18 < __iter18.length; __idx18++) { - var key = __iter18[ __idx18 ]; - out.push(self["$wrapped"][((key.__uid__) ? key.__uid__ : key)]); + var __iter34 = keys; + if (! (__iter34 instanceof Array || typeof __iter34 == "string" || __is_typed_array(__iter34) || __is_some_array(__iter34) )) { __iter34 = __object_keys__(__iter34) } + for (var __idx34=0; __idx34 < __iter34.length; __idx34++) { + var key = __iter34[ __idx34 ]; + out.push(self["$wrapped"][key]); } return out; -} - -__dict_values.NAME = "__dict_values"; -__dict_values.args_signature = ["self"]; -__dict_values.kwargs_signature = { }; -__dict_values.types_signature = { }; -__dict_values.pythonscript_function = true; +};__dict_values.is_wrapper = true; __dict_attrs.values = __dict_values; -__dict___contains__ = function(args, kwargs) { - var __sig__, __args__; +var __dict___contains__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2950,18 +3099,13 @@ return true; return false; } -} - -__dict___contains__.NAME = "__dict___contains__"; -__dict___contains__.args_signature = ["self", "value"]; -__dict___contains__.kwargs_signature = { }; -__dict___contains__.types_signature = { }; -__dict___contains__.pythonscript_function = true; +};__dict___contains__.is_wrapper = true; __dict_attrs.__contains__ = __dict___contains__; -__dict___iter__ = function(args, kwargs) { - var __sig__, __args__; +var __dict___iter__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2970,21 +3114,14 @@ __dict___iter__ = function(args, kwargs) { __args__ = __getargs__("__dict___iter__", __sig__, args, kwargs); var self = __args__['self']; return __get__(Iterator, "__call__")([__jsdict_keys(self), 0], __NULL_OBJECT__); -} - -__dict___iter__.NAME = "__dict___iter__"; -__dict___iter__.args_signature = ["self"]; -__dict___iter__.kwargs_signature = { }; -__dict___iter__.types_signature = { }; -__dict___iter__.return_type = "Iterator"; -__dict___iter__.pythonscript_function = true; +};__dict___iter__.is_wrapper = true; __dict_attrs.__iter__ = __dict___iter__; dict = __create_class__("dict", __dict_parents, __dict_attrs, __dict_properties); -set = function(args, kwargs) { - var keys, mask, s, hashtable, key, fallback; - var __sig__, __args__; +var set = function(args, kwargs) { + var keys,mask,s,hashtable,key,fallback; + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -2992,10 +3129,7 @@ set = function(args, kwargs) { } __args__ = __getargs__("set", __sig__, args, kwargs); var a = __args__['a']; - "\n This returns an array that is a minimal implementation of set.\n Often sets are used simply to remove duplicate entries from a list, \n and then it get converted back to a list, it is safe to use fastset for this.\n\n The array prototype is overloaded with basic set functions:\n difference\n intersection\n issubset\n\n Note: sets in Python are not subscriptable, but can be iterated over.\n\n Python docs say that set are unordered, some programs may rely on this disorder\n for randomness, for sets of integers we emulate the unorder only uppon initalization \n of the set, by masking the value by bits-1. Python implements sets starting with an \n array of length 8, and mask of 7, if set length grows to 6 (3/4th), then it allocates \n a new array of length 32 and mask of 31. This is only emulated for arrays of \n integers up to an array length of 1536.\n\n "; - if (__test_if_true__(a instanceof Array)) { - a = a["$wrapped"]; - } + "\n This returns an array that is a minimal implementation of set.\n Often sets are used simply to remove duplicate entries from a list, \n and then it get converted back to a list, it is safe to use fastset for this.\n The array prototype is overloaded with basic set functions:\n difference\n intersection\n issubset\n Note: sets in Python are not subscriptable, but can be iterated over.\n Python docs say that set are unordered, some programs may rely on this disorder\n for randomness, for sets of integers we emulate the unorder only uppon initalization \n of the set, by masking the value by bits-1. Python implements sets starting with an \n array of length 8, and mask of 7, if set length grows to 6 (3/4th), then it allocates \n a __new__>>array of length 32 and mask of 31. This is only emulated for arrays of \n integers up to an array length of 1536.\n "; hashtable = null; if (( a.length ) <= 1536) { hashtable = __jsdict([]); @@ -3020,13 +3154,13 @@ set = function(args, kwargs) { } fallback = false; if (__test_if_true__(hashtable)) { - var __iter19 = a; - if (! (__iter19 instanceof Array || typeof __iter19 == "string" || __is_typed_array(__iter19)) ) { __iter19 = __object_keys__(__iter19) } - for (var __idx19=0; __idx19 < __iter19.length; __idx19++) { - var b = __iter19[ __idx19 ]; - if (__test_if_true__(typeof(b, "number") && ( b ) === ( (b | 0) ))) { + var __iter35 = a; + if (! (__iter35 instanceof Array || typeof __iter35 == "string" || __is_typed_array(__iter35) || __is_some_array(__iter35) )) { __iter35 = __object_keys__(__iter35) } + for (var __idx35=0; __idx35 < __iter35.length; __idx35++) { + var b = __iter35[ __idx35 ]; + if (__test_if_true__(((typeof(b) instanceof Array ? JSON.stringify(typeof(b))==JSON.stringify("number") : typeof(b)==="number") && ( b ) === ( (b | 0) )))) { key = (b & mask); - hashtable[((key.__uid__) ? key.__uid__ : key)] = b; + hashtable[key] = b; keys.push(key); } else { fallback = true; @@ -3038,35 +3172,30 @@ set = function(args, kwargs) { } s = []; if (__test_if_true__(fallback)) { - var __iter20 = a; - if (! (__iter20 instanceof Array || typeof __iter20 == "string" || __is_typed_array(__iter20)) ) { __iter20 = __object_keys__(__iter20) } - for (var __idx20=0; __idx20 < __iter20.length; __idx20++) { - var item = __iter20[ __idx20 ]; - if (( s.indexOf(item) ) == -1) { + var __iter36 = a; + if (! (__iter36 instanceof Array || typeof __iter36 == "string" || __is_typed_array(__iter36) || __is_some_array(__iter36) )) { __iter36 = __object_keys__(__iter36) } + for (var __idx36=0; __idx36 < __iter36.length; __idx36++) { + var item = __iter36[ __idx36 ]; + if ((s.indexOf(item) instanceof Array ? JSON.stringify(s.indexOf(item))==JSON.stringify(-1) : s.indexOf(item)===-1)) { s.push(item); } } } else { - keys.sort(); - var __iter21 = keys; - if (! (__iter21 instanceof Array || typeof __iter21 == "string" || __is_typed_array(__iter21)) ) { __iter21 = __object_keys__(__iter21) } - for (var __idx21=0; __idx21 < __iter21.length; __idx21++) { - var key = __iter21[ __idx21 ]; - s.push(hashtable[((key.__uid__) ? key.__uid__ : key)]); + __sort_method(keys); + var __iter37 = keys; + if (! (__iter37 instanceof Array || typeof __iter37 == "string" || __is_typed_array(__iter37) || __is_some_array(__iter37) )) { __iter37 = __object_keys__(__iter37) } + for (var __idx37=0; __idx37 < __iter37.length; __idx37++) { + var key = __iter37[ __idx37 ]; + s.push(hashtable[key]); } } return s; -} - -set.NAME = "set"; -set.args_signature = ["a"]; -set.kwargs_signature = { }; -set.types_signature = { }; -set.pythonscript_function = true; -frozenset = function(args, kwargs) { - var __sig__, __args__; +};set.is_wrapper = true; +var frozenset = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["a"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3075,14 +3204,8 @@ frozenset = function(args, kwargs) { __args__ = __getargs__("frozenset", __sig__, args, kwargs); var a = __args__['a']; return set([a], __NULL_OBJECT__); -} - -frozenset.NAME = "frozenset"; -frozenset.args_signature = ["a"]; -frozenset.kwargs_signature = { }; -frozenset.types_signature = { }; -frozenset.pythonscript_function = true; -var array, __array_attrs, __array_parents; +};frozenset.is_wrapper = true; +var array,__array_attrs,__array_parents; __array_attrs = {}; __array_parents = []; __array_properties = {}; @@ -3090,11 +3213,11 @@ __array_typecodes = __jsdict([["c", 1], ["b", 1], ["B", 1], ["u", 2], ["h", 2], __array_attrs.typecodes = __array_typecodes; __array_typecode_names = __jsdict([["c", "Int8"], ["b", "Int8"], ["B", "Uint8"], ["u", "Uint16"], ["h", "Int16"], ["H", "Uint16"], ["i", "Int32"], ["I", "Uint32"], ["f", "Float32"], ["d", "Float64"], ["float32", "Float32"], ["float16", "Int16"], ["float8", "Int8"], ["int32", "Int32"], ["uint32", "Uint32"], ["int16", "Int16"], ["uint16", "Uint16"], ["int8", "Int8"], ["uint8", "Uint8"]]); __array_attrs.typecode_names = __array_typecode_names; -__array___init__ = function(args, kwargs) { - var size, buff; - var __sig__, __args__; +var __array___init__ = function(args, kwargs) { + var size,buff; + var __sig__,__args__; __sig__ = { kwargs:{"initializer": null, "little_endian": false},args:["self", "typecode", "initializer", "little_endian"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3106,17 +3229,17 @@ __array___init__ = function(args, kwargs) { var initializer = __args__['initializer']; var little_endian = __args__['little_endian']; self.typecode = typecode; - self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1168: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1168: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); + self.itemsize = __get__(__get__(self, "typecodes", "missing attribute `typecodes` - line 1436: self.itemsize = self.typecodes[ typecode ]"), "__getitem__", "line 1436: self.itemsize = self.typecodes[ typecode ]")([typecode], __NULL_OBJECT__); self.little_endian = little_endian; if (__test_if_true__(initializer)) { self.length = len([initializer], __NULL_OBJECT__); self.bytes = (self.length * self.itemsize); - if (( self.typecode ) == "float8") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float8") : self.typecode==="float8")) { self._scale = max([[abs([min([initializer], __NULL_OBJECT__)], __NULL_OBJECT__), max([initializer], __NULL_OBJECT__)]], __NULL_OBJECT__); self._norm_get = (self._scale / 127); self._norm_set = (1.0 / self._norm_get); } else { - if (( self.typecode ) == "float16") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float16") : self.typecode==="float16")) { self._scale = max([[abs([min([initializer], __NULL_OBJECT__)], __NULL_OBJECT__), max([initializer], __NULL_OBJECT__)]], __NULL_OBJECT__); self._norm_get = (self._scale / 32767); self._norm_set = (1.0 / self._norm_get); @@ -3130,19 +3253,14 @@ __array___init__ = function(args, kwargs) { buff = new ArrayBuffer(size); self.dataview = new DataView(buff); self.buffer = buff; - __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1192: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); -} - -__array___init__.NAME = "__array___init__"; -__array___init__.args_signature = ["self", "typecode", "initializer", "little_endian"]; -__array___init__.kwargs_signature = { initializer:null,little_endian:false }; -__array___init__.types_signature = { initializer:"None",little_endian:"False" }; -__array___init__.pythonscript_function = true; + __get__(__get__(self, "fromlist", "missing attribute `fromlist` - line 1457: self.fromlist( initializer )"), "__call__")([initializer], __NULL_OBJECT__); +};__array___init__.is_wrapper = true; __array_attrs.__init__ = __array___init__; -__array___len__ = function(args, kwargs) { - var __sig__, __args__; +var __array___len__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3151,19 +3269,13 @@ __array___len__ = function(args, kwargs) { __args__ = __getargs__("__array___len__", __sig__, args, kwargs); var self = __args__['self']; return self.length; -} - -__array___len__.NAME = "__array___len__"; -__array___len__.args_signature = ["self"]; -__array___len__.kwargs_signature = { }; -__array___len__.types_signature = { }; -__array___len__.pythonscript_function = true; +};__array___len__.is_wrapper = true; __array_attrs.__len__ = __array___len__; -__array___contains__ = function(args, kwargs) { +var __array___contains__ = function(args, kwargs) { var arr; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3172,25 +3284,19 @@ __array___contains__ = function(args, kwargs) { __args__ = __getargs__("__array___contains__", __sig__, args, kwargs); var self = __args__['self']; var value = __args__['value']; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1200: arr = self.to_array()"), "__call__")(); - if (( arr.indexOf(value) ) == -1) { + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1463: arr = self.to_array()"), "__call__")(); + if ((arr.indexOf(value) instanceof Array ? JSON.stringify(arr.indexOf(value))==JSON.stringify(-1) : arr.indexOf(value)===-1)) { return false; } else { return true; } -} - -__array___contains__.NAME = "__array___contains__"; -__array___contains__.args_signature = ["self", "value"]; -__array___contains__.kwargs_signature = { }; -__array___contains__.types_signature = { }; -__array___contains__.pythonscript_function = true; +};__array___contains__.is_wrapper = true; __array_attrs.__contains__ = __array___contains__; -__array___getitem__ = function(args, kwargs) { - var func_name, dataview, value, step, func, offset; - var __sig__, __args__; +var __array___getitem__ = function(args, kwargs) { + var func_name,dataview,value,step,func,offset; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3202,17 +3308,14 @@ __array___getitem__ = function(args, kwargs) { step = self.itemsize; offset = (step * index); dataview = self.dataview; - var __left34, __right35; - __left34 = "get"; - __right35 = __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1210: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1210: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__); - func_name = ((( typeof(__left34) ) == "number") ? (__left34 + __right35) : __add_op(__left34, __right35)); + func_name = ("get" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1471: func_name = 'get'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1471: func_name = 'get'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { value = func(offset); - if (( self.typecode ) == "float8") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float8") : self.typecode==="float8")) { value = (value * self._norm_get); } else { - if (( self.typecode ) == "float16") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float16") : self.typecode==="float16")) { value = (value * self._norm_get); } } @@ -3220,19 +3323,13 @@ __array___getitem__ = function(args, kwargs) { } else { throw new IndexError(index); } -} - -__array___getitem__.NAME = "__array___getitem__"; -__array___getitem__.args_signature = ["self", "index"]; -__array___getitem__.kwargs_signature = { }; -__array___getitem__.types_signature = { }; -__array___getitem__.pythonscript_function = true; +};__array___getitem__.is_wrapper = true; __array_attrs.__getitem__ = __array___getitem__; -__array___setitem__ = function(args, kwargs) { - var func_name, dataview, step, func, offset; - var __sig__, __args__; +var __array___setitem__ = function(args, kwargs) { + var func_name,dataview,step,func,offset; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3244,23 +3341,17 @@ __array___setitem__ = function(args, kwargs) { var value = __args__['value']; step = self.itemsize; if (( index ) < 0) { - var __left36, __right37; - __left36 = self.length; - __right37 = index; - index = (((( typeof(__left36) ) == "number") ? (__left36 + __right37) : __add_op(__left36, __right37)) - 1); + index = ((self.length + index) - 1); } offset = (step * index); dataview = self.dataview; - var __left38, __right39; - __left38 = "set"; - __right39 = __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1229: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1229: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__); - func_name = ((( typeof(__left38) ) == "number") ? (__left38 + __right39) : __add_op(__left38, __right39)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1487: func_name = 'set'+self.typecode_names[ self.typecode ]"), "__getitem__", "line 1487: func_name = 'set'+self.typecode_names[ self.typecode ]")([self.typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( offset ) < self.bytes) { - if (( self.typecode ) == "float8") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float8") : self.typecode==="float8")) { value = (value * self._norm_set); } else { - if (( self.typecode ) == "float16") { + if ((self.typecode instanceof Array ? JSON.stringify(self.typecode)==JSON.stringify("float16") : self.typecode==="float16")) { value = (value * self._norm_set); } } @@ -3268,18 +3359,13 @@ __array___setitem__ = function(args, kwargs) { } else { throw new IndexError(index); } -} - -__array___setitem__.NAME = "__array___setitem__"; -__array___setitem__.args_signature = ["self", "index", "value"]; -__array___setitem__.kwargs_signature = { }; -__array___setitem__.types_signature = { }; -__array___setitem__.pythonscript_function = true; +};__array___setitem__.is_wrapper = true; __array_attrs.__setitem__ = __array___setitem__; -__array___iter__ = function(args, kwargs) { - var __sig__, __args__; +var __array___iter__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3288,19 +3374,13 @@ __array___iter__ = function(args, kwargs) { __args__ = __getargs__("__array___iter__", __sig__, args, kwargs); var self = __args__['self']; return __get__(Iterator, "__call__")([self, 0], __NULL_OBJECT__); -} - -__array___iter__.NAME = "__array___iter__"; -__array___iter__.args_signature = ["self"]; -__array___iter__.kwargs_signature = { }; -__array___iter__.types_signature = { }; -__array___iter__.return_type = "Iterator"; -__array___iter__.pythonscript_function = true; +};__array___iter__.is_wrapper = true; __array_attrs.__iter__ = __array___iter__; -__array_get = function(args, kwargs) { - var __sig__, __args__; +var __array_get = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "index"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3310,19 +3390,13 @@ __array_get = function(args, kwargs) { var self = __args__['self']; var index = __args__['index']; return __array___getitem__([self, index], {}); -} - -__array_get.NAME = "__array_get"; -__array_get.args_signature = ["self", "index"]; -__array_get.kwargs_signature = { }; -__array_get.types_signature = { }; -__array_get.pythonscript_function = true; +};__array_get.is_wrapper = true; __array_attrs.get = __array_get; -__array_fromlist = function(args, kwargs) { - var typecode, i, func_name, dataview, length, item, step, func, offset, size; - var __sig__, __args__; +var __array_fromlist = function(args, kwargs) { + var typecode,i,func_name,dataview,length,item,step,func,offset,size; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "lst"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3336,20 +3410,17 @@ __array_fromlist = function(args, kwargs) { typecode = self.typecode; size = (length * step); dataview = self.dataview; - var __left40, __right41; - __left40 = "set"; - __right41 = __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1254: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1254: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__); - func_name = ((( typeof(__left40) ) == "number") ? (__left40 + __right41) : __add_op(__left40, __right41)); + func_name = ("set" + __get__(__get__(self, "typecode_names", "missing attribute `typecode_names` - line 1507: func_name = 'set'+self.typecode_names[ typecode ]"), "__getitem__", "line 1507: func_name = 'set'+self.typecode_names[ typecode ]")([typecode], __NULL_OBJECT__)); func = dataview[func_name].bind(dataview); if (( size ) <= self.bytes) { i = 0; offset = 0; while (( i ) < length) { - item = __get__(lst, "__getitem__", "line 1259: item = lst[i]")([i], __NULL_OBJECT__); - if (( typecode ) == "float8") { + item = ((lst instanceof Array) ? lst[i] : __get__(lst, "__getitem__", "line 1512: item = lst[i]")([i], __NULL_OBJECT__)); + if ((typecode instanceof Array ? JSON.stringify(typecode)==JSON.stringify("float8") : typecode==="float8")) { item *= self._norm_set; } else { - if (( typecode ) == "float16") { + if ((typecode instanceof Array ? JSON.stringify(typecode)==JSON.stringify("float16") : typecode==="float16")) { item *= self._norm_set; } } @@ -3360,19 +3431,13 @@ __array_fromlist = function(args, kwargs) { } else { throw new TypeError; } -} - -__array_fromlist.NAME = "__array_fromlist"; -__array_fromlist.args_signature = ["self", "lst"]; -__array_fromlist.kwargs_signature = { }; -__array_fromlist.types_signature = { }; -__array_fromlist.pythonscript_function = true; +};__array_fromlist.is_wrapper = true; __array_attrs.fromlist = __array_fromlist; -__array_resize = function(args, kwargs) { - var source, new_buff, target, new_size, buff; - var __sig__, __args__; +var __array_resize = function(args, kwargs) { + var source,new_buff,target,new_size,buff; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "length"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3391,19 +3456,13 @@ __array_resize = function(args, kwargs) { self.bytes = new_size; self.buffer = new_buff; self.dataview = new DataView(new_buff); -} - -__array_resize.NAME = "__array_resize"; -__array_resize.args_signature = ["self", "length"]; -__array_resize.kwargs_signature = { }; -__array_resize.types_signature = { }; -__array_resize.pythonscript_function = true; +};__array_resize.is_wrapper = true; __array_attrs.resize = __array_resize; -__array_append = function(args, kwargs) { +var __array_append = function(args, kwargs) { var length; - var __sig__, __args__; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "value"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3413,23 +3472,15 @@ __array_append = function(args, kwargs) { var self = __args__['self']; var value = __args__['value']; length = self.length; - var __left42, __right43; - __left42 = self.length; - __right43 = 1; - __get__(__get__(self, "resize", "missing attribute `resize` - line 1287: self.resize( self.length + 1 )"), "__call__")([((( typeof(__left42) ) == "number") ? (__left42 + __right43) : __add_op(__left42, __right43))], __NULL_OBJECT__); + __get__(__get__(self, "resize", "missing attribute `resize` - line 1535: self.resize( self.length + 1 )"), "__call__")([(self.length + 1)], __NULL_OBJECT__); __get__(__get__(self, "__setitem__"), "__call__")([length, value], {}); -} - -__array_append.NAME = "__array_append"; -__array_append.args_signature = ["self", "value"]; -__array_append.kwargs_signature = { }; -__array_append.types_signature = { }; -__array_append.pythonscript_function = true; +};__array_append.is_wrapper = true; __array_attrs.append = __array_append; -__array_extend = function(args, kwargs) { - var __sig__, __args__; +var __array_extend = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "lst"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3438,27 +3489,21 @@ __array_extend = function(args, kwargs) { __args__ = __getargs__("__array_extend", __sig__, args, kwargs); var self = __args__['self']; var lst = __args__['lst']; - var value, __iterator__31; - __iterator__31 = __get__(__get__(lst, "__iter__", "no iterator - line 1291: for value in lst:"), "__call__")([], __NULL_OBJECT__); - var __next__31; - __next__31 = __get__(__iterator__31, "next"); - while (( __iterator__31.index ) < __iterator__31.length) { - value = __next__31(); - __get__(__get__(self, "append", "missing attribute `append` - line 1292: self.append( value )"), "__call__")([value], __NULL_OBJECT__); - } -} - -__array_extend.NAME = "__array_extend"; -__array_extend.args_signature = ["self", "lst"]; -__array_extend.kwargs_signature = { }; -__array_extend.types_signature = { }; -__array_extend.pythonscript_function = true; + var value,__iterator__54; + __iterator__54 = __get__(__get__(lst, "__iter__", "no iterator - line 1538: for value in lst:"), "__call__")([], __NULL_OBJECT__); + var __next__54; + __next__54 = __get__(__iterator__54, "next"); + while (( __iterator__54.index ) < __iterator__54.length) { + value = __next__54(); + __get__(__get__(self, "append", "missing attribute `append` - line 1539: self.append( value )"), "__call__")([value], __NULL_OBJECT__); + } +};__array_extend.is_wrapper = true; __array_attrs.extend = __array_extend; -__array_to_array = function(args, kwargs) { - var i, item, arr; - var __sig__, __args__; +var __array_to_array = function(args, kwargs) { + var i,item,arr; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3474,18 +3519,13 @@ __array_to_array = function(args, kwargs) { i += 1; } return arr; -} - -__array_to_array.NAME = "__array_to_array"; -__array_to_array.args_signature = ["self"]; -__array_to_array.kwargs_signature = { }; -__array_to_array.types_signature = { }; -__array_to_array.pythonscript_function = true; +};__array_to_array.is_wrapper = true; __array_attrs.to_array = __array_to_array; -__array_to_list = function(args, kwargs) { - var __sig__, __args__; +var __array_to_list = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3493,20 +3533,14 @@ __array_to_list = function(args, kwargs) { } __args__ = __getargs__("__array_to_list", __sig__, args, kwargs); var self = __args__['self']; - return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1304: return self.to_array()"), "__call__")(); -} - -__array_to_list.NAME = "__array_to_list"; -__array_to_list.args_signature = ["self"]; -__array_to_list.kwargs_signature = { }; -__array_to_list.types_signature = { }; -__array_to_list.pythonscript_function = true; + return __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1549: return self.to_array()"), "__call__")(); +};__array_to_list.is_wrapper = true; __array_attrs.to_list = __array_to_list; -__array_to_ascii = function(args, kwargs) { - var i, length, arr, string; - var __sig__, __args__; +var __array_to_ascii = function(args, kwargs) { + var i,length,arr,string; + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3515,9 +3549,9 @@ __array_to_ascii = function(args, kwargs) { __args__ = __getargs__("__array_to_ascii", __sig__, args, kwargs); var self = __args__['self']; string = ""; - arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1308: arr = self.to_array()"), "__call__")(); + arr = __get__(__get__(self, "to_array", "missing attribute `to_array` - line 1552: arr = self.to_array()"), "__call__")(); i = 0; - length = __get__(arr, "length", "missing attribute `length` - line 1309: i = 0; length = arr.length"); + length = __get__(arr, "length", "missing attribute `length` - line 1553: i = 0; length = arr.length"); while (( i ) < length) { var num = arr[i]; var char = String.fromCharCode(num); @@ -3525,23 +3559,18 @@ __array_to_ascii = function(args, kwargs) { i += 1; } return string; -} - -__array_to_ascii.NAME = "__array_to_ascii"; -__array_to_ascii.args_signature = ["self"]; -__array_to_ascii.kwargs_signature = { }; -__array_to_ascii.types_signature = { }; -__array_to_ascii.pythonscript_function = true; +};__array_to_ascii.is_wrapper = true; __array_attrs.to_ascii = __array_to_ascii; array = __create_class__("array", __array_parents, __array_attrs, __array_properties); -var file, __file_attrs, __file_parents; +var file,__file_attrs,__file_parents; __file_attrs = {}; __file_parents = []; __file_properties = {}; -__file___init__ = function(args, kwargs) { - var __sig__, __args__; +var __file___init__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self", "path", "flags"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3552,11 +3581,11 @@ __file___init__ = function(args, kwargs) { var path = __args__['path']; var flags = __args__['flags']; self.path = path; - if (( flags ) == "rb") { + if ((flags instanceof Array ? JSON.stringify(flags)==JSON.stringify("rb") : flags==="rb")) { self.flags = "r"; self.binary = true; } else { - if (( flags ) == "wb") { + if ((flags instanceof Array ? JSON.stringify(flags)==JSON.stringify("wb") : flags==="wb")) { self.flags = "w"; self.binary = true; } else { @@ -3565,19 +3594,13 @@ __file___init__ = function(args, kwargs) { } } self.flags = flags; -} - -__file___init__.NAME = "__file___init__"; -__file___init__.args_signature = ["self", "path", "flags"]; -__file___init__.kwargs_signature = { }; -__file___init__.types_signature = { }; -__file___init__.pythonscript_function = true; +};__file___init__.is_wrapper = true; __file_attrs.__init__ = __file___init__; -__file_read = function(args, kwargs) { - var _fs, path; - var __sig__, __args__; +var __file_read = function(args, kwargs) { + var _fs,path; + var __sig__,__args__; __sig__ = { kwargs:{"binary": false},args:["self", "binary"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3588,24 +3611,18 @@ __file_read = function(args, kwargs) { var binary = __args__['binary']; _fs = __get__(require, "__call__")(["fs"], __NULL_OBJECT__); path = self.path; - if (__test_if_true__(binary || self.binary)) { - return _fs.readFileSync(path); + if (__test_if_true__((binary || self.binary))) { + return _fs.readFileSync(path, { encoding:null }); } else { return _fs.readFileSync(path, __jsdict([["encoding", "utf8"]])); } -} - -__file_read.NAME = "__file_read"; -__file_read.args_signature = ["self", "binary"]; -__file_read.kwargs_signature = { binary:false }; -__file_read.types_signature = { binary:"False" }; -__file_read.pythonscript_function = true; +};__file_read.is_wrapper = true; __file_attrs.read = __file_read; -__file_write = function(args, kwargs) { - var _fs, path; - var __sig__, __args__; +var __file_write = function(args, kwargs) { + var path,buff,_fs; + var __sig__,__args__; __sig__ = { kwargs:{"binary": false},args:["self", "data", "binary"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3617,23 +3634,24 @@ __file_write = function(args, kwargs) { var binary = __args__['binary']; _fs = __get__(require, "__call__")(["fs"], __NULL_OBJECT__); path = self.path; - if (__test_if_true__(binary || self.binary)) { - _fs.writeFileSync(path, data); + if (__test_if_true__((binary || self.binary))) { + binary = (binary || self.binary); + if ((binary instanceof Array ? JSON.stringify(binary)==JSON.stringify("base64") : binary==="base64")) { + buff = new Buffer(data, "base64"); + _fs.writeFileSync(path, buff, __jsdict([["encoding", null]])); + } else { + _fs.writeFileSync(path, data, __jsdict([["encoding", null]])); + } } else { _fs.writeFileSync(path, data, __jsdict([["encoding", "utf8"]])); } -} - -__file_write.NAME = "__file_write"; -__file_write.args_signature = ["self", "data", "binary"]; -__file_write.kwargs_signature = { binary:false }; -__file_write.types_signature = { binary:"False" }; -__file_write.pythonscript_function = true; +};__file_write.is_wrapper = true; __file_attrs.write = __file_write; -__file_close = function(args, kwargs) { - var __sig__, __args__; +var __file_close = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{},args:["self"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3642,19 +3660,14 @@ __file_close = function(args, kwargs) { __args__ = __getargs__("__file_close", __sig__, args, kwargs); var self = __args__['self']; /*pass*/ -} - -__file_close.NAME = "__file_close"; -__file_close.args_signature = ["self"]; -__file_close.kwargs_signature = { }; -__file_close.types_signature = { }; -__file_close.pythonscript_function = true; +};__file_close.is_wrapper = true; __file_attrs.close = __file_close; file = __create_class__("file", __file_parents, __file_attrs, __file_properties); -__open__ = function(args, kwargs) { - var __sig__, __args__; +var __open__ = function(args, kwargs) { + + var __sig__,__args__; __sig__ = { kwargs:{"mode": null},args:["path", "mode"] }; - if (args instanceof Array && ( Object.prototype.toString.call(kwargs) ) == "[object Object]" && ( arguments.length ) == 2) { + if ((args instanceof Array && (Object.prototype.toString.call(kwargs) instanceof Array ? JSON.stringify(Object.prototype.toString.call(kwargs))==JSON.stringify("[object Object]") : Object.prototype.toString.call(kwargs)==="[object Object]") && (arguments.length instanceof Array ? JSON.stringify(arguments.length)==JSON.stringify(2) : arguments.length===2))) { /*pass*/ } else { args = Array.prototype.slice.call(arguments, 0, __sig__.args.length); @@ -3664,29 +3677,22 @@ __open__ = function(args, kwargs) { var path = __args__['path']; var mode = __args__['mode']; return __get__(file, "__call__")([path, mode], __NULL_OBJECT__); -} - -__open__.NAME = "__open__"; -__open__.args_signature = ["path", "mode"]; -__open__.kwargs_signature = { mode:null }; -__open__.types_signature = { mode:"None" }; -__open__.return_type = "file"; -__open__.pythonscript_function = true; +};__open__.is_wrapper = true; json = __jsdict([["loads", (function (s) {return JSON.parse(s);})], ["dumps", (function (o) {return JSON.stringify(o);})]]); -__get_other_workers_with_shared_arg = function(worker, ob) { - var a, other, args; +var __get_other_workers_with_shared_arg = function(worker, ob) { + var a,other,args; a = []; - var __iter22 = threading.workers; - if (! (__iter22 instanceof Array || typeof __iter22 == "string" || __is_typed_array(__iter22)) ) { __iter22 = __object_keys__(__iter22) } - for (var __idx22=0; __idx22 < __iter22.length; __idx22++) { - var b = __iter22[ __idx22 ]; - other = b[(("worker".__uid__) ? "worker".__uid__ : "worker")]; - args = b[(("args".__uid__) ? "args".__uid__ : "args")]; + var __iter38 = threading.workers; + if (! (__iter38 instanceof Array || typeof __iter38 == "string" || __is_typed_array(__iter38) || __is_some_array(__iter38) )) { __iter38 = __object_keys__(__iter38) } + for (var __idx38=0; __idx38 < __iter38.length; __idx38++) { + var b = __iter38[ __idx38 ]; + other = b["worker"]; + args = b["args"]; if (( other ) !== worker) { - var __iter23 = args; - if (! (__iter23 instanceof Array || typeof __iter23 == "string" || __is_typed_array(__iter23)) ) { __iter23 = __object_keys__(__iter23) } - for (var __idx23=0; __idx23 < __iter23.length; __idx23++) { - var arg = __iter23[ __idx23 ]; + var __iter39 = args; + if (! (__iter39 instanceof Array || typeof __iter39 == "string" || __is_typed_array(__iter39) || __is_some_array(__iter39) )) { __iter39 = __object_keys__(__iter39) } + for (var __idx39=0; __idx39 < __iter39.length; __idx39++) { + var arg = __iter39[ __idx39 ]; if (( arg ) === ob) { if (! (__contains__(a, other))) { a.append(other); @@ -3698,49 +3704,45 @@ __get_other_workers_with_shared_arg = function(worker, ob) { return a; } -__get_other_workers_with_shared_arg.NAME = "__get_other_workers_with_shared_arg"; -__get_other_workers_with_shared_arg.args_signature = ["worker", "ob"]; -__get_other_workers_with_shared_arg.kwargs_signature = { }; -__get_other_workers_with_shared_arg.types_signature = { }; threading = __jsdict([["workers", []], ["_blocking_callback", null]]); -__start_new_thread = function(f, args) { - var jsargs, worker; +var __start_new_thread = function(f, args) { + var jsargs,worker; worker = new Worker(f); worker.__uid__ = len(threading.workers); threading.workers.append(__jsdict([["worker", worker], ["args", args]])); - var func = function(event) { - var a, res, value; - if (( event.data.type ) == "terminate") { + var func = function(event) { + var a,res,value; + if ((event.data.type instanceof Array ? JSON.stringify(event.data.type)==JSON.stringify("terminate") : event.data.type==="terminate")) { worker.terminate(); } else { - if (( event.data.type ) == "call") { - res = __module__[((event.data.function.__uid__) ? event.data.function.__uid__ : event.data.function)].apply(null, event.data.args); - if (__test_if_true__(( res ) !== null && ( res ) !== undefined)) { + if ((event.data.type instanceof Array ? JSON.stringify(event.data.type)==JSON.stringify("call") : event.data.type==="call")) { + res = __module__[event.data.function].apply(null, event.data.args); + if (__test_if_true__((( res ) !== null && ( res ) !== undefined))) { worker.postMessage(__jsdict([["type", "return_to_blocking_callback"], ["result", res]])); } } else { - if (( event.data.type ) == "append") { - a = args[((event.data.argindex.__uid__) ? event.data.argindex.__uid__ : event.data.argindex)]; + if ((event.data.type instanceof Array ? JSON.stringify(event.data.type)==JSON.stringify("append") : event.data.type==="append")) { + a = args[event.data.argindex]; a.push(event.data.value); - var __iter24 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter24 instanceof Array || typeof __iter24 == "string" || __is_typed_array(__iter24)) ) { __iter24 = __object_keys__(__iter24) } - for (var __idx24=0; __idx24 < __iter24.length; __idx24++) { - var other = __iter24[ __idx24 ]; + var __iter40 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter40 instanceof Array || typeof __iter40 == "string" || __is_typed_array(__iter40) || __is_some_array(__iter40) )) { __iter40 = __object_keys__(__iter40) } + for (var __idx40=0; __idx40 < __iter40.length; __idx40++) { + var other = __iter40[ __idx40 ]; other.postMessage(__jsdict([["type", "append"], ["argindex", event.data.argindex], ["value", event.data.value]])); } } else { - if (( event.data.type ) == "__setitem__") { - a = args[((event.data.argindex.__uid__) ? event.data.argindex.__uid__ : event.data.argindex)]; + if ((event.data.type instanceof Array ? JSON.stringify(event.data.type)==JSON.stringify("__setitem__") : event.data.type==="__setitem__")) { + a = args[event.data.argindex]; value = event.data.value; if (__test_if_true__(a.__setitem__)) { a.__setitem__(event.data.index, value); } else { - a[((event.data.index.__uid__) ? event.data.index.__uid__ : event.data.index)] = value; + a[event.data.index] = value; } - var __iter25 = __get_other_workers_with_shared_arg(worker, a); - if (! (__iter25 instanceof Array || typeof __iter25 == "string" || __is_typed_array(__iter25)) ) { __iter25 = __object_keys__(__iter25) } - for (var __idx25=0; __idx25 < __iter25.length; __idx25++) { - var other = __iter25[ __idx25 ]; + var __iter41 = __get_other_workers_with_shared_arg(worker, a); + if (! (__iter41 instanceof Array || typeof __iter41 == "string" || __is_typed_array(__iter41) || __is_some_array(__iter41) )) { __iter41 = __object_keys__(__iter41) } + for (var __idx41=0; __idx41 < __iter41.length; __idx41++) { + var other = __iter41[ __idx41 ]; other.postMessage(__jsdict([["type", "__setitem__"], ["argindex", event.data.argindex], ["key", event.data.index], ["value", event.data.value]])); } } else { @@ -3751,18 +3753,14 @@ __start_new_thread = function(f, args) { } } - func.NAME = "func"; - func.args_signature = ["event"]; - func.kwargs_signature = { }; - func.types_signature = { }; worker.onmessage = func; jsargs = []; var i; i = 0; - var __iter26 = args; - if (! (__iter26 instanceof Array || typeof __iter26 == "string" || __is_typed_array(__iter26)) ) { __iter26 = __object_keys__(__iter26) } - for (var __idx26=0; __idx26 < __iter26.length; __idx26++) { - var arg = __iter26[ __idx26 ]; + var __iter42 = args; + if (! (__iter42 instanceof Array || typeof __iter42 == "string" || __is_typed_array(__iter42) || __is_some_array(__iter42) )) { __iter42 = __object_keys__(__iter42) } + for (var __idx42=0; __idx42 < __iter42.length; __idx42++) { + var arg = __iter42[ __idx42 ]; if (__test_if_true__(arg.jsify)) { jsargs.append(arg.jsify()); } else { @@ -3777,71 +3775,49 @@ __start_new_thread = function(f, args) { return worker; } -__start_new_thread.NAME = "__start_new_thread"; -__start_new_thread.args_signature = ["f", "args"]; -__start_new_thread.kwargs_signature = { }; -__start_new_thread.types_signature = { }; -__gen_worker_append = function(worker, ob, index) { - var append = function(item) { +var __gen_worker_append = function(worker, ob, index) { + + var append = function(item) { + worker.postMessage(__jsdict([["type", "append"], ["argindex", index], ["value", item]])); ob.push(item); } - append.NAME = "append"; - append.args_signature = ["item"]; - append.kwargs_signature = { }; - append.types_signature = { }; Object.defineProperty(ob, "append", __jsdict([["enumerable", false], ["value", append], ["writeable", true], ["configurable", true]])); } -__gen_worker_append.NAME = "__gen_worker_append"; -__gen_worker_append.args_signature = ["worker", "ob", "index"]; -__gen_worker_append.kwargs_signature = { }; -__gen_worker_append.types_signature = { }; -__webworker_wrap = function(ob, argindex) { +var __webworker_wrap = function(ob, argindex) { + if (__test_if_true__(ob instanceof Array)) { - var func = function(index, item) { + var func = function(index, item) { + postMessage(__jsdict([["type", "__setitem__"], ["index", index], ["value", item], ["argindex", argindex]])); Array.prototype.__setitem__.call(ob, index, item); } - func.NAME = "func"; - func.args_signature = ["index", "item"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(ob, "__setitem__", __jsdict([["enumerable", false], ["value", func], ["writeable", true], ["configurable", true]])); - var func = function(item) { + var func = function(item) { + postMessage(__jsdict([["type", "append"], ["value", item], ["argindex", argindex]])); Array.prototype.push.call(ob, item); } - func.NAME = "func"; - func.args_signature = ["item"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(ob, "append", __jsdict([["enumerable", false], ["value", func], ["writeable", true], ["configurable", true]])); } else { - if (( typeof(ob) ) == "object") { - var func = function(key, item) { + if ((typeof(ob) instanceof Array ? JSON.stringify(typeof(ob))==JSON.stringify("object") : typeof(ob)==="object")) { + var func = function(key, item) { + postMessage(__jsdict([["type", "__setitem__"], ["index", key], ["value", item], ["argindex", argindex]])); - ob[((key.__uid__) ? key.__uid__ : key)] = item; + ob[key] = item; } - func.NAME = "func"; - func.args_signature = ["key", "item"]; - func.kwargs_signature = { }; - func.types_signature = { }; Object.defineProperty(ob, "__setitem__", __jsdict([["enumerable", false], ["value", func], ["writeable", true], ["configurable", true]])); } } return ob; } -__webworker_wrap.NAME = "__webworker_wrap"; -__webworker_wrap.args_signature = ["ob", "argindex"]; -__webworker_wrap.kwargs_signature = { }; -__webworker_wrap.types_signature = { }; -__rpc__ = function(url, func, args) { +var __rpc__ = function(url, func, args) { var req; req = new XMLHttpRequest(); req.open("POST", url, false); @@ -3850,7 +3826,28 @@ __rpc__ = function(url, func, args) { return JSON.parse(req.responseText); } -__rpc__.NAME = "__rpc__"; -__rpc__.args_signature = ["url", "func", "args"]; -__rpc__.kwargs_signature = { }; -__rpc__.types_signature = { }; \ No newline at end of file +var __rpc_iter__ = function(url, attr) { + var req; + req = new XMLHttpRequest(); + req.open("POST", url, false); + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + req.send(JSON.stringify(__jsdict([["iter", attr]]))); + return JSON.parse(req.responseText); +} + +var __rpc_set__ = function(url, attr, value) { + var req; + req = new XMLHttpRequest(); + req.open("POST", url, false); + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + req.send(JSON.stringify(__jsdict([["set", attr], ["value", value]]))); +} + +var __rpc_get__ = function(url, attr) { + var req; + req = new XMLHttpRequest(); + req.open("POST", url, false); + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + req.send(JSON.stringify(__jsdict([["get", attr]]))); + return JSON.parse(req.responseText); +} diff --git a/pythonjs/pythonjs.py b/pythonjs/pythonjs.py index 94f41a4..159f25c 100755 --- a/pythonjs/pythonjs.py +++ b/pythonjs/pythonjs.py @@ -17,11 +17,18 @@ #import inline_function #import code_writer +import typedpython + +class SwapLambda( RuntimeError ): + def __init__(self, node): + self.node = node + RuntimeError.__init__(self) class JSGenerator(NodeVisitor): #, inline_function.Inliner): - def __init__(self, requirejs=True, insert_runtime=True, webworker=False): + def __init__(self, requirejs=True, insert_runtime=True, webworker=False, function_expressions=True): #writer = code_writer.Writer() #self.setup_inliner( writer ) + self._func_expressions = function_expressions self._indent = 0 self._global_functions = {} self._function_stack = [] @@ -29,43 +36,112 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False): self._insert_runtime = insert_runtime self._webworker = webworker self._exports = set() + self._inline_lambda = False + + self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__', 'expression']) + self._glsl = False + self._has_glsl = False + self._typed_vars = dict() + + ## the helper function below _mat4_to_vec4 is invalid because something can only be indexed + ## with a constant expression. The GLSL compiler will throw this ERROR: 0:19: '[]' : Index expression must be constant" + #self.glsl_runtime = 'vec4 _mat4_to_vec4( mat4 a, int col) { return vec4(a[col][0], a[col][1], a[col][2],a[col][3]); }' + self.glsl_runtime = 'int _imod(int a, int b) { return int(mod(float(a),float(b))); }' def indent(self): return ' ' * self._indent def push(self): self._indent += 1 def pull(self): if self._indent > 0: self._indent -= 1 + def visit_ClassDef(self, node): + raise NotImplementedError(node) + + + def visit_Global(self, node): + return '/*globals: %s */' %','.join(node.names) def visit_Assign(self, node): # XXX: I'm not sure why it is a list since, mutiple targets are inside a tuple target = node.targets[0] if isinstance(target, Tuple): - raise NotImplementedError + raise NotImplementedError('target tuple assignment should have been transformed to flat assignment by python_to_pythonjs.py') else: target = self.visit(target) value = self.visit(node.value) - code = '%s = %s;' % (target, value) - if self._requirejs and target not in self._exports and self._indent == 0 and '.' not in target: - self._exports.add( target ) - return code + ## visit_BinOp checks for `numpy.float32` and changes the operands from `a*a` to `a[id]*a[id]` + if self._glsl and value.startswith('numpy.'): + self._typed_vars[ target ] = value + return '' + else: + code = '%s = %s;' % (target, value) + if self._requirejs and target not in self._exports and self._indent == 0 and '.' not in target: + self._exports.add( target ) + return code def visit_AugAssign(self, node): - a = '%s %s= %s;' %(self.visit(node.target), self.visit(node.op), self.visit(node.value)) + ## n++ and n-- are slightly faster than n+=1 and n-=1 + target = self.visit(node.target) + op = self.visit(node.op) + value = self.visit(node.value) + if op=='+' and isinstance(node.value, ast.Num) and node.value.n == 1: + a = '%s ++;' %target + if op=='-' and isinstance(node.value, ast.Num) and node.value.n == 1: + a = '%s --;' %target + else: + a = '%s %s= %s;' %(target, op, value) return a + def visit_With(self, node): + r = [] + is_switch = False + if isinstance( node.context_expr, Name ) and node.context_expr.id == '__default__': + r.append('default:') + elif isinstance( node.context_expr, Name ) and node.context_expr.id == '__select__': + r.append('select {') + is_switch = True + elif isinstance( node.context_expr, ast.Call ): + if not isinstance(node.context_expr.func, ast.Name): + raise SyntaxError( self.visit(node.context_expr)) + + if len(node.context_expr.args): + a = self.visit(node.context_expr.args[0]) + else: + assert len(node.context_expr.keywords) + a = '%s = %s' %(node.context_expr.keywords[0].arg, self.visit(node.context_expr.keywords[0].value)) + + if node.context_expr.func.id == '__case__': + r.append('case %s:' %a) + elif node.context_expr.func.id == '__switch__': + r.append('switch (%s) {' %self.visit(node.context_expr.args[0])) + is_switch = True + else: + raise SyntaxError( 'invalid use of with') + + + for b in node.body: + a = self.visit(b) + if a: r.append(a) + + if is_switch: + r.append('}') + + return '\n'.join(r) + def visit_Module(self, node): + header = [] + lines = [] + if self._requirejs and not self._webworker: - lines = [ + header.extend([ 'define( function(){', '__module__ = {}' - ] - else: - lines = [] + ]) + if self._insert_runtime: dirname = os.path.dirname(os.path.abspath(__file__)) runtime = open( os.path.join(dirname, 'pythonjs.js') ).read() - lines.append( runtime.replace('\n', ';') ) + lines.append( runtime ) #.replace('\n', ';') ) for b in node.body: line = self.visit(b) @@ -82,14 +158,20 @@ def visit_Module(self, node): lines.append( 'return __module__') lines.append('}) //end requirejs define') - return '\n'.join(lines) + if self._has_glsl: + header.append( 'var __shader_header__ = ["%s"]'%self.glsl_runtime ) + + lines = header + lines + ## fixed by Foxboron + return '\n'.join(l if isinstance(l,str) else l.encode("utf-8") for l in lines) def visit_Expr(self, node): # XXX: this is UGLY s = self.visit(node.value) - if not s.endswith(';'): + if s.strip() and not s.endswith(';'): s += ';' - return s + if s==';': return '' + else: return s def visit_In(self, node): @@ -99,7 +181,13 @@ def visit_Tuple(self, node): return '[%s]' % ', '.join(map(self.visit, node.elts)) def visit_List(self, node): - return '[%s]' % ', '.join(map(self.visit, node.elts)) + a = [] + for elt in node.elts: + b = self.visit(elt) + if b is None: raise SyntaxError(elt) + a.append( b ) + return '[%s]' % ', '.join(a) + def visit_TryExcept(self, node): out = [] @@ -143,7 +231,12 @@ def visit_ExceptHandler(self, node): def visit_Lambda(self, node): args = [self.visit(a) for a in node.args.args] - return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) + if args and args[0]=='__INLINE_FUNCTION__': + self._inline_lambda = True + #return '' ## skip node, the next function contains the real def + raise SwapLambda( node ) + else: + return '(function (%s) {return %s;})' %(','.join(args), self.visit(node.body)) @@ -159,41 +252,369 @@ def visit_FunctionDef(self, node): self._function_stack.pop() return buffer + def _visit_call_helper_var_glsl(self, node): + lines = [] + for key in node.keywords: + ptrs = key.value.id.count('POINTER') + if ptrs: + ## TODO - preallocate array size - if nonliteral arrays are used later ## + #name = key.arg + #pid = '[`%s.length`]' %name + #ptrs = pid * ptrs + #lines.append( '%s %s' %(key.value.id.replace('POINTER',''), name+ptrs)) + + ## assume that this is a dynamic variable and will be typedef'ed by + ## __glsl_dynamic_typedef() is inserted just before the assignment. + pass + else: + self._typed_vars[ key.arg ] = key.value.id + lines.append( '%s %s' %(key.value.id, key.arg)) + + return ';'.join(lines) + + def _visit_function(self, node): + is_main = node.name == 'main' + is_annon = node.name == '' + is_pyfunc = False + return_type = None + glsl = False + glsl_wrapper_name = False + gpu_return_types = {} + gpu_vectorize = False + gpu_method = False + args_typedefs = {} + func_expr = False + + for decor in node.decorator_list: + if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'expression': + assert len(decor.args)==1 + func_expr = True + node.name = self.visit(decor.args[0]) + + elif isinstance(decor, ast.Name) and decor.id == '__pyfunction__': + is_pyfunc = True + elif isinstance(decor, ast.Name) and decor.id == '__glsl__': + glsl = True + elif isinstance(decor, ast.Attribute) and isinstance(decor.value, ast.Name) and decor.value.id == '__glsl__': + glsl_wrapper_name = decor.attr + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__': + for key in decor.keywords: + args_typedefs[ key.arg ] = key.value.id + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'returns': + if decor.keywords: + for k in decor.keywords: + key = k.arg + assert key == 'array' or key == 'vec4' + gpu_return_types[ key ] = self.visit(k.value) + + else: + return_type = decor.args[0].id + if return_type in typedpython.glsl_types: + gpu_return_types[ return_type ] = True + + elif isinstance(decor, Attribute) and isinstance(decor.value, Name) and decor.value.id == 'gpu': + if decor.attr == 'vectorize': + gpu_vectorize = True + elif decor.attr == 'main': + is_main = True + elif decor.attr == 'method': + gpu_method = True + args = self.visit(node.args) - if len(node.decorator_list): - assert len(node.decorator_list)==1 + + if glsl: + self._has_glsl = True ## triggers extras in header + lines = [] + x = [] + for i,arg in enumerate(args): + if gpu_vectorize and arg not in args_typedefs: + x.append( 'float* %s' %arg ) + else: + if arg in args_typedefs: + x.append( '%s %s' %(args_typedefs[arg].replace('POINTER', '*'), arg) ) + elif gpu_method and i==0: + x.append( '%s self' %arg ) + else: + #x.append( 'float* %s' %arg ) ## this could be a way to default to the struct. + raise SyntaxError('GLSL functions require a typedef: %s' %arg) + + if is_main: + lines.append( 'var glsljit = glsljit_runtime(__shader_header__);') ## each call to the wrapper function recompiles the shader + if x: + lines.append( 'glsljit.push("void main(%s) {");' %','.join(x) ) + else: + lines.append( 'glsljit.push("void main( ) {");') ## WebCLGL parser requires the space in `main( )` + + elif return_type: + #if gpu_method: + # lines.append( '__shader_header__.push("%s %s(struct this, %s ) {");' %(return_type, node.name, ', '.join(x)) ) + #else: + lines.append( '__shader_header__.push("%s %s( %s ) {");' %(return_type, node.name, ', '.join(x)) ) + else: + lines.append( '__shader_header__.push("void %s( %s ) {");' %(node.name, ', '.join(x)) ) + + self.push() + # `_id_` always write out an array of floats or array of vec4floats + if is_main: + #lines.append( 'glsljit.push("vec2 _id_ = get_global_id(); int _FRAGMENT_ID_ = int(_id_.x + _id_.y * 100.0);");') + pass + else: + lines.append( '__shader_header__.push("vec2 _id_ = get_global_id();");') + + self._glsl = True + for child in node.body: + if isinstance(child, Str): + continue + else: + for sub in self.visit(child).splitlines(): + if is_main: + if '`' in sub: ## "`" runtime lookups + + if '``' in sub: + raise SyntaxError('inliner syntax error: %s'%sub) + + sub = sub.replace('``', '') + chunks = sub.split('`') + if len(chunks) == 1: + raise RuntimeError(chunks) + sub = [] + for ci,chk in enumerate(chunks): + #if not chk.startswith('@'): ## special inline javascript. + # chk = '```'+chk+'```' + #chk = chk.replace('$', '```') + + if not ci%2: + if '@' in chk: + raise SyntaxError(chunks) + + if ci==0: + if chk: + sub.append('"%s"'%chk) + else: + if chk: + if sub: + sub.append(' + "%s"'%chk) + else: + sub.append('"%s"'%chk) + + elif chk.startswith('@'): ## special inline javascript. + lines.append( chk[1:] ) + else: + if sub: + sub.append(' + %s' %chk) + else: + sub.append(chk) + + if sub: + lines.append( 'glsljit.push(%s);' %''.join(sub)) + + else: + sub = sub.replace('$', '```') + lines.append( 'glsljit.push("%s");' %(self.indent()+sub) ) + + + else: ## subroutine or method + if '`' in sub: sub = sub.replace('`', '') + lines.append( '__shader_header__.push("%s");' %sub ) + + + self._glsl = False + self.pull() + if is_main: + lines.append('glsljit.push(";(1+1);");') ## fixes WebCLGL 2.0 parser + lines.append('glsljit.push("}");') + else: + lines.append('__shader_header__.push("%s}");' %self.indent()) + + lines.append(';') + + if is_main: + #insert = lines + #lines = [] + + if not glsl_wrapper_name: + glsl_wrapper_name = node.name + + if args: + lines.append('function %s( %s, __offset ) {' %(glsl_wrapper_name, ','.join(args)) ) + else: + lines.append('function %s( __offset ) {' %glsl_wrapper_name ) + + lines.append(' __offset = __offset || 1024') ## note by default: 0 allows 0-1.0 ## TODO this needs to be set per-buffer + + #lines.extend( insert ) + + lines.append(' var __webclgl = new WebCLGL()') + lines.append(' var header = glsljit.compile_header()') + lines.append(' var shader = glsljit.compile_main()') + + #lines.append(' console.log(header)') + lines.append(' console.log("-----------")') + lines.append(' console.log(shader)') + + ## create the webCLGL kernel, compiles GLSL source + lines.append(' var __kernel = __webclgl.createKernel( shader, header );') + + if gpu_return_types: + if 'array' in gpu_return_types: + if ',' in gpu_return_types['array']: + w,h = gpu_return_types['array'][1:-1].split(',') + lines.append(' var __return_length = %s * %s' %(w,h)) + else: + lines.append(' var __return_length = %s' %gpu_return_types['array']) + elif 'vec4' in gpu_return_types: + if ',' in gpu_return_types['vec4']: + w,h = gpu_return_types['vec4'][1:-1].split(',') + lines.append(' var __return_length_vec4 = %s * %s' %(w,h)) + else: + lines.append(' var __return_length_vec4 = %s' %gpu_return_types['vec4']) + + elif 'mat4' in gpu_return_types: + lines.append(' var __return_length = 64') ## minimum size is 64 + else: + raise NotImplementedError + else: + lines.append(' var __return_length = 64') ## minimum size is 64 + + for i,arg in enumerate(args): + lines.append(' if (%s instanceof Array) {' %arg) + #lines.append(' __return_length = %s.length==2 ? %s : %s.length' %(arg,arg, arg) ) + lines.append(' var %s_buffer = __webclgl.createBuffer(%s.dims || %s.length, "FLOAT", %s.scale || __offset)' %(arg,arg,arg,arg)) + lines.append(' __webclgl.enqueueWriteBuffer(%s_buffer, %s)' %(arg, arg)) + lines.append(' __kernel.setKernelArg(%s, %s_buffer)' %(i, arg)) + lines.append(' } else { __kernel.setKernelArg(%s, %s) }' %(i, arg)) + + #lines.append(' console.log("kernel.compile...")') + lines.append(' __kernel.compile()') + #lines.append(' console.log("kernel.compile OK")') + + if gpu_return_types: + if 'vec4' in gpu_return_types: + dim = gpu_return_types[ 'vec4' ] + lines.append(' var rbuffer_vec4 = __webclgl.createBuffer(%s, "FLOAT4", __offset)' %dim) + lines.append(' __webclgl.enqueueNDRangeKernel(__kernel, rbuffer_vec4)') + lines.append(' var __res = __webclgl.enqueueReadBuffer_Float4( rbuffer_vec4 )') + lines.append(' return glsljit.unpack_vec4(__res, %s)' %gpu_return_types['vec4']) + elif 'array' in gpu_return_types: + dim = gpu_return_types[ 'array' ] + lines.append(' var rbuffer_array = __webclgl.createBuffer(%s, "FLOAT", __offset)' %dim) + lines.append(' __webclgl.enqueueNDRangeKernel(__kernel, rbuffer_array)') + lines.append(' var __res = __webclgl.enqueueReadBuffer_Float( rbuffer_array )') + lines.append(' return glsljit.unpack_array2d(__res, %s)' %gpu_return_types['array']) + + elif 'mat4' in gpu_return_types: + lines.append(' var rbuffer = __webclgl.createBuffer([4,glsljit.matrices.length], "FLOAT4", __offset)') + lines.append(' __webclgl.enqueueNDRangeKernel(__kernel, rbuffer)') + lines.append(' var __res = __webclgl.enqueueReadBuffer_Float4( rbuffer )') ## slow + lines.append(' return glsljit.unpack_mat4(__res)') + else: + raise SyntaxError('invalid GPU return type: %s' %gpu_return_types) + + else: + raise SyntaxError('GPU return type must be given') + lines.append(' var __return = __webclgl.createBuffer(__return_length, "FLOAT", __offset)') + lines.append(' __webclgl.enqueueNDRangeKernel(__kernel, __return)') + lines.append(' return __webclgl.enqueueReadBuffer_Float( __return )') + + lines.append('} // end of wrapper') + lines.append('%s.return_matrices = glsljit.matrices' %glsl_wrapper_name ) + + + return '\n'.join(lines) + + elif len(node.decorator_list)==1 and not (isinstance(node.decorator_list[0], ast.Call) and node.decorator_list[0].func.id in self.special_decorators ) and not (isinstance(node.decorator_list[0], ast.Name) and node.decorator_list[0].id in self.special_decorators): dec = self.visit(node.decorator_list[0]) buffer = self.indent() + '%s.%s = function(%s) {\n' % (dec,node.name, ', '.join(args)) + elif len(self._function_stack) == 1: ## this style will not make function global to the eval context in NodeJS ## #buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) - ## this is required for eval to be able to work in NodeJS, note there is no var keyword. - buffer = self.indent() + '%s = function(%s) {\n' % (node.name, ', '.join(args)) + + ## note if there is no var keyword and this function is at the global level, + ## then it should be callable from eval in NodeJS - this is not correct. + ## infact, var should always be used with function expressions. + + if self._func_expressions or func_expr: + buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args)) + else: + buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) if self._requirejs and node.name not in self._exports: self._exports.add( node.name ) else: - buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args)) + if self._func_expressions or func_expr: + buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args)) + else: + buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args)) self.push() body = list() - for child in node.body: - if isinstance(child, Str): + next = None + for i,child in enumerate(node.body): + if isinstance(child, Str) or hasattr(child, 'SKIP'): continue - if isinstance(child, GeneratorType): ## not tested - for sub in child: - body.append( self.indent()+self.visit(sub)) + #try: + # v = self.visit(child) + #except SwapLambda as error: + # error.node.__class__ = ast.FunctionDef + # next = node.body[i+1] + # if not isinstance(next, ast.FunctionDef): + # raise SyntaxError('inline def is only allowed in javascript mode') + # error.node.__dict__ = next.__dict__ + # error.node.name = '' + # v = self.visit(child) + + v = self.try_and_catch_swap_lambda(child, node.body) + + + if v is None: + msg = 'error in function: %s'%node.name + msg += '\n%s' %child + raise SyntaxError(msg) else: - body.append( self.indent()+self.visit(child)) + body.append( self.indent()+v) buffer += '\n'.join(body) self.pull() - buffer += '\n%s}\n' %self.indent() - return buffer + buffer += '\n%s}' %self.indent() + #if self._inline_lambda: + # self._inline_lambda = False + if is_annon: + buffer = '__wrap_function__(' + buffer + ')' + elif is_pyfunc: + ## TODO change .is_wrapper to .__pyfunc__ + buffer += ';%s.is_wrapper = true;' %node.name + else: + buffer += '\n' + + return self.indent() + buffer + + def try_and_catch_swap_lambda(self, child, body): + try: + return self.visit(child) + except SwapLambda as e: + + next = None + for i in range( body.index(child), len(body) ): + n = body[ i ] + if isinstance(n, ast.FunctionDef): + if hasattr(n, 'SKIP'): + continue + else: + next = n + break + assert next + next.SKIP = True + e.node.__class__ = ast.FunctionDef + e.node.__dict__ = next.__dict__ + e.node.name = '' + return self.try_and_catch_swap_lambda( child, body ) + + def _visit_subscript_ellipsis(self, node): name = self.visit(node.value) @@ -202,7 +623,11 @@ def _visit_subscript_ellipsis(self, node): def visit_Subscript(self, node): if isinstance(node.slice, ast.Ellipsis): - return self._visit_subscript_ellipsis( node ) + if self._glsl: + #return '%s[_id_]' % self.visit(node.value) + return '%s[matrix_index()]' % self.visit(node.value) + else: + return self._visit_subscript_ellipsis( node ) else: return '%s[%s]' % (self.visit(node.value), self.visit(node.slice)) @@ -210,10 +635,7 @@ def visit_Index(self, node): return self.visit(node.value) def visit_Slice(self, node): - #print(node.lower) - #print(node.upper) - #print(node.step) - raise SyntaxError(node) ## slicing not allowed here at js level + raise SyntaxError('list slice') ## slicing not allowed here at js level def visit_arguments(self, node): out = [] @@ -235,6 +657,11 @@ def visit_Name(self, node): def visit_Attribute(self, node): name = self.visit(node.value) attr = node.attr + if self._glsl and name not in ('self', 'this'): + if name not in self._typed_vars: + return '`%s.%s`' % (name, attr) + else: + return '%s.%s' % (name, attr) return '%s.%s' % (name, attr) def visit_Print(self, node): @@ -261,9 +688,97 @@ def _visit_call_helper_new(self, node): else: raise SyntaxError( args ) + def _visit_call_helper_go( self, node ): + raise NotImplementedError('go call') + + def visit_Call(self, node): name = self.visit(node.func) - if name == 'instanceof': ## this gets used by "with javascript:" blocks to test if an instance is a JavaScript type + if name in typedpython.GO_SPECIAL_CALLS.values(): + return self._visit_call_helper_go( node ) + + elif self._glsl and isinstance(node.func, ast.Attribute): + if isinstance(node.func.value, ast.Name) and node.func.value.id in self._typed_vars: + args = ','.join( [self.visit(a) for a in node.args] ) + return '`__struct_name__`_%s(%s, %s)' %(node.func.attr, node.func.value.id, args) + else: + return '`%s`' %self._visit_call_helper(node) + + elif self._glsl and name == 'len': + if isinstance(node.args[0], ast.Name): + return '`%s.length`' %node.args[0].id + elif isinstance(node.args[0], ast.Subscript): + s = node.args[0] + v = self.visit(s).replace('`', '') + return '`%s.length`' %v + + elif isinstance(node.args[0], ast.Attribute): ## assume struct array attribute + s = node.args[0] + v = self.visit(s).replace('`', '') + return '`%s.length`' %v + + elif name == 'glsl_inline_assign_from_iterable': + ## the target must be declared without a typedef, because if declared first, it can not be redeclared, + ## in the if-assignment block, the typedef is not given because `Iter_n` already has been typed beforehand. + sname = node.args[0].s + target = node.args[1].s + iter = node.args[2].id + self._typed_vars[ target ] = sname + + + lines = [ + '`@var __length__ = %s.length;`' %iter, + #'`@console.log("DEBUG iter: "+%s);`' %iter, + #'`@console.log("DEBUG first item: "+%s[0]);`' %iter, + #'`@var __struct_name__ = %s[0].__struct_name__;`' %iter, + ##same as above - slower ##'`@var __struct_name__ = glsljit.define_structure(%s[0]);`' %iter, + #'`@console.log("DEBUG sname: "+__struct_name__);`', + '`@var %s = %s[0];`' %(target, iter) ## capture first item with target name so that for loops can get the length of member arrays + ] + + #lines.append('for (int _iter=0; _iter < `__length__`; _iter++) {' ) + + ## declare struct variable ## + #lines.append( '%s %s;' %(sname, target)) + + ## at runtime loop over subarray, for each index inline into the shader's for-loop an if test, + lines.append( '`@for (var __j=0; __j<__length__; __j++) {`') + #lines.append( '`@glsljit.push("if (OUTPUT_INDEX==" +__j+ ") { %s %s=%s_" +__j+ ";}");`' %(sname, target, iter)) + lines.append( '`@glsljit.push("if (matrix_index()==" +__j+ ") { %s=%s_" +__j+ ";}");`' %(target, iter)) + lines.append( '`@}`') + + + #lines.append( '}' ) ## end of for loop + return '\n'.join(lines) + + elif name == 'glsl_inline_push_js_assign': + # '@' triggers a new line of generated code + n = node.args[0].s + if isinstance(node.args[1], ast.Attribute): ## special case bypass visit_Attribute + v = '%s.%s' %(node.args[1].value.id, node.args[1].attr ) + else: + v = self.visit(node.args[1]) + + v = v.replace('`', '') ## this is known this entire expression is an external call. + + ## check if number is required because literal floats like `1.0` will get transformed to `1` by javascript toString + orelse = 'typeof(%s)=="object" ? glsljit.object(%s, "%s") : glsljit.push("%s="+%s+";")' %(n, n,n, n,n) + + ## if a constant number literal directly inline + if v.isdigit() or (v.count('.')==1 and v.split('.')[0].isdigit() and v.split('.')[1].isdigit()): + #if_number = ' if (typeof(%s)=="number") { glsljit.push("%s=%s;") } else {' %(n, n,v) + #return '`@%s=%s; %s if (%s instanceof Array) {glsljit.array(%s, "%s")} else {%s}};`' %(n,v, if_number, n, n,n, orelse) + return '`@%s=%s; glsljit.push("%s=%s;");`' %(n,v, n,v) + else: + return '`@%s=%s; if (%s instanceof Array) {glsljit.array(%s, "%s")} else { if (%s instanceof Int16Array) {glsljit.int16array(%s,"%s")} else {%s} };`' %(n,v, n, n,n, n,n,n, orelse) + + #elif name == 'glsl_inline': + # return '`%s`' %self.visit(node.args[0]) + #elif name == 'glsl_inline_array': + # raise NotImplementedError + # return '`__glsl_inline_array(%s, "%s")`' %(self.visit(node.args[0]), node.args[1].s) + + elif name == 'instanceof': ## this gets used by "with javascript:" blocks to test if an instance is a JavaScript type return self._visit_call_helper_instanceof( node ) elif name == 'new': @@ -278,11 +793,17 @@ def visit_Call(self, node): else: raise SyntaxError( args ) + elif name == 'numpy.array': + return self._visit_call_helper_numpy_array(node) + elif name == 'JSObject': return self._visit_call_helper_JSObject( node ) elif name == 'var': - return self._visit_call_helper_var( node ) + if self._glsl: + return self._visit_call_helper_var_glsl( node ) + else: + return self._visit_call_helper_var( node ) elif name == 'JSArray': return self._visit_call_helper_JSArray( node ) @@ -308,6 +829,8 @@ def visit_Call(self, node): # return_id = self.inline_function( node ) # code = self.writer.getvalue() # return '\n'.join([code, return_id]) + elif name.split('.')[-1] == '__go__receive__': + raise SyntaxError('__go__receive__') else: return self._visit_call_helper(node) @@ -318,7 +841,9 @@ def _visit_call_helper(self, node): args = ', '.join([e for e in args if e]) else: args = '' - return '%s(%s)' % (self.visit(node.func), args) + fname = self.visit(node.func) + if fname=='__DOLLAR__': fname = '$' + return '%s(%s)' % (fname, args) def inline_helper_remap_names(self, remap): return "var %s;" %','.join(remap.values()) @@ -326,6 +851,11 @@ def inline_helper_remap_names(self, remap): def inline_helper_return_id(self, return_id): return "var __returns__%s = null;"%return_id + def _visit_call_helper_numpy_array(self, node): + if self._glsl: + return self.visit(node.keywords[0].value) + else: + return self.visit(node.args[0]) def _visit_call_helper_list(self, node): name = self.visit(node.func) @@ -378,18 +908,20 @@ def _visit_call_helper_var(self, node): fnode._local_vars.add( arg ) for arg in rem: args.remove( arg ) - + out = [] if args: - out = ', '.join(args) - return 'var %s' % out - else: - return '' - + out.append( 'var ' + ','.join(args) ) + if node.keywords: + out.append( 'var ' + ','.join([key.arg for key in node.keywords]) ) + return ';'.join(out) def _inline_code_helper(self, s): + ## TODO, should newline be changed here? s = s.replace('\n', '\\n').replace('\0', '\\0') ## AttributeError: 'BinOp' object has no attribute 's' - this is caused by bad quotes if s.strip().startswith('#'): s = '/*%s*/'%s - if '"' in s or "'" in s: ## can not trust direct-replace hacks + if '__new__>>' in s: ## fixes inline `JS("new XXX")` + s = s.replace('__new__>>', ' new ') + elif '"' in s or "'" in s: ## can not trust direct-replace hacks pass else: if ' or ' in s: @@ -419,6 +951,37 @@ def visit_BinOp(self, node): left = self.visit(node.left) op = self.visit(node.op) right = self.visit(node.right) + + if op == '>>' and left == '__new__': + return ' new %s' %right + + elif op == '<<': + if left in ('__go__receive__', '__go__send__'): + return '<- %s' %right + elif isinstance(node.left, ast.Call) and isinstance(node.left.func, ast.Name) and node.left.func.id in ('__go__array__', '__go__arrayfixed__', '__go__map__'): + if node.left.func.id == '__go__map__': + key_type = self.visit(node.left.args[0]) + value_type = self.visit(node.left.args[1]) + if value_type == 'interface': value_type = 'interface{}' + return 'map[%s]%s%s' %(key_type, value_type, right) + else: + if not right.startswith('{') and not right.endswith('}'): + right = '{%s}' %right[1:-1] + + if node.left.func.id == '__go__array__': + return '[]%s%s' %(self.visit(node.left.args[0]), right) + elif node.left.func.id == '__go__arrayfixed__': + asize = self.visit(node.left.args[0]) + atype = self.visit(node.left.args[1]) + return '[%s]%s%s' %(asize, atype, right) + elif isinstance(node.left, ast.Name) and node.left.id=='__go__array__' and op == '<<': + return '[]%s' %self.visit(node.right) + + if left in self._typed_vars and self._typed_vars[left] == 'numpy.float32': + left += '[_id_]' + if right in self._typed_vars and self._typed_vars[right] == 'numpy.float32': + right += '[_id_]' + return '(%s %s %s)' % (left, op, right) def visit_Mult(self, node): @@ -482,19 +1045,34 @@ def visit_Is(self, node): return '===' def visit_Compare(self, node): - comp = [ '('] - comp.append( self.visit(node.left) ) - comp.append( ')' ) + if self._glsl: + comp = [self.visit(node.left)] + elif isinstance(node.ops[0], ast.Eq): + left = self.visit(node.left) + right = self.visit(node.comparators[0]) + return '(%s instanceof Array ? JSON.stringify(%s)==JSON.stringify(%s) : %s===%s)' %(left, left, right, left, right) + elif isinstance(node.ops[0], ast.NotEq): + left = self.visit(node.left) + right = self.visit(node.comparators[0]) + return '(!(%s instanceof Array ? JSON.stringify(%s)==JSON.stringify(%s) : %s===%s))' %(left, left, right, left, right) - for i in range( len(node.ops) ): - comp.append( self.visit(node.ops[i]) ) + else: + comp = [ '('] + comp.append( self.visit(node.left) ) + comp.append( ')' ) - if isinstance(node.comparators[i], ast.BinOp): - comp.append('(') - comp.append( self.visit(node.comparators[i]) ) - comp.append(')') - else: - comp.append( self.visit(node.comparators[i]) ) + for i in range( len(node.ops) ): + comp.append( self.visit(node.ops[i]) ) + + if isinstance(node.ops[i], ast.Eq): + raise SyntaxError('TODO') + + elif isinstance(node.comparators[i], ast.BinOp): + comp.append('(') + comp.append( self.visit(node.comparators[i]) ) + comp.append(')') + else: + comp.append( self.visit(node.comparators[i]) ) return ' '.join( comp ) @@ -519,7 +1097,7 @@ def visit_Or(self, node): def visit_BoolOp(self, node): op = self.visit(node.op) - return op.join( [self.visit(v) for v in node.values] ) + return '('+ op.join( [self.visit(v) for v in node.values] ) +')' def visit_If(self, node): out = [] @@ -559,7 +1137,7 @@ def _visit_for_prep_iter_helper(self, node, out, iter_name): #out.append( self.indent() + 'if (! (iter instanceof Array) ) { iter = Object.keys(iter) }' ) ## new style - Object.keys only works for normal JS-objects, not ones created with `Object.create(null)` out.append( - self.indent() + 'if (! (%s instanceof Array || typeof %s == "string" || __is_typed_array(%s)) ) { %s = __object_keys__(%s) }' %(iter_name, iter_name, iter_name, iter_name, iter_name) + self.indent() + 'if (! (%s instanceof Array || typeof %s == "string" || __is_typed_array(%s) || __is_some_array(%s) )) { %s = __object_keys__(%s) }' %(iter_name, iter_name, iter_name, iter_name, iter_name, iter_name) ) @@ -578,6 +1156,69 @@ def visit_For(self, node): above works because [...] returns the internal Array of mylist ''' + if self._glsl: + target = self.visit(node.target) + + if isinstance(node.iter, ast.Call) and isinstance(node.iter.func, ast.Name) and node.iter.func.id=='iter': ## `for i in iter(n):` + assert isinstance(node.iter.args[0], ast.Name) + iter = node.iter.args[0].id + self._typed_vars[target] = 'struct*' ## this fixes attributes on structs + + lines = [ + '`@var __length__ = %s.length;`' %iter, + #'`@console.log("DEBUG iter: "+%s);`' %iter, + #'`@console.log("DEBUG first item: "+%s[0]);`' %iter, + '`@var __struct_name__ = %s[0].__struct_name__;`' %iter, + ##same as above - slower ##'`@var __struct_name__ = glsljit.define_structure(%s[0]);`' %iter, + #'`@console.log("DEBUG sname: "+__struct_name__);`', + '`@var %s = %s[0];`' %(target, iter) ## capture first item with target name so that for loops can get the length of member arrays + ] + + ##TODO## lines.append('$') ## optimizes webclgl parser + + lines.append('for (int _iter=0; _iter < `__length__`; _iter++) {' ) + + ## declare struct variable ## + lines.append( '`__struct_name__` %s;' %target) + + ## at runtime loop over subarray, for each index inline into the shader's for-loop an if test, + lines.append( '`@for (var __j=0; __j<__length__; __j++) {`') + lines.append( '`@glsljit.push("if (_iter==" +__j+ ") { %s=%s_" +__j+ ";}");`' %(target, iter)) + lines.append( '`@}`') + + ##TODO## lines.append('$') ## optimizes webclgl parser + + + elif isinstance(node.iter, ast.Call): ## `for i in range(n):` + iter = self.visit(node.iter.args[0]) + lines = ['for (int %s=0; %s < %s; %s++) {' %(target, target, iter, target)] + elif isinstance(node.iter, ast.Name): ## `for subarray in arrayofarrays:` + ## capture the length of the subarray into the current javascript scope + ## this is required to inline the lengths as constants into the GLSL for loops + lines = ['`@var __length__ = %s[0].length;`' %node.iter.id] + ## start the GLSL for loop - `__length__` is set above ## + lines.append('for (int _iter=0; _iter < `__length__`; _iter++) {' ) + + ## declare subarray with size ## + lines.append( 'float %s[`__length__`];' %target) + + ## at runtime loop over subarray, for each index inline into the shader's for-loop an if test, + lines.append( '`@for (var __j=0; __j<__length__; __j++) {`') + ## below checks if the top-level iterator is the same index, and if so copy its contents into the local subarray, + lines.append( '`@glsljit.push("if (_iter==" +__j+ ") { for (int _J=0; _J<" +__length__+ "; _J++) {%s[_J] = %s_" +__j+ "[_J];} }");`' %(target, node.iter.id)) + lines.append( '`@}`') + ## this works because the function glsljit.array will unpack an array of arrays using the variable name with postfix "_n" + ## note the extra for loop `_J` is required because the local subarray can not be assigned to `A_n` + + else: + raise SyntaxError(node.iter) + + for b in node.body: + lines.append( self.visit(b) ) + lines.append( '}' ) ## end of for loop + return '\n'.join(lines) + + self._iter_id += 1 iname = '__iter%s' %self._iter_id index = '__idx%s' %self._iter_id @@ -623,14 +1264,84 @@ def visit_Break(self, node): def generate_runtime(): from python_to_pythonjs import main as py2pyjs lines = [ - main( open('runtime/pythonpythonjs.py', 'rb').read(), requirejs=False, insert_runtime=False ), ## lowlevel pythonjs - main( py2pyjs(open('runtime/builtins.py', 'rb').read()), requirejs=False, insert_runtime=False ) + main( open('runtime/pythonpythonjs.py', 'rb').read(), requirejs=False, insert_runtime=False, function_expressions=True ), ## lowlevel pythonjs + main( py2pyjs(open('runtime/builtins.py', 'rb').read()), requirejs=False, insert_runtime=False, function_expressions=True ) ] return '\n'.join( lines ) -def main(script, requirejs=True, insert_runtime=True, webworker=False): - tree = ast.parse( script ) - return JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker ).visit(tree) +def main(source, requirejs=True, insert_runtime=True, webworker=False, function_expressions=True): + head = [] + tail = [] + script = False + osource = source + if source.strip().startswith('') + script = list() + elif line.strip() == '': + if type(script) is list: + source = '\n'.join(script) + script = True + tail.append( '') + elif script is True: + tail.append( '') + else: + head.append( '') + + elif isinstance( script, list ): + script.append( line ) + + elif script is True: + tail.append( line ) + + else: + head.append( line ) + + + try: + tree = ast.parse( source ) + #raise SyntaxError(source) + except SyntaxError: + import traceback + err = traceback.format_exc() + sys.stderr.write( err ) + sys.stderr.write( '\n--------------error in second stage translation--------------\n' ) + + lineno = 0 + for line in err.splitlines(): + if "" in line: + lineno = int(line.split()[-1]) + + + lines = source.splitlines() + if lineno > 10: + for i in range(lineno-5, lineno+5): + sys.stderr.write( 'line %s->'%i ) + sys.stderr.write( lines[i] ) + if i==lineno-1: + sys.stderr.write(' <>') + sys.stderr.write( '\n' ) + + else: + sys.stderr.write( lines[lineno] ) + sys.stderr.write( '\n' ) + + if '--debug' in sys.argv: + sys.stderr.write( osource ) + sys.stderr.write( '\n' ) + + sys.exit(1) + + gen = JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ) + output = gen.visit(tree) + if head: + head.append( output ) + head.extend( tail ) + output = '\n'.join( head ) + + return output def command(): diff --git a/pythonjs/pythonjs_to_dart.py b/pythonjs/pythonjs_to_dart.py index 9f7443b..2082b1e 100644 --- a/pythonjs/pythonjs_to_dart.py +++ b/pythonjs/pythonjs_to_dart.py @@ -355,11 +355,15 @@ def visit_Assign(self, node): def _visit_function(self, node): getter = False setter = False + args_typedefs = {} for decor in node.decorator_list: if isinstance(decor, ast.Name) and decor.id == 'property': getter = True elif isinstance(decor, ast.Attribute) and isinstance(decor.value, ast.Name) and decor.attr == 'setter': setter = True + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__': + for key in decor.keywords: + args_typedefs[ key.arg ] = key.value.id else: raise SyntaxError @@ -370,6 +374,8 @@ def _visit_function(self, node): varargs_name = None for i, arg in enumerate(node.args.args): a = arg.id + if a in args_typedefs: + a = '%s %s' %(args_typedefs[a], a) dindex = i - offset if a.startswith('__variable_args__'): varargs_name = a.split('__')[-1] @@ -431,15 +437,43 @@ def _visit_call_helper(self, node): else: args = '' + if isinstance(node.func, ast.Name) and node.func.id == 'range' and len(node.args)==2: + func = '__range2' + else: + func = self.visit(node.func) + if node.keywords: kwargs = ','.join( ['%s:%s'%(x.arg, self.visit(x.value)) for x in node.keywords] ) if args: - return '%s(%s, %s)' %( self.visit(node.func), ','.join(args), kwargs ) + return '%s(%s, %s)' %( func, ','.join(args), kwargs ) else: - return '%s( %s )' %( self.visit(node.func), kwargs ) + return '%s( %s )' %( func, kwargs ) else: - return '%s(%s)' % (self.visit(node.func), args) + return '%s(%s)' % (func, args) + + def _visit_call_helper_var(self, node): + args = [ self.visit(a) for a in node.args ] + if self._function_stack: + fnode = self._function_stack[-1] + rem = [] + for arg in args: + if arg in fnode._local_vars: + rem.append( arg ) + else: + fnode._local_vars.add( arg ) + for arg in rem: + args.remove( arg ) + + out = [] + + if args: + out.append( 'var ' + ','.join(args) ) + if node.keywords: + for key in node.keywords: + out.append( '%s %s' %(key.value.id, key.arg) ) + + return ';'.join(out) def _visit_call_helper_list(self, node): name = self.visit(node.func) @@ -451,6 +485,33 @@ def _visit_call_helper_list(self, node): return '%s(%s)' % (name, args) + def _visit_call_helper_numpy_array(self, node): + simd = { + 'float32': 'Float32x4' + } + arg_name = args = None + direct = False + if isinstance(node.args[0], ast.Name): + arg_name = node.args[0].id + else: + args = ','.join( [self.visit(a) for a in node.args[0].elts] ) + if len(node.args[0].elts) == 4: ## simple rule: if there are 4 items, its a direct SIMD type + direct = True + + if node.keywords: + for key in node.keywords: + if key.arg == 'dtype': + if isinstance(key.value, ast.Attribute) and key.value.attr in simd: + if arg_name: + return 'new float32vec( %s )' %arg_name + elif direct: + return 'new %s(%s)' %(simd[key.value.attr] ,args) + else: + return 'new float32vec( [%s] )' %args + else: + raise NotImplementedError('numpy.array requires dtype is given') + + def _visit_call_helper_instanceof(self, node): args = map(self.visit, node.args) if len(args) == 2: diff --git a/pythonjs/pythonjs_to_go.py b/pythonjs/pythonjs_to_go.py new file mode 100644 index 0000000..c0ff87c --- /dev/null +++ b/pythonjs/pythonjs_to_go.py @@ -0,0 +1,570 @@ +#!/usr/bin/env python +# PythonJS to Go Translator +# by Brett Hartshorn - copyright 2014 +# License: "New BSD" +import os, sys +import ast +import pythonjs + + + +class GoGenerator( pythonjs.JSGenerator ): + + def __init__(self, requirejs=False, insert_runtime=False): + pythonjs.JSGenerator.__init__(self, requirejs=False, insert_runtime=False) + + self._class_stack = list() + self._classes = dict() + self._class_props = dict() + + self._vars = set() + self._known_vars = set() + self._kwargs_type_ = dict() + + self._imports = [] + + def visit_ClassDef(self, node): + self._class_stack.append( node ) + node._parents = set() + node._struct_def = dict() + out = [] + sdef = dict() + props = set() + bases = set() + base_classes = set() + + self._classes[ node.name ] = node + self._class_props[ node.name ] = props + + + for base in node.bases: + n = self.visit(base) + if n == 'object': + continue + node._parents.add( n ) + + bases.add( n ) + if n in self._class_props: + props.update( self._class_props[n] ) + base_classes.add( self._classes[n] ) + #else: ## special case - subclassing a builtin like `list` + # continue + + for p in self._classes[ n ]._parents: + bases.add( p ) + props.update( self._class_props[p] ) + base_classes.add( self._classes[p] ) + + + for decor in node.decorator_list: ## class decorators + if isinstance(decor, ast.Call): + assert decor.func.id=='__struct__' + #props.update( [self.visit(a) for a in decor.args] ) + for kw in decor.keywords: + props.add( kw.arg ) + sdef[ kw.arg ] = kw.value.id + + node._struct_def.update( sdef ) + out.append( 'type %s struct {' %node.name) + if base_classes: + for bnode in base_classes: + ## Go only needs the name of the parent struct and all its items are inserted automatically ## + out.append('%s' %bnode.name) + + for name in sdef: + out.append('%s %s' %(name, sdef[name])) + out.append('}') + + + init = None + method_names = set() + for b in node.body: + assert isinstance(b, ast.FunctionDef) + method_names.add( b.name ) + out.append( self.visit(b) ) + if b.name == '__init__': + init = b + + + parent_init = None + if base_classes: + for bnode in base_classes: + for b in bnode.body: + if isinstance(b, ast.FunctionDef): + if b.name in method_names: + continue + if b.name == '__init__': + parent_init = {'class':bnode, 'init':b} + #continue + out.append( self.visit(b) ) + + if init or parent_init: + if parent_init: + classname = parent_init['class'].name + init = parent_init['init'] + else: + classname = node.name + + out.append( 'func __new__%s( %s ) *%s {' %(node.name, init._args_signature, node.name)) + out.append( ' ob := %s{}' %node.name ) + out.append( ' ob.__init__(%s)' %','.join(init._arg_names)) + out.append( ' return &ob') + out.append('}') + + else: + out.append( 'func __new__%s() *%s { return &%s{} }' %(node.name, node.name, node.name)) + + + self._class_stack.pop() + return '\n'.join(out) + + + def visit_Slice(self, node): + lower = upper = step = None + if node.lower: + lower = self.visit(node.lower) + if node.upper: + upper = self.visit(node.upper) + if node.step: + step = self.visit(node.step) + + if lower and upper: + return '%s:%s' %(lower,upper) + elif upper: + return ':%s' %upper + elif lower: + return '%s:'%lower + else: + raise SyntaxError('TODO slice') + + + def visit_Print(self, node): + r = [] + for e in node.values: + s = self.visit(e) + if isinstance(e, ast.List): + r.append('fmt.Println(%s);' %s[1:-1]) + else: + r.append('fmt.Println(%s);' %s) + return ''.join(r) + + def visit_Expr(self, node): + return self.visit(node.value) + + def visit_Import(self, node): + r = [alias.name.replace('__SLASH__', '/') for alias in node.names] + if r: + for name in r: + self._imports.append('import("%s");' %name) + return '' + + def visit_Module(self, node): + header = [ + 'package main', + 'import "fmt"' + ] + lines = [] + + for b in node.body: + line = self.visit(b) + + if line: + for sub in line.splitlines(): + if sub==';': + raise SyntaxError(line) + else: + lines.append( sub ) + else: + if isinstance(b, ast.Import): + pass + else: + raise SyntaxError(b) + + lines.append('type _kwargs_type_ struct {') + for name in self._kwargs_type_: + type = self._kwargs_type_[name] + lines.append( ' %s %s' %(name,type)) + lines.append( ' __use__%s bool' %name) + lines.append('}') + + lines = header + self._imports + lines + return '\n'.join( lines ) + + + def visit_Compare(self, node): + comp = [ '('] + comp.append( self.visit(node.left) ) + comp.append( ')' ) + + for i in range( len(node.ops) ): + comp.append( self.visit(node.ops[i]) ) + + if isinstance(node.comparators[i], ast.BinOp): + comp.append('(') + comp.append( self.visit(node.comparators[i]) ) + comp.append(')') + else: + comp.append( self.visit(node.comparators[i]) ) + + return ' '.join( comp ) + + def visit_For(self, node): + target = self.visit(node.target) + lines = [] + if isinstance(node.iter, ast.Call) and isinstance(node.iter.func, ast.Name): + + if node.iter.func.id == 'range': + if len(node.iter.args)==1: + iter = self.visit(node.iter.args[0]) + lines.append('for %s := 0; %s < %s; %s++ {' %(target, target, iter, target)) + elif len(node.iter.args)==2: + start = self.visit(node.iter.args[0]) + iter = self.visit(node.iter.args[1]) + lines.append('for %s := %s; %s < %s; %s++ {' %(target, start, target, iter, target)) + else: + raise SyntaxError('invalid for range loop') + + elif node.iter.func.id == 'enumerate': + iter = self.visit(node.iter.args[0]) + idx = self.visit(node.target.elts[0]) + tar = self.visit(node.target.elts[1]) + lines.append('for %s,%s := range %s {' %(idx,tar, iter)) + + else: + raise SyntaxError('invalid for loop - bad iterator') + + elif isinstance(node.target, ast.List) or isinstance(node.target, ast.Tuple): + iter = self.visit( node.iter ) + key = self.visit(node.target.elts[0]) + val = self.visit(node.target.elts[1]) + lines.append('for %s,%s := range %s {' %(key,val, iter)) + + else: + iter = self.visit( node.iter ) + lines.append('for _,%s := range %s {' %(target, iter)) + + self.push() + for b in node.body: + lines.append( self.indent()+self.visit(b) ) + self.pull() + lines.append( self.indent()+'}' ) ## end of for loop + return '\n'.join(lines) + + + def _visit_call_helper(self, node): + fname = self.visit(node.func) + if fname=='__DOLLAR__': fname = '$' + elif fname == 'range': + assert len(node.args) + fname += str(len(node.args)) + + + if node.args: + args = [self.visit(e) for e in node.args] + args = ', '.join([e for e in args if e]) + else: + args = '' + + if node.keywords: + if args: args += ',' + args += '_kwargs_type_{' + x = ['%s:%s' %(kw.arg,self.visit(kw.value)) for kw in node.keywords] + x.extend( ['__use__%s:true' %kw.arg for kw in node.keywords] ) + args += ','.join( x ) + args += '}' + + if node.starargs: + if args: args += ',' + args += '%s...' %self.visit(node.starargs) + + return '%s(%s)' % (fname, args) + + def _visit_call_helper_go(self, node): + name = self.visit(node.func) + if name == '__go__': + return 'go %s' %self.visit(node.args[0]) + elif name == '__go_make__': + if len(node.args)==2: + return 'make(%s, %s)' %(self.visit(node.args[0]), self.visit(node.args[1])) + elif len(node.args)==3: + return 'make(%s, %s, %s)' %(self.visit(node.args[0]), self.visit(node.args[1]), self.visit(node.args[1])) + else: + raise SyntaxError('go make requires 2 or 3 arguments') + elif name == '__go_make_chan__': + return 'make(chan %s)' %self.visit(node.args[0]) + elif name == '__go__array__': + if isinstance(node.args[0], ast.BinOp):# and node.args[0].op == '<<': ## todo assert right is `typedef` + a = self.visit(node.args[0].left) + return '[]%s' %a + else: + a = self.visit(node.args[0]) + return '[]%s{}' %a + else: + raise SyntaxError(name) + + def visit_Return(self, node): + if isinstance(node.value, ast.Tuple): + return 'return %s' % ', '.join(map(self.visit, node.value.elts)) + if node.value: + return 'return %s' % self.visit(node.value) + return 'return' + + def _visit_function(self, node): + if self._function_stack[0] is node: + self._vars = set() + self._known_vars = set() + + args_typedefs = {} + chan_args_typedefs = {} + return_type = None + for decor in node.decorator_list: + if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__': + for key in decor.keywords: + #args_typedefs[ key.arg ] = key.value.id + args_typedefs[ key.arg ] = self.visit(key.value) + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef_chan__': + for key in decor.keywords: + chan_args_typedefs[ key.arg ] = self.visit(key.value) + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'returns': + if decor.keywords: + raise SyntaxError('invalid go return type') + else: + return_type = decor.args[0].id + + + node._arg_names = [] + args = [] + oargs = [] + offset = len(node.args.args) - len(node.args.defaults) + varargs = False + varargs_name = None + is_method = False + for i, arg in enumerate(node.args.args): + arg_name = arg.id + + if arg_name not in args_typedefs.keys()+chan_args_typedefs.keys(): + if arg_name=='self': + assert i==0 + is_method = True + continue + else: + err = 'error in function: %s' %node.name + err += '\n missing typedef: %s' %arg.id + raise SyntaxError(err) + + if arg_name in args_typedefs: + arg_type = args_typedefs[arg_name] + a = '%s %s' %(arg_name, arg_type) + else: + arg_type = chan_args_typedefs[arg_name] + a = '%s chan %s' %(arg_name, arg_type) + + dindex = i - offset + + if a.startswith('__variable_args__'): ## TODO support go `...` varargs + #varargs_name = a.split('__')[-1] + #varargs = ['_vararg_%s'%n for n in range(16) ] + #args.append( '[%s]'%','.join(varargs) ) + raise SyntaxError('TODO *args') + + elif dindex >= 0 and node.args.defaults: + default_value = self.visit( node.args.defaults[dindex] ) + self._kwargs_type_[ arg_name ] = arg_type + oargs.append( (arg_name, default_value) ) + else: + args.append( a ) + node._arg_names.append( arg_name ) + + if oargs: + #args.append( '[%s]' % ','.join(oargs) ) + #args.append( '{%s}' % ','.join(oargs) ) + args.append( '__kwargs _kwargs_type_') + node._arg_names.append( '__kwargs' ) + + if node.args.vararg: + starargs = node.args.vararg + assert starargs in args_typedefs + args.append( '%s ...%s' %(starargs, args_typedefs[starargs])) + node._arg_names.append( starargs ) + + node._args_signature = ','.join(args) + + #### + if is_method: + assert self._class_stack + method = '(self *%s) ' %self._class_stack[-1].name + else: + method = '' + out = [] + if return_type: + out.append( self.indent() + 'func %s%s(%s) %s {\n' % (method, node.name, ', '.join(args), return_type) ) + else: + out.append( self.indent() + 'func %s%s(%s) {\n' % (method, node.name, ', '.join(args)) ) + self.push() + + if oargs: + for n,v in oargs: + out.append('%s := %s' %(n,v)) + out.append('if __kwargs.__use__%s {' %n ) + out.append( ' %s = __kwargs.%s' %(n,n)) + out.append('}') + #out.append('} else { %s := %s }' %(n,v)) + + for b in node.body: + v = self.visit(b) + if v: + out.append( self.indent() + v ) + + self.pull() + out.append( self.indent()+'}' ) + return '\n'.join(out) + + def _visit_call_helper_var(self, node): + args = [ self.visit(a) for a in node.args ] + #if args: + # out.append( 'var ' + ','.join(args) ) + if node.keywords: + for key in node.keywords: + args.append( key.arg ) + + for name in args: + if name not in self._vars: + self._vars.add( name ) + + #out = [] + #for v in args: + # out.append( self.indent() + 'var ' + v + ' int') + + #return '\n'.join(out) + return '' + + def visit_With(self, node): + r = [] + is_switch = False + if isinstance( node.context_expr, ast.Name ) and node.context_expr.id == '__default__': + r.append('default:') + elif isinstance( node.context_expr, ast.Name ) and node.context_expr.id == '__select__': + r.append('select {') + is_switch = True + elif isinstance( node.context_expr, ast.Call ): + if not isinstance(node.context_expr.func, ast.Name): + raise SyntaxError( self.visit(node.context_expr)) + + if len(node.context_expr.args): + a = self.visit(node.context_expr.args[0]) + else: + assert len(node.context_expr.keywords) + ## need to catch if this is a new variable ## + name = node.context_expr.keywords[0].arg + if name not in self._known_vars: + a = '%s := %s' %(name, self.visit(node.context_expr.keywords[0].value)) + else: + a = '%s = %s' %(name, self.visit(node.context_expr.keywords[0].value)) + + if node.context_expr.func.id == '__case__': + r.append('case %s:' %a) + elif node.context_expr.func.id == '__switch__': + r.append('switch (%s) {' %self.visit(node.context_expr.args[0])) + is_switch = True + else: + raise SyntaxError( 'invalid use of with') + + + for b in node.body: + a = self.visit(b) + if a: r.append(a) + + if is_switch: + r.append('}') + + return '\n'.join(r) + + def visit_Assign(self, node): + target = node.targets[0] + if isinstance(target, ast.Tuple): + raise NotImplementedError('TODO') + + elif isinstance(node.value, ast.BinOp) and self.visit(node.value.op)=='<<' and isinstance(node.value.left, ast.Name) and node.value.left.id=='__go__send__': + target = self.visit(target) + value = self.visit(node.value.right) + return '%s <- %s;' % (target, value) + + elif not self._function_stack: + target = self.visit(target) + value = self.visit(node.value) + return 'var %s = %s;' % (target, value) + + elif isinstance(node.targets[0], ast.Name) and target.id in self._vars: + target = self.visit(target) + value = self.visit(node.value) + self._vars.remove( target ) + self._known_vars.add( target ) + return '%s := %s;' % (target, value) + + else: + target = self.visit(target) + value = self.visit(node.value) + + #if '<-' in value: + # raise RuntimeError(target+value) + + return '%s = %s;' % (target, value) + + def visit_While(self, node): + cond = self.visit(node.test) + if cond == 'true' or cond == '1': cond = '' + body = [ 'for %s {' %cond] + self.push() + for line in list( map(self.visit, node.body) ): + body.append( self.indent()+line ) + self.pull() + body.append( self.indent() + '}' ) + return '\n'.join( body ) + + def _inline_code_helper(self, s): + return s + #return 'js.Global.Call("eval", "%s")' %s ## TODO inline JS() + + + + + +def main(script, insert_runtime=True): + + if insert_runtime: + dirname = os.path.dirname(os.path.abspath(__file__)) + dirname = os.path.join(dirname, 'runtime') + runtime = open( os.path.join(dirname, 'go_builtins.py') ).read() + script = runtime + '\n' + script + + tree = ast.parse(script) + #return GoGenerator().visit(tree) + try: + return GoGenerator().visit(tree) + except SyntaxError as err: + sys.stderr.write(script) + raise err + + + +def command(): + scripts = [] + if len(sys.argv) > 1: + for arg in sys.argv[1:]: + if arg.endswith('.py'): + scripts.append( arg ) + + if len(scripts): + a = [] + for script in scripts: + a.append( open(script, 'rb').read() ) + data = '\n'.join( a ) + else: + data = sys.stdin.read() + + out = main( data ) + print( out ) + + +if __name__ == '__main__': + command() diff --git a/pythonjs/pythonjs_to_lua.py b/pythonjs/pythonjs_to_lua.py index 8342863..5a0e7cf 100644 --- a/pythonjs/pythonjs_to_lua.py +++ b/pythonjs/pythonjs_to_lua.py @@ -241,6 +241,8 @@ def _visit_function(self, node): setter = True elif isinstance(decor, ast.Attribute) and isinstance(decor.value, ast.Name) and decor.attr == 'prototype': klass = self.visit(decor) + elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__': + pass else: raise SyntaxError(decor) diff --git a/pythonjs/runtime/builtins.py b/pythonjs/runtime/builtins.py index 81014c4..7047472 100644 --- a/pythonjs/runtime/builtins.py +++ b/pythonjs/runtime/builtins.py @@ -2,17 +2,338 @@ # by Amirouche Boubekki and Brett Hartshorn - copyright 2013 # License: "New BSD" -pythonjs.configure(runtime_exceptions=False) +pythonjs.configure( runtime_exceptions=False ) +pythonjs.configure( direct_operator='+' ) +pythonjs.configure( direct_operator='*' ) +pythonjs.configure( direct_keys=True ) _PythonJS_UID = 0 -JS('IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError";') -JS('KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError";') -JS('ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError";') -JS('AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError";') -JS('RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError";') +inline('IndexError = function(msg) {this.message = msg || "";}; IndexError.prototype = Object.create(Error.prototype); IndexError.prototype.name = "IndexError";') +inline('KeyError = function(msg) {this.message = msg || "";}; KeyError.prototype = Object.create(Error.prototype); KeyError.prototype.name = "KeyError";') +inline('ValueError = function(msg) {this.message = msg || "";}; ValueError.prototype = Object.create(Error.prototype); ValueError.prototype.name = "ValueError";') +inline('AttributeError = function(msg) {this.message = msg || "";}; AttributeError.prototype = Object.create(Error.prototype);AttributeError.prototype.name = "AttributeError";') +inline('RuntimeError = function(msg) {this.message = msg || "";}; RuntimeError.prototype = Object.create(Error.prototype);RuntimeError.prototype.name = "RuntimeError";') with lowlevel: + def __getfast__(ob, attr): + v = ob[ attr ] + if v is undefined: + raise AttributeError(attr) + else: + return v + + +with javascript: + def __wrap_function__(f): + f.is_wrapper = True + return f + + + def __gpu_object(cls, struct_name, data_name): + cls.prototype.__struct_name__ = struct_name + cls.prototype.__struct_data__ = data_name + with lowlevel: + gpu = { + 'object' : __gpu_object + } + + def glsljit_runtime(header): + return new( GLSLJITRuntime(header) ) + + class GLSLJITRuntime: + def __init__(self, header): + self.header = header + self.shader = [] + self.object_packagers = [] + self.struct_types = {} + self.glsltypes = ['vec2', 'vec3', 'vec4', 'mat4'] + self.matrices = [] + + def compile_header(self): + a = [] ## insert structs at top of header + for sname in self.struct_types: + if sname in self.glsltypes: + pass + else: + a.push( self.struct_types[sname]['code'] ) + + ## calls get_global_id, see WebCLGL API docs. ## + a.push('int matrix_index() { return int(get_global_id().y*%s.0); }' %self.matrices.length) + a.push('int matrix_row() { return int(get_global_id().x*4.0); }') ## returns: 0, 1, 2, 3 + + ## first class array error, can not return an array, even when the size is known ## + #a.push('float[3] floatN( float a, float b, float c) { float f[3]; f[0]=a; f[1]=b; f[2]=b; return f; }') + + ## these could be generated for each array size to reduce the mess in main, + ## TODO it would be better to upload them as uniforms. + #a.push('void floatN( float f[3], float a, float b, float c) { f[0]=a; f[1]=b; f[2]=b; }') + + ## the array can be declared in the header, but not filled with data here. + #a.push('float XXX[3];') + #a.push('floatN( XXX, 1.1, 2.2, 3.3 );') + #a.push('XXX[0]=1.1;') + + + a = '\n'.join(a) + ## code in header could be methods that reference the struct types above. + b = "\n".join(self.header) + return '\n'.join([a,b]) + + def compile_main(self): + return '\n'.join(self.shader) + + def push(self, s): + self.shader.push(s) + + + def define_structure(self, ob): + struct_name = None + #if Object.hasOwnProperty.call(ob,'__struct_name__'): + if ob.__struct_name__: + struct_name = ob.__struct_name__ + if struct_name in self.struct_types: + return struct_name + + arrays = [] + floats = [] + integers = [] + structs = [] + struct_type = [] ## fallback for javascript objects + + if struct_name and struct_name in self.glsltypes: + return struct_name + + #for key in ob.keys(): + for key in dir( ob ): + if key.length==1 and key in '0123456789': + raise RuntimeError(key) + t = typeof( ob[key] ) + if t=='object' and instanceof(ob[key], Array) and ob[key].length and typeof(ob[key][0])=='number': + struct_type.push( 'ARY_'+key ) + arrays.push(key) + elif t=='number': + struct_type.push( 'NUM_'+key) + floats.push(key) + elif instanceof(ob[key], Int16Array): + struct_type.push( 'INT_'+key) + if ob[key].length == 1: + integers.push(key) + else: + pass ## TODO int16array + elif t=='object' and ob[key].__struct_name__: + struct_type.push( 'S_'+key) + structs.push( key ) + if ob[key].__struct_name__ not in self.struct_types: + if ob[key].__struct_name__ in self.glsltypes: + pass + else: + self.define_structure( ob[key] ) + + if struct_name is None: + #print('DEGUG: new struct name', ob.__struct_name__) + #print(ob) + struct_name = ''.join( struct_type ) + ob.__struct_name__ = struct_name + + if struct_name not in self.struct_types: + member_list = [] + for key in integers: + member_list.append('int '+key+';') + for key in floats: + member_list.append('float '+key+';') + for key in arrays: + arr = ob[key] + member_list.append('float '+key+'['+arr.length+'];') + for key in structs: + subtype = ob[key].__struct_name__ + member_list.append( subtype+' '+key+';') + + if len(member_list)==0: + raise RuntimeError(struct_name) + + members = ''.join(member_list) + code = 'struct ' +struct_name+ ' {' +members+ '};' + #print('-------struct glsl code-------') + #print(code) + #print('------------------------------') + self.struct_types[ struct_name ] = { + 'arrays' : arrays, + 'floats' : floats, + 'integers': integers, + 'structs' : structs, + 'code' : code + } + return struct_name + + def structure(self, ob, name): + wrapper = None + if instanceof(ob, Object): + pass + elif ob.__class__ is dict: + wrapper = ob + ob = ob[...] + + sname = self.define_structure(ob) + if wrapper: + wrapper.__struct_name__ = sname + + args = [] + stype = self.struct_types[ sname ] + + # if stype is None: ## TODO fix me + if sname not in self.struct_types: + if sname in self.glsltypes: + if sname == 'mat4': + if ob.__struct_data__: + o = ob[ ob.__struct_data__ ] + else: + o = ob + + for i in range(o.length): + value = o[i] +'' + if '.' not in value: value += '.0' + args.push( value ) + + else: + raise RuntimeError('no method to pack structure: ' +sname) + + has_arrays = False + if stype: + if stype['arrays'].length > 0: + has_arrays = True + + for key in stype['integers']: + args.push( ob[key][0]+'' ) + + for key in stype['floats']: + value = ob[key] + '' + if '.' not in value: + value += '.0' + args.push( value ) + + for key in stype['arrays']: + #args.push( '{'+ob[key].toString()+ '}') ## this will not work + ## arrays need to be assigned to a local variable before passing + ## it to the struct constructor. + aname = '_'+key+name + self.array(ob[key], aname) + args.push( aname ) + + for key in stype['structs']: + aname = '_'+key+name + self.structure(ob[key], aname) + args.push( aname ) + + args = ','.join(args) + if has_arrays: + self.shader.push( sname + ' ' +name+ '=' +sname+ '(' +args+ ');' ) + else: + self.header.push( 'const ' + sname + ' ' +name+ '=' +sname+ '(' +args+ ');' ) + return stype + + def int16array(self, ob, name): + a = ['int ' + name + '[' + ob.length + ']'] + i = 0 + while i < ob.length: + a.push(';'+name+'['+i+']='+ob[i]) + i += 1 + + self.shader.push( ''.join(a) ) + + def array(self, ob, name): + if instanceof(ob[0], Array): + a = [] #'float ' + name + '[' + ob.length + ']'] + i = 0 + while i < ob.length: + subarr = ob[i] + subname = '%s_%s'%(name,i) + if a.length==0: + a.append('float ' + subname + '[' + subarr.length + ']') + else: + a.append(';float ' + subname + '[' + subarr.length + ']') + j = 0 + while j < subarr.length: + v = subarr[j] + '' + if '.' not in v: + v += '.0' + a.push(';'+subname+'['+j+']='+v) + j += 1 + + i += 1 + + self.shader.push( ''.join(a) ) + + elif instanceof(ob[0], Object) or ob[0].__class__ is dict: + i = 0 + while i < ob.length: + self.structure( ob[i], name+'_'+i) + i += 1 + + else: + a = ['float ' + name + '[' + ob.length + '];'] + i = 0 + while i < ob.length: + a.push(name+'['+i+']='+ob[i] + ';') + i += 1 + + self.shader.push( ''.join(a) ) + + def object(self, ob, name): + for p in self.object_packagers: + cls, func = p + if instanceof(ob, cls): + return func(ob) + + def unpack_array2d(self, arr, dims): + if typeof(dims)=='number': + return arr + + w,h = dims + row = [] + rows = [row] + for value in arr: + row.append(value) + if row.length >= w: + row = [] + rows.append(row) + rows.pop() + if rows.length != h: + print('ERROR: __unpack_array2d, invalid height.') + return rows + + def unpack_vec4(self, arr, dims): + if typeof(dims)=='number': + w = dims + h = 1 + else: + w,h = dims + rows = [] + i=0 + for y in range(h): + row = [] + rows.append( row ) + for x in range(w): + vec = [] + for j in range(4): + vec.append( arr[i]) + i += 1 + row.append( vec ) + + if rows.length != h: + print('ERROR: __unpack_vec4, invalid height.') + return rows + + def unpack_mat4(self, arr): + i = 0 + for mat in self.matrices: + for j in range(16): + mat[j] = arr[i] + i += 1 + return self.matrices + +with lowlevel: + def __getattr__(ob, a ): if ob.__getattr__: return JS("ob.__getattr__(a)") @@ -62,6 +383,27 @@ def __split_method( ob, delim ): with javascript: + __dom_array_types__ = [] + if typeof(NodeList) == 'function': ## NodeList is only available in browsers + ## minimal dom array types common to allow browsers ## + __dom_array_types__ = [ NodeList, FileList, DOMStringList, HTMLCollection, SVGNumberList, SVGTransformList] + + ## extra dom array types ## + if typeof(DataTransferItemList) == 'function': ## missing in NodeWebkit + __dom_array_types__.push( DataTransferItemList ) + if typeof(HTMLAllCollection) == 'function': ## missing in Firefox + __dom_array_types__.push( HTMLAllCollection ) + if typeof(SVGElementInstanceList) == 'function':## missing in Firefox + __dom_array_types__.push( SVGElementInstanceList ) + if typeof(ClientRectList) == 'function': ## missing in Firefox-trunk + __dom_array_types__.push( ClientRectList ) + + def __is_some_array( ob ): + if __dom_array_types__.length > 0: + for t in __dom_array_types__: + if instanceof(ob, t): + return True + return False def __is_typed_array( ob ): if instanceof( ob, Int8Array ) or instanceof( ob, Uint8Array ): @@ -118,17 +460,41 @@ def __add_op(a, b): else: raise TypeError('invalid objects for addition') + def __mul_op(a, b): + t = typeof(a) + if t == 'number': + return JS("a * b") + elif t == 'string': + arr = [] + for i in range(b): + arr.append(a) + return ''.join(arr) + elif instanceof(a, Array): + c = [] + for i in range(b): + c.extend(a) + return c + elif a.__mul__: + return a.__mul__(b) + else: + raise TypeError('invalid objects for multiplication') + + def __jsdict( items ): d = JS("{}") for item in items: key = item[0] - if key.__uid__: + if instanceof(key, Array): + key = JSON.stringify(key) + elif key.__uid__: key = key.__uid__ d[ key ] = item[1] return d def __jsdict_get(ob, key, default_value): if instanceof(ob, Object): + if instanceof(key, Array): + key = JSON.stringify(key) if JS("key in ob"): return ob[key] return default_value else: ## PythonJS object instance ## @@ -140,6 +506,8 @@ def __jsdict_get(ob, key, default_value): def __jsdict_set(ob, key, value): if instanceof(ob, Object): + if instanceof(key, Array): + key = JSON.stringify(key) ob[ key ] = value else: ## PythonJS object instance ## ## this works because instances from PythonJS are created using Object.create(null) ## @@ -147,6 +515,9 @@ def __jsdict_set(ob, key, value): def __jsdict_keys(ob): if instanceof(ob, Object): + ## in the case of tuple keys this would return stringified JSON instead of the original arrays, + ## TODO, should this loop over the keys and convert the json strings back to objects? + ## but then how would we know if a given string was json... special prefix character? return JS("Object.keys( ob )") else: ## PythonJS object instance ## ## this works because instances from PythonJS are created using Object.create(null) ## @@ -179,9 +550,14 @@ def __jsdict_items(ob): def __jsdict_pop(ob, key, _default=None): if instanceof(ob, Array): if ob.length: - return JS("ob.pop(key)") + ## note: javascript array.pop only pops the end of an array + if key is undefined: + return inline("ob.pop()") + else: + return ob.splice( key, 1 )[0] else: raise IndexError(key) + elif instanceof(ob, Object): if JS("key in ob"): v = ob[key] @@ -195,6 +571,13 @@ def __jsdict_pop(ob, key, _default=None): ## this works because instances from PythonJS are created using Object.create(null) ## return JS("ob.pop(key, _default)") + + def dir(ob): + if instanceof(ob, Object): + return JS("Object.keys( ob )") + else: + return __object_keys__(ob) + def __object_keys__(ob): ''' notes: @@ -330,7 +713,7 @@ def __call__(): return object - __call__.pythonscript_function = True + __call__.is_wrapper = True klass.__call__ = __call__ return klass @@ -415,24 +798,36 @@ def int(a): raise ValueError('not a number') return a +with javascript: + def int16(a): ## used by glsljit when packing structs. + arr = new(Int16Array(1)) + arr[0]=a + return arr + def float(a): with javascript: - a = Number(a) - if isNaN(a): - raise ValueError('not a number') - return a - -def round(a, places): + if typeof(a)=='string': + if a.lower()=='nan': + return NaN + elif a.lower()=='inf': + return Infinity + + b = Number(a) + if isNaN(b): + ## invalid strings also convert to NaN, throw error ## + raise ValueError('can not convert to float: '+a) + return b + +def round(a, places=0): with javascript: b = '' + a if b.indexOf('.') == -1: return a else: - c = b.split('.') - x = c[0] - y = c[1].substring(0, places) - return parseFloat( x+'.'+y ) - + ## this could return NaN with large numbers and large places, + ## TODO check for NaN and instead fallback to `a.toFixed(places)` + p = Math.pow(10, places) + return Math.round(a * p) / p def str(s): return ''+s @@ -546,6 +941,14 @@ def func(): else: return False return True + @String.prototype.isnumber + def func(): + digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'] + for char in this: + if char in digits: pass + else: return False + return True + ## TODO - for now these are just dummy functions. @String.prototype.decode def func(encoding): @@ -566,6 +969,23 @@ def func(fmt): _setup_str_prototype() + +## note Arrays in javascript by default sort by string order, even if the elements are numbers. +with javascript: + def __sort_method(ob): + if instanceof(ob, Array): + def f(a,b): + if a < b: + return -1 + elif a > b: + return 1 + else: + return 0 + return JS("ob.sort( f )") + + else: + return JS("ob.sort()") + def _setup_array_prototype(): with javascript: @@ -610,17 +1030,83 @@ def func(): @Array.prototype.__getslice__ def func(start, stop, step): - if start is undefined and stop is undefined: - arr = [] - i = 0 - while i < this.length: + arr = [] + + start = start | 0 + if stop is undefined: + stop = this.length + + if start < 0: + start = this.length + start + if stop < 0: + stop = this.length + stop + + #reverse = step < 0 ## in javascript `null<0` and `undefined<0` are false + #reverse = False + + if typeof(step)=='number': + #reverse = step < 0 + #if reverse: + if step < 0: + #step = Math.abs(step) + i = start + while i >= 0: + arr.push( this[i] ) + i += step + return arr + + else: + i = start + n = stop + while i < n: + arr.push( this[i] ) + i += step + return arr + + else: + i = start + n = stop + while i < n: + #arr[ i ] = this[i] ## slower in chrome arr.push( this[i] ) - i += step + i += 1 ## this gets optimized to i++ return arr - else: - if stop < 0: - stop = this.length + stop - return this.slice(start, stop) + + #if reverse: + # arr.reverse() + + #if step == 1: + # arr = new(Array(this.length)) + # i = 0 + # while i < this.length: + # arr[ i ] = this[i] + # i += 1 ## this gets optimized to i++ + #else: + # arr = [] + # i = 0 + # while i < this.length: + # arr.push( this[i] ) + # i += step + + #if start is undefined and stop is undefined: + # if reverse: arr.reverse() + #elif reverse: + # arr = arr.slice(stop, start+1) + # arr.reverse() + #else: + # #if stop < 0: ## mozilla spec says negative indices are supported + # # stop = arr.length + stop + # arr = arr.slice(start, stop) + + #return arr + + @Array.prototype.__setslice__ + def func(start, stop, step, items): + if start is undefined: start = 0 + if stop is undefined: stop = this.length + arr = [start, stop-start] + for item in items: arr.push( item ) + this.splice.apply(this, arr ) @Array.prototype.append def func(item): @@ -689,6 +1175,17 @@ def func(other): return False return True + ## non-standard utils ## + @Array.prototype.copy + def func(): + arr = [] + i = 0 + while i < this.length: + arr.push( this[i] ) + i += 1 + return arr + + _setup_array_prototype() @@ -735,9 +1232,9 @@ def index(obj): def bisect(a, x, low=None, high=None): - #if isinstance(a, list): - # return a[...].bisect(x, low, high) - return a.bisect(x, low, high) + ## bisect function from bisect module of the stdlib + with javascript: + return a.bisect(x, low, high) def range(num, stop, step): @@ -777,11 +1274,10 @@ def len(ob): return ob.length elif instanceof(ob, ArrayBuffer): return ob.byteLength - elif instanceof(ob, Object): + elif ob.__len__: + return ob.__len__() + else: #elif instanceof(ob, Object): return Object.keys(ob).length - else: - with python: - return ob.__len__() def next(obj): @@ -888,7 +1384,25 @@ def list(a): raise TypeError - +with javascript: + def __tuple_key__(arr): + r = [] + i = 0 + while i < arr.length: + item = arr[i] + t = typeof(item) + if t=='string': + r.append( "'"+item+"'") + elif instanceof(item, Array): + r.append( __tuple_key__(item) ) + elif t=='object': + if item.__uid__ is undefined: + raise KeyError(item) + r.append( item.__uid__ ) + else: + r.append( item ) + i += 1 + return r.join(',') class dict: # http://stackoverflow.com/questions/10892322/javascript-hashtable-use-object-key @@ -905,10 +1419,17 @@ def __init__(self, js_object=None, pointer=None): ob = js_object if instanceof(ob, Array): for o in ob: - if instanceof(o, Array): - self.__setitem__( o[0], o[1] ) - else: - self.__setitem__( o['key'], o['value'] ) + with lowlevel: + if instanceof(o, Array): + k= o[0]; v= o[1] + else: + k= o['key']; v= o['value'] + + try: + self.__setitem__( k,v ) + except KeyError: + raise KeyError('error in dict init, bad key') + elif isinstance(ob, dict): for key in ob.keys(): value = ob[ key ] @@ -972,38 +1493,55 @@ def __len__(self): def __getitem__(self, key): ''' - notes: - . '4' and 4 are the same key - . it is possible that the translator mistakes a javascript-object for a dict and inlines this function, - that is why below we return the key in self if __dict is undefined. + note: `"4"` and `4` are the same key in javascript, is there a sane way to workaround this, + that can remain compatible with external javascript? ''' - __dict = self[...] - if JS("typeof(key) === 'object' || typeof(key) === 'function'"): - # Test undefined because it can be in the dict - if JS("key.__uid__ && key.__uid__ in __dict"): - return JS('__dict[key.__uid__]') - raise KeyError(key) + with javascript: + __dict = self[...] + err = False + if instanceof(key, Array): + #key = JSON.stringify( key ) ## fails on objects with circular references ## + key = __tuple_key__(key) + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): + # Test undefined because it can be in the dict + if JS("key.__uid__ && key.__uid__ in __dict"): + return JS('__dict[key.__uid__]') + else: + err = True - # Tested after in order to not convert functions to strings. - # The slow down is negligible - if __dict and JS("key in __dict"): - return JS('__dict[key]') + if __dict and JS("key in __dict"): + return JS('__dict[key]') + else: + err = True - raise KeyError(key) + if err: + msg = "missing key: %s -\n" %key + raise KeyError(__dict.keys()) def __setitem__(self, key, value): - __dict = self[...] - if JS("typeof(key) === 'object' || typeof(key) === 'function'"): - if JS("key.__uid__ === undefined"): - # "" is needed so that integers can also be - # used as keys - JS(u"key.__uid__ = '' + _PythonJS_UID++") - JS('__dict[key.__uid__] = value') - else: - JS('__dict[key] = value') + with javascript: + if key is undefined: + raise KeyError('undefined is invalid key type') + if key is null: + raise KeyError('null is invalid key type') + + __dict = self[...] + if instanceof(key, Array): + #key = JSON.stringify( key ) ## fails on objects with circular references ## + key = __tuple_key__(key) + if key is undefined: + raise KeyError('undefined is invalid key type (tuple)') + inline( '__dict[key] = value') + elif JS("typeof(key) === 'object' || typeof(key) === 'function'"): + if JS("key.__uid__ === undefined"): + # "" is needed so that integers can also be used as keys # + JS(u"key.__uid__ = '' + _PythonJS_UID++") + JS('__dict[key.__uid__] = value') + else: + JS('__dict[key] = value') def keys(self): - with javascript: + with lowlevel: return Object.keys( self[...] ) def pop(self, key, d=None): @@ -1057,7 +1595,7 @@ def set(a): ''' with javascript: - if isinstance(a, list): a = a[...] + hashtable = null if a.length <= 1536: hashtable = {} @@ -1076,7 +1614,7 @@ def set(a): fallback = False if hashtable: for b in a: - if typeof(b,'number') and b is (b|0): ## set if integer + if typeof(b)=='number' and b is (b|0): ## set if integer key = b & mask hashtable[ key ] = b keys.push( key ) @@ -1341,7 +1879,7 @@ def read(self, binary=False): path = self.path with javascript: if binary or self.binary: - return _fs.readFileSync( path ) + return _fs.readFileSync( path, encoding=None ) else: return _fs.readFileSync( path, {'encoding':'utf8'} ) @@ -1350,8 +1888,18 @@ def write(self, data, binary=False): path = self.path with javascript: if binary or self.binary: - _fs.writeFileSync( path, data ) + binary = binary or self.binary + if binary == 'base64': ## TODO: fixme, something bad in this if test + #print('write base64 data') + buff = new Buffer(data, 'base64') + _fs.writeFileSync( path, buff, {'encoding':None}) + + else: + #print('write binary data') + #print(binary) + _fs.writeFileSync( path, data, {'encoding':None}) else: + #print('write utf8 data') _fs.writeFileSync( path, data, {'encoding':'utf8'} ) def close(self): @@ -1487,3 +2035,23 @@ def __rpc__( url, func, args): req.send( JSON.stringify({'call':func, 'args':args}) ) return JSON.parse( req.responseText ) + def __rpc_iter__( url, attr): + req = new( XMLHttpRequest() ) + req.open('POST', url, False) ## false is sync + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8") + req.send( JSON.stringify({'iter':attr}) ) + return JSON.parse( req.responseText ) + + def __rpc_set__( url, attr, value): + req = new( XMLHttpRequest() ) + req.open('POST', url, False) ## false is sync + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8") + req.send( JSON.stringify({'set':attr, 'value':value}) ) + + def __rpc_get__( url, attr): + req = new( XMLHttpRequest() ) + req.open('POST', url, False) ## false is sync + req.setRequestHeader("Content-Type", "application/json;charset=UTF-8") + req.send( JSON.stringify({'get':attr}) ) + return JSON.parse( req.responseText ) + diff --git a/pythonjs/runtime/dart_builtins.py b/pythonjs/runtime/dart_builtins.py index 55ee89a..02c44a1 100644 --- a/pythonjs/runtime/dart_builtins.py +++ b/pythonjs/runtime/dart_builtins.py @@ -3,8 +3,74 @@ # License: "New BSD" dart_import('dart:collection') +dart_import('dart:typed_data') dart_import('dart:math', 'Math') +__random_gen__ = new(Math.Random()) +def __random__(): return __random_gen__.nextDouble() + + +class float32vec: + def __init__(self, items): + self[...] = new( List() ) + self.length = items.length + + i = 0; s = 0 + while i < items.length: + x = items[i] + y = items[i+1] + z = items[i+2] + w = items[i+3] + vec = new( Float32x4(x,y,z,w) ) + self[...].add( vec ) + i += 4 + + + def __getitem__(self, index): + if index < 0: index = self.length + index + + float32x4 vec = self[...][ index // 4 ] + lane = index % 4 + if lane == 0: return vec.x + elif lane == 1: return vec.y + elif lane == 2: return vec.z + elif lane == 3: return vec.w + + def __setitem__(self, index, value): + if index < 0: index = self.length + index + + vec = self[...][ index // 4 ] + lane = index % 4 + if lane == 0: vec = vec.withX(value) + elif lane == 1: vec = vec.withY(value) + elif lane == 2: vec = vec.withZ(value) + elif lane == 3: vec = vec.withW(value) + + self[...][ index // 4 ] = vec + + def __add__(self, other): + arr = new( List() ) + for i, vec1 in enumerate( self[...] ): + vec2 = other[...][ i ] + arr.add( vec1+vec2 ) + + v = inline("new float32vec([])") + v.length = self.length + v[...] = arr + return v + + def __mul__(self, other): + arr = new( List() ) + for i, vec1 in enumerate( self[...] ): + vec2 = other[...][ i ] + arr.add( vec1*vec2 ) + + v = inline("new float32vec([])") + v.length = self.length + v[...] = arr + return v + + #@dart.extends #class list( ListBase ): class list: @@ -51,23 +117,50 @@ def __setitem__(self, index, value): self[...][index] = value def __getslice__(self, start, stop, step): - if step == -1: - return list( self[...].reversed ) - elif stop == null and step == null: + + if start == null and stop == null and step == null: return list( self[...] ) - elif stop == null: - return list( self[...].sublist(start) ) - elif stop < 0: - stop = self[...].length + stop - if start != null: - return list( self[...].sublist(start, stop) ) - else: - return list( self[...].sublist(0, stop) ) else: - if start != null: - return list( self[...].sublist(start, stop) ) + if step == null: step = 1 + reverse = False + if step < 0: + step = step.abs() + reverse = True + + a = new( List() ) + i = 0 + while i < self[...].length: + a.add( self[...][i] ) + i += step + + if start == null: start = 0 + if stop == null: stop = a.length + if start < 0: + start = a.length + start + if stop < 0: + stop = a.length + stop + + if reverse: + b = new( List() ) + b.addAll( a.reversed ) + return list( b.sublist(a.length-(start+1), stop) ) else: - return list( self[...].sublist(0, stop) ) + return list( a.sublist(start, stop) ) + + + def __setslice__(self, start, stop, step, items): + if start == null: start = 0 + if stop == null: stop = self[...].length + stop -= start + while stop != 0: + self[...].removeAt(start) + stop -= 1 + if instanceof(items, String): + items = items.split('') + elif instanceof(items, list): + items = items[...] + self[...].insertAll(start, items) + def __add__(self, other): self[...].addAll( other[...] ) @@ -79,6 +172,13 @@ def append(self, item): def index(self, obj): return self[...].indexOf(obj) + def pop(self, n): + return self[...].removeAt( n ) + + def insert(self, i, o): + if i < 0: i = self.length+i + self[...].insert(i,o) + def tuple(a): return list(a) @@ -134,6 +234,14 @@ def range(n): i += 1 return r +def __range2(start, stop): + r = [] + i = start + while i < stop: + r.append( i ) + i += 1 + return r + def len(a): return a.length @@ -169,7 +277,8 @@ def __getslice__(a, start, stop, step): return b else: - return list.____getslice__(a, start, stop, step) + #return list.____getslice__(a, start, stop, step) + return a.__getslice__(start, stop, step) def __reverse__(a): if instanceof(a, String): diff --git a/pythonjs/runtime/go_builtins.py b/pythonjs/runtime/go_builtins.py new file mode 100644 index 0000000..0cb2019 --- /dev/null +++ b/pythonjs/runtime/go_builtins.py @@ -0,0 +1,57 @@ +# PythonJS Go builtins +# by Brett Hartshorn - copyright 2014 +# License: "New BSD" + +import strconv + +inline(""" + +func str(v interface{}) string { + switch v.(type) { + case nil: + return "None" + case int: + i,_ := v.(int) + return strconv.Itoa(i) + case float64: + return "TODO float" + case bool: + b,_ := v.(bool) + if b { return "True" + } else { return "False" } + case string: + s,_ := v.(string) + return s + default: + return "TODO unknown type" + + } +} + +func range1( x int ) []int { + arr := make([]int, x) + for i := 0; i < x; i++ { + arr[i]=i + } + return arr +} + +func range2( start int, stop int ) []int { + arr := make([]int, stop-start) + for i := start; i < stop; i++ { + arr[i]=i + } + return arr +} + +func range3( start int, stop int, step int ) []int { + arr := make([]int, stop-start) + for i := start; i < stop; i+=step { + arr[i]=i + } + return arr +} + +""") + + diff --git a/pythonjs/runtime/pythonpythonjs.py b/pythonjs/runtime/pythonpythonjs.py index 4fb8aa6..70bbf09 100644 --- a/pythonjs/runtime/pythonpythonjs.py +++ b/pythonjs/runtime/pythonpythonjs.py @@ -56,8 +56,13 @@ def __get__(object, attribute, error_message): else: raise AttributeError('undefined has no attribute: ' +attribute) + #if attribute == '__getitem__' and instanceof(object, Array): ## NOT REQUIRED + # ## allows list comp on Array called from Python-mode ## + # def wrapper(args,kwargs): return object[ args[0] ] + # wrapper.is_wrapper = True + # return wrapper if attribute == '__call__': - if object.pythonscript_function or object.is_wrapper: ## common case + if object.pythonscript_function or object.is_wrapper: ## common case - TODO replaced by __pyfunc__ return object elif object.cached_wrapper: ## rare case return object.cached_wrapper @@ -124,7 +129,7 @@ def wrapper(args,kwargs): return attr.apply(object, args) ## attr can be null and will return, undefined will raise AttributeError ## if attr is not undefined: if typeof(attr) == 'function': - if JS("attr.pythonscript_function === undefined && attr.is_wrapper === undefined"): + if JS("attr.pythonscript_function === undefined && attr.is_wrapper === undefined"): ## TODO pythonscript_function will be replaced with __pyfunc__ ## if there is a prototype with methods, then we can be sure that the user indends to call `new` on it, ## however rare, it is still possible that it is a constructor without a prototype of any length, @@ -328,7 +333,14 @@ def method(args,kwargs): ## getting/setting from a normal JavaScript Object ## if attribute == '__getitem__': - def wrapper(args,kwargs): return object[ args[0] ] + ## TODO, should object be checked if it really is an object here? + ## new rule: if value to return is `undefined` throw KeyError, + ## this could be a problem with some external js libraries but should be rare, + ## because most libraries will initalize keys to `null` + def wrapper(args,kwargs): + v = object[ args[0] ] + if v is undefined: + raise KeyError( args[0] ) wrapper.is_wrapper = True return wrapper elif attribute == '__setitem__': diff --git a/pythonjs/translator.py b/pythonjs/translator.py index 12cdd83..0b772f9 100755 --- a/pythonjs/translator.py +++ b/pythonjs/translator.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -import sys, traceback, json +import os, sys, traceback, json from python_to_pythonjs import main as python_to_pythonjs from pythonjs import main as pythonjs_to_javascript @@ -7,69 +7,132 @@ from pythonjs_to_coffee import main as pythonjs_to_coffee from pythonjs_to_lua import main as pythonjs_to_lua from pythonjs_to_luajs import main as pythonjs_to_luajs +from pythonjs_to_go import main as pythonjs_to_go +cmdhelp = """\ +usage: translator.py [--dart|--coffee|--lua|--go|--visjs|--no-wrapper|--analyze] file.py -def main(script): - if '--visjs' in sys.argv: - import python_to_visjs - return python_to_visjs.main( script ) - else: - code = '' - if '--dart' in sys.argv: - a = python_to_pythonjs(script, dart=True) - code = pythonjs_to_dart( a ) - elif '--coffee' in sys.argv: - a = python_to_pythonjs(script, coffee=True) - code = pythonjs_to_coffee( a ) - elif '--lua' in sys.argv: - a = python_to_pythonjs(script, lua=True) - try: code = pythonjs_to_lua( a ) - except SyntaxError: - err = traceback.format_exc() - lineno = 0 - for line in err.splitlines(): - if "" in line: - lineno = int(line.split()[-1]) - - b = a.splitlines()[ lineno ] - sys.stderr.write( '\n'.join([err,b]) ) - - elif '--luajs' in sys.argv: - a = python_to_pythonjs(script, lua=True) - code = pythonjs_to_luajs( a ) - else: - a = python_to_pythonjs(script) - if isinstance(a, dict): - res = {} - for jsfile in a: - res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' ) - return res - else: - code = pythonjs_to_javascript( a ) - - return code +example: + translator.py --no-wrapper myscript.py > myscript.js +""" + + +def main(script, module_path=None): + if '--visjs' in sys.argv: + import python_to_visjs + return python_to_visjs.main( script ) + else: + code = '' + res = None + if '--go' in sys.argv: + a = python_to_pythonjs(script, go=True, module_path=module_path) + code = pythonjs_to_go( a ) + elif '--gopherjs' in sys.argv: + a = python_to_pythonjs(script, go=True, module_path=module_path) + code = pythonjs_to_go( a ) + + exe = os.path.expanduser('~/go/bin/gopherjs') + if not os.path.isfile(exe): + raise RuntimeError('gopherjs not installed to ~/go/bin/gopherjs') + import subprocess + path = '/tmp/gopherjs-input.go' + open(path, 'wb').write(code) + subprocess.check_call([exe, 'build', path], cwd='/tmp') + code = open('/tmp/gopherjs-input.js', 'rb').read() + + elif '--dart' in sys.argv: + a = python_to_pythonjs(script, dart=True, module_path=module_path) + code = pythonjs_to_dart( a ) + elif '--coffee' in sys.argv: + a = python_to_pythonjs(script, coffee=True, module_path=module_path) + code = pythonjs_to_coffee( a ) + elif '--lua' in sys.argv: + a = python_to_pythonjs(script, lua=True, module_path=module_path) + try: code = pythonjs_to_lua( a ) + except SyntaxError: + err = traceback.format_exc() + lineno = 0 + for line in err.splitlines(): + if "" in line: + lineno = int(line.split()[-1]) + + b = a.splitlines()[ lineno ] + sys.stderr.write( '\n'.join([err,b]) ) + + elif '--luajs' in sys.argv: ## converts back to javascript + a = python_to_pythonjs(script, lua=True, module_path=module_path) + code = pythonjs_to_luajs( a ) + else: + a = python_to_pythonjs(script, module_path=module_path) + + if isinstance(a, dict): + res = {} + for jsfile in a: + res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' ) + return res + else: + ## requirejs module is on by default, this wraps the code in a `define` function + ## and returns `__module__` + ## if --no-wrapper is used, then the raw javascript is returned. + code = pythonjs_to_javascript( a, requirejs='--no-wrapper' not in sys.argv ) + + if '--analyze' in sys.argv: + dartanalyzer = os.path.expanduser('~/dart-sdk/bin/dartanalyzer') + #dart2js = os.path.expanduser('~/dart-sdk/bin/dart2js') + assert os.path.isfile( dartanalyzer ) + + x = python_to_pythonjs(script, dart=True, module_path=module_path) + dartcode = pythonjs_to_dart( x ) + path = '/tmp/debug.dart' + open(path, 'wb').write( dartcode ) + import subprocess + try: + subprocess.check_output( [dartanalyzer, path] ) + except subprocess.CalledProcessError as err: + dartcodelines = dartcode.splitlines() + for line in err.output.splitlines(): + if line.startswith('[error]'): + a,b = line.split( path ) + a = a[:-1] + print( '\x1B[0;31m' + a + '\x1B[0m' ) + lineno = int( b.split('line ')[-1].split(',')[0] ) + print('line: %s' %lineno) + print( dartcodelines[lineno-1] ) + sys.exit(1) + + if res: ## dict return + return res + else: + return code def command(): - scripts = [] - if len(sys.argv) > 1: - for arg in sys.argv[1:]: - if arg.endswith('.py'): - scripts.append( arg ) - - if len(scripts): - a = [] - for script in scripts: - a.append( open(script, 'rb').read() ) - data = '\n'.join( a ) - else: - data = sys.stdin.read() - - js = main(data) - if isinstance(js, dict): - print( json.dumps(js) ) - else: - print(js) + if '-h' in sys.argv or '--help' in sys.argv: + print(cmdhelp) + return + + mpath = None + scripts = [] + if len(sys.argv) > 1: + for arg in sys.argv[1:]: + if arg.endswith('.py') or arg.endswith('.html'): + scripts.append( arg ) + if mpath is None: + mpath = os.path.split(arg)[0] + + if len(scripts): + a = [] + for script in scripts: + a.append( open(script, 'rb').read() ) + data = '\n'.join( a ) + else: + data = sys.stdin.read() + + js = main(data, module_path=mpath) + if isinstance(js, dict): + print( json.dumps(js) ) + else: + print(js) if __name__ == '__main__': - command() + command() diff --git a/pythonjs/typedpython.py b/pythonjs/typedpython.py index ec96a30..f5bf3f3 100644 --- a/pythonjs/typedpython.py +++ b/pythonjs/typedpython.py @@ -1,33 +1,353 @@ -whitespace = [' ', '\t'] +types = ['str', 'list', 'dict'] + +glsl_types = ['struct*', 'int*', 'float*', 'vec2', 'vec3', 'vec4', 'mat2', 'mat3', 'mat4'] +glsl_xtypes = ['mat2x2', 'mat3x3', 'mat4x4'] ## others not supported in WebGLSL +glsl_types.extend( glsl_xtypes ) +glsl_aliases = ['floatPOINTER', 'intPOINTER', 'structPOINTER'] + +types.extend( glsl_types ) +types.extend( glsl_aliases ) + native_number_types = ['int', 'float', 'double'] ## float and double are the same +simd_types = ['float32x4', 'int32x4'] +vector_types = ['float32vec'] +vector_types.extend( simd_types ) number_types = ['long'] ## requires https://github.com/dcodeIO/Long.js number_types.extend( native_number_types ) -types = ['str', 'list', 'dict'] types.extend( number_types) +types.extend( vector_types ) + +__whitespace = [' ', '\t'] + +GO_SPECIAL_CALLS = { + 'go' : '__go__', + 'go.channel' : '__go_make_chan__', + 'go.array' : '__go__array__', + 'go.make' : '__go_make__' +} def transform_source( source, strip=False ): output = [] + output_post = None + for line in source.splitlines(): a = [] - for char in line: - if a and char in whitespace: + hit_go_typedef = False + gotype = None + + for i,char in enumerate(line): + nextchar = None + j = i+1 + while j < len(line): + nextchar = line[j] + if nextchar.strip(): break + j += 1 + + if a and char==']' and j==i+1 and nextchar!=None and nextchar in '[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ': + assert '[' in a + gotype = [] + b = a.pop() + while b != '[': + gotype.append(b) + b = a.pop() + gotype.reverse() + gotype = ''.join(gotype) + if not gotype: + if nextchar=='[': + a.append('__go__array__<<') + else: + a.append('__go__array__(') + elif gotype.isdigit(): + a.append('__go__arrayfixed__(%s,' %gotype) + else: + assert ''.join(a[-3:])=='map' + a.pop(); a.pop(); a.pop() + a.append('__go__map__(%s,' %gotype) + hit_go_typedef = True + + elif hit_go_typedef and char=='(': + a.append(')<<(') + hit_go_typedef = False + elif hit_go_typedef and char=='{': + a.append(')<<{') + hit_go_typedef = False + elif hit_go_typedef and char==',': + #a.append(', type=True),') ## this breaks function annotations that splits on ',' + a.append('<' in c: ## python3 syntax + c, rtype = c.split('->') + c += ':' + rtype = rtype.strip()[:-1] + indent = [] + for char in c: + if char in __whitespace: + indent.append(char) + else: + break + indent = ''.join(indent) + output.append( indent + '@returns(%s)' %rtype) + + if c.startswith('import '): + if '-' in c: + c = c.replace('-', '__DASH__') + if '/' in c: + c = c.replace('/', '__SLASH__') + if '"' in c: + c = c.replace('"', '') + + + if ' new ' in c: + c = c.replace(' new ', ' __new__>>') + if '\tnew ' in c: + c = c.replace('\tnew ', ' __new__>>') + + + ## golang + + if c.strip().startswith('switch '): + c = c.replace('switch ', 'with __switch__(').replace(':', '):') + + if c.strip().startswith('default:'): + c = c.replace('default:', 'with __default__:') + + if c.strip().startswith('select:'): + c = c.replace('select:', 'with __select__:') + + if c.strip().startswith('case ') and c.strip().endswith(':'): + c = c.replace('case ', 'with __case__(').replace(':', '):') + + if '<-' in c: + if '=' in c: + c = c.replace('<-', '__go__receive__<<') + else: + ## keeping `=` allows for compatible transform to stacklessPython API, + ## this is not used now because it is not required by the Go backend. + c = c.replace('<-', '= __go__send__<<') + #c = c.replace('<-', '<<__go__send__<<') + + + ## X.method.bind(X) shortcut `->` + if '->' in c: + a,b = c.split('->') + this_name = a.split()[-1].split('=')[-1].split(':')[-1].split(',')[-1] + method_name = b.split()[0].split('(')[0] + c = c.replace('->'+method_name, '.'+method_name+'.bind(%s)'%this_name) + + ## callback=def .. inline function ## + if '=def ' in c or '= def ' in c or ': def ' in c or ':def ' in c: + if '=def ' in c: + d = '=def ' + elif '= def ' in c: + d = '= def ' + elif ': def ' in c: + d = ': def ' + elif ':def ' in c: + d = ':def ' + + if 'def (' in c: + c = c.replace('def (', 'def __NAMELESS__(') + c, tail = c.split(d) + + #if d.startswith('='): + # if '(' in c: + # c += '=lambda __INLINE_FUNCTION__: %s )' %tail.strip().split(':')[0] + # else: + # c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] + # output_post = 'def %s'%tail + + if d.startswith('='): + c += '=lambda __INLINE_FUNCTION__: %s' %tail.strip().split(':')[0] + + if output_post: + if output_post[-1][-1]==',': + output_post[-1] = output_post[-1][:-1] + output[-1] += ',' + else: output_post = list() + + output.append( c ) + + c = 'def %s'%tail + + else: + c += ':lambda __INLINE_FUNCTION__: %s,' %tail.strip().split(':')[0] + output.append( c ) + if output_post: + if output_post[-1][-1]==',': + output_post[-1] = output_post[-1][:-1] + else: output_post = list() + c = 'def %s'%tail + + + ## python3 annotations + if 'def ' in c and c.count(':') > 1: + indent = 0 + for u in c: + if u == ' ' or u == '\t': + indent += 1 + else: + break + indent = '\t'*indent + + #head, tail = c.split('(') + head = c[ : c.index('(') ] + tail = c[ c.index('(')+1 : ] + args = [] + #tail, tailend = tail.split(')') + tailend = tail[ tail.rindex(')')+1 : ] + tail = tail[ : tail.rindex(')') ] + + + for x in tail.split(','): + y = x + if ':' in y: + kw = None + if '=' in y: + y, kw = y.split('=') + arg, typedef = y.split(':') + chan = False + if len(typedef.strip().split()) == 2: + chan = True + typedef = typedef.strip().split()[-1] + if '*' in arg: + arg_name = arg.split('*')[-1] + else: + arg_name = arg + + if chan: + output.append('%s@typedef_chan(%s=%s)' %(indent, arg_name, typedef)) + else: + output.append('%s@typedef(%s=%s)' %(indent, arg_name, typedef)) + if kw: + arg += '=' + kw + args.append(arg) + else: + args.append(x) + c = head +'(' + ','.join(args) + ')'+tailend + + + ## jquery ## + ## TODO ensure this is not inside quoted text + if '$(' in c: + c = c.replace('$(', '__DOLLAR__(') + if '$' in c and 'def ' in c: ## $ as function parameter + c = c.replace('$', '__DOLLAR__') + if '$.' in c: + c = c.replace('$.', '__DOLLAR__.') + + if c.strip().startswith('nonlocal '): ## Python3 syntax + c = c.replace('nonlocal ', 'global ') ## fake nonlocal with global + + if type(output_post) is list: + output_post.append( c ) + else: + output.append( c ) + + if type(output_post) is str: ## DEPRECATED + indent = 0 + for u in output[-1]: + if u == ' ' or u == '\t': + indent += 1 + else: + break + output.append( ('\t'*indent)+output_post) + output_post = True + elif output_post == True: ## DEPRECATED + if output[-1].strip()==')': + output.pop() + output_post = None + + elif type(output_post) is list: + if output_post[-1].strip().endswith( ('}',')') ): + output.append( output_post.pop() ) + indent = 0 + for u in output[-1]: + if u == ' ' or u == '\t': + indent += 1 + else: + break + for ln in output_post: + output.append( ('\t'*indent)+ln ) + + output_post = None + + r = '\n'.join(output) + return r test = ''' @@ -35,6 +355,99 @@ def transform_source( source, strip=False ): float b = 1.1 str c = "hi" int d +int def xxx(): pass +if True: + float* def Y(): + pass + +A.callback = B->method +A.do_something( x,y,z, B->method ) +A.do_something( x,y,z, callback=B->method ) +A.do_something( x,y,z, callback=def cb(x): + return x+y +) +A.do_something( x,y,z, callback=def (x,y,z): + return x+y +) +a = { + 'cb1': def (x,y): + return x+y +} +def xxx(): + b = { + 'cb1': def (x,y): + return x+y, + 'cb2': def (x,y): + return x+y + } + +X.func( cb1=def (): + return 1, + cb2=def (): + return 2 +) + +c = function(x,y): + return x+y +if True: + d = a[ 'somekey' ] except KeyError: 'mydefault' + +## <- becomes __go__send__<int: + return cb(3) + +def wrapper(a:int, c:chan int): + result = longCalculation(a) + c <- result + +switch a.f(): + case 1: + print(x) + case 2: + print(y) + default: + break + +select: + case x = <- a: + y += x + case x = <- b: + y += x + +## in go becomes: []string{x,y,z} +## becomes: __go__array__(string) << (x,y,z) +a = []string(x,y,z) + +## in go becomes: [3]int{x,y,z} +## becomes: __go__arrayfixed__(3, string) << (x,y,z) +a = [3]int(x,y,z) + +## in go becomes: map[string]int{x,y,z} +## becomes: __go__map__(string, int) << {'x':x, 'y':y, 'z':z} +a = map[string]int{ + "x":x, "y":y, "z":z +} + +def f(a:int, b:int, c:int) ->int: + return a+b+c + +def f(a:int=100, b:int=100) ->int: + return a+b + +def f(*args:int, **kwargs:int) ->int: + return a+b + +a = []int(x for x in range(3)) + +y = go.make([]float64, 1000) + +def plot(id:string, latency:[]float64, xlabel:string, title:string ): + pass + ''' if __name__ == '__main__': diff --git a/regtests/bench/copy_list.py b/regtests/bench/copy_list.py new file mode 100644 index 0000000..02a2c71 --- /dev/null +++ b/regtests/bench/copy_list.py @@ -0,0 +1,29 @@ +'''copy list micro benchmark''' + +from time import time + +def main(): + if PYTHON=='PYTHONJS': + pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_keys=True ) + pass + + a = list(range(1000)) + times = [] + for i in range(4): + t0 = time() + res = copy_list(a, 10000) + tk = time() + times.append(tk - t0) + avg = sum(times) / len(times) + print(avg) + +def copy_list( a, n ): + x = [] + for i in range(n): + b = a[:] + for j in range(10): + b.append( j ) + x.append( b ) + return x + diff --git a/regtests/bench/fannkuch.py b/regtests/bench/fannkuch.py new file mode 100644 index 0000000..222695f --- /dev/null +++ b/regtests/bench/fannkuch.py @@ -0,0 +1,74 @@ +# The Computer Language Benchmarks Game +# http://shootout.alioth.debian.org/ +# +# contributed by Sokolov Yura +# modified by Tupteq +# modified by hartsantler 2014 + +from time import time + +DEFAULT_ARG = 9 + +def main(): + if PYTHON=='PYTHONJS': + pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_keys=True ) + pass + + times = [] + for i in range(4): + t0 = time() + #res = fannkuch(DEFAULT_ARG) + res = fannkuch(8) + tk = time() + times.append(tk - t0) + avg = sum(times) / len(times) + print(avg) + +def fannkuch(n): + count = range(1, n+1) + max_flips = 0 + m = n-1 + r = n + check = 0 + perm1 = range(n) + perm = range(n) + #perm1_ins = perm1.insert + #perm1_pop = perm1.pop + if PYTHON=='PYTHON3': + count = list(count) + perm1 = list(perm1) + perm = list(perm) + + while True: + if check < 30: + check += 1 + + while r != 1: + count[r-1] = r + r -= 1 + + if perm1[0] != 0 and perm1[m] != m: + perm = perm1[:] + flips_count = 0 + k = perm[0] + #while k: ## TODO fix for dart + while k != 0: + perm[:k+1] = perm[k::-1] + flips_count += 1 + k = perm[0] + + if flips_count > max_flips: + max_flips = flips_count + + while r != n: + #perm1_ins(r, perm1_pop(0)) + perm1.insert(r, perm1.pop(0)) + count[r] -= 1 + if count[r] > 0: + break + r += 1 + else: + return max_flips + + diff --git a/regtests/bench/float.py b/regtests/bench/float.py index ded3ece..f3869e2 100644 --- a/regtests/bench/float.py +++ b/regtests/bench/float.py @@ -6,8 +6,10 @@ from math import sin, cos, sqrt def main(): - if PYTHON=='PYTHONJS': ## about 25% faster with normal and javascript backends + if PYTHON=='PYTHONJS': pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_operator='*' ) + pythonjs.configure( direct_keys=True ) pass times = test( 3 ) diff --git a/regtests/bench/mandelbrot.py b/regtests/bench/mandelbrot.py new file mode 100644 index 0000000..9692a91 --- /dev/null +++ b/regtests/bench/mandelbrot.py @@ -0,0 +1,60 @@ +"""mandelbrot benchmark""" +from time import time + +def pprint(arr, w): + x = [] + for a in arr: + x.append(a) + if len(x) >= w: + print( [ round(y,2) for y in x] ) + x = [] + +def mandelbrot_numpy(size=512, exit_limit=100): + img_array = numpy.zeros([size, size], int) + for y in range(size): + for x in range(size): + c = complex(x / float(size) * 4 - 2, + y / float(size) * 4 - 2) + z = c + for i in range(exit_limit): + z = (z**2) + c + img_array[y, x] += 1 + if abs(z) > 2: + # z is escaping to infinity, so point is not in set + break + else: + # if loop is exausted, point is inside the set + img_array[y, x] = 0 + return img_array + + +def main(): + + @returns( array=[512,512] ) + @typedef( x=float, y=float, tempX=float, i=int, runaway=int, c=vec2) + @gpu.main + def gpufunc(): + c = get_global_id() + x = 0.0 + y = 0.0 + tempX = 0.0 + i = 0 + runaway = 0 + for i in range(100): + tempX = x * x - y * y + float(c.x) + y = 2.0 * x * y + float(c.y) + x = tempX + if runaway == 0 and x * x + y * y > 100.0: + runaway = i + + return float(runaway) * 0.01 + + start = time() + + if PYTHON == 'PYTHONJS': + res = gpufunc() + #pprint(res, 32) + else: + res = mandelbrot_numpy() + + print(time()-start) diff --git a/regtests/bench/nbody.py b/regtests/bench/nbody.py index 3735526..8f9a843 100644 --- a/regtests/bench/nbody.py +++ b/regtests/bench/nbody.py @@ -9,8 +9,10 @@ def main(): - if PYTHON=='PYTHONJS': - pythonjs.configure( direct_operator='+' ) ## about 25% faster with normal and javascript backends + if PYTHON=='PYTHONJS': + pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_operator='*' ) + pythonjs.configure( direct_keys=True ) pass times = test_nbody( 3 ) diff --git a/regtests/bench/new_list.py b/regtests/bench/new_list.py new file mode 100644 index 0000000..316466c --- /dev/null +++ b/regtests/bench/new_list.py @@ -0,0 +1,23 @@ +'''new list micro benchmark''' + +from time import time + +def main(): + if PYTHON=='PYTHONJS': + pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_keys=True ) + pass + + times = [] + a = [] + for i in range(10): + t0 = time() + for j in range(100000): + b = [1,2,3,4,5,6,7,8,9] + a.append( b ) + tk = time() + times.append(tk - t0) + avg = sum(times) / len(times) + print(avg) + + diff --git a/regtests/bench/pystone.py b/regtests/bench/pystone.py index dfd4b8a..bea191e 100644 --- a/regtests/bench/pystone.py +++ b/regtests/bench/pystone.py @@ -9,8 +9,9 @@ def main(): LOOPS = 100000 if PYTHON=='PYTHONJS': - pythonjs.configure( direct_operator='+' ) ## about 25% faster with normal and javascript backends - #pythonjs.configure( inline=True ) ## TODO fix dart backend + pythonjs.configure( direct_operator='+' ) + pythonjs.configure( direct_operator='*' ) + pythonjs.configure( direct_keys=True ) pass a = pystones( LOOPS ) benchtime = a[0] @@ -68,10 +69,6 @@ def create_array2glob(n): - - - - def Proc0(loops): global IntGlob global BoolGlob diff --git a/regtests/bench/simd_float32vec.py b/regtests/bench/simd_float32vec.py new file mode 100644 index 0000000..60b77ac --- /dev/null +++ b/regtests/bench/simd_float32vec.py @@ -0,0 +1,30 @@ +"""simd float32vec micro benchmark""" +from time import time +from random import random + +## SIMD in dart broken down into multiple float32x4 instances, with multiply implemented by looping +## over each element is slower than CPython with NumPy for an array larger than 32 elements. +## 64 elements runs about half the speed of NumPy in CPython. + +def main(): + ARRAY_SIZE = 32 ## note, size must be divisible by 4 + x = [] + y = [] + z = [] + for i in range( ARRAY_SIZE ): + x.append( random()+0.5 ) + y.append( random()+0.5 ) + z.append( random()+0.5 ) + + a = numpy.array( x, dtype=numpy.float32 ) + b = numpy.array( y, dtype=numpy.float32 ) + c = numpy.array( z, dtype=numpy.float32 ) + + ## start benchmark + start = time() + + arr = [] + for i in range(20000): + arr.append( a*b*c ) + + print(time()-start) \ No newline at end of file diff --git a/regtests/bench/simd_float32x4.py b/regtests/bench/simd_float32x4.py new file mode 100644 index 0000000..940f022 --- /dev/null +++ b/regtests/bench/simd_float32x4.py @@ -0,0 +1,15 @@ +"""simd float32x4 micro benchmark""" +from time import time + +def main(): + start = time() + float32x4 a = numpy.array( [1.0001, 1.0002, 1.0003, 1.0004], dtype=numpy.float32 ) + float32x4 b = numpy.array( [1.00009, 1.00008, 1.00007, 1.00006], dtype=numpy.float32 ) + float32x4 c = numpy.array( [1.00005, 1.00004, 1.00003, 1.00002], dtype=numpy.float32 ) + + arr = [] + for i in range(20000): + c *= a*b + arr.append( a*b*c ) + + print(time()-start) \ No newline at end of file diff --git a/regtests/bench/webclgl_array_mult.py b/regtests/bench/webclgl_array_mult.py new file mode 100644 index 0000000..868b5fc --- /dev/null +++ b/regtests/bench/webclgl_array_mult.py @@ -0,0 +1,36 @@ +"""big array mult""" +from time import time +from random import random + +ARRAY_SIZE = 1024*1024*4 + +@returns( array=ARRAY_SIZE ) +@gpu.main +def myfunc(A, B, C, D): + float* A + float* B + float* C + float* D + vec2 n = get_global_id() ## WebCL API + return A[n] * B[n] * C[n] * D[n] + +def main(): + + a = [ random() for i in range(ARRAY_SIZE)] + b = [ random() for i in range(ARRAY_SIZE)] + c = [ random() for i in range(ARRAY_SIZE)] + d = [ random() for i in range(ARRAY_SIZE)] + + if PYTHON=='PYTHONJS': + start = time() + res = myfunc( a,b,c,d ) + #print(res) + print( time()-start ) + else: + a = numpy.array(a, dtype=numpy.float32 ) + b = numpy.array(b, dtype=numpy.float32 ) + c = numpy.array(c, dtype=numpy.float32 ) + d = numpy.array(d, dtype=numpy.float32 ) + start = time() + res = a * b * c * d + print( time()-start ) diff --git a/regtests/calling/function_expression.py b/regtests/calling/function_expression.py new file mode 100644 index 0000000..9c12bc7 --- /dev/null +++ b/regtests/calling/function_expression.py @@ -0,0 +1,8 @@ +"""func expr""" + +F = function( x,y ): + return x+y + +def main(): + TestError( F(1,2) == 3 ) + diff --git a/regtests/calling/inline_def.py b/regtests/calling/inline_def.py new file mode 100644 index 0000000..431ffca --- /dev/null +++ b/regtests/calling/inline_def.py @@ -0,0 +1,14 @@ +"""inline def""" + +def test( callback1=None, callback2=None ): + return {'cb1': callback1, 'cb2': callback2 } + +def main(): + o = test( callback1=def (x,y): + return x+y, + callback2 = def (x): + return x*2 + ) + TestError( o['cb1'](1,2) == 3 ) + TestError( o['cb2'](100) == 200 ) + diff --git a/regtests/calling/variable_kwargs_class.py b/regtests/calling/variable_kwargs_class.py new file mode 100644 index 0000000..dff64f9 --- /dev/null +++ b/regtests/calling/variable_kwargs_class.py @@ -0,0 +1,11 @@ +"""variable keywords""" +class A: + def f2(self, **kw): + a = 0 + for key in kw: + a += kw[key] + return a + +def main(): + a = A() + TestError( a.f2(x=1,y=2) == 3 ) \ No newline at end of file diff --git a/regtests/calling/variable_kwargs_class_init.py b/regtests/calling/variable_kwargs_class_init.py new file mode 100644 index 0000000..8086762 --- /dev/null +++ b/regtests/calling/variable_kwargs_class_init.py @@ -0,0 +1,11 @@ +"""variable keywords""" +class A: + def __init__(self, **kw): + a = 0 + for key in kw: + a += kw[key] + self.value = a + +def main(): + a = A(x=1,y=2) + TestError( a.value == 3 ) \ No newline at end of file diff --git a/regtests/class/__add__.py b/regtests/class/__add__.py new file mode 100644 index 0000000..075d401 --- /dev/null +++ b/regtests/class/__add__.py @@ -0,0 +1,15 @@ +"""custom addition""" + +class A: + def __init__(self): + self.x = 5 + def __add__(self, other): + return self.x + other.x + + +def main(): + a = A() + b = A() + c = a + b + TestError( c == 10 ) + diff --git a/regtests/class/__call__.py b/regtests/class/__call__.py new file mode 100644 index 0000000..5f03499 --- /dev/null +++ b/regtests/class/__call__.py @@ -0,0 +1,13 @@ +"""custom callable""" + +class A: + def __init__(self): + self.x = 5 + def __call__(self): + return 'XXX' + + +def main(): + a = A() + TestError(a.x == 5) + TestError( a()=='XXX' ) \ No newline at end of file diff --git a/regtests/class/__mul__.py b/regtests/class/__mul__.py new file mode 100644 index 0000000..1890efe --- /dev/null +++ b/regtests/class/__mul__.py @@ -0,0 +1,15 @@ +"""custom multiplication""" + +class A: + def __init__(self): + self.x = 5 + def __mul__(self, other): + return self.x * other.x + + +def main(): + a = A() + b = A() + c = a * b + TestError( c == 25 ) + diff --git a/regtests/class/init_keyword.py b/regtests/class/init_keyword.py new file mode 100644 index 0000000..3a01559 --- /dev/null +++ b/regtests/class/init_keyword.py @@ -0,0 +1,11 @@ +''' +test __init__ with keyword arg +''' + +def main(): + class Cell: + def __init__(self, x=1): + self.x = x + + a = Cell(x=2) + TestError(a.x == 2) \ No newline at end of file diff --git a/regtests/class/mi.py b/regtests/class/mi.py index 0b96290..5c1a591 100644 --- a/regtests/class/mi.py +++ b/regtests/class/mi.py @@ -2,21 +2,21 @@ multiple inheritance ''' class A: - def foo(self): + def foo(self) -> int: return 1 class B: - def bar(self): + def bar(self) -> int: return 2 class C( A, B ): - def call_foo_bar(self): + def call_foo_bar(self) -> int: a = self.foo() a += self.bar() return a ## extend foo ## - def foo(self): + def foo(self) -> int: a = A.foo(self) a += 100 return a diff --git a/regtests/class/mi_override.py b/regtests/class/mi_override.py new file mode 100644 index 0000000..d36fb6f --- /dev/null +++ b/regtests/class/mi_override.py @@ -0,0 +1,32 @@ +''' +multiple inheritance +''' +class A: + def foo(self) -> int: + return 1 + +class B: + def bar(self) -> int: + return 2 + +class C( A, B ): + def call_foo_bar(self) -> int: + a = self.foo() + a += self.bar() + return a + + ## override foo ## + def foo(self) -> int: + return 100 + +def main(): + a = A() + TestError( a.foo()==1 ) + b = B() + TestError( b.bar()==2 ) + + c = C() + TestError( c.foo()==100 ) + TestError( c.bar()==2 ) + + TestError( c.call_foo_bar()==102 ) diff --git a/regtests/dict/dict_inline_def.py b/regtests/dict/dict_inline_def.py new file mode 100644 index 0000000..e4ad9cb --- /dev/null +++ b/regtests/dict/dict_inline_def.py @@ -0,0 +1,17 @@ +"""dict inline def""" + + +def main(): + + d = { 'callback': def (x,y): + return x+y + } + TestError( d['callback'](1,2) == 3 ) + + a = { 'cb1': def (x,y): + return x+y, + 'cb2' : def (x): + return x*2 + } + TestError( a['cb1'](1,2) == 3 ) + TestError( a['cb2'](100) == 200 ) diff --git a/regtests/dict/keys.py b/regtests/dict/keys.py index d47bca9..c7ccdf6 100644 --- a/regtests/dict/keys.py +++ b/regtests/dict/keys.py @@ -4,4 +4,3 @@ def main(): a = {'foo':'bar'} keys = a.keys() TestError( 'foo' in keys ) - diff --git a/regtests/dict/tuple_keys.py b/regtests/dict/tuple_keys.py new file mode 100644 index 0000000..7d3dea0 --- /dev/null +++ b/regtests/dict/tuple_keys.py @@ -0,0 +1,34 @@ +"""dict tuple key""" + +class A: pass +class B: + def __init__(self): + pass + +def main(): + s = ("1", "2", "3") + a = (1,2,3) + b = (1,2,3) + c = ( a, b, 'XXX' ) + d = ('1', 2, 3) + + D = { d:100, s: 11, a: 22, c:44 } + TestError( D[ d ] == 100) + TestError( D[ s ] == 11) + TestError( D[ a ] == 22) + TestError( D[ b ] == 22) + TestError( D[ c ] == 44) + + aa = A() + bb = B() + ab = ( A(), B() ) + D2 = { aa: 'hello', bb: 'world', ab:'XXX' } + TestError( D2[aa]=='hello' ) + TestError( D2[bb]=='world' ) + TestError( D2[ab]=='XXX') + + r = { s:1, a:aa } + r2 = {} + for x in [ s, a ]: + r2[ x ] = r[ x ] + TestError( r[s] is r2[s] ) \ No newline at end of file diff --git a/regtests/exceptions/AttributeError.py b/regtests/exceptions/AttributeError.py new file mode 100644 index 0000000..bb302ae --- /dev/null +++ b/regtests/exceptions/AttributeError.py @@ -0,0 +1,13 @@ +"""catch AttributeError""" + +class A: pass + +def main(): + a = A() + b = False + try: + b = a.xxx + except AttributeError: + b = True + + TestError( b == True ) diff --git a/regtests/exceptions/KeyError.py b/regtests/exceptions/KeyError.py new file mode 100644 index 0000000..f48ec0d --- /dev/null +++ b/regtests/exceptions/KeyError.py @@ -0,0 +1,11 @@ +"""catch KeyError""" + +def main(): + D = {} + a = False + try: + a = D['XXX'] + except KeyError: + a = True + + TestError( a == True ) diff --git a/regtests/go/arrays.py b/regtests/go/arrays.py new file mode 100644 index 0000000..76d84e5 --- /dev/null +++ b/regtests/go/arrays.py @@ -0,0 +1,22 @@ +"""array types""" + +def main(): + a = []int(1,2,3) + TestError( a[0]==1 ) + TestError( len(a)==3 ) + + b = [2]int(100,200) + TestError( b[0]==100 ) + TestError( b[1]==200 ) + + c = a[:2] + TestError( len(c)==2 ) + + d = range(10) + TestError(len(d)==10) + + #e = range(2,10) + #TestError(len(e)==8) + + #f = range(2,10, 2) + #TestError(len(f)==4) diff --git a/regtests/go/chan-transfer-speed.py b/regtests/go/chan-transfer-speed.py new file mode 100644 index 0000000..9b0c7fb --- /dev/null +++ b/regtests/go/chan-transfer-speed.py @@ -0,0 +1,107 @@ +# based on the go test by Dennis Francis +# https://github.com/dennisfrancis/gopherjs-channeltransfer-speed + + +import "github.com/gopherjs/gopherjs/js" + + +data_chan = go.channel(int) + +document = js.Global.Get("document") + +def main(): + js.Global.Get("window").Set("onload", setup) + +def setup(): + + go( receive() ) + bt = document.Call("getElementById", "startbt") + bt.Set("onclick", runtests) + + +def runtests(): + var bt = document.Call("getElementById", "startbt") + bt.Set("disabled", true) + + #go func() { + # test_calldepth() + # test_localmem() + #}() + + go( test_calldepth() ) + go( test_localmem() ) + + +def test_calldepth(): + + latency = go.make([]float64, 1000) + perf = js.Global.Get("performance") + #for cd := 1; cd <= 1000; cd++ { + for cd in range(1, 1000): + t0 = perf.Call("now").Float() + #for ii:=0; ii<50; ii++ { + for ii in range(50): + send_func(cd, 1, ii) + t1 = perf.Call("now").Float() + latency[cd-1] = (t1 - t0)/50.0 + print("test1 calldepth =", cd) + plot("ctsgraph1", latency, "Call depth", "Variation of Kilo Channel Transfers per second (KCTps) with call depth") + +def test_localmem(): + + latency = go.make([]float64, 1000) + perf = js.Global.Get("performance") + #for varsz := 1; varsz <= 1000; varsz++ { + for varsz in range(1, 1000): + t0 = perf.Call("now").Float() + #for ii:=0; ii<50; ii++ { + for ii in range(50): + send_func(1, varsz, ii) + + t1 = perf.Call("now").Float() + latency[varsz-1] = (t1 - t0)/50.0 + plot("ctsgraph2", latency, "Local variable size", "Variation of Kilo Channel Transfers per second (KCTps) with local variable size") + + +def plot(id:string, latency:[]float64, xlabel:string, title:string ): + + div = document.Call("getElementById", id) + #options = map[string]interface{}{ + options = map[string]interface{ + #"legend" : "always", + "title" : title, + "showRoller" : true, + "rollPeriod" : 1, + "ylabel" : "KCTps", + "labels" : []string("x", "CTS"), + } + + data = go.make([][]float64, len(latency)) + + #for rowid := 0; rowid < len(latency); rowid++ { + for rowid in range(len(latency)): + data[rowid] = []float64( + float64(rowid + 1), + 1.0/latency[rowid] + ) + + + js.Global.Get("Dygraph").New(div, data, options) + + +def send_func(call_depth:int, varsize:int, data:int ): + locvar = go.make([]int, varsize) + + if call_depth <= 1: + data_chan <- data + return + + send_func(call_depth-1, varsize, data) + + print(locvar) + +def receive(): + int data = 0 + while True: + data = <-data_chan + print("Received data =", data) diff --git a/regtests/go/chan.py b/regtests/go/chan.py new file mode 100644 index 0000000..fdf6e02 --- /dev/null +++ b/regtests/go/chan.py @@ -0,0 +1,16 @@ +"""send int over channel""" + +def wrapper(a:int, c: chan int): + result = 100 + c <- result + +def main(): + c = go.channel(int) + + go( wrapper(17, c) ) + + # Do other work in the current goroutine until the channel has a result. + + x = <-c + print(x) + TestError(x==100) diff --git a/regtests/go/class.py b/regtests/go/class.py new file mode 100644 index 0000000..316ca2f --- /dev/null +++ b/regtests/go/class.py @@ -0,0 +1,31 @@ +''' +simple class +''' +class A: + { + x:int, + y:int, + z:int, + } + def __init__(self, x:int, y:int, z:int=1): + self.x = x + self.y = y + self.z = z + + def mymethod(self, m:int) -> int: + return self.x * m + +def call_method( cb:func(int)(int), mx:int ) ->int: + return cb(mx) + +def main(): + a = A( 100, 200, z=9999 ) + print( a.x ) + print( a.y ) + print( a.z ) + + b = a.mymethod(3) + print( b ) + + c = call_method( a.mymethod, 4 ) + print( c ) \ No newline at end of file diff --git a/regtests/go/func_calls.py b/regtests/go/func_calls.py new file mode 100644 index 0000000..bfcd797 --- /dev/null +++ b/regtests/go/func_calls.py @@ -0,0 +1,20 @@ +"""function call""" +def f(a:int, b:int, c:int) ->int: + return a+b+c + +def f2(a:int=1, b:int=2, c:int=3) ->int: + return a+b+c + +def f3( *args:int ) ->int: + return args[0] + args[1] + args[2] + + +def main(): + TestError( f(1,2,3) == 6) + + x = f2( b=100 ) + TestError(x==104) + + arr = [1,2,3] + y = f3( *arr ) + TestError( y==6 ) \ No newline at end of file diff --git a/regtests/go/list_comprehension.py b/regtests/go/list_comprehension.py new file mode 100644 index 0000000..75c7f7a --- /dev/null +++ b/regtests/go/list_comprehension.py @@ -0,0 +1,11 @@ +''' +go list comprehensions +''' + +def main(): + a = []int(x for x in range(3)) + + TestError( len(a)==3 ) + TestError( a[0]==0 ) + TestError( a[1]==1 ) + TestError( a[2]==2 ) diff --git a/regtests/go/loop_arrays.py b/regtests/go/loop_arrays.py new file mode 100644 index 0000000..b1ec850 --- /dev/null +++ b/regtests/go/loop_arrays.py @@ -0,0 +1,34 @@ +''' +array loop +''' + +def main(): + + a = [1,2,3] + y = 0 + for x in a: + y += x + TestError( y==6 ) + + z = '' + arr = ['a', 'b', 'c'] + for v in arr: + z += v + TestError( z == 'abc' ) + + b = 0 + for i in range(10): + b += 1 + TestError( b == 10 ) + + c = '' + d = 0 + for i,v in enumerate(arr): + c += v + d += i + TestError( c == 'abc' ) + + e = 0 + for i in range( len(arr) ): + e += 1 + TestError( e == 3 ) diff --git a/regtests/go/loop_map.py b/regtests/go/loop_map.py new file mode 100644 index 0000000..403647d --- /dev/null +++ b/regtests/go/loop_map.py @@ -0,0 +1,14 @@ +''' +map loop +''' + +def main(): + a = {'x':100, 'y':200} + b = '' + c = 0 + for key,value in a: + b += key + c += value + + print( b ) + print( c ) \ No newline at end of file diff --git a/regtests/go/maps.py b/regtests/go/maps.py new file mode 100644 index 0000000..23248a3 --- /dev/null +++ b/regtests/go/maps.py @@ -0,0 +1,24 @@ +"""map types""" + +def main(): + a = map[string]int{ + 'x': 1, + 'y': 2, + 'z': 3, + } + + #print( a['x'] ) + TestError( a['x']==1 ) + + b = map[int]string{ 0:'a', 1:'b' } + #print( b[0] ) + #print( b[1] ) + TestError( b[0]=='a' ) + TestError( b[1]=='b' ) + + c = {'x':100, 'y':200} + #print( c['x'] ) + #print( c['y'] ) + + TestError( c['x']==100 ) + TestError( c['y']==200 ) diff --git a/regtests/go/print.py b/regtests/go/print.py new file mode 100644 index 0000000..363f081 --- /dev/null +++ b/regtests/go/print.py @@ -0,0 +1,4 @@ +"""hello world""" + +def main(): + print "hi" diff --git a/regtests/go/select.py b/regtests/go/select.py new file mode 100644 index 0000000..6bcb8fe --- /dev/null +++ b/regtests/go/select.py @@ -0,0 +1,43 @@ +"""go select""" + +def send_data( A:chan int, B:chan int, X:int, Y:int): + while True: + print('sending data..') + A <- X + B <- Y + +def select_loop(A:chan int, B:chan int, W:chan int) -> int: + print('starting select loop') + y = 0 + while True: + print('select loop:',y) + select: + case x = <- A: + y += x + W <- y + case x = <- B: + y += x + W <- y + print('end select loop', y) + return y + +def main(): + a = go.channel(int) + b = go.channel(int) + w = go.channel(int) + + go( + select_loop(a,b, w) + ) + + + go( + send_data(a,b, 5, 10) + ) + + z = 0 + while z < 100: + z = <- w + print('main loop', z) + + print('end test') \ No newline at end of file diff --git a/regtests/go/subclass.py b/regtests/go/subclass.py new file mode 100644 index 0000000..69e87b9 --- /dev/null +++ b/regtests/go/subclass.py @@ -0,0 +1,43 @@ +''' +simple class +''' +class A: + { + x:int, + y:int, + z:int, + } + def __init__(self, x:int, y:int, z:int=1): + self.x = x + self.y = y + self.z = z + + def mymethod(self, m:int) -> int: + return self.x * m + +class B(A): + { + w:string + } + + def method2(self, v:string) ->string: + self.w = v + return self.w + +def call_method( cb:func(int)(int), mx:int ) ->int: + return cb(mx) + +def main(): + a = A( 100, 200, z=9999 ) + print( a.x ) + print( a.y ) + print( a.z ) + + b = a.mymethod(3) + print( b ) + + c = call_method( a.mymethod, 4 ) + print( c ) + + x = B(1,2,z=3) + print( x.method2('hello world') ) \ No newline at end of file diff --git a/regtests/go/vars.py b/regtests/go/vars.py new file mode 100644 index 0000000..86c1722 --- /dev/null +++ b/regtests/go/vars.py @@ -0,0 +1,6 @@ +"""var assignment :=, and reassignment =""" + +def main(): + a = 1 + a = 2 + TestError( a==2 ) \ No newline at end of file diff --git a/regtests/html/date.html b/regtests/html/date.html new file mode 100644 index 0000000..97b3f50 --- /dev/null +++ b/regtests/html/date.html @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/regtests/html/dddom.py b/regtests/html/dddom.py new file mode 100644 index 0000000..0335b5e --- /dev/null +++ b/regtests/html/dddom.py @@ -0,0 +1,799 @@ +# PythonJS WebGL/CSS3D Hybrid Toolkit +# by Brett Hartshorn - copyright 2014 +# You may destribute this file using the "New BSD" or MIT license +# requires: Twitter Bootstrap and jQuery + +pythonjs.configure(javascript=True) + +def __setup_slider_class( $ ): + + def PPSliderClass(el, opts): + var element = $(el); + var options = opts; + var isMouseDown = false; + var currentVal = 0; + + element.wrap('
') + var container = $(el).parent(); ## this requires that the slider html element has a parent + + container.addClass('pp-slider'); + container.addClass('clearfix'); + + container.append('
-
+
'); + + #if (typeof(options) != 'undefined' && typeof(options.hideTooltip) != 'undefined' && options.hideTooltip == true) + #{ + # container.find('.pp-slider-tooltip').hide(); + #} + + if typeof(options.width) != 'undefined': + container.css('width',(options.width+'px')); + + container.find('.pp-slider-scale').css('width',(container.width()-30)+'px'); + + def startSlide(e): + nonlocal isMouseDown, startMouseX, lastElemLeft + isMouseDown = true; + var pos = getMousePosition(e); + startMouseX = pos.x; + lastElemLeft = ($(this).offset().left - $(this).parent().offset().left); + updatePosition(e); + return False + + def getMousePosition(e): + var posx = 0; + var posy = 0; + if not e: e = window.event; + if (e.pageX or e.pageY): + posx = e.pageX; + posy = e.pageY; + elif (e.clientX or e.clientY): + posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + + return { 'x': posx, 'y': posy } + + def updatePosition(e): + var pos = getMousePosition(e); + var spanX = (pos.x - startMouseX); + var newPos = (lastElemLeft + spanX) + var upperBound = (container.find('.pp-slider-scale').width()-container.find('.pp-slider-button').width()); + newPos = Math.max(0,newPos); + newPos = Math.min(newPos,upperBound); + currentVal = Math.round((newPos/upperBound)*100,0); + container.find('.pp-slider-button').css("left", newPos); + container.find('.pp-slider-tooltip').html(currentVal+'%'); + container.find('.pp-slider-tooltip').css('left', newPos-6); + if typeof(options.onInput) == 'function': + options.onInput( newPos/upperBound ) + + def moving(e): + if isMouseDown: + updatePosition(e); + return False + + def dropCallback(e): + nonlocal isMouseDown + isMouseDown = False + element.val(currentVal); + if typeof(options.onChanged) == 'function': + options.onChanged.call(this, null); + + container.find('.pp-slider-button').bind('mousedown',startSlide); + + $(document).mousemove( lambda e: moving(e) ) + $(document).mouseup( lambda e: dropCallback(e) ) + + if options.value: + w = container.find('.pp-slider-scale').width()-container.find('.pp-slider-button').width() + container.find('.pp-slider-button').css( + "left", + w * options.value + ) + + + def __init__(options): + var opts = $.extend({}, $.fn.PPSlider.defaults, options); + return this.each( lambda: new PPSliderClass($(this), opts) ) + $.fn.PPSlider = __init__ + + $.fn.PPSlider.defaults = { + 'width': 300 + }; + +__setup_slider_class( jQuery ) + +__sid = 0 + +class TabMenuWrapper: + ## provides a workaround for bootstrap failing to update the active page when a tab is clicked + def __init__(self, manager): + self.manager = manager + self.root = document.createElement('div') + self.root.setAttribute('class', 'tabbable tabs-left') + self.tabs = document.createElement('ul') + self.tabs.setAttribute('class', 'nav nav-tabs') + self.root.appendChild( self.tabs ) + #container.appendChild( menu ) + + self.pages_container = document.createElement('div') + self.pages_container.id = '_' + manager.newid() ## scroll bars will show on this div + self.pages_container.setAttribute('class', 'tab-content') + self.root.appendChild( self.pages_container ) + + ## setting the tab page container to 100% width and height breaks twitter-bootstrap + #self.pages_container.style.width = '100%' + #self.pages_container.style.height = '100%' + ## for some reason, bootstrap appears to do something "funky" on the tab-content div, + ## `scrollTop` can be read on the source tab-content div, but not written to the clone. + + ## this cheat will not work either, scrollTop on the clone is readonly and zero ## + #def onscroll(evt): + # print(this.scrollTop) + # if this._clone: + # print(this._clone) + # this._clone.scrollTop = this.scrollTop + #self.pages_container.onscroll = onscroll + + ## workaround to disable scrollbars + self.pages_container.style.overflow = 'hidden' + + + self._tab_pages = [] + + + def add_tab(self, tabname): + + tab = document.createElement('li') + taba = document.createElement('a') + #taba.setAttribute('href', '#'+tabid) ## not required + taba.setAttribute('data-toggle', 'tab') + + tab.appendChild( taba ) + self.tabs.appendChild( tab ) + taba.appendChild( document.createTextNode(tabname) ) + + + page = document.createElement('div') + a = 'tab-pane' + if len(self._tab_pages)==0: a += ' active' + page.setAttribute('class', a) + + #page.setAttribute('id', self.manager.newid() ) ## required to sync scrollbars + + self.pages_container.appendChild( page ) + self._tab_pages.append( page ) + + ## TODO force page to be full size, or sync scroll bars + page.style.width = '100%' ## this fails to force the window to resize + page.style.height = '100%' + + _tab_pages = self._tab_pages + def clicktab(): + for other in _tab_pages: + other.setAttribute('class', 'tab-pane') + this._tab_page.setAttribute('class', 'tab-pane active') + + taba._tab_page = page + taba.onclick = clicktab + + return page + + + +def create_slider(value, onchange=None, width=200): + slider = document.createElement('input') + + ## the native slider looks different on each platform, + ## and it is not clickable, because the camera controls preventDefault? + ## however, if focused the keyboard arrow keys, can still change the slider values. + ## to be safe, instead of using a native slider, we use the custom jquery/css slider. + ##slider.setAttribute('type', 'range') ## do not use native slider + #slider.setAttribute('min', 0) + #slider.setAttribute('max', 100) + #slider.setAttribute('step', 1) + #slider.setAttribute('value', 100) + + slider.setAttribute('type', 'hidden') + #$("#"+id).PPSlider( width=300, onInput=onchange, value=value ) + + div = document.createElement('div') ## a parent container is required + div.appendChild( slider ) + $( slider ).PPSlider( width=width, onInput=onchange, value=value ) + + slider.onclick = lambda : slider.focus() + + return div + +def create_textarea(): + global __sid + __sid += 1 + ta = document.createElement('textarea') + ta.setAttribute('id', '__sid'+__sid) + def func(): ta.focus() ## this allows normal keyboard input + ta.onclick = func + ta.style.backgroundColor = 'black' + ta.style.color = 'green' + ta.style.fontWeight = 'bold' + ta.setAttribute('class', 'focused alert alert-info') + return ta + +def create_checkbox( checked, onchange=None ): + ## no special hacks required for checkboxes ## + c = document.createElement('input') + c.setAttribute('type', 'checkbox') + if checked: c.setAttribute('checked', 'true') + if onchange: c.onchange = onchange + return c + +def create_number_input(value, step=1, onchange=None): + input = document.createElement('input') + input.setAttribute('type', 'number') + input.setAttribute('step', step) + input.value = value + input.style.width = 64 + input.style.height = 32 + input.onclick = lambda : this.focus() + if onchange: input.onchange = onchange + return input + +def create_float_input(value, step=0.01, onchange=None): + input = document.createElement('input') + input.setAttribute('type', 'number') + input.setAttribute('step', step) + input.value = value + input.style.width = 64 + input.style.height = 32 + input.onclick = lambda : this.focus() + if onchange: input.onchange = onchange + return input + + +def create_dropdown_button( name, options ): + div = document.createElement('div') + div.setAttribute('class', 'btn-group') + + b = document.createElement('button') + b.setAttribute('class', 'btn dropdown-toggle') + b.setAttribute('data-toggle', 'dropdown') + caret = document.createElement('span') + caret.setAttribute('class', 'caret') + b.appendChild( document.createTextNode(name)) + b.appendChild(caret) + + ## the darkstrap css fails to properly expand the options, + ## TODO - fix darkstrap or convert this to a 3D dropdown. + ul = document.createElement('ul') + ul.setAttribute('class', 'dropdown-menu') + for opt in options: + li = document.createElement('li') + a = document.createElement('a') + a.appendChild( document.createTextNode(opt) ) + li.appendChild( a ) + ul.appendChild( li ) + + div.appendChild(b) + div.appendChild(ul) + return div + + +CLICKABLES = [] +class SelectManager: + def __init__(self, camera): + self.camera = camera + document.addEventListener('mouseup', self.on_mouse_up.bind(self), false) + + def on_mouse_up(self, evt): + x = ( event.clientX / window.innerWidth ) * 2 - 1; + y = - ( event.clientY / window.innerHeight ) * 2 + 1; + vector = new THREE.Vector3( x, y, 0.5 ); + projector = new THREE.Projector(); + projector.unprojectVector( vector, self.camera ); + raycaster = new THREE.Raycaster( self.camera.position, vector.sub( self.camera.position ).normalize() ); + intersects = raycaster.intersectObjects( CLICKABLES ); + #if intersects.length > 0: + # ob = intersects[0].object + for inter in intersects: + ob = inter.object + print(ob) + if hasattr(ob, 'onclick'): + ob.onclick( inter ) + + + +class Window3D: + def __init__(self, element, scene, shadow_scene, interact_scene, position, scale ): + ## required for select dropdowns because `selectedIndex` is not updated by `e.cloneNode()` ## + self._sid = 0 + self.interact_scene = interact_scene + self.shadow_scene = shadow_scene + self.object = object = new THREE.CSS3DObject( element ) + self.position = object.position + self.rotation = object.rotation + self.scale = object.scale + + self.shadow = new THREE.CSS3DObject( element.cloneNode() ) + self.element = element + self.active = False + self.collasped = False + + ## shadow_images is required because every frame the entire dom is cloned to be rendered under webgl layer, + ## image data is lazy loaded, so even if the image is shown on the top interactive layer and cloned, + ## it still takes time before the clone will lazy load the image data, + ## below shadow_images holds a mapping of url and image, these must be inserted into the cloned dom each update. + self.shadow_images = {} + self.clone_videos = {} + self._video_textures = [] ## list of : {texture, video, context} + self.clone_iframes = {} ## this will not work, iframes are not lazy in the same way as images and videos. + + self.dropdown = None + self._scrollbars = {} + + x,y,z = position + self.object.position.set(x,y,z+1) + self.shadow.position.set(x,y,z) + + x,y,z = scale + self.object.scale.set(x,y,z) + self.shadow.scale.set(x,y,z) + + shadow_scene.add( self.shadow ) + interact_scene.add( self.object ) + + self.root = new THREE.Object3D() + scene.add( self.root ) + + self.create_windowframe() + + def newid(self): + self._sid += 1 + return self._sid + + def create_tab_menu(self): + return TabMenuWrapper( self ) + + + def create_iframe( self, url, element ): + ## this currently only renders on the top layer transparent layer, + ## to make iframes visible the top layer needs to become semi-transparent or opaque. + ## `element` is the DOM element that will have its opacity adjusted on mouse enter/leave + iframe = document.createElement('iframe') + iframe.setAttribute('src', url) + iframe.style.width = '100%' + iframe.style.height = '100%' + iframe.style.border = 0 + self._sid += 1 + id = '__fid'+self._sid + iframe.setAttribute('id', id) + + def f1(evt): + print('mouse enter') + element.style.opacity = 0.8 + def f2(evt): + print('mouse leave') + element.style.opacity = 0.2 + iframe.onmouseenter = f1 + iframe.onmouseleave = f2 + + return iframe + + def create_video( self, mp4=None, ogv=None ): + self._sid += 1 + id = '__vid'+self._sid + v = document.createElement('video') + v.setAttribute('id', id) + #v.setAttribute('autoplay', 'true') ## this must not be set, otherwise the clone will also play + #v.setAttribute('style', "color: rgba(255, 255, 0, 1)") ## this will not work + #v.setAttribute('style', "opacity: 2") ## this will not work either + + ## for some reason play/pause can not be forced on the clone, + ## this might have something to do with the clone always being reparented. + #def onclick_not_working(evt): + # vclone = self.clone_videos[ id ] + # print(vclone) + # if vclone.paused: + # print('playing...') + # vclone.play() + # else: + # vclone.pause() + # print('pause!') + + def onclick(evt): + print('video clicked') + if v.paused: + print('playing...') + v.play() + else: + v.pause() + print('pause!') + + v.onclick = onclick.bind(self) + + def onmetaload(evt): + print('video metadata loaded...') + + image = document.createElement( 'canvas' ); + image.width = v.videoWidth; + image.height = v.videoHeight; + + imageContext = image.getContext( '2d' ); + imageContext.fillStyle = '#000000'; + imageContext.fillRect( 0, 0, v.videoWidth, v.videoHeight ); + + texture = new THREE.Texture( image ); + texture.minFilter = THREE.LinearFilter; + texture.magFilter = THREE.LinearFilter; + + material = new THREE.MeshBasicMaterial( map=texture, overdraw=true ) + #plane = new THREE.PlaneGeometry( v.videoWidth, v.videoHeight, 4, 4 ); + plane = new THREE.PlaneGeometry( 1, 1, 4, 4 ); + mesh = new THREE.Mesh( plane, material ); + H = v.videoHeight + X = v.offsetLeft / 2 + Y = ((self.element.clientHeight-H) / 2) - v.offsetTop + #mesh.position.x = v.offsetLeft ## TODO + mesh.position.y = Y + mesh.position.z = 1 + mesh.scale.x = v.videoWidth + mesh.scale.y = v.videoHeight + + self.root.add( mesh ) + + + self._video_textures.append( {'texture':texture, 'video':v, 'context':imageContext, 'image':image} ) + + + v.addEventListener('loadedmetadata', onmetaload.bind(self), false) + + if mp4: + s = document.createElement('source') + s.setAttribute('src', mp4) + s.setAttribute('type', 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"') + v.appendChild( s ) + if ogv: + s = document.createElement('source') + s.setAttribute('src', ogv) + s.setAttribute('type', 'video/ogg; codecs="theora, vorbis"') + v.appendChild( s ) + + return v + + + def display_dropdown(self, e, options): + if not self.dropdown: + self.create_dropdown( e, options ) + else: + self.object.remove( self.dropdown ) + self.shadow.remove( self.dropdown_clone ) + self.root.remove( self._ddmesh1 ) + self.root.remove( self._ddmesh2 ) + self.dropdown = None + + def hide_dropdown(self): ## not working, three.js bug? + self.dropdown.visible = false + self.dropdown_clone.visible = false + + + def create_dropdown(self, e, options): + #global sel, g + #g = e + sel = document.createElement('select') + sel.setAttribute('multiple', 'multiple') + self._sid += 1 + id = '_sid'+self._sid + sel.setAttribute('id', id) + self._scrollbars[ id ] = 0 + + + for i,opt in enumerate(options): + o = document.createElement('option') + o.setAttribute('index', i) + o.appendChild( document.createTextNode(opt) ) + sel.appendChild( o ) + + ##print('clientHeight', sel.clientHeight) + ## sel.clientHeight can not be used here because the dom has not been updated, + ## as a simple workaround guess height based on number of options, + ## this needs to be done anyways because `sel` must be given a height in pixels, + ## to force it to display all the options, and not display a scroll bar (which are not synced). + H = 12 * options.length + if H < 100: H = 100 + sel.style.height = int(H * 0.95) + X = e.offsetLeft / 2 + Y = ((self.element.clientHeight-H) / 2) - (e.offsetHeight + e.offsetTop) + + ## create dropdown css object and add it to self.object, + ## this makes it part of the interactive scene, + ## it is also needs its own shadow clone to be updated. + self.dropdown = new THREE.CSS3DObject( sel ) + self.object.add( self.dropdown ) + self.dropdown_clone = new THREE.CSS3DObject(sel.cloneNode()) + self.shadow.add( self.dropdown_clone ) + + self.dropdown.position.x = X + self.dropdown.position.y = Y + self.dropdown.position.z += 20 + self.dropdown_clone.position.copy( self.dropdown.position ) + self.dropdown_clone.position.z -= 1 + + sel.focus() # required? + + ## this is used to capture a click on the dropdown popup, and copy selectedIndex + ## from the clone to the source, and if the source has an onchange callback, call it. + def onclick(evt): + #sel.focus() ## this triggers a bug that offsets the interactive layer + print(evt.toElement.getAttribute('index')) + e.selectedIndex = sel.selectedIndex = int(evt.toElement.getAttribute('index')) + ## setting `selectedIndex` on the source e will not trigger its `onchange` callback to fire, + ## so call onchange directly. Note that the event `evt` from the clone is passed the source + ## as the first argument. end-user code inside e.onchange should not modify elements referenced in the event. + ## note that the calling context is set to the source by `e.onchange(evt)` so it is safe to use `this` + ## inside of onchange. + if e.onchange: + e.onchange( evt ) + sel.onclick = onclick + + def onscroll(evt): ## this hack is required to capture the scroll position + self.dropdown_clone.element.scrollTop = sel.scrollTop + sel.onscroll = onscroll.bind(self) + + geo = new THREE.BoxGeometry( 1.1, H*1.1, 3 ); + mat = new THREE.MeshBasicMaterial( {'color': 0x00ffff, 'transparent':true, 'opacity':0.18, 'blending':THREE.AdditiveBlending } ); + self._ddmesh1 = m = new THREE.Mesh( geo, mat ); + self.root.add( m ); + m.castShadow = true; + m.position.x = X + m.position.y = Y + m.position.y += 10 + m.position.z = 1 + m.scale.x = e.clientWidth + + geo = new THREE.BoxGeometry( 1.07, H, 3 ); + mat = new THREE.MeshBasicMaterial( {'color': 0xffffff, 'transparent':true, 'opacity':0.48, 'blending':THREE.SubtractiveBlending } ); + self._ddmesh2 = m = new THREE.Mesh( geo, mat ); + self.root.add( m ); + m.castShadow = true; + m.position.x = X + m.position.y = Y + m.position.y += 10 + m.position.z = 15 + m.scale.x = e.clientWidth + + + def create_select_dropdown(self, options ): + self._sid += 1 + a = document.createElement('select') + a.setAttribute('id', '_sid'+self._sid) + + def onclick(e): + a.focus() ## allows the enter key to display options + self.display_dropdown(a, options) + a.onclick = onclick.bind(self) + + for opt in options: + o = document.createElement('option') + o.appendChild(document.createTextNode(opt)) + a.appendChild(o) + + return a + + def hide_windowframe(self): + self.mask.visible = False + self.shaded_border.visible = False + self.glowing_border.visible = False + + def create_windowframe(self): + geo = new THREE.BoxGeometry( 1, 1, 1 ); + mat = new THREE.MeshBasicMaterial( color=0x000000, opacity=0 ) + mat.blending = THREE.NoBlending + self.mask = r = new THREE.Mesh( geo, mat ); + self.root.add( r ); + #r.position.copy( self.object.position ) + r.position.z -= 5 + + geo = new THREE.BoxGeometry( 0.7, 1, 20 ); + mat = new THREE.MeshPhongMaterial( {'color': 0xffffff, 'transparent':true, 'opacity':0.8, 'blending':THREE.AdditiveBlending } ); + self.shaded_border = m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.z -= 12 + m.castShadow = true; + m.receiveShadow = true; + + geo = new THREE.BoxGeometry( 1.1, 1.1, 1 ); + mat = new THREE.MeshBasicMaterial( {'color': 0x00ffff, 'transparent':true, 'opacity':0.18, 'blending':THREE.AdditiveBlending } ); + self.glowing_border = m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.z -= 2 + + geo = new THREE.BoxGeometry( 1.1, 1.1, 50 ); + mat = new THREE.MeshBasicMaterial( {'color': 0x00ffff, 'transparent':true, 'opacity':0.28, 'blending':THREE.AdditiveBlending, 'wireframe':true } ); + m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.z -= 40 + + + geo = new THREE.BoxGeometry( 0.025, 0.5, 30 ); + mat = new THREE.MeshPhongMaterial( {'color': 0xffffff } ); + self.right_bar = m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.y += 0.3 + m.position.x -= 0.55 + m.position.z -= 10 + m.castShadow = true; + CLICKABLES.append( m ) + def expand(inter): + self.expand() + m.onclick = expand.bind(self) + + geo = new THREE.BoxGeometry( 0.9, 0.1, 20 ); + mat = new THREE.MeshPhongMaterial( color=0xffff00, transparent=True, opacity=0.84 ); + self.footer = m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.y -= 0.6 + m.position.z -= 5 + m.castShadow = true; + CLICKABLES.append( m ) + + def clickfooter(inter): + self.active = True + if self.collasped: + self.expand() + m.onclick = clickfooter.bind(self) + + geo = new THREE.BoxGeometry( 0.2, 0.1, 10 ); + mat = new THREE.MeshPhongMaterial( {'color': 0xffff00 } ); + self.minimize_object = m = new THREE.Mesh( geo, mat ); + r.add( m ); + m.position.y += 0.8 + m.position.x += 0.45 + m.position.z -= 2 + m.castShadow = true; + CLICKABLES.append( m ) + def collaspe(inter): + self.collaspe() + m.onclick = collaspe.bind(self) + + def collaspe(self): + self.collasped = True + self.active = False + self.object.rotation.x = -Math.PI / 2 + self.object.position.y = 0 + + def expand(self): + self.collasped = False + self.active = True + self.object.rotation.x = 0 + + def spin90(self): + self.object.rotation.y += Math.PI / 2 + + def update(self): + if self.shadow.element.parentNode: + self.shadow.element.parentNode.removeChild( self.shadow.element ) + + if self.active and self.object.position.y < 400: + self.object.position.y += 10 + + self.root.position.copy( self.object.position ) + self.root.rotation.copy( self.object.rotation ) + + self.shadow.position.copy( self.object.position ) + self.shadow.rotation.copy( self.object.rotation ) + + w = self.element.clientWidth * 0.01 + h = self.element.clientHeight * 0.01 + + self.mask.scale.x = w*99 + self.mask.scale.y = h*99 + + ## this is just to display content, cloneNode(true) ensures deep copy + self.shadow.element = self.element.cloneNode(true) + + ## sync scrollbars of any div with an id, + ## note: this will not work with tab-content div's. + a = self.element.getElementsByTagName('DIV') + b = self.shadow.element.getElementsByTagName('DIV') + c = {} + for d in b: + if not d.id: continue + c[ d.id ] = d + + for d in a: + if not d.id: continue + clone = c[ d.id ] + #d._clone = clone ## no help for tab-content + if d.scrollTop: + clone.scrollTop = d.scrollTop + + ################################################ + + a = self.element.getElementsByTagName('SELECT') + b = self.shadow.element.getElementsByTagName('SELECT') + c = {} + for sel in b: + c[ sel.getAttribute('id') ] = sel + + for sel in a: + id = sel.getAttribute('id') + clone = c[ id ] + clone.selectedIndex = sel.selectedIndex + if sel.scrollTop: ## select `multiple` type boxes. (note: self.dropdown is not updated here) + clone.scrollTop = sel.scrollTop + + + a = self.element.getElementsByTagName('TEXTAREA') + b = self.shadow.element.getElementsByTagName('TEXTAREA') + c = {} + for sel in b: + c[ sel.getAttribute('id') ] = sel + + for sel in a: + c[ sel.getAttribute('id') ].value = sel.value + + + ## do not load iframes in the clone ## + iframes = self.shadow.element.getElementsByTagName('IFRAME') + for iframe in iframes: + iframe.src = None + + ## insert lazy loading iframes into shadow dom ## + ## it appears that this will not work, because when an iframe is reparented, + ## it triggers a reload of the iframe, there might be a way to cheat around this, + ## (possible workaround: block dom clone update until iframe has fully loaded) + ## but it would be better to have a different solution anyways that only single + ## renders the iframe - workaround: on mouse enter/leave adjust opacity of top css3d layer. + if False: + iframes = self.shadow.element.getElementsByTagName('IFRAME') + for frame in iframes: + #if frame.src in self.clone_iframes: + # lazy = self.clone_iframes[ frame.src ] + # frame.parentNode.replaceChild(lazy, frame) + if frame.getAttribute('srcHACK') in self.clone_iframes: + #lazy = self.clone_iframes[ frame.getAttribute('srcHACK') ] + #frame.parentNode.replaceChild(lazy, frame) + pass + else: + #self.clone_iframes[ frame.src ] = frame + iframe = document.createElement('iframe') + #iframe.setAttribute('src', frame.src) + #iframe.setAttribute('src', frame.getAttribute('srcHACK')) + #iframe.src = 'file://'+frame.getAttribute('srcHACK') + iframe.setAttribute('src','http://localhost:8000/') + iframe.style.width = '100%' + iframe.style.height = '100%' + iframe.style.zIndex = 100 + #self.clone_iframes[ frame.src ] = iframe + self.clone_iframes[ frame.getAttribute('srcHACK') ] = iframe + print('new iframe---') + print(iframe) + + + + + ## insert lazy loading images into shadow dom ## + images = self.shadow.element.getElementsByTagName('IMG') + for img in images: + if img.src in self.shadow_images: + lazy = self.shadow_images[ img.src ] + img.parentNode.replaceChild(lazy, img) + else: + self.shadow_images[ img.src ] = img + + ## this is still required because when the video lazy loads it sets + ## the proper size for the clone. + videos = self.shadow.element.getElementsByTagName('VIDEO') + for vid in videos: + id = vid.getAttribute('id') + if id in self.clone_videos: + lazy = self.clone_videos[ id ] + vid.parentNode.replaceChild(lazy, vid) + else: + #vid.setAttribute('autoplay', 'true') ## no help + #vid.play() ## no help + self.clone_videos[ id ] = vid + + for d in self._video_textures: + video = d['video'] + if video.readyState == video.HAVE_ENOUGH_DATA: + d['context'].drawImage( video, 0, 0 ) + d['texture'].needsUpdate = True diff --git a/regtests/html/three_basic_geoms.html b/regtests/html/three_basic_geoms.html new file mode 100644 index 0000000..6432a72 --- /dev/null +++ b/regtests/html/three_basic_geoms.html @@ -0,0 +1,91 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/regtests/html/three_catmull_clark.html b/regtests/html/three_catmull_clark.html new file mode 100644 index 0000000..3b5a5a4 --- /dev/null +++ b/regtests/html/three_catmull_clark.html @@ -0,0 +1,216 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/regtests/html/threepy.py b/regtests/html/threepy.py new file mode 100644 index 0000000..18de547 --- /dev/null +++ b/regtests/html/threepy.py @@ -0,0 +1,504 @@ +# Three.js HTML UI Generator +# by Brett Hartshorn - copyright 2014 +# You may destribute this file using the "New BSD" or MIT license + +pythonjs.configure(javascript=True) +from dddom import * ## provides Window3D and SelectManager + + +class Editor( Window3D ): + def __init__(self, engine, position=None): + element = document.createElement( 'div' ) + Window3D.__init__(self, element, engine.scene, engine.scene2, engine.scene3, position, [1,1,1] ) + element.setAttribute('class', 'well') + self.engine = engine + + b = document.createElement('button') + b.appendChild(document.createTextNode('run script')) + b.setAttribute('class', 'btn btn-inverse btn-small') + element.appendChild(b) + + opts = ['javascript', 'python'] + element.appendChild(document.createTextNode(' mode:')) + element.appendChild( self.create_select_dropdown(opts) ) + + element.appendChild(document.createElement('br')) + + con = document.createElement('div') + element.appendChild(con) + ta = create_textarea() + con.appendChild( ta ) + + def ondrop(evt): + print(evt) + evt.preventDefault() + if evt.dataTransfer.files.length==0: + url = evt.dataTransfer.getData("text/plain") + self.open_iframe(url) + else: + self.handle_drop_event(evt.dataTransfer.files) + + element.ondrop = ondrop.bind( self ) + element.ondragover = lambda evt: evt.preventDefault() + + + def onclick(evt): + eval( ta.value ) + b.onclick = onclick.bind(self) + + def open_iframe(self, url): + iframe = self.create_iframe( url, self.engine.renderer3.domElement ) + self.element.appendChild(iframe) + + def _gen_material_ui(self, model): + print(model.material) + div = document.createElement('div') + + ## Material.js + faceopts = ['FrontSide', 'BackSide', 'DoubleSide'] + div.appendChild(document.createTextNode(' face direction:')) + dd = self.create_select_dropdown(faceopts) + div.appendChild( dd ) + div.appendChild( document.createElement('br') ) + def onchange(evt): + opt = faceopts[this.selectedIndex] + print(opt) + model.material.side = eval('THREE.'+opt) + dd.onchange = onchange + + blendopts = ['NormalBlending', 'AdditiveBlending', 'SubtractiveBlending', 'NoBlending'] + div.appendChild(document.createTextNode(' blending:')) + dd = self.create_select_dropdown(blendopts) + div.appendChild( dd ) + div.appendChild( document.createElement('br') ) + def change_blending(evt): + opt = blendopts[this.selectedIndex] + print(opt) + model.material.blending = eval('THREE.'+opt) + dd.onchange = change_blending + + def change_wireframe(evt): model.material.wireframe = this.checked + div.appendChild(document.createTextNode(' wireframe:')) + checkbox = create_checkbox( model.material.wireframe, onchange=change_wireframe ) + div.appendChild( checkbox ) + + def change_wireframe_width(val): model.material.wireframeLinewidth = val * 10 + slider = create_slider( model.material.wireframeLinewidth*0.1, onchange=change_wireframe_width ) + div.appendChild( slider ) + + div.appendChild( document.createElement('br') ) + + + def change_opacity(val): + model.material.opacity = val + slider = create_slider( model.material.opacity, onchange=change_opacity ) + div.appendChild( document.createTextNode('opacity:') ) + div.appendChild( slider ) + + div.appendChild( document.createElement('br') ) + + + well = document.createElement('div') + well.setAttribute('class', 'well') + div.appendChild( well ) + + ## MeshBasicMaterial.js + well.appendChild(document.createTextNode(' diffuse:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + well.appendChild( input ) + def change_diffuse(evt): + hex = int( '0x'+this.value[1:] ) + model.material.color.setHex( hex ) + print(model.material.color) + ## oninput fails, can only get update after use has picked color + input.onchange = change_diffuse + + + ## MeshPhongMaterial.js + if hasattr(model.material, 'ambient'): + well.appendChild(document.createTextNode(' ambient:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + well.appendChild( input ) + def change_ambient(evt): + hex = int( '0x'+this.value[1:] ) + model.material.ambient.setHex( hex ) + print(model.material.ambient) + input.onchange = change_ambient + + if hasattr(model.material, 'emissive'): + well.appendChild(document.createTextNode(' emissive:')) + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + well.appendChild( input ) + def change_emissive(evt): + hex = int( '0x'+this.value[1:] ) + model.material.emissive.setHex( hex ) + print(model.material.emissive) + input.onchange = change_emissive + + if hasattr(model.material, 'specular'): + #div.appendChild( document.createElement('br') ) + + div.appendChild(document.createTextNode(' specular:')) + + def change_shininess(val): + model.material.shininess = val * 100 + slider = create_slider( model.material.shininess*0.01, onchange=change_shininess ) + #div.appendChild( document.createTextNode(' shininess:') ) + div.appendChild( slider ) + + input = document.createElement('input') + input.setAttribute('type', 'color') + input.style.width=64; input.style.height=32 + div.appendChild( input ) + def change_specular(evt): + hex = int( '0x'+this.value[1:] ) + model.material.specular.setHex( hex ) + print(model.material.specular) + input.onchange = change_specular + + + + return div + + + def _gen_ui_single(self, model): + div = document.createElement('div') + div.setAttribute('class', 'well') + #h3 = document.createElement('h3') + #h3.appendChild( document.createTextNode(model.name) ) + #div.appendChild( h3 ) + + div.appendChild( document.createTextNode(' position:') ) + + def set_pos_x(evt): model.position.x = this.value + input = create_float_input( model.position.x, onchange=set_pos_x) + div.appendChild( input ) + + def set_pos_y(evt): model.position.y = this.value + input = create_float_input( model.position.y, onchange=set_pos_y) + div.appendChild( input ) + + def set_pos_z(evt): model.position.z = this.value + input = create_float_input( model.position.z, onchange=set_pos_z) + div.appendChild( input ) + + div.appendChild( document.createElement('br') ) + + div.appendChild( document.createTextNode(' rotation:') ) + + def set_rot_x(evt): model.rotation.x = this.value + input = create_float_input( model.rotation.x, onchange=set_rot_x) + div.appendChild( input ) + + def set_rot_y(evt): model.rotation.y = this.value + input = create_float_input( model.rotation.y, onchange=set_rot_y) + div.appendChild( input ) + + def set_rot_z(evt): model.rotation.z = this.value + input = create_float_input( model.rotation.z, onchange=set_rot_z) + div.appendChild( input ) + + div.appendChild( document.createElement('br') ) + + div.appendChild( document.createTextNode(' scale:') ) + + def set_scale_x(evt): model.scale.x = this.value + input = create_float_input( model.scale.x, onchange=set_scale_x) + div.appendChild( input ) + + def set_scale_y(evt): model.scale.y = this.value + input = create_float_input( model.scale.y, onchange=set_scale_y) + div.appendChild( input ) + + def set_scale_z(evt): model.scale.z = this.value + input = create_float_input( model.scale.z, onchange=set_scale_z) + div.appendChild( input ) + + + + + if hasattr(model, 'material'): ## could be THREE.Mesh or THREE.SkinnedMesh + ui = self._gen_material_ui(model) + div.appendChild( ui ) + return div + + def _gen_ui_multi(self, arr): + menu = self.create_tab_menu() + for i,model in enumerate(arr): + page = menu.add_tab( model.name ) + div = self._gen_ui_single( model ) + page.appendChild( div ) + return menu.root + + def _gen_ui(self, o): + + if instanceof(o, Array): + return self._gen_ui_multi(o) + elif instanceof(o, THREE.Object3D): + return self._gen_ui_single(o) + else: + raise RuntimeError('can not generate ui for type:'+o) + + + + def handle_drop_event(self, files): + self.engine.pointlight1.position.copy( self.position ) + self.engine.pointlight1.position.z += 40 + self.engine.gizmo.attach( self.right_bar ) + + images = [] + videos = [] + for file in files: + ## note: `file.path` is only available in NodeWebkit, + ## for simple testing we will fake it here. + file.path = '/home/brett/Desktop/'+file.name + + if file.path.endswith('.dae'): + loader = new THREE.ColladaLoader(); + loader.options.convertUpAxis = true; + #def on_load(collada): + # print(collada) + # element3D.root.add( collada.scene ) + #loader.load( 'http://localhost:8000'+file.path, on_load ) + + def onload(evt): + parser = new DOMParser() + collada = loader.parse( parser.parseFromString(evt.target.result, "application/xml") ) + print(collada.scene) + collada.scene.scale.set(0.25, 0.25, 0.25) + collada.scene.position.set(0, -100, 200) + self.root.add( collada.scene ) + self.collada = collada.scene + + self.element.appendChild( self._gen_ui(collada.scene.children) ) + + reader = new FileReader() + reader.onload = onload.bind(self) + reader.readAsText( file ) + + elif file.path.endswith('.html'): + iframe = element3D.create_iframe( file.path, renderer3.domElement ) + self.element.appendChild(iframe) + + elif file.path.endswith('.css'): + print( 'TODO css' ) + elif file.path.endswith('.js'): + print( 'TODO js' ) + elif file.path.endswith('.jpg') or file.path.endswith('.png') or file.path.endswith('.gif'): + + li = document.createElement('li') + images.append(li) + img = document.createElement('img') + img.setAttribute('src', file.path) + img.setAttribute('class', 'well img-rounded') + li.appendChild( img ) + + + elif file.path.endswith('.mp4'): + li = document.createElement('li') + video = self.create_video( mp4=file.path ) + li.appendChild( video ) + videos.append( li ) + + ## note, nodewebkit is missing libffmpegsumo, then it only plays ogv videos + elif file.path.endswith('.ogv'): + #li = document.createElement('li') + video = self.create_video( ogv=file.path ) + self.element.appendChild(video) + #li.appendChild( video ) + #videos.append( li ) + + elif file.path.endswith('.py'): + def on_load(event): + contents = event.target.result + py_body_editor.setValue( contents ) + + Reader.onload = on_load + Reader.readAsText( file ) + + if images: + print('loading images') + ul = document.createElement('ul') + self.element.appendChild(ul) + for li in images: + ul.appendChild(li) + + if videos: + print('loading videos') + ul = document.createElement('ul') + self.element.appendChild(ul) + for li in videos: + ul.appendChild(li) + + + +class Engine: + def Editor(self, **kw): + e = Editor(self, **kw) + self.windows.append( e ) + return e + + + def __init__(self): + self.windows = [] + + SCREEN_WIDTH = window.innerWidth + SCREEN_HEIGHT = window.innerHeight + + self.camera = camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 10000 ); + camera.position.set( 200, 250, 800 ); + + self._selectman = SelectManager(self.camera) + + self.controls = controls = new THREE.TrackballControls( camera ); + camera.smooth_target = controls.target.clone() + camera.smooth_target.y = 300 + + controls.rotateSpeed = 1.0; + controls.zoomSpeed = 1.2; + controls.panSpeed = 0.8; + + controls.noZoom = false; + controls.noPan = false; + + controls.staticMoving = false; + controls.dynamicDampingFactor = 0.3; + + controls.keys = [ 65, 83, 68 ]; + + self.scene = scene = new THREE.Scene(); + self.scene3 = scene3 = new THREE.Scene(); + + + self.renderer = renderer = new THREE.WebGLRenderer(alpha=True); + renderer.shadowMapEnabled = true + renderer.shadowMapType = THREE.PCFSoftShadowMap + renderer.shadowMapSoft = true + + + renderer.setSize( window.innerWidth, window.innerHeight ); + renderer.domElement.style.position = 'absolute'; + renderer.domElement.style.top = 0; + renderer.domElement.style.zIndex = 1; + + self.gizmo = new THREE.TransformControls( camera, renderer.domElement ) + scene.add( self.gizmo ) + + self.spotlight = light = new( + THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2, 1 ) + ) + light.position.set( 0, 1400, 400 ) + light.target.position.set( 0, 0, 0 ) + + light.castShadow = True + light.shadowCameraNear = 400 + light.shadowCameraFar = 1900 + light.shadowCameraFov = 64 + light.shadowCameraVisible = True + + light.shadowBias = 0.0001 + light.shadowDarkness = 0.4 + + light.shadowMapWidth = 512 + light.shadowMapHeight = 512 + + scene.add( light ); + + self.pointlight1 = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) + pointlight.position.set( 10, 100, 300 ) + scene.add( pointlight ) + + self.pointlight2 = pointlight = new( THREE.PointLight(0xffffff, 2, 500) ) + pointlight.position.set( -10, -100, 200 ) + scene.add( pointlight ) + + renderer.sortObjects = false + renderer.autoClear = false + + renderTarget = new( + THREE.WebGLRenderTarget( + SCREEN_WIDTH, + SCREEN_HEIGHT, + minFilter = THREE.LinearFilter, + magFilter = THREE.LinearFilter, + format = THREE.RGBAFormat, ## RGBA format is required to composite over css3d render + stencilBuffer = false + ) + ) + + + hblur = new(THREE.ShaderPass( THREE.HorizontalTiltShiftShader )) + vblur = new(THREE.ShaderPass( THREE.VerticalTiltShiftShader )) + + bluriness = 1.7; + hblur.uniforms[ 'h' ].value = bluriness / SCREEN_WIDTH; + vblur.uniforms[ 'v' ].value = bluriness / SCREEN_HEIGHT; + + hblur.uniforms[ 'r' ].value = 0.1 + vblur.uniforms[ 'r' ].value = 0.1 + + + self.composer = composer = new(THREE.EffectComposer( renderer, renderTarget )) + + renderModel = new(THREE.RenderPass( scene, camera )) + + vblur.renderToScreen = true; + composer.addPass( renderModel ); + composer.addPass( hblur ); + composer.addPass( vblur ); + + + self.scene2 = scene2 = new THREE.Scene(); + + + self.renderer2 = renderer2 = new THREE.CSS3DRenderer(); + renderer2.setSize( window.innerWidth, window.innerHeight ); + renderer2.domElement.style.position = 'absolute'; + renderer2.domElement.style.top = 0; + renderer2.domElement.style.zIndex = 0; + document.body.appendChild( renderer2.domElement ); + + self.renderer3 = renderer3 = new THREE.CSS3DRenderer(); + renderer3.setSize( window.innerWidth, window.innerHeight ); + renderer3.domElement.style.position = 'absolute'; + renderer3.domElement.style.top = 0; + renderer3.domElement.style.opacity = 0.1; + renderer3.domElement.style.zIndex=4; + + document.body.appendChild( renderer2.domElement ); + document.body.appendChild( renderer.domElement ); + document.body.appendChild( renderer3.domElement ); + + + + def animate(self): + requestAnimationFrame( self.animate.bind(self) ); + self.gizmo.update() + + d = self.camera.smooth_target.clone() + d.sub(self.controls.target) + self.controls.target.add( d.multiplyScalar(0.03) ) + self.controls.update() + + for win in self.windows: win.update() + self.renderer2.render( self.scene2, self.camera ) + self.renderer.clear() + self.composer.render( self.scene, self.camera ) + self.renderer3.render( self.scene3, self.camera ) + + def run(self): + #self.animate() + setTimeout(self.animate.bind(self), 1000) + +threepy = { + 'Engine' : lambda : Engine(), +} + +#pythonjs.configure(javascript=False) +#threepy.Editor = lambda **kw: Engine(**kw) diff --git a/regtests/html/webgl_css3d_domshadow.html b/regtests/html/webgl_css3d_domshadow.html new file mode 100644 index 0000000..df6d9c3 --- /dev/null +++ b/regtests/html/webgl_css3d_domshadow.html @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regtests/html/webgl_css3d_editor.html b/regtests/html/webgl_css3d_editor.html new file mode 100644 index 0000000..2154bf3 --- /dev/null +++ b/regtests/html/webgl_css3d_editor.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regtests/html/webgl_css3d_sandbox.html b/regtests/html/webgl_css3d_sandbox.html new file mode 100644 index 0000000..bd2ade9 --- /dev/null +++ b/regtests/html/webgl_css3d_sandbox.html @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regtests/html/webgl_css3d_simple_editor.html b/regtests/html/webgl_css3d_simple_editor.html new file mode 100644 index 0000000..f81cbdb --- /dev/null +++ b/regtests/html/webgl_css3d_simple_editor.html @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/regtests/lang/builtins.py b/regtests/lang/builtins.py new file mode 100644 index 0000000..61cbd2a --- /dev/null +++ b/regtests/lang/builtins.py @@ -0,0 +1,28 @@ +''' +builtin functions +''' + + +def main(): + n = float('1.1') + TestError( n==1.1 ) + + n = float('NaN') + TestError( isNaN(n)==True ) + + r = round( 1.1234, 2) + #print(r) + TestError( str(r) == '1.12' ) + + r = round( 100.001, 2) + TestError( r == 100 ) + + i = int( 100.1 ) + TestError( i == 100 ) + + r = round( 5.49 ) + TestError( r == 5 ) + + r = round( 5.49, 1 ) + TestError( r == 5.5 ) + diff --git a/regtests/lang/equality.py b/regtests/lang/equality.py new file mode 100644 index 0000000..f5c273d --- /dev/null +++ b/regtests/lang/equality.py @@ -0,0 +1,31 @@ +''' +== +''' +# https://github.com/PythonJS/PythonJS/issues/129 + +def main(): + TestError( 0==0 ) + TestError( 1==1 ) + TestError( 1.0==1 ) + TestError('a'=='a') + + + a = [6] + b = [6] + t = a==b + TestError( t==True ) + + a = (6,) + b = (6,) + t = a==b + TestError( t==True ) + + t = ''==0 ## javascript gotcha + TestError( t==False ) + + t = [1,2]==[1,2] ## javascript gotcha + TestError( t==True ) + + t = ["1","2"] != [1,2] ## javascript gotcha + TestError( t==True ) + diff --git a/regtests/lang/eval.py b/regtests/lang/eval.py new file mode 100644 index 0000000..f68b971 --- /dev/null +++ b/regtests/lang/eval.py @@ -0,0 +1,12 @@ +''' +eval +''' + +def foo(): return 42 +bar = lambda: 42 + +def main(): + eval('a = bar()') # This one works + eval('b = foo()') # 'foo' is undefined in normal mode under NodeJS but works in NodeWebkit and Chrome!? + TestError( a==42 ) + TestError( b==42 ) diff --git a/regtests/lang/eval_order.py b/regtests/lang/eval_order.py new file mode 100644 index 0000000..149ec0e --- /dev/null +++ b/regtests/lang/eval_order.py @@ -0,0 +1,8 @@ +''' +evaluation order +''' +# https://github.com/PythonJS/PythonJS/issues/131 + +def main(): + a = False and (False or True) + TestError( a==False ) \ No newline at end of file diff --git a/regtests/lang/inline.py b/regtests/lang/inline.py new file mode 100644 index 0000000..7a8e3e4 --- /dev/null +++ b/regtests/lang/inline.py @@ -0,0 +1,5 @@ +"""inline""" + +def main(): + JS("now = new Date()") + inline("now = new Date()") diff --git a/regtests/lang/new.py b/regtests/lang/new.py new file mode 100644 index 0000000..b65296b --- /dev/null +++ b/regtests/lang/new.py @@ -0,0 +1,8 @@ +''' +js new keyword +''' + +def main(): + #a = new Date() ## this also works + a = JS(' new Date()') + TestError( a.getFullYear()==2014 ) diff --git a/regtests/lang/switch.py b/regtests/lang/switch.py new file mode 100644 index 0000000..75aca9f --- /dev/null +++ b/regtests/lang/switch.py @@ -0,0 +1,17 @@ +''' +switch case default +''' + +def main(): + x = None + a = 2 + switch a: + case 1: + x = 'fail' + case 2: + x = 'ok' + default: + break + + TestError( x=='ok' ) + diff --git a/regtests/list/insert.py b/regtests/list/insert.py new file mode 100644 index 0000000..8596ce4 --- /dev/null +++ b/regtests/list/insert.py @@ -0,0 +1,12 @@ +"""insert""" +def main(): + a = [1,2,3,4] + TestError( len(a)==4 ) + + a.insert(0, 'hi') + TestError( len(a)==5 ) + TestError( a[0]=='hi' ) + + a.insert(1, a.pop(0)) + TestError( a[0]==1 ) + TestError( a[1]=='hi' ) diff --git a/regtests/list/mul.py b/regtests/list/mul.py new file mode 100644 index 0000000..5938f4d --- /dev/null +++ b/regtests/list/mul.py @@ -0,0 +1,9 @@ +"""list multiplication""" + + +def main(): + a = ['hi'] + b = a * 2 + TestError( len(b)==2 ) + TestError( b[0]=='hi' ) + TestError( b[1]=='hi' ) diff --git a/regtests/list/pop.py b/regtests/list/pop.py new file mode 100644 index 0000000..c9e1558 --- /dev/null +++ b/regtests/list/pop.py @@ -0,0 +1,13 @@ +"""list.pop(n)""" + + +def main(): + a = list(range(10)) + b = a.pop() + TestError( b==9 ) + c = a.pop(0) + TestError( c==0 ) + + d = ['A', 'B'] + TestError( d.pop(1)=='B' ) + TestError( len(d)==1 ) \ No newline at end of file diff --git a/regtests/list/range.py b/regtests/list/range.py new file mode 100644 index 0000000..a553042 --- /dev/null +++ b/regtests/list/range.py @@ -0,0 +1,12 @@ +"""range""" +def main(): + a = range(10) + TestError( len(a)==10 ) + TestError( a[0] == 0 ) + TestError( a[9] == 9 ) + + b = range(1,10) + TestError( len(b)==9 ) + TestError( b[0] == 1 ) + TestError( b[8] == 9 ) + diff --git a/regtests/list/set_slice.py b/regtests/list/set_slice.py new file mode 100644 index 0000000..c09c62d --- /dev/null +++ b/regtests/list/set_slice.py @@ -0,0 +1,42 @@ +"""list slice set""" + + +def main(): + a = list(range(10)) + a[ 2:4 ] = 'XXXY' + + #if BACKEND=='DART': + # print(a[...]) + #else: + # print(a) + + TestError( a[0]==0 ) + TestError( a[1]==1 ) + + TestError( a[2]=='X' ) + TestError( a[3]=='X' ) + TestError( a[4]=='X' ) + TestError( a[5]=='Y' ) + + TestError( a[6]==4 ) + TestError( a[7]==5 ) + TestError( a[8]==6 ) + TestError( a[9]==7 ) + TestError( a[10]==8 ) + TestError( a[11]==9 ) + + b = list(range(3)) + c = b [ :2 ] + TestError( c[0]==0 ) + TestError( c[1]==1 ) + + b[ :2 ] = 'ABC' + TestError( len(b)==4 ) + TestError( b[0]=='A' ) + + d = list(range(10)) + d[ 2:4 ] = [99, 100] + TestError( d[0]==0 ) + TestError( d[1]==1 ) + TestError( d[2]==99 ) + TestError( d[3]==100 ) diff --git a/regtests/list/slice.py b/regtests/list/slice.py index e945967..11b12f3 100644 --- a/regtests/list/slice.py +++ b/regtests/list/slice.py @@ -11,6 +11,12 @@ def main(): TestError( len(a)==5 ) TestError( a[4]==4 ) + #if BACKEND=='DART': + # print(a[...]) + #else: + # print(a) + + b = range(10)[::2] TestError( len(b)==5 ) TestError( b[0]==0 ) @@ -19,8 +25,20 @@ def main(): TestError( b[3]==6 ) TestError( b[4]==8 ) + #if BACKEND=='DART': + # print(b[...]) + #else: + # print(b) + + c = range(20) d = c[ len(b) : ] + + #if BACKEND=='DART': + # print(d[...]) + #else: + # print(d) + TestError( len(d)==15 ) x = XXX() diff --git a/regtests/list/slice_reverse.py b/regtests/list/slice_reverse.py new file mode 100644 index 0000000..dfe0a2d --- /dev/null +++ b/regtests/list/slice_reverse.py @@ -0,0 +1,30 @@ +"""list reverse slice""" + + +def main(): + a = range(10) + b = a[ 4::-1 ] + + #if BACKEND=='DART': + # print(b[...]) + #else: + # print(b) + + + TestError( b[0]==4 ) + TestError( b[1]==3 ) + TestError( b[2]==2 ) + TestError( b[3]==1 ) + TestError( b[4]==0 ) + + c = range(20) + d = c[ 2::-1 ] + + #if BACKEND=='DART': + # print(d[...]) + #else: + # print(d) + + TestError( d[0]==2 ) + TestError( d[1]==1 ) + TestError( d[2]==0 ) diff --git a/regtests/list/sort.py b/regtests/list/sort.py new file mode 100644 index 0000000..a990fb0 --- /dev/null +++ b/regtests/list/sort.py @@ -0,0 +1,16 @@ +"""list sort""" + +def main(): + x = [100, 10, 3,2,1] + x.sort() + TestError( x[0]==1 ) + TestError( x[1]==2 ) + TestError( x[2]==3 ) + TestError( x[3]==10 ) + TestError( x[4]==100 ) + + y = ['C', 'B', 'A'] + y.sort() + TestError( y[0]=='A' ) + TestError( y[1]=='B' ) + TestError( y[2]=='C' ) diff --git a/regtests/loop/for_else.py b/regtests/loop/for_else.py new file mode 100644 index 0000000..f8c0839 --- /dev/null +++ b/regtests/loop/for_else.py @@ -0,0 +1,13 @@ +''' +for else loop (DEPRECATED) +''' + +def main(): + for i in range(10): + if i==0: + break + + else: + pass + + diff --git a/regtests/loop/while_else.py b/regtests/loop/while_else.py new file mode 100644 index 0000000..447050f --- /dev/null +++ b/regtests/loop/while_else.py @@ -0,0 +1,25 @@ +''' +while else loop (DEPRECATED) +''' + +def main(): + + a = False + i = 0 + while i < 10: + i += 1 + else: + a = True + + TestError( a==True ) + + b = False + i = 0 + while i < 10: + i += 1 + break + else: + b = True + + TestError( b==False ) + diff --git a/regtests/rpc/async_iter.py b/regtests/rpc/async_iter.py new file mode 100644 index 0000000..3cc9243 --- /dev/null +++ b/regtests/rpc/async_iter.py @@ -0,0 +1,16 @@ +"""iteration""" +## note mycollection is hard coded in run.py as `range(10)` + +def main(): + a = [] + with rpc('http://localhost:8080') as server: + for ob in server.mycollection: + a.append( ob ) + + print(a) + TestError( len(a)==10 ) + TestError( a[0]==0 ) + TestError( a[1]==1 ) + TestError( a[2]==2 ) + + \ No newline at end of file diff --git a/regtests/rpc/attr.py b/regtests/rpc/attr.py new file mode 100644 index 0000000..be03b81 --- /dev/null +++ b/regtests/rpc/attr.py @@ -0,0 +1,15 @@ +"""get/set remote attributes""" + +def main(): + x = None + y = None + with rpc('http://localhost:8080') as server: + server.A = 'hi' + server.B = 100 + x = server.A + y = server.B + + TestError( x == 'hi' ) + TestError( y == 100 ) + + \ No newline at end of file diff --git a/regtests/rpc/hello_server_as.py b/regtests/rpc/hello_server_as.py index 52c7021..722f7e2 100644 --- a/regtests/rpc/hello_server_as.py +++ b/regtests/rpc/hello_server_as.py @@ -1,5 +1,8 @@ """simple rpc call""" +def f(v): + return v * 2 + def main(): a = 'hello' b = 'server' @@ -8,8 +11,10 @@ def main(): with rpc('http://localhost:8080') as server: c = server.concat( a, b ) z = server.add( x, y ) + w = f(z) TestError( c == 'helloserver' ) TestError( z == 300 ) + TestError( w == 600 ) \ No newline at end of file diff --git a/regtests/run.py b/regtests/run.py index 7c25392..cf5ff34 100755 --- a/regtests/run.py +++ b/regtests/run.py @@ -36,36 +36,68 @@ ] +__sandbox = { + 'mycollection' : range(10) +} +__clients = {} ## keeps track of iterator indices + def httpd_reply( env, start_response ): + path = env['PATH_INFO'] host = env['HTTP_HOST'] client = env['REMOTE_ADDR'] arg = env['QUERY_STRING'] + + if client not in __clients: + __clients[ client ] = {} + length = 0 - if 'CONTENT_LENGTH' in env: - length = int(env['CONTENT_LENGTH']) + if 'CONTENT_LENGTH' in env: length = int(env['CONTENT_LENGTH']) data = env['wsgi.input'].read( length ).decode('utf-8') - - print('http_reply ->', path, host, client, arg, data) + #print('http_reply ->', path, host, client, arg, data) msg = json.loads( data ) - assert 'call' in msg - assert 'args' in msg - if msg['call'] == 'concat': - res = ''.join( msg['args'] ) - elif msg['call'] == 'add': - res = msg['args'][0] + msg['args'][1] + res = '' + + if 'call' in msg: + assert 'args' in msg + if msg['call'] == 'concat': + res = ''.join( msg['args'] ) + elif msg['call'] == 'add': + res = msg['args'][0] + msg['args'][1] + else: + raise NotImplementedError( msg ) + + elif 'iter' in msg: + name = msg['iter'] + assert name in __sandbox + if name not in __clients[ client ]: + __clients[ client ][name] = 0 + index = __clients[ client ][name] + iterable = __sandbox[name] + if index == len(iterable): + index = 0 + res = '__STOP_ITERATION__' + else: + res = iterable[ index ] + index += 1 + __clients[ client ][name] = index + + elif 'set' in msg: + __sandbox[ msg['set'] ] = msg['value'] + + elif 'get' in msg: + res = __sandbox[ msg['get'] ] + else: raise NotImplementedError( msg ) - print( res ) start_response( '200 OK', [] ) return [ json.dumps(res).encode('utf-8') ] httpd = wsgiref.simple_server.make_server( 'localhost', 8080, httpd_reply ) import threading -httpd = threading._start_new_thread( httpd.serve_forever, ()) -print(httpd) +thread_id = threading._start_new_thread( httpd.serve_forever, ()) def runnable(command): @@ -81,9 +113,46 @@ def runnable(command): except OSError: return False -## rhino has problems: like maximum callstack errors simply freeze up rhino -pypy_runnable = runnable( 'pypy --help' ) +def run_pypy_test_on(filename): + """PyPy""" + write("%s.py" % tmpname, patch_python(filename, python='PYPY')) + return run_command("%s %s.py %s" % (pypy_exe, tmpname, display_errors)) + +def run_old_pypy_test_on(filename): + """PyPy 1.9""" + write("%s.py" % tmpname, patch_python(filename, python='PYPY')) + return run_command("%s %s.py %s" % (old_pypy_exe, tmpname, display_errors)) + + +old_pypy_runnable = pypy_runnable = False +old_pypy_exe = pypy_exe = None +if os.path.isfile( os.path.expanduser('~/pypy-2.3.1-linux64/bin/pypy') ): + pypy_runnable = True + pypy_exe = os.path.expanduser('~/pypy-2.3.1-linux64/bin/pypy') + run_pypy_test_on.__doc__ = 'PyPy 2.3.1' +elif os.path.isfile( os.path.expanduser('~/pypy-2.2-linux64/bin/pypy') ): + pypy_runnable = True + pypy_exe = os.path.expanduser('~/pypy-2.2-linux64/bin/pypy') + run_pypy_test_on.__doc__ = 'PyPy 2.2' +elif runnable( 'pypy --help' ): + pypy_runnable = True + pypy_exe = 'pypy' + +if os.path.isfile( os.path.expanduser('~/pypy-1.9/bin/pypy') ) and '--old-pypy' in sys.argv: + old_pypy_runnable = True + old_pypy_exe = os.path.expanduser('~/pypy-1.9/bin/pypy') + +webclgl = [] +if os.path.isdir( os.path.expanduser('~/webclgl') ): + #webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGL_2.0.Min.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLUtils.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLBuffer.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGLKernel.class.js'), 'rb').read().decode('utf-8') ) + webclgl.append( open( os.path.expanduser('~/webclgl/WebCLGL.class.js'), 'rb').read().decode('utf-8') ) + +## rhino is not run by default because it simply freezes up on maximum callstack errors rhino_runnable = '--rhino' in sys.argv and runnable("rhino -e 'quit()'") + node_runnable = runnable("node --help") ## sudo npm install nodewebkit -g @@ -93,28 +162,39 @@ def runnable(command): ## download https://github.com/rogerwang/node-webkit/releases/tag/nw-v0.9.2 ## and extract to your home directory. nodewebkit_runnable = False -nodewebkit = os.path.expanduser('~/node-webkit-v0.9.2-linux-x64/nw') + + +nodewebkit = os.path.expanduser('~/node-webkit-v0.10.0-rc1-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True else: - nodewebkit = os.path.expanduser('~/node-webkit-v0.9.1-linux-x64/nw') + nodewebkit = os.path.expanduser('~/node-webkit-v0.9.2-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True else: - nodewebkit = os.path.expanduser('~/node-webkit-v0.8.4-linux-x64/nw') + nodewebkit = os.path.expanduser('~/node-webkit-v0.9.1-linux-x64/nw') if os.path.isfile( nodewebkit ): nodewebkit_runnable = True + else: + nodewebkit = os.path.expanduser('~/node-webkit-v0.8.4-linux-x64/nw') + if os.path.isfile( nodewebkit ): nodewebkit_runnable = True -if not show_details: +if not show_details or '--no-nodewebkit' in sys.argv: nodewebkit_runnable = False #dart2js = os.path.expanduser( '~/dart-sdk-1.0/dart-sdk/bin/dart2js') ## TODO support dart-sdk-1.3+ dart2js = os.path.expanduser( '~/dart-sdk/bin/dart2js') # tested with dart 1.3 +dart2js_runnable = runnable( dart2js + ' -h' ) and '--dart2js' in sys.argv + +dart_exe = os.path.expanduser( '~/dart-sdk/bin/dart') +dart_runnable = os.path.isfile( dart_exe ) -dart2js_runnable = runnable( dart2js + ' -h' ) -coffee_runnable = runnable( "coffee -v" ) and '--all-backends' in sys.argv -lua_runnable = runnable( "lua -v" ) and '--all-backends' in sys.argv -luajit_runnable = runnable( "luajit -v" ) +coffee_runnable = runnable( "coffee -v" ) and '--coffee' in sys.argv +lua_runnable = runnable( "lua -v" ) and '--lua' in sys.argv +luajit_runnable = runnable( "luajit -v" ) and '--luajit' in sys.argv lua2js = os.path.abspath( '../external/lua.js/lua2js' ) -luajs_runnable = os.path.isfile( lua2js ) and '--all-backends' in sys.argv +luajs_runnable = os.path.isfile( lua2js ) and '--lua2js' in sys.argv + +go_runnable = runnable( 'go version') +gopherjs_runnable = runnable( 'gopherjs') assert rhino_runnable or node_runnable @@ -124,18 +204,38 @@ def runnable(command): display_errors = "2>/dev/null" def files(): - """All the filenames of the regression tests""" + """returns all the filenames of the regression tests. + this also needs to copy all the original python files to /tmp + because `from xxx import *` syntax will trigger the translator + to read files from the same directory and insert them. + """ tests = [] + html_tests = [] benchmarks = [] + mods = [] for dirpath, dirnames, filenames in os.walk('.'): if dirpath == '.': continue for filename in filenames: + a = dirpath + os.path.sep + filename if filename.endswith(".py"): if 'bench' in dirpath: - benchmarks.append( dirpath + os.path.sep + filename ) + benchmarks.append( a ) else: - tests.append( dirpath + os.path.sep + filename ) + tests.append( a ) + elif 'html' in dirpath: + if filename.endswith(".html"): + html_tests.append( a ) + elif filename.endswith('.py'): ## these are modules + mods.append( filename ) + + tmpdir = tempfile.gettempdir() + for mod in mods+tests: + data = open(mod,'rb').read() + name = os.path.split(mod)[-1] + open(os.path.join(tmpdir, name), 'wb').write( data ) + + tests.extend( html_tests ) tests.extend( benchmarks ) return tests @@ -157,7 +257,14 @@ def run_command(command, returns_stdout_stderr=False, nodewebkit_workaround=Fals if os.path.isfile("%s.errors" % tmpname): os.unlink("%s.errors" % tmpname) f = os.popen(command + " 2>%s.errors" % tmpname, 'r') - stdout = f.read().strip() + + killed = False + try: + stdout = f.read().strip() + except KeyboardInterrupt: + stdout = f.read().strip() + killed = True + f.close() @@ -170,6 +277,8 @@ def run_command(command, returns_stdout_stderr=False, nodewebkit_workaround=Fals a = [] for line in stdout.splitlines(): if 'INFO:CONSOLE' in line: + line = line.replace('\\n', '\n') + line = line.replace('\\u003C', '<') start = line.index('"') end = line.rindex('"') a.append( line[start+1:end] ) @@ -180,7 +289,11 @@ def run_command(command, returns_stdout_stderr=False, nodewebkit_workaround=Fals if show_details: print('TEST ERROR!') print(stderr) - #sys.exit() + + if killed: + print(stdout) + sys.exit() + if returns_stdout_stderr: return stdout, stderr @@ -259,17 +372,55 @@ def TestWarning(file, line, result, test): print(file + ":" + str(line) + " Warning fail " + test) """ -_python_only_extra_header = """ -import threading -threading.start_webworker = lambda f,a: threading._start_new_thread(f,a) -threading.start_new_thread = threading._start_new_thread +_patch_header_go = """# -*- coding: utf-8 -*- +def TestError(file:string, line:int, result:bool, test:string): + if result == False: + print(file + ":" + str(line) + " Error fail " + test) +""" + -class webworker(object): +_python_only_extra_header = """ +try: + import threading + threading.start_webworker = lambda f,a: threading._start_new_thread(f,a) + threading.start_new_thread = threading._start_new_thread +except ImportError: + pass + +class __faker__(object): def __enter__(self, *args): pass def __exit__(self, *args): pass - def __call__(self, name): + def __call__(self, *args, **kw): return lambda f: f -webworker = webworker() + def vectorize(self, f): + return f + def main(self, f): + return f + def object(self, f): + return f + def method(self, f): + return f + +webworker = __faker__() +glsl = __faker__() +gpu = __faker__() +returns = __faker__() +typedef = __faker__() +vec2 = None +mat4 = None + +def int16(a): return int(a) + +try: + import numpy +except ImportError: + try: + import numpypy as numpy + except ImportError: + pass + +from math import isnan as isNaN + """ @@ -293,10 +444,13 @@ def patch_python(filename, dart=False, python='PYTHONJS', backend=None): # out.append( line ) # code = '\n'.join( out ) a = [ - _patch_header, 'PYTHON="%s"'%python, 'BACKEND="%s"'%backend, ] + if backend == 'GO': + a.append(_patch_header_go) + else: + a.append(_patch_header) if python != 'PYTHONJS': code = typedpython.transform_source( code, strip=True ) @@ -319,17 +473,14 @@ def run_python3_test_on(filename): write("%s.py" % tmpname, patch_python(filename, python='PYTHON3')) return run_command("python3 %s.py %s" % (tmpname, display_errors)) -def run_pypy_test_on(filename): - """PyPy""" - write("%s.py" % tmpname, patch_python(filename, python='PYPY')) - return run_command("pypy %s.py %s" % (tmpname, display_errors)) -def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, multioutput=False): +def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False, luajs=False, go=False, gopherjs=False, multioutput=False, requirejs=True): global tmpname tmpname = os.path.join( tempfile.gettempdir(), - 'test-%s-js=%s-dart=%s-lua=%s' %(filename.split('/')[-1], javascript, dart, lua) + #'test-%s-js=%s-dart=%s-lua=%s' %(filename.split('/')[-1], javascript, dart, lua) + 'regtest-%s'%filename.split('/')[-1] ) output_name = "%s.py" % tmpname @@ -356,6 +507,9 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False ] content = '\n'.join( source ) + elif go or gopherjs: + content = patch_python(filename, backend='GO') + else: content = patch_python(filename) @@ -380,6 +534,13 @@ def translate_js(filename, javascript=False, dart=False, coffee=False, lua=False cmd.append( '--lua') elif luajs: cmd.append( '--luajs') + elif go: + cmd.append( '--go' ) + elif gopherjs: + cmd.append( '--gopherjs' ) + + if not requirejs: + cmd.append( '--no-wrapper' ) stdout, stderr = run_command(' '.join(cmd), returns_stdout_stderr=True) if stderr: @@ -546,7 +707,20 @@ def run_js_nodewebkit(content): "main()", "__nw.App.quit()" ] - write("/tmp/test.html", '' %'\n'.join(lines)) + + html = [''] + if webclgl: + for data in webclgl: + html.append('') + + html.append('') + + html.append('') + write("/tmp/test.html", '\n'.join(html)) #write("%s.js" % tmpname, '\n'.join(lines)) #return run_command("node %s.js" % tmpname) @@ -555,7 +729,7 @@ def run_js_nodewebkit(content): def run_pythonjs_dart_test_on_node(dummy_filename): - """PythonJS (Dart backend)""" + """PythonJS (Dart backend - dart2js)""" return run_if_no_error(run_dart2js_node) def run_dart2js_node(content): @@ -563,6 +737,16 @@ def run_dart2js_node(content): write("%s.js" % tmpname, content) return run_command("node %s.js" % tmpname) +def run_pythonjs_dart_test_on_dart(dummy_filename): + """PythonJS (Dart backend - Dart VM)""" + return run_if_no_error(run_dart) + +def run_dart(content): + """Run Dart2js using Node""" + #write("%s.js" % tmpname, content) + return run_command("%s %s" % (dart_exe, "/tmp/dart2js-input.dart")) + + def run_pythonjs_coffee_test_on_node(dummy_filename): """PythonJS (CoffeeScript)""" return run_if_no_error(run_coffee_node) @@ -604,6 +788,93 @@ def run_luajs_node(content): return run_command("node %s.js" % tmpname) +def run_pythonjs_go_test(dummy_filename): + """PythonJS (Go backend)""" + return run_if_no_error(run_go) + +def run_go(content): + """compile and run go program""" + write("%s.go" % tmpname, content) + errors = run_command("go build -o /tmp/regtest-go %s.go" % tmpname) + if errors: + return errors + else: + return run_command( '/tmp/regtest-go' ) + + +def run_pythonjs_gopherjs_test(dummy_filename): + """PythonJS (Gopherjs)""" + return run_if_no_error(run_gopherjs_node) + +def run_gopherjs_node(content): + """Run Gopherjs using Node""" + write("%s.js" % tmpname, content) + return run_command("node %s.js" % tmpname) + +def run_html_test( filename, sum_errors ): + lines = open(filename, 'rb').read().decode('utf-8').splitlines() + filename = os.path.split(filename)[-1] + doc = []; script = None + for line in lines: + if line.strip().startswith('') + css = line.split('href=')[-1].split()[0][1:-1] + print('css', css) + assert css.startswith('~/') + assert css.endswith('.css') + assert os.path.isfile( os.path.expanduser(css) ) + doc.append( open(os.path.expanduser(css), 'rb').read().decode('utf-8') ) + doc.append('') + elif line.strip().startswith('') + script = list() + elif 'src=' in line and '~/' in line: ## external javascripts installed in users home folder + x = line.split('src="')[-1].split('"')[0] + if os.path.isfile(os.path.expanduser(x)): + + doc.append( '') + else: + doc.append( line ) + + elif line.strip() == '': + if script: + open('/tmp/%s.js'%filename, 'wb').write( ('\n'.join(script)).encode('utf-8') ) + js = translate_js( '/tmp/%s.js'%filename, requirejs=False ) ## inserts TestError and others + doc.append( js ) + doc.append( line ) + script = None + + elif isinstance( script, list ): + script.append( line ) + + else: + doc.append( line ) + + html = '\n'.join(doc) + open('/tmp/%s.html'%filename, 'wb').write( html.encode('utf-8') ) + if '--nodewebkit' in sys.argv: + ## nodewebkit can bypass all cross origin browser-side security + cfg = '{"name":"test", "main":"%s.html", "window":{"width":1200, "height":700}}' %filename + write("/tmp/package.json", cfg) + run_command("%s /tmp" %nodewebkit, nodewebkit_workaround=True) + + else: + ## chrome-extension that won't force you to close your browser windows when deving: `Allow-Control-Allow-Origin:*` + ## this still fails with iframes that do not allow cross origin. + cmd = [ + 'google-chrome', + '--app=file:///tmp/%s.html'%filename, + '--allow-file-access-from-files', ## only takes affect if chrome is closed + '--allow-file-access', ## only takes affect if chrome is closed + '--disable-web-security' ## only takes affect if chrome is closed + ] + ## non-blocking, TODO check for chrome extension that allows output of console.log to stdout + subprocess.check_call(cmd) + + table_header = "%-12.12s %-28.28s" table_cell = '%-6.6s' @@ -615,6 +886,11 @@ def run_test_on(filename): f.close() print(table_header % (filename[2:-3], comment), end='') sum_errors = {} + + if filename.endswith('.html'): + run_html_test( filename, sum_errors ) + return sum_errors + def display(function): global _test_description _test_description = function.__doc__ @@ -638,28 +914,31 @@ def display(function): if show_details: print('-'*77) - if 'requirejs' not in filename: + if 'requirejs' not in filename and not filename.startswith('./go/'): display(run_python_test_on) display(run_python3_test_on) if pypy_runnable: display(run_pypy_test_on) + if old_pypy_runnable: + display(run_old_pypy_test_on) global js - js = translate_js( - filename, - javascript=False, - multioutput=filename.startswith('./threads/' or filename.startswith('./bench/webworker')) - ) - if rhino_runnable: - display(run_pythonjs_test_on) - if node_runnable: - display(run_pythonjs_test_on_node) + if not filename.startswith('./go/'): + js = translate_js( + filename, + javascript=False, + multioutput=filename.startswith('./threads/' or filename.startswith('./bench/webworker')) + ) + if rhino_runnable: + display(run_pythonjs_test_on) + if node_runnable: + display(run_pythonjs_test_on_node) - if nodewebkit_runnable: - display(run_pythonjs_test_on_nodewebkit) + if nodewebkit_runnable: + display(run_pythonjs_test_on_nodewebkit) - if '--no-javascript-mode' not in sys.argv: + if '--no-javascript-mode' not in sys.argv and not filename.startswith('./go/'): js = translate_js(filename, javascript=True, multioutput=filename.startswith('./threads/' or filename.startswith('./bench/webworker'))) if rhino_runnable: display(run_pythonjsjs_test_on) @@ -672,6 +951,10 @@ def display(function): if 'requirejs' not in filename: + if dart_runnable: + js = translate_js(filename, javascript=False, dart=True) + display(run_pythonjs_dart_test_on_dart) + if dart2js_runnable and node_runnable: js = translate_js(filename, javascript=False, dart=True) display(run_pythonjs_dart_test_on_node) @@ -692,6 +975,14 @@ def display(function): js = translate_js(filename, lua=True) display(run_pythonjs_lua_test_on_luajit) + if go_runnable: + js = translate_js(filename, go=True) + display(run_pythonjs_go_test) + + if gopherjs_runnable: + js = translate_js(filename, gopherjs=True) + display(run_pythonjs_gopherjs_test) + print() return sum_errors @@ -702,6 +993,10 @@ def run(): headers = ["Py-\nthon2", "Py-\nthon3"] if pypy_runnable: headers.append("PyPy\n") + + if old_pypy_runnable: + headers.append("PyPy\n1.9") + if rhino_runnable: headers.append("JS\nRhino") if node_runnable: @@ -719,6 +1014,9 @@ def run(): if nodewebkit_runnable: headers.append("JSJS\nWebkit") + if dart_runnable: + headers.append("Dart\nDart") + if node_runnable: if dart2js_runnable: @@ -735,6 +1033,10 @@ def run(): if luajit_runnable: headers.append("Lua\nJIT") + if go_runnable: + headers.append("Go\n-") + + print(table_header % ("", "Regtest run on") + ''.join(table_cell % i.split('\n')[0] for i in headers) diff --git a/regtests/set/issubset.py b/regtests/set/issubset.py new file mode 100644 index 0000000..9e2b3df --- /dev/null +++ b/regtests/set/issubset.py @@ -0,0 +1,10 @@ +"""get/set remote attributes""" + +def main(): + x = set([1,2,3]) + y = set([1,2,3,4]) + + TestError( x.issubset(y)==True ) + TestError( y.issubset(x)==False ) + + \ No newline at end of file diff --git a/regtests/str/mul.py b/regtests/str/mul.py new file mode 100644 index 0000000..f71ca45 --- /dev/null +++ b/regtests/str/mul.py @@ -0,0 +1,8 @@ +"""string multiplication""" + + +def main(): + a = 'hi' + b = a * 2 + TestError( b == 'hihi' ) + diff --git a/regtests/typed/float32vec.py b/regtests/typed/float32vec.py new file mode 100644 index 0000000..77524d3 --- /dev/null +++ b/regtests/typed/float32vec.py @@ -0,0 +1,21 @@ +"""simd float32vec""" + +def get_data(): + return [1.9, 1.8, 1.7, 0.6, 0.99,0.88,0.77,0.66] +def main(): + ## the translator knows this is a float32vec because there are more than 4 elements + x = y = z = w = 22/7 + a = numpy.array( [1.1, 1.2, 1.3, 0.4, x,y,z,w], dtype=numpy.float32 ) + + ## in this case the translator is not sure what the length of `u` is, so it defaults + ## to using a float32vec. + u = get_data() + b = numpy.array( u, dtype=numpy.float32 ) + + c = a + b + print(c) + + TestError( c[0]==3.0 ) + TestError( c[1]==3.0 ) + TestError( c[2]==3.0 ) + TestError( c[3]==1.0 ) diff --git a/regtests/typed/float32x4.py b/regtests/typed/float32x4.py new file mode 100644 index 0000000..75c3e26 --- /dev/null +++ b/regtests/typed/float32x4.py @@ -0,0 +1,20 @@ +"""simd float32x4""" + +def main(): + float32x4 a = numpy.array( [1.1, 1.2, 1.3, 0.4], dtype=numpy.float32 ) + float32x4 b = numpy.array( [1.9, 1.8, 1.7, 0.6], dtype=numpy.float32 ) + + c = a + b + print(c) + + if PYTHON == 'PYTHONJS': + TestError( c.x==3.0 ) + TestError( c.y==3.0 ) + TestError( c.z==3.0 ) + TestError( c.w==1.0 ) + + else: + TestError( c[0]==3.0 ) + TestError( c[1]==3.0 ) + TestError( c[2]==3.0 ) + TestError( c[3]==1.0 ) diff --git a/regtests/typed/long.py b/regtests/typed/long.py index 76f637e..cfacbc9 100644 --- a/regtests/typed/long.py +++ b/regtests/typed/long.py @@ -15,3 +15,5 @@ def main(): TestError( y <= b ) TestError( b >= y ) + +## TODO check why this fails when used with translator.py directly (bad indent bug) \ No newline at end of file diff --git a/regtests/webclgl/array_of_array.py b/regtests/webclgl/array_of_array.py new file mode 100644 index 0000000..025863b --- /dev/null +++ b/regtests/webclgl/array_of_array.py @@ -0,0 +1,26 @@ +class myclass: + def __init__(self, s): + self.s = s + def my_method(self): + return self.s + + def run(self, w, h): + self.array = [ [x*y*0.5 for y in range(h)] for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + float* A = self.array + float b = self.my_method() + + for subarray in A: + for j in range( len(self.array[0]) ): + b += subarray[j] + return b + + return gpufunc() + +def main(): + m = myclass( 0.1 ) + r = m.run(8,4) + print(r) \ No newline at end of file diff --git a/regtests/webclgl/array_of_struct.py b/regtests/webclgl/array_of_struct.py new file mode 100644 index 0000000..ff4a18c --- /dev/null +++ b/regtests/webclgl/array_of_struct.py @@ -0,0 +1,41 @@ +'''array of structs''' +from random import random + +class myclass: + def __init__(self, a): self.a = a + def my_method(self): return self.a + + def new_struct(self, g): + return { + 'attr1' : 0.6 + g, + 'attr2' : 0.4 + g + } + + + def run(self, w): + self.array = [ self.new_struct( x ) for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + struct* A = self.array + float b = self.my_method() + + for s in iter(A): + b += s.attr1 + s.attr2 + return b + + return gpufunc() + +def main(): + f = 0.1234 + m = myclass( f ) + r = m.run(8) + print(r) + t = round(r[0]-64.0, 4) + print(t) + f = round(f, 4) + print(f) + ok = f==t + print('test passed: %s' %ok ) + #TestError( f==t ) \ No newline at end of file diff --git a/regtests/webclgl/array_of_structs_with_array.py b/regtests/webclgl/array_of_structs_with_array.py new file mode 100644 index 0000000..e137d8a --- /dev/null +++ b/regtests/webclgl/array_of_structs_with_array.py @@ -0,0 +1,38 @@ +'''struct with array''' +from random import random + +class myclass: + + def new_struct(self, g): + return { + 'num' : g, + 'arr' : [0.1 for s in range(6)] + } + + + def run(self, w): + self.array = [ self.new_struct( x ) for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + struct* A = self.array + float b = 0.0 + + for s in iter(A): + b += s.num + for i in range(len(s.arr)): + b += s.arr[i] + + ## note: assignment of a struct's array member to a variable is not allowed + #float* a = s.arr ## not allowed + + + return b + + return gpufunc() + +def main(): + m = myclass() + r = m.run(8) + print(r) diff --git a/regtests/webclgl/call_external_method.py b/regtests/webclgl/call_external_method.py new file mode 100644 index 0000000..3194a29 --- /dev/null +++ b/regtests/webclgl/call_external_method.py @@ -0,0 +1,31 @@ +"""external method""" + +class myclass: + def __init__(self, i): + self.index = i + + def get_index(self): + return self.index + + def run(self, n): + self.intarray = new(Int16Array(n)) + self.intarray[ self.index ] = 99 + + @returns( array=n ) + @gpu.main + def gpufunc(): + int* A = self.intarray + + ## GLSL compile error: `Index expression must be constant` + #int idx = self.get_index() + #return float( A[idx] ) + + return float( A[self.get_index()] ) + + return gpufunc() + +def main(): + m = myclass(10) + r = m.run(64) + print(r) + TestError( int(r[10])==99 ) \ No newline at end of file diff --git a/regtests/webclgl/dynamic_attributes.py b/regtests/webclgl/dynamic_attributes.py new file mode 100644 index 0000000..ff4fb31 --- /dev/null +++ b/regtests/webclgl/dynamic_attributes.py @@ -0,0 +1,28 @@ +class myclass: + def __init__(self): + self.width = 100 + self.height = 64 + self.step = 0.01 + + def run(self, w, h, s): + self.width = w + self.height = h + self.step = s + + @returns( array=[8,8] ) + @gpu.main + def gpufunc(): + float b = 0.0 + for x in range( self.width ): + for y in range( self.height ): + b += self.step + return b + + return gpufunc() + +def main(): + A = myclass() + r = A.run(4,4, 0.8) + print(r) + r = A.run(16,16, 0.5) + print(r) \ No newline at end of file diff --git a/regtests/webclgl/dynamic_list.py b/regtests/webclgl/dynamic_list.py new file mode 100644 index 0000000..ac12f83 --- /dev/null +++ b/regtests/webclgl/dynamic_list.py @@ -0,0 +1,29 @@ +"""inline dynamic list""" +from random import random + +class G: + def __init__(self): + self.pi = 7/22.0 + self.scale = 0.1 + self.arr1 = [ random() for i in range(4) ] + self.arr2 = [ random()*0.01 for i in range(32) ] + + @returns( array=[16,16] ) + @gpu.main + def gpufunc(x,y,z,w): + float x + float y + float z + float w + float* a = self.arr1 + float m = self.scale + a[3] = 0.5 + return a[0] * self.pi * m + + self.gpufunc = gpufunc + + +def main(): + g = G() + res = g.gpufunc(0.1, 0.2, 0.3, 0.4) + print(res) diff --git a/regtests/webclgl/dynamic_return_size.py b/regtests/webclgl/dynamic_return_size.py new file mode 100644 index 0000000..b90f863 --- /dev/null +++ b/regtests/webclgl/dynamic_return_size.py @@ -0,0 +1,30 @@ +class myclass: + def __init__(self): + self.width = 100 + self.height = 64 + self.step = 0.01 + + def run(self, w, h, s, retw, reth): + self.width = w + self.height = h + self.step = s + + @returns( array=[retw,reth] ) + @gpu.main + def gpufunc(): + float b = 0.0 + for x in range( self.width ): + for y in range( self.height ): + b += self.step + return b + + return gpufunc() + +def main(): + A = myclass() + r = A.run(4,4, 0.8, 16,128) + TestError( len(r)==128 ) + TestError( len(r[0])==16 ) + r = A.run(16,16, 0.5, 64,16) + TestError( len(r[0])==64 ) + TestError( len(r)==16 ) diff --git a/regtests/webclgl/for_loop_dynamic_list.py b/regtests/webclgl/for_loop_dynamic_list.py new file mode 100644 index 0000000..63ce9b9 --- /dev/null +++ b/regtests/webclgl/for_loop_dynamic_list.py @@ -0,0 +1,38 @@ +"""iterate over dynamic list""" +from random import random + +class G: + def __init__(self, s): + self.arr1 = [ random() for i in range(s) ] + + def run(self, X): + + @returns( array=[8,8] ) + @gpu.main + def gpufunc(x): + float x + float* a = self.arr1 + #return float( len(a) ) *0.1 ## this also works + float b = x * 0.5 + for i in range( len(a) ): + b += a[i] + return b + + return gpufunc(X) + + +def main(): + u = -1.0 + g = G(64) + res = g.run( u ) + print(res) + for i in range(3): ## test dynamic size + if i==0: + g.arr1 = [ 0.01 for x in range(8) ] + elif i==1: + g.arr1 = [ 0.01 for x in range(16) ] + else: + g.arr1 = [ 0.01 for x in range(32) ] + + res = g.run( u ) + print(res) \ No newline at end of file diff --git a/regtests/webclgl/gpu_class.py b/regtests/webclgl/gpu_class.py new file mode 100644 index 0000000..85339a0 --- /dev/null +++ b/regtests/webclgl/gpu_class.py @@ -0,0 +1,55 @@ +'''@gpu class''' + +@gpu.object +class MyObject: + ## below `self` is not `this` in javascript + ## `self` is a GLSL struct of MyObject + @gpu.method + float def subroutine(self, x,y): + float x + float y + return x + y * self.attr2 + ## subroutines must be defined ahead of where they are used + + @gpu.method + float def mymethod(self, x,y): + float x + float y + if self.index == 0: + return -20.5 + elif self.index == 0: + return 0.6 + else: + return self.subroutine(x,y) * self.attr1 + + + ## here `self` is javascript's `this` + def __init__(self, a, b, i): + self.attr1 = a + self.attr2 = b + self.index = int16(i) + + + + +class myclass: + def run(self, w): + self.array = [ MyObject( 1.1, 1.2, x ) for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + struct* A = self.array + float b = 0.0 + + for s in iter(A): + b += s.mymethod(1.1, 2.2) + + return b + + return gpufunc() + +def main(): + m = myclass() + r = m.run(8) + print(r) diff --git a/regtests/webclgl/gpu_class_three.py b/regtests/webclgl/gpu_class_three.py new file mode 100644 index 0000000..e5e748d --- /dev/null +++ b/regtests/webclgl/gpu_class_three.py @@ -0,0 +1,45 @@ +'''@gpu class three.js''' +import three + +#three.Vector3.prototype.__struct_name__='ThreeVec3' ## this also works +#three.Vector3.prototype.__struct_name__='vec3' +gpu.object( three.Vector3, 'vec3' ) +#gpu.object( three.Matrix4, 'mat4x4', 'elements') ## note: mat4x4 is not part of WebGLSL +gpu.object( three.Matrix4, 'mat4', 'elements') + +@gpu.object +class MyObject: + @gpu.method + def mymethod(self, s) -> float: + float s + return (self.vec.x + self.vec.y + self.vec.z) * s + + def __init__(self, x,y,z): + self.vec = new( three.Vector3(x,y,z) ) + self.mat = new( three.Matrix4() ) + print('THREE mat4') + print(self.mat) + + + +class myclass: + def run(self, w): + self.array = [ MyObject( 1.1, 1.2, 1.3 ) for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + struct* A = self.array + float b = 0.0 + + for s in iter(A): + b += s.mymethod(1.1) + + return b + + return gpufunc() + +def main(): + m = myclass() + r = m.run(8) + print(r) diff --git a/regtests/webclgl/gpu_sibling_class.py b/regtests/webclgl/gpu_sibling_class.py new file mode 100644 index 0000000..5696e41 --- /dev/null +++ b/regtests/webclgl/gpu_sibling_class.py @@ -0,0 +1,57 @@ +'''@gpu sibling class''' +import three + +gpu.object( three.Vector3, 'vec3' ) + +@gpu.object +class Other: + #@gpu.method + def __init__(self, a, b): + #vec3 a + #vec3 b + self.vecA = a + self.vecB = b + + @gpu.method + float def omethod(self, s): + float s + return (self.vecA.x + self.vecA.y + self.vecB.z) * s + + +@gpu.object +class MyObject: + @typedef( ob=Other ) + @gpu.method + float def mymethod(self, s): + float s + #o = Other( self.v1, self.v2 ) + #return o.omethod(s) + return self.ob.omethod(s) + + def __init__(self, x,y,z): + self.v1 = new( three.Vector3(x,y,z) ) + self.v2 = new( three.Vector3(x,y,z) ) + self.ob = Other(self.v1, self.v2) + + +class myclass: + def run(self, w): + self.array = [ MyObject( 1.1, 1.2, 1.3 ) for x in range(w) ] + + @returns( array=64 ) + @gpu.main + def gpufunc(): + struct* A = self.array + float b = 0.0 + + for s in iter(A): + b += s.mymethod(1.1) + + return b + + return gpufunc() + +def main(): + m = myclass() + r = m.run(8) + print(r) diff --git a/regtests/webclgl/hello_gpu.py b/regtests/webclgl/hello_gpu.py new file mode 100644 index 0000000..2161d3a --- /dev/null +++ b/regtests/webclgl/hello_gpu.py @@ -0,0 +1,19 @@ +"""gpu test""" + +def main(): + @returns( array=[4,16]) + @gpu.main + def myfunc(a, b, num): + float* a + float* b + float num + vec2 n = get_global_id() ## WebCL API + float result = 0.0 + for i in range(1000): + result = sqrt(result + a[n] + b[n] + float(i)) + return result * num + + A = [ 0.5 for x in range(64) ] + B = [ 0.25 for x in range(64) ] + res = myfunc( A, B, 0.1 ) + print(res) \ No newline at end of file diff --git a/regtests/webclgl/inline_objects.py b/regtests/webclgl/inline_objects.py new file mode 100644 index 0000000..c2e7e32 --- /dev/null +++ b/regtests/webclgl/inline_objects.py @@ -0,0 +1,25 @@ +"""inline dynamic object data""" +class A: + def __init__(self, value): + self.readonly_attr = value + +def main(): + def my_wrapper(a,b, x,y,z,w): + + @returns( array=[32,32] ) + @gpu.main + def gpufunc(x,y,z,w): + float x + float y + float z + float w + float D = a.readonly_attr + vec4 V = vec4( x+D, y+b.readonly_attr,z,w) + return V.x + + return gpufunc(x,y,z,w) + + ai = A(22/7.0) + bi = A(0.420) + res = my_wrapper(ai,bi, 0.1, 0.2, 0.3, 0.4) + print(res) diff --git a/regtests/webclgl/integer_array.py b/regtests/webclgl/integer_array.py new file mode 100644 index 0000000..be2df5f --- /dev/null +++ b/regtests/webclgl/integer_array.py @@ -0,0 +1,21 @@ +"""integer array""" + +class myclass: + def __init__(self): + pass + def run(self, n): + self.intarray = new(Int16Array(n)) + self.intarray[0] = 100 + @returns( array=n ) + @gpu.main + def gpufunc(): + int* A = self.intarray + return float( A[0] ) + + return gpufunc() + +def main(): + m = myclass() + r = m.run(64) + print(r) + TestError( int(r[0])==100 ) \ No newline at end of file diff --git a/regtests/webclgl/mandel.py b/regtests/webclgl/mandel.py new file mode 100644 index 0000000..9bd2ca9 --- /dev/null +++ b/regtests/webclgl/mandel.py @@ -0,0 +1,54 @@ +"""mandelbrot""" + +def pprint(arr, w): + x = [] + for a in arr: + x.append(a) + if len(x) >= w: + print( [ round(y,2) for y in x] ) + x = [] + +def main(): + + #@gpu.returns( array=[32,32], vec4=[4,4] ) ## TODO support dual return + @returns( array=[32,32] ) + @gpu.main + def gpufunc(): + + vec2 c = get_global_id() + #float cx = 0.5 + #float cy = 0.5 + + float hue; + float saturation; + float value; + float hueRound; + int hueIndex; + float f; + float p; + float q; + float t; + + + float x = 0.0; + float y = 0.0; + float tempX = 0.0; + int i = 0; + int runaway = 0; + for i in range(100): + tempX = x * x - y * y + float(c.x); + y = 2.0 * x * y + float(c.y); + x = tempX; + if runaway == 0 and x * x + y * y > 100.0: + runaway = i; + + return float(runaway) * 0.01 + + w = 32 + h = 32 + + #A = [w,h] + + res = gpufunc() + pprint(res, w) + diff --git a/regtests/webclgl/mandel_purepy.py b/regtests/webclgl/mandel_purepy.py new file mode 100644 index 0000000..5071a13 --- /dev/null +++ b/regtests/webclgl/mandel_purepy.py @@ -0,0 +1,39 @@ +"""mandelbrot pure python""" + +def pprint(arr, w): + x = [] + for a in arr: + x.append(a) + if len(x) >= w: + print( [ round(y,2) for y in x] ) + x = [] + +def main(): + + @returns( array=[64,64] ) + @typedef( x=float, y=float, tempX=float, i=int, runaway=int, c=vec2) + @gpu.main + def gpufunc(): + c = get_global_id() + x = 0.0 + y = 0.0 + tempX = 0.0 + i = 0 + runaway = 0 + for i in range(100): + tempX = x * x - y * y + float(c.x) + y = 2.0 * x * y + float(c.y) + x = tempX + if runaway == 0 and x * x + y * y > 100.0: + runaway = i + + return float(runaway) * 0.01 + + res = gpufunc() + print(res) + TestError( len(res)==64*64 ) + + #pprint(res, 32) + #for row in res: + # a = [ round(v,3) for v in row ] + # print( a ) diff --git a/regtests/webclgl/returns_vec4.py b/regtests/webclgl/returns_vec4.py new file mode 100644 index 0000000..0fa3dcb --- /dev/null +++ b/regtests/webclgl/returns_vec4.py @@ -0,0 +1,17 @@ +"""while loop""" + + +def main(): + + @returns( vec4=[2,32] ) + @gpu.main + def gpufunc(x,y,z,w): + float x + float y + float z + float w + vec4 V = vec4(x,y,z,w) + return V + + res = gpufunc( 0.1, 0.2, 0.3, 0.4 ) + print(res) diff --git a/regtests/webclgl/slice_dynamic_list.py b/regtests/webclgl/slice_dynamic_list.py new file mode 100644 index 0000000..b80fc3a --- /dev/null +++ b/regtests/webclgl/slice_dynamic_list.py @@ -0,0 +1,40 @@ +"""slice and iterate over dynamic list""" +from random import random + +class G: + def __init__(self, s): + self.arr1 = [ random() for i in range(s) ] + + def func(self, x,y): + return x+y + + def run(self, X): + + @returns( array=[8,8] ) + @gpu.main + def gpufunc(x): + float x + float b = self.func(1.1, 2.1) #x * 0.5 + float* a = self.arr1[ 4: ] + for i in range( len(a) ): + b += a[i] + return b + + return gpufunc(X) + + +def main(): + u = -1.0 + g = G(10) + res = g.run( u ) + print(res) + for i in range(3): ## test dynamic size + if i==0: + g.arr1 = [ 0.01 for x in range(8) ] + elif i==1: + g.arr1 = [ 0.01 for x in range(16) ] + else: + g.arr1 = [ 0.01 for x in range(32) ] + + res = g.run( u ) + print(res) \ No newline at end of file diff --git a/regtests/webclgl/subroutine.py b/regtests/webclgl/subroutine.py new file mode 100644 index 0000000..6850832 --- /dev/null +++ b/regtests/webclgl/subroutine.py @@ -0,0 +1,20 @@ +"""subroutine""" + +def main(): + @gpu + float def mysub(x,y): + float x + float y + return x-y + + @returns( array=64 ) + @gpu.main + def myfunc(a): + float* a + vec2 id = get_global_id() + return mysub( 1.1 * a[id], 2.2 ) + + + A = [1.3 for i in range(64)] + res = myfunc( A ) + print(res) \ No newline at end of file diff --git a/regtests/webclgl/three_returns_mat4.py b/regtests/webclgl/three_returns_mat4.py new file mode 100644 index 0000000..fdeb955 --- /dev/null +++ b/regtests/webclgl/three_returns_mat4.py @@ -0,0 +1,50 @@ +'''@gpu class three.js''' +import three + +gpu.object( three.Matrix4, 'mat4', 'elements') + +@gpu.object +class MyObject: + @gpu.method + def mymethod(self, other) -> mat4: + mat4 other + return self.mat * other + + def __init__(self, x): + self.mat = new( three.Matrix4() ) + print('THREE mat4') + print(dir(self.mat)) + for i in range(16): + self.mat.elements[i] = i*10 + self.mat.multiplyScalar(x) + + + + +class myclass: + def run(self, w): + self.array = [ MyObject( x+1.0 ) for x in range(w) ] + + @typedef(o=MyObject) + @gpu.main + def gpufunc() -> mat4: + struct* A = self.array + mat4 b = mat4(1.0) + #mat4 c = mat4(1.1) + + #for s in iter(A): + # b *= s.mymethod(c) + + o = A[...] ## gets the current index in gpufunc.return_matrices + return o.mat #.mymethod(b) + + for ob in self.array: + gpufunc.return_matrices.append( ob.mat.elements ) + + return gpufunc() + +def main(): + m = myclass() + r = m.run(8) + for a in r: + print(a) diff --git a/regtests/webclgl/while_loop.py b/regtests/webclgl/while_loop.py new file mode 100644 index 0000000..85e5816 --- /dev/null +++ b/regtests/webclgl/while_loop.py @@ -0,0 +1,17 @@ +"""while loop""" + + +def main(): + + @returns( array=[32,32] ) + @gpu.main + def gpufunc(): + int i = 0 + while i < 10: + i += 1 + return float(i) * 0.01 + + res = gpufunc() + for row in res: + a = [ round(v,3) for v in row ] + print( a )