Skip to content

Commit af64cfd

Browse files
author
hartsantler
committed
refactoring requirejs imports, allow import with dash import a-b because many npm package names use dash.
1 parent 0a56457 commit af64cfd

8 files changed

Lines changed: 96 additions & 76 deletions

File tree

pythonjs/python_to_pythonjs.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,14 @@ def visit_Import(self, node):
381381
writer.write( 'if __NODEJS__==True and typeof(Worker)=="undefined": Worker = require("workerjs")')
382382

383383
elif alias.asname:
384-
writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.asname, alias.name) )
384+
#writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.asname, alias.name) )
385+
writer.write( '''inline("var %s = require('%s')")''' %(alias.asname, alias.name.replace('__DASH__', '-')) )
385386

386387
elif '.' in alias.name:
387388
raise NotImplementedError('import with dot not yet supported: line %s' % node.lineno)
388389
else:
389-
writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.name, alias.name) )
390+
#writer.write( '''inline("var %s = requirejs('%s')")''' %(alias.name, alias.name) )
391+
writer.write( '''inline("var %s = require('%s')")''' %(alias.name, alias.name) )
390392

391393
def visit_ImportFrom(self, node):
392394
if self._with_dart:
@@ -1145,6 +1147,8 @@ def visit_TryExcept(self, node):
11451147
map(self.visit, node.body)
11461148
writer.pull()
11471149
map(self.visit, node.handlers)
1150+
if len(node.handlers)==0:
1151+
raise SyntaxError(self.format_error('no except handlers'))
11481152

11491153
def visit_Raise(self, node):
11501154
#if self._with_js or self._with_dart:
@@ -2693,19 +2697,6 @@ def visit_FunctionDef(self, node):
26932697
writer.write('self.onmessage = onmessage' )
26942698

26952699

2696-
if return_type or return_type_keywords:
2697-
if return_type_keywords and return_type:
2698-
kw = ['%s=%s' %(k,v) for k,v in return_type_keywords.items()]
2699-
writer.write('@returns(%s, %s)' %(return_type,','.join(kw)) )
2700-
elif return_type_keywords:
2701-
writer.write('@returns(%s)' %','.join( ['%s=%s' %(k,v) for k,v in return_type_keywords.items()] ))
2702-
else:
2703-
writer.write('@returns(%s)' %return_type)
2704-
2705-
if gpu_vectorize:
2706-
writer.write('@gpu.vectorize')
2707-
if gpu_method:
2708-
writer.write('@gpu.method')
27092700

27102701
## force python variable scope, and pass user type information to second stage of translation.
27112702
## the dart backend can use this extra type information.
@@ -2718,6 +2709,7 @@ def visit_FunctionDef(self, node):
27182709
raise SyntaxError( self.format_error(err) )
27192710

27202711
local_vars = local_vars-global_vars
2712+
inlined_long = False
27212713
if local_vars:
27222714
args_typedefs = []
27232715
args = [ a.id for a in node.args.args ]
@@ -2730,7 +2722,8 @@ def visit_FunctionDef(self, node):
27302722
t = t[0].upper() + t[1:]
27312723
v = '%s=%s' %(n,t) ## reverse
27322724
local_typedef_names.add( n )
2733-
if t == 'long':
2725+
if t == 'long' and inlined_long == False:
2726+
inlined_long = True
27342727
writer.write('''inline("if (__NODEJS__==true) var long = require('long')")''') ## this is ugly
27352728

27362729
if n in args:
@@ -2744,6 +2737,24 @@ def visit_FunctionDef(self, node):
27442737
writer.write('@__typedef__(%s)' %','.join(args_typedefs))
27452738

27462739

2740+
if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl:
2741+
writer.write('@__pyfunction__')
2742+
2743+
if return_type or return_type_keywords:
2744+
if return_type_keywords and return_type:
2745+
kw = ['%s=%s' %(k,v) for k,v in return_type_keywords.items()]
2746+
writer.write('@returns(%s, %s)' %(return_type,','.join(kw)) )
2747+
elif return_type_keywords:
2748+
writer.write('@returns(%s)' %','.join( ['%s=%s' %(k,v) for k,v in return_type_keywords.items()] ))
2749+
else:
2750+
writer.write('@returns(%s)' %return_type)
2751+
2752+
if gpu_vectorize:
2753+
writer.write('@gpu.vectorize')
2754+
if gpu_method:
2755+
writer.write('@gpu.method')
2756+
2757+
27472758
if self._with_dart:
27482759
## dart supports optional positional params [x=1, y=2], or optional named {x:1, y:2}
27492760
## but not both at the same time.
@@ -3087,8 +3098,8 @@ def visit_FunctionDef(self, node):
30873098

