Skip to content

Commit 4d5b4a8

Browse files
author
hartsantler
committed
new function expression syntax.
1 parent 7ab57cf commit 4d5b4a8

5 files changed

Lines changed: 38 additions & 7 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ a = {}
139139
b = a['somekey'] except KeyError: 'my-default'
140140
```
141141

142+
. function expressions
143+
```
144+
F = function(x):
145+
return x
146+
```
142147

143148
Speed
144149
---------------

pythonjs/python_to_pythonjs.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,7 @@ def visit_FunctionDef(self, node):
25922592
gpu_vectorize = False
25932593
gpu_method = False
25942594
local_typedefs = []
2595+
func_expr = None
25952596

25962597
## deprecated?
25972598
self._cached_property = None
@@ -2605,6 +2606,10 @@ def visit_FunctionDef(self, node):
26052606
if isinstance(decorator, Name) and decorator.id == 'gpu':
26062607
gpu = True
26072608

2609+
elif isinstance(decorator, Call) and decorator.func.id == 'expression':
2610+
assert len(decorator.args)==1
2611+
func_expr = self.visit(decorator.args[0])
2612+
26082613
elif isinstance(decorator, Call) and decorator.func.id == 'typedef':
26092614
c = decorator
26102615
assert len(c.args) == 0 and len(c.keywords)
@@ -2780,6 +2785,9 @@ def visit_FunctionDef(self, node):
27802785
if args_typedefs:
27812786
writer.write('@__typedef__(%s)' %','.join(args_typedefs))
27822787

2788+
if func_expr:
2789+
writer.write('@expression(%s)' %func_expr)
2790+
27832791

27842792
if not self._with_dart and not self._with_lua and not self._with_js and not javascript and not self._with_glsl:
27852793
writer.write('@__pyfunction__')

pythonjs/pythonjs.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False, functio
3838
self._exports = set()
3939
self._inline_lambda = False
4040

41-
self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__'])
41+
self.special_decorators = set(['__typedef__', '__glsl__', '__pyfunction__', 'expression'])
4242
self._glsl = False
4343
self._has_glsl = False
4444
self._typed_vars = dict()
@@ -242,8 +242,15 @@ def _visit_function(self, node):
242242
gpu_vectorize = False
243243
gpu_method = False
244244
args_typedefs = {}
245+
func_expr = False
246+
245247
for decor in node.decorator_list:
246-
if isinstance(decor, ast.Name) and decor.id == '__pyfunction__':
248+
if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'expression':
249+
assert len(decor.args)==1
250+
func_expr = True
251+
node.name = self.visit(decor.args[0])
252+
253+
elif isinstance(decor, ast.Name) and decor.id == '__pyfunction__':
247254
is_pyfunc = True
248255
elif isinstance(decor, ast.Name) and decor.id == '__glsl__':
249256
glsl = True
@@ -473,10 +480,13 @@ def _visit_function(self, node):
473480
elif len(self._function_stack) == 1:
474481
## this style will not make function global to the eval context in NodeJS ##
475482
#buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args))
476-
## this is required for eval to be able to work in NodeJS, note there is no var keyword.
477483

478-
if self._func_expressions:
479-
buffer = self.indent() + '%s = function(%s) {\n' % (node.name, ', '.join(args))
484+
## note if there is no var keyword and this function is at the global level,
485+
## then it should be callable from eval in NodeJS - this is not correct.
486+
## infact, var should always be used with function expressions.
487+
488+
if self._func_expressions or func_expr:
489+
buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args))
480490
else:
481491
buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args))
482492

@@ -485,7 +495,7 @@ def _visit_function(self, node):
485495

486496
else:
487497

488-
if self._func_expressions:
498+
if self._func_expressions or func_expr:
489499
buffer = self.indent() + 'var %s = function(%s) {\n' % (node.name, ', '.join(args))
490500
else:
491501
buffer = self.indent() + 'function %s(%s) {\n' % (node.name, ', '.join(args))

pythonjs/typedpython.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def transform_source( source, strip=False ):
6565
if '= function(' in c:
6666
k = '= function('
6767
a,b = c.split(k)
68-
output.append( '@func_expression(%s)' %a.strip())
68+
output.append( '@expression(%s)' %a.strip())
6969
c = 'def __NAMELESS__(' + b
7070

7171
if ' except ' in c: ## PEP 463 - exception expressions
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""func expr"""
2+
3+
F = function( x,y ):
4+
return x+y
5+
6+
def main():
7+
TestError( F(1,2) == 3 )
8+

0 commit comments

Comments
 (0)