Skip to content

Commit 71c9c58

Browse files
author
hartsantler
committed
fixed <- go syntax
1 parent 702975b commit 71c9c58

5 files changed

Lines changed: 58 additions & 32 deletions

File tree

pythonjs/python_to_pythonjs.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,9 @@ def visit_Call(self, node):
20662066

20672067

20682068
name = self.visit(node.func)
2069+
if name in typedpython.GO_SPECIAL_CALLS:
2070+
name = typedpython.GO_SPECIAL_CALLS[ name ]
2071+
return '%s( %s )' %(name, self.visit(node.args[0]))
20692072

20702073
if self._with_rpc:
20712074
if not self._with_rpc_name:
@@ -2514,7 +2517,7 @@ def visit_Call(self, node):
25142517

25152518
elif hasattr(node,'constant') or name in self._builtin_functions:
25162519
if args and kwargs:
2517-
return '%s([%s], {%s})' %(args, kwargs)
2520+
return '%s([%s], {%s})' %(name, args, kwargs)
25182521
elif args:
25192522
return '%s([%s], __NULL_OBJECT__)' %(name,args)
25202523
elif kwargs:
@@ -2998,19 +3001,19 @@ def visit_FunctionDef(self, node):
29983001
# First check the arguments are well formed
29993002
# ie. that this function is not a callback of javascript code
30003003

3004+
if not self._with_go:
3005+
writer.write("""if instanceof(args,Array) and Object.prototype.toString.call(kwargs) == '[object Object]' and arguments.length==2:""")
3006+
writer.push()
3007+
writer.write('pass') # do nothing if it's not called from javascript
3008+
writer.pull()
30013009

3002-
writer.write("""if instanceof(args,Array) and Object.prototype.toString.call(kwargs) == '[object Object]' and arguments.length==2:""")
3003-
writer.push()
3004-
writer.write('pass') # do nothing if it's not called from javascript
3005-
writer.pull()
3006-
3007-
writer.write('else:')
3008-
writer.push()
3009-
# If it's the case, move use ``arguments`` to ``args``
3010-
writer.write('args = Array.prototype.slice.call(arguments, 0, __sig__.args.length)')
3011-
# This means you can't pass keyword argument from javascript but we already knew that
3012-
writer.write('kwargs = JSObject()')
3013-
writer.pull()
3010+
writer.write('else:')
3011+
writer.push()
3012+
# If it's the case, move use ``arguments`` to ``args``
3013+
writer.write('args = Array.prototype.slice.call(arguments, 0, __sig__.args.length)')
3014+
# This means you can't pass keyword argument from javascript but we already knew that
3015+
writer.write('kwargs = JSObject()')
3016+
writer.pull()
30143017

30153018

30163019

@@ -3665,7 +3668,7 @@ def visit_With(self, node):
36653668
self._with_js = True
36663669
writer.write('with %s:' %self.visit(node.context_expr))
36673670
self._with_js = restore
3668-
3671+
36693672
writer.push()
36703673
for b in node.body:
36713674
a = self.visit(b)

pythonjs/pythonjs.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -672,10 +672,16 @@ def _visit_call_helper_new(self, node):
672672
else:
673673
raise SyntaxError( args )
674674

675+
def _visit_call_helper_go( self, node ):
676+
raise NotImplementedError('go call')
677+
678+
675679
def visit_Call(self, node):
676680
name = self.visit(node.func)
681+
if name in typedpython.GO_SPECIAL_CALLS.values():
682+
return self._visit_call_helper_go( node )
677683

678-
if self._glsl and isinstance(node.func, ast.Attribute):
684+
elif self._glsl and isinstance(node.func, ast.Attribute):
679685
if isinstance(node.func.value, ast.Name) and node.func.value.id in self._typed_vars:
680686
args = ','.join( [self.visit(a) for a in node.args] )
681687
return '`__struct_name__`_%s(%s, %s)' %(node.func.attr, node.func.value.id, args)
@@ -923,12 +929,13 @@ def visit_Str(self, node):
923929
return '"%s"' % s
924930