30883099
writer.pull() ## end function body
30893100

3090-
if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl:
3091-
writer.write('%s.pythonscript_function=True'%node.name)
3101+
#if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl:
3102+
# writer.write('%s.pythonscript_function=True'%node.name)
30923103

30933104

30943105
if gpu:

pythonjs/pythonjs.js

Lines changed: 38 additions & 43 deletions
Large diffs are not rendered by default.

pythonjs/pythonjs.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False, functio
3232
self._webworker = webworker
3333
self._exports = set()
3434

35-
self.special_decorators = set(['__typedef__', '__glsl__'])
35+
self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__'])
3636
self._glsl = False
3737
self._has_glsl = False
3838
self._typed_vars = dict()
@@ -215,6 +215,7 @@ def _visit_call_helper_var_glsl(self, node):
215215

216216
def _visit_function(self, node):
217217
is_main = node.name == 'main'
218+
is_pyfunc = False
218219
return_type = None
219220
glsl = False
220221
glsl_wrapper_name = False
@@ -223,7 +224,9 @@ def _visit_function(self, node):
223224
gpu_method = False
224225
args_typedefs = {}
225226
for decor in node.decorator_list:
226-
if isinstance(decor, ast.Name) and decor.id == '__glsl__':
227+
if isinstance(decor, ast.Name) and decor.id == '__pyfunction__':
228+
is_pyfunc = True
229+
elif isinstance(decor, ast.Name) and decor.id == '__glsl__':
227230
glsl = True
228231
elif isinstance(decor, ast.Attribute) and isinstance(decor.value, ast.Name) and decor.value.id == '__glsl__':
229232
glsl_wrapper_name = decor.attr
@@ -371,7 +374,7 @@ def _visit_function(self, node):
371374
lines.append(' var __webclgl = new WebCLGL()')
372375
lines.append(' var header = glsljit.compile_header()')
373376
lines.append(' var shader = glsljit.compile_main()')
374-
lines.append(' console.log(shader)')
377+
#lines.append(' console.log(shader)')
375378
## create the webCLGL kernel, compiles GLSL source
376379
lines.append(' var __kernel = __webclgl.createKernel( shader, header );')
377380

@@ -425,7 +428,7 @@ def _visit_function(self, node):
425428
elif 'mat4' in gpu_return_types:
426429
lines.append(' var rbuffer = __webclgl.createBuffer([4,glsljit.matrices.length], "FLOAT4", __offset)')
427430
lines.append(' __webclgl.enqueueNDRangeKernel(__kernel, rbuffer)')
428-
lines.append(' var __res = __webclgl.enqueueReadBuffer_Float4( rbuffer )')
431+
lines.append(' var __res = __webclgl.enqueueReadBuffer_Float4( rbuffer )') ## slow
429432
lines.append(' return glsljit.unpack_mat4(__res)')
430433
else:
431434
raise SyntaxError('invalid GPU return type: %s' %gpu_return_types)
@@ -442,7 +445,7 @@ def _visit_function(self, node):
442445

443446
return '\n'.join(lines)
444447

445-
elif len(node.decorator_list)==1 and not ( isinstance(node.decorator_list[0], ast.Call) and node.decorator_list[0].func.id not in self.special_decorators ):
448+
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):
446449
dec = self.visit(node.decorator_list[0])
447450
buffer = self.indent() + '%s.%s = function(%s) {\n' % (dec,node.name, ', '.join(args))
448451

@@ -481,6 +484,8 @@ def _visit_function(self, node):
481484
buffer += '\n'.join(body)
482485
self.pull()
483486
buffer += '\n%s}\n' %self.indent()
487+
if is_pyfunc:
488+
buffer += ';%s.is_wrapper = true;' %node.name ## TODO change to .__pyfunc__
484489
return buffer
485490

