Skip to content

Commit 276b5f7

Browse files
author
hartsantler
committed
Go backend: fixed chan test, and sending data over a channel.
1 parent c7a7744 commit 276b5f7

4 files changed

Lines changed: 29 additions & 17 deletions

File tree

pythonjs/python_to_pythonjs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,6 +2780,7 @@ def visit_FunctionDef(self, node):
27802780
local_typedefs.append( '%s=%s' %(kw.arg, kwval))
27812781
if decorator.func.id=='typedef_chan':
27822782
typedef_chans.append( kw.arg )
2783+
writer.write('@__typedef_chan__(%s=%s)' %(kw.arg, kwval))
27832784
else:
27842785
writer.write('@__typedef__(%s=%s)' %(kw.arg, kwval))
27852786

pythonjs/pythonjs_to_go.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,26 @@ def _visit_call_helper_go(self, node):
217217
return 'go %s' %self.visit(node.args[0])
218218
elif name == '__gomake__':
219219
return 'make(%s)' %self.visit(node.args[0])
220+
elif name == '__go_make_chan__':
221+
return 'make(chan %s)' %self.visit(node.args[0])
220222
else:
221-
return SyntaxError('invalid special go call')
223+
raise SyntaxError('invalid special go call')
222224

223225
def _visit_function(self, node):
224226
if self._function_stack[0] is node:
225227
self._vars = set()
226228

227229
args_typedefs = {}
230+
chan_args_typedefs = {}
228231
return_type = None
229232
for decor in node.decorator_list:
230233
if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__':
231234
for key in decor.keywords:
232235
#args_typedefs[ key.arg ] = key.value.id
233236
args_typedefs[ key.arg ] = self.visit(key.value)
237+
elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef_chan__':
238+
for key in decor.keywords:
239+
chan_args_typedefs[ key.arg ] = self.visit(key.value)
234240
elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'returns':
235241
if decor.keywords:
236242
raise SyntaxError('invalid go return type')
@@ -248,7 +254,7 @@ def _visit_function(self, node):
248254
for i, arg in enumerate(node.args.args):
249255
arg_name = arg.id
250256

251-
if arg_name not in args_typedefs:
257+
if arg_name not in args_typedefs.keys()+chan_args_typedefs.keys():
252258
if arg_name=='self':
253259
assert i==0
254260
is_method = True
@@ -258,8 +264,13 @@ def _visit_function(self, node):
258264
err += '\n missing typedef: %s' %arg.id
259265
raise SyntaxError(err)
260266

261-
arg_type = args_typedefs[arg_name]
262-
a = '%s %s' %(arg_name, arg_type)
267+
if arg_name in args_typedefs:
268+
arg_type = args_typedefs[arg_name]
269+
a = '%s %s' %(arg_name, arg_type)
270+
else:
271+
arg_type = chan_args_typedefs[arg_name]
272+
a = '%s chan %s' %(arg_name, arg_type)
273+
263274
dindex = i - offset
264275

265276
if a.startswith('__variable_args__'): ## TODO support go `...` varargs
@@ -347,7 +358,7 @@ def visit_Assign(self, node):
347358
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__':
348359
target = self.visit(target)
349360
value = self.visit(node.value.right)
350-
return 'var %s <- %s;' % (target, value)
361+
return '%s <- %s;' % (target, value)
351362

352363
elif not self._function_stack:
353364
target = self.visit(target)

pythonjs/typedpython.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
GO_SPECIAL_CALLS = {
2525
'go' : '__go__',
26-
'go.channel' : '__gomake__',
26+
'go.channel' : '__go_make_chan__',
2727
}
2828

2929
def transform_source( source, strip=False ):
@@ -267,8 +267,9 @@ def transform_source( source, strip=False ):
267267
y, kw = y.split('=')
268268
arg, typedef = y.split(':')
269269
chan = False
270-
if len(arg.split()) == 2:
271-
chan, arg = arg.split()
270+
if len(typedef.strip().split()) == 2:
271+
chan = True
272+
typedef = typedef.strip().split()[-1]
272273
if '*' in arg:
273274
arg_name = arg.split('*')[-1]
274275
else:
@@ -385,7 +386,7 @@ def xxx():
385386
def call_method( cb:func(int)(int) ) ->int:
386387
return cb(3)
387388
388-
def wrapper(a:int, chan c:int):
389+
def wrapper(a:int, c:chan int):
389390
result = longCalculation(a)
390391
c <- result
391392

regtests/go/chan.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
"""a <- """
1+
"""send int over channel"""
2+
3+
def wrapper(a:int, c: chan int):
4+
result = 100
5+
c <- result
26

37
def main():
48
c = go.channel(int)
5-
6-
def wrapper(a:int, chan c:int):
7-
result = 100
8-
c <- result
99

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

1412
# Do other work in the current goroutine until the channel has a result.
1513

1614
x = <-c
1715
print(x)
16+
TestError(x==100)

0 commit comments

Comments
 (0)