Skip to content

Commit dff6fa0

Browse files
author
hartsantler
committed
go backend: fixed function defs and basic calling.
1 parent 659df41 commit dff6fa0

5 files changed

Lines changed: 99 additions & 9 deletions

File tree

pythonjs/python_to_pythonjs.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,9 @@ def visit_BinOp(self, node):
14031403
elif op == '**':
14041404
return 'Math.pow(%s,%s)' %(left, right)
14051405

1406+
elif self._with_go:
1407+
pass
1408+
14061409
elif op == '+' and not self._with_dart:
14071410
if '+' in self._direct_operators:
14081411
return '%s+%s'%(left, right)
@@ -2660,6 +2663,8 @@ def visit_FunctionDef(self, node):
26602663
local_typedefs.append( '%s=%s' %(kw.arg, kw.value.id))
26612664
if decorator.func.id=='typedef_chan':
26622665
typedef_chans.append( kw.arg )
2666+
else:
2667+
writer.write('@__typedef__(%s=%s)' %(kw.arg, kw.value.id))
26632668

26642669

26652670
elif isinstance(decorator, Name) and decorator.id == 'inline':
@@ -2789,7 +2794,8 @@ def visit_FunctionDef(self, node):
27892794

27902795

27912796
## force python variable scope, and pass user type information to second stage of translation.
2792-
## the dart backend can use this extra type information.
2797+
## the dart backend can use this extra type information for speed and debugging.
2798+
## the Go and GLSL backends require this extra type information.
27932799
vars = []
27942800
local_typedef_names = set()
27952801
if not self._with_coffee:
@@ -2877,7 +2883,7 @@ def visit_FunctionDef(self, node):
28772883
writer.write( 'def %s( %s ):' % (node.name, ','.join(args)) )
28782884

28792885

2880-
elif self._with_js or javascript or self._with_ll or self._with_glsl:
2886+
elif self._with_js or javascript or self._with_ll or self._with_glsl or self._with_go:
28812887

28822888
if self._with_glsl:
28832889
writer.write('@__glsl__')
@@ -2921,7 +2927,7 @@ def visit_FunctionDef(self, node):
29212927
writer.write('var(%s)' %a)
29222928

29232929
#####################################################################
2924-
if self._with_dart or self._with_glsl:
2930+
if self._with_dart or self._with_glsl or self._with_go:
29252931
pass
29262932

29272933
elif self._with_js or javascript or self._with_ll:

pythonjs/pythonjs_to_go.py

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def __init__(self, requirejs=False, insert_runtime=False):
1616
#self._class_props = dict()
1717

1818
def visit_Print(self, node):
19-
r = [ 'fmt.Print(%s);' %self.visit(e) for e in node.values]
19+
r = [ 'fmt.Println(%s);' %self.visit(e) for e in node.values]
2020
return ''.join(r)
2121

2222
def visit_Expr(self, node):
@@ -32,6 +32,7 @@ def visit_Module(self, node):
3232

3333
for b in node.body:
3434
line = self.visit(b)
35+
3536
if line:
3637
for sub in line.splitlines():
3738
if sub==';':
@@ -45,6 +46,24 @@ def visit_Module(self, node):
4546
lines = header + lines
4647
return '\n'.join( lines )
4748

49+
50+
def visit_Compare(self, node):
51+
comp = [ '(']
52+
comp.append( self.visit(node.left) )
53+
comp.append( ')' )
54+
55+
for i in range( len(node.ops) ):
56+
comp.append( self.visit(node.ops[i]) )
57+
58+
if isinstance(node.comparators[i], ast.BinOp):
59+
comp.append('(')
60+
comp.append( self.visit(node.comparators[i]) )
61+
comp.append(')')
62+
else:
63+
comp.append( self.visit(node.comparators[i]) )
64+
65+
return ' '.join( comp )
66+
4867
def _visit_call_helper_go(self, node):
4968
name = self.visit(node.func)
5069
if name == '__go__':
@@ -55,9 +74,57 @@ def _visit_call_helper_go(self, node):
5574
return SyntaxError('invalid special go call')
5675