486491
def _visit_subscript_ellipsis(self, node):
@@ -1086,6 +1091,7 @@ def generate_runtime():
10861091
return '\n'.join( lines )
10871092

10881093
def main(script, requirejs=True, insert_runtime=True, webworker=False, function_expressions=False):
1094+
#print(script)
10891095
tree = ast.parse( script )
10901096
return JSGenerator( requirejs=requirejs, insert_runtime=insert_runtime, webworker=webworker, function_expressions=function_expressions ).visit(tree)
10911097

pythonjs/runtime/builtins.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def push(self, s):
6363

6464
def define_structure(self, ob):
6565
struct_name = None
66-
##if Object.hasOwnProperty(ob,'__struct_name__'): ## this is not right?
66+
#if Object.hasOwnProperty.call(ob,'__struct_name__'):
6767
if ob.__struct_name__:
6868
struct_name = ob.__struct_name__
6969
if struct_name in self.struct_types:
@@ -128,9 +128,9 @@ def define_structure(self, ob):
128128

129129
members = ''.join(member_list)
130130
code = 'struct ' +struct_name+ ' {' +members+ '};'
131-
print('-------struct glsl code-------')
132-
print(code)
133-
print('------------------------------')
131+
#print('-------struct glsl code-------')
132+
#print(code)
133+
#print('------------------------------')
134134
self.struct_types[ struct_name ] = {
135135
'arrays' : arrays,
136136
'floats' : floats,
@@ -291,14 +291,11 @@ def unpack_vec4(self, arr, dims):
291291
return rows
292292

293293
def unpack_mat4(self, arr):
294-
print('unpack_mat4')
295-
print(arr)
296294
i = 0
297295
for mat in self.matrices:
298296
for j in range(16):
299297
mat[j] = arr[i]
300298
i += 1
301-
302299
return self.matrices
303300

304301
with lowlevel:
@@ -652,7 +649,7 @@ def __call__():
652649

653650
return object
654651

655-
__call__.pythonscript_function = True
652+
__call__.is_wrapper = True
656653
klass.__call__ = __call__
657654
return klass
658655

pythonjs/runtime/pythonpythonjs.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,13 @@ def __get__(object, attribute, error_message):
5656
else:
5757
raise AttributeError('undefined has no attribute: ' +attribute)
5858

59+
#if attribute == '__getitem__' and instanceof(object, Array): ## NOT REQUIRED
60+
# ## allows list comp on Array called from Python-mode ##
61+
# def wrapper(args,kwargs): return object[ args[0] ]
62+
# wrapper.is_wrapper = True
63+
# return wrapper
5964
if attribute == '__call__':
60-
if object.pythonscript_function or object.is_wrapper: ## common case
65+
if object.pythonscript_function or object.is_wrapper: ## common case - TODO replaced by __pyfunc__
6166
return object
6267
elif object.cached_wrapper: ## rare case
6368
return object.cached_wrapper
@@ -124,7 +129,7 @@ def wrapper(args,kwargs): return attr.apply(object, args)
124129
## attr can be null and will return, undefined will raise AttributeError ##
125130
if attr is not undefined:
126131
if typeof(attr) == 'function':
127-
if JS("attr.pythonscript_function === undefined && attr.is_wrapper === undefined"):
132+
if JS("attr.pythonscript_function === undefined && attr.is_wrapper === undefined"): ## TODO pythonscript_function will be replaced with __pyfunc__
128133

129134
## if there is a prototype with methods, then we can be sure that the user indends to call `new` on it,
130135
## however rare, it is still possible that it is a constructor without a prototype of any length,

pythonjs/typedpython.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ def transform_source( source, strip=False ):
7676
break
7777
indent = ''.join(indent)
7878
output.append( indent + '@returns(%s)' %rtype)
79+
elif c.startswith('import ') and '-' in c:
80+
c = c.replace('-', '__DASH__')
81+
7982

8083
output.append( c )
8184

regtests/run.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ def method(self, f):
365365
returns = __faker__()
366366
typedef = __faker__()
367367
vec2 = None
368+
mat4 = None
368369
369370
def int16(a): return int(a)
370371

regtests/typed/long.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ def main():
1515

1616
TestError( y <= b )
1717
TestError( b >= y )
18+
19+
## TODO check why this fails when used with translator.py directly (bad indent bug)

0 commit comments

Comments
 (0)