925931
def visit_BinOp(self, node):
926-
if isinstance(node.op, ast.Eq):
927-
raise SyntaxError('xx-')
928932
left = self.visit(node.left)
929933
op = self.visit(node.op)
930934
right = self.visit(node.right)
931935

936+
if left in ('__go__receive__', '__go__send__') and op == '<<':
937+
return '<- %s' %right
938+
932939
if left in self._typed_vars and self._typed_vars[left] == 'numpy.float32':
933940
left += '[_id_]'
934941
if right in self._typed_vars and self._typed_vars[right] == 'numpy.float32':

pythonjs/pythonjs_to_go.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ def visit_Module(self, node):
4444
lines = header + lines
4545
return '\n'.join( lines )
4646

47+
def _visit_call_helper_go(self, node):
48+
name = self.visit(node.func)
49+
if name == '__go__':
50+
return 'go %s' %self.visit(node.args[0])
51+
elif name == '__gomake__':
52+
return 'make(%s)' %self.visit(node.args[0])
53+
else:
54+
return SyntaxError('invalid special go call')
55+
4756
def visit_FunctionDef(self, node):
4857
args = self.visit(node.args)
4958
out = []
@@ -76,14 +85,12 @@ def _visit_call_helper_var(self, node):
7685
def visit_Assign(self, node):
7786
target = node.targets[0]
7887
if isinstance(target, ast.Tuple):
79-
raise NotImplementedError('target tuple assignment should have been transformed to flat assignment by python_to_pythonjs.py')
80-
elif isinstance(node.value, ast.Attribute) and node.value.attr in ('__go__send__','__go__receive__'):
88+
raise NotImplementedError('TODO')
89+
90+
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__':
8191
target = self.visit(target)
82-
value = self.visit(node.value.value)
83-
if node.value.attr == '__go__send__':
84-
return 'var %s <- %s;' % (target, value)
85-
else:
86-
return 'var %s = <-%s;' % (target, value)
92+
value = self.visit(node.value.right)
93+
return 'var %s <- %s;' % (target, value)
8794

8895
else:
8996
target = self.visit(target)

pythonjs/typedpython.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121

2222
__whitespace = [' ', '\t']
2323

24+
GO_SPECIAL_CALLS = {
25+
'go' : '__go__',
26+
'go.channel' : '__gomake__',
27+
}
28+
2429
def transform_source( source, strip=False ):
2530
output = []
2631
output_post = None
@@ -142,9 +147,12 @@ def transform_source( source, strip=False ):
142147

143148
if '<-' in c:
144149
if '=' in c:
145-
c = c.replace('<-', '') + '.__go__receive__'
150+
c = c.replace('<-', '__go__receive__<<')
146151
else:
147-
c = c.replace('<-', '=') + '.__go__send__'
152+
## keeping `=` allows for compatible transform to stacklessPython API,
153+
## this is not used now because it is not required by the Go backend.
154+
c = c.replace('<-', '= __go__send__<<')
155+
#c = c.replace('<-', '<<__go__send__<<')
148156

149157

150158
## X.method.bind(X) shortcut `->`
@@ -320,9 +328,9 @@ def xxx():
320328
if True:
321329
d = a[ 'somekey' ] except KeyError: 'mydefault'
322330
323-
## <- becomes a.__go__send__
331+
## <- becomes __go__send__<<a
324332
g <- a
325-
## = <- becomes b.__go__receive__
333+
## = <- becomes __go__receive__<<b
326334
g = <- b
327335
328336
def wrapper(a:int, chan c:int):

regtests/go/chan.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"""a <- """
2-
import go
32

43
def main():
5-
c = go.make_channel(int)
4+
c = go.channel(int)
65

76
def wrapper(a:int, chan c:int):
8-
result = longCalculation(a)
7+
result = 100
98
c <- result
109

11-
go( wrapper(17, c) )
10+
go(
11+
wrapper(17, c)
12+
)
1213

1314
# Do other work in the current goroutine until the channel has a result.
1415

0 commit comments

Comments
 (0)