5776
def visit_FunctionDef(self, node):
58-
args = self.visit(node.args)
77+
args_typedefs = {}
78+
return_type = None
79+
for decor in node.decorator_list:
80+
if isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == '__typedef__':
81+
for key in decor.keywords:
82+
args_typedefs[ key.arg ] = key.value.id
83+
elif isinstance(decor, ast.Call) and isinstance(decor.func, ast.Name) and decor.func.id == 'returns':
84+
if decor.keywords:
85+
raise SyntaxError('invalid go return type')
86+
else:
87+
return_type = decor.args[0].id
88+
89+
90+
#args = self.visit(node.args)
91+
args = []
92+
oargs = []
93+
offset = len(node.args.args) - len(node.args.defaults)
94+
varargs = False
95+
varargs_name = None
96+
for i, arg in enumerate(node.args.args):
97+
a = arg.id
98+
if a in args_typedefs:
99+
#a = '%s %s' %(args_typedefs[a], a)
100+
a = '%s %s' %(a, args_typedefs[a])
101+
else:
102+
err = 'error in function: %s' %node.name
103+
err += '\n missing typedef: %s' %arg.id
104+
raise SyntaxError(err)
105+
106+
dindex = i - offset
107+
if a.startswith('__variable_args__'): ## TODO support go `...` varargs
108+
varargs_name = a.split('__')[-1]
109+
varargs = ['_vararg_%s'%n for n in range(16) ]
110+
args.append( '[%s]'%','.join(varargs) )
111+
112+
elif dindex >= 0 and node.args.defaults:
113+
default_value = self.visit( node.args.defaults[dindex] )
114+
oargs.append( '%s:%s' %(a, default_value) )
115+
else:
116+
args.append( a )
117+
118+
if oargs:
119+
#args.append( '[%s]' % ','.join(oargs) )
120+
args.append( '{%s}' % ','.join(oargs) )
121+
122+
####
59123
out = []
60-
out.append( self.indent() + 'func %s(%s) {\n' % (node.name, ', '.join(args)) )
124+
if return_type:
125+
out.append( self.indent() + 'func %s(%s) %s {\n' % (node.name, ', '.join(args), return_type) )
126+
else:
127+
out.append( self.indent() + 'func %s(%s) {\n' % (node.name, ', '.join(args)) )
61128
self.push()
62129
for b in node.body:
63130
v = self.visit(b)
@@ -119,7 +186,12 @@ def main(script, insert_runtime=True):
119186
script = runtime + '\n' + script
120187

121188
tree = ast.parse(script)
122-
return GoGenerator().visit(tree)
189+
try:
190+
return GoGenerator().visit(tree)
191+
except SyntaxError as err:
192+
sys.stderr.write(script)
193+
raise err
194+
123195

124196

125197
def command():

pythonjs/typedpython.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,11 @@ def wrapper(a:int, chan c:int):
393393
a = map[string]int{
394394
"x":x, "y":y, "z":z
395395
}
396+
397+
def f(a:int, b:int, c:int) ->int:
398+
return a+b+c
399+
400+
396401
'''
397402

398403
if __name__ == '__main__':

regtests/go/func_calls.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""function call"""
2+
def f(a:int, b:int, c:int) ->int:
3+
return a+b+c
4+
5+
def main():
6+
TestError( f(1,2,3) == 6)
7+

regtests/run.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,11 +783,11 @@ def run_pythonjs_go_test(dummy_filename):
783783
def run_go(content):
784784
"""compile and run go program"""
785785
write("%s.go" % tmpname, content)
786-
errors = run_command("go build %s.go" % tmpname)
786+
errors = run_command("go build -o /tmp/regtest-go %s.go" % tmpname)
787787
if errors:
788788
return errors
789789
else:
790-
return run_command( tmpname)
790+
return run_command( '/tmp/regtest-go' )
791791

792792

793793
def run_html_test( filename, sum_errors ):

0 commit comments

Comments
 (0)