1
1
#! /usr/bin/env python
2
- """Generate C code from an ASDL description."""
2
+ """Generate Go code from an ASDL description."""
3
3
4
4
# TO DO
5
5
# handle fields that have a type but no name
12
12
TABSIZE = 4
13
13
MAX_COL = 80
14
14
15
- def get_c_type (name ):
16
- """Return a string for the C name of the type.
15
+ def get_go_type (name ):
16
+ """Return a string for the Go name of the type.
17
17
18
18
This function special cases the default types provided by asdl:
19
19
identifier, string, int.
20
20
"""
21
21
# XXX ack! need to figure out where Id is useful and where string
22
22
if isinstance (name , asdl .Id ):
23
23
name = name .value
24
+ #if not name.startswith("[]"):
25
+ # name= "*"+name
24
26
if name in asdl .builtin_types :
25
27
return name
26
28
else :
27
29
#return "%s_ty" % name
28
30
return name
29
31
32
+ def go_name (name ):
33
+ """Returns a name for exportable go"""
34
+ name = str (name )
35
+ if name [0 ].isupper ():
36
+ return name
37
+ return "" .join (n .title () for n in name .split ("_" ))
38
+
30
39
def is_simple (sum ):
31
40
"""Return True if a sum is a simple.
32
41
@@ -76,7 +85,7 @@ def visitSum(self, sum, name, depth):
76
85
self .sum_with_constructors (sum , name , depth )
77
86
78
87
def simple_sum (self , sum , name , depth ):
79
- ctype = get_c_type (name )
88
+ ctype = get_go_type (name )
80
89
enum = []
81
90
for i in range (len (sum .types )):
82
91
type = sum .types [i ]
@@ -87,13 +96,13 @@ def simple_sum(self, sum, name, depth):
87
96
self .emit ("" , depth )
88
97
89
98
def sum_with_constructors (self , sum , name , depth ):
90
- ctype = get_c_type (name )
99
+ ctype = get_go_type (name )
91
100
s = "type %(ctype)s * _%(name)s" % locals ()
92
- self .emit (s , depth )
101
+ # self.emit(s, depth)
93
102
self .emit ("" , depth )
94
103
95
104
def visitProduct (self , product , name , depth ):
96
- ctype = get_c_type (name )
105
+ ctype = get_go_type (name )
97
106
#s = "type %(ctype)s *_%(name)s" % locals()
98
107
#self.emit(s, depth)
99
108
#self.emit("", depth)
@@ -117,52 +126,60 @@ def sum_with_constructors(self, sum, name, depth):
117
126
def emit (s , depth = depth ):
118
127
self .emit (s % sys ._getframe (1 ).f_locals , depth )
119
128
enum = []
129
+ name = go_name (name )
120
130
for i in range (len (sum .types )):
121
131
type = sum .types [i ]
122
- enum .append ("%s_kind=%s (%d)" % (type .name , name , i + 1 ))
132
+ enum .append ("%s_kind=%s_kind (%d)" % (type .name , name , i + 1 ))
123
133
124
- emit ("type _ %(name)s_kind int\n const (\n " + "\n " .join (enum ) + "\n )" )
134
+ # emit("type %(name)s_kind int\nconst (\n" + "\n".join(enum) + "\n)")
125
135
126
- emit ("type _%(name)s struct {" )
127
- emit ("kind _%(name)s_kind;" , depth + 1 )
128
- emit ("v struct {" , depth + 1 )
129
- for t in sum .types :
130
- self .visit (t , depth + 2 )
131
- emit ("}" , depth + 1 )
136
+ emit ('var %(name)sType = ASTType.NewType("%(name)s", "%(name)s Node", nil, nil)' )
137
+ self .emit ("func (o *%s) Ast() {}" % name , depth )
138
+ self .emit ("func (o *%s) Type() *py.Type {return %sType}" % (name , name ), depth )
139
+
140
+ emit ("type %(name)s struct {" )
141
+ emit ("kind %(name)s_kind;" , depth + 1 )
142
+ #emit("v struct {", depth + 1)
143
+ #emit("}", depth + 1)
132
144
for field in sum .attributes :
133
145
# rudimentary attribute handling
134
146
type = str (field .type )
135
147
assert type in asdl .builtin_types , type
136
- emit ("%s %s" % (field .name , type ), depth + 1 );
148
+ emit ("%s %s" % (go_name ( field .name ) , type ), depth + 1 );
137
149
emit ("}" )
150
+ self .name = name
151
+ for t in sum .types :
152
+ self .visit (t , depth + 2 )
138
153
emit ("" )
139
154
140
155
def visitConstructor (self , cons , depth ):
141
- if cons .fields :
142
- self .emit ("%s struct {" % cons .name , depth )
143
- for f in cons .fields :
144
- self .visit (f , depth + 1 )
145
- self .emit ("}" , depth )
146
- self .emit ("" , depth )
147
- else :
148
- # XXX not sure what I want here, nothing is probably fine
149
- pass
156
+ parent = self .name
157
+ name = go_name (cons .name )
158
+ self .emit (('var %(name)sType = %(parent)sType.NewType("%(name)s", "%(name)s Node", nil, nil)' ) % locals (), 0 )
159
+ self .emit ("type %s struct {" % cons .name , depth )
160
+ self .emit ("%s" % self .name , depth )
161
+ for f in cons .fields :
162
+ self .visit (f , depth + 1 )
163
+ self .emit ("}" , depth )
164
+ self .emit ("func (o *%s) Ast() {}" % cons .name , depth )
165
+ self .emit ("func (o *%s) Type() *py.Type {return %sType}" % (cons .name , cons .name ), depth )
166
+ self .emit ("" , depth )
150
167
151
168
def visitField (self , field , depth ):
152
169
# XXX need to lookup field.type, because it might be something
153
170
# like a builtin...
154
- ctype = get_c_type (field .type )
171
+ ctype = get_go_type (field .type )
155
172
name = field .name
156
173
if field .seq :
157
174
if field .type .value in ('cmpop' ,):
158
- self .emit ("%(name)s []asdl_int_seq " % locals (), depth )
175
+ self .emit ("%(name)s []Ast " % locals (), depth )
159
176
else :
160
- self .emit ("%(name)s []asdl_seq " % locals (), depth )
177
+ self .emit ("%(name)s []Ast " % locals (), depth )
161
178
else :
162
179
self .emit ("%(name)s %(ctype)s" % locals (), depth )
163
180
164
181
def visitProduct (self , product , name , depth ):
165
- self .emit ("type _ %(name)s struct {" % locals (), depth )
182
+ self .emit ("type %(name)s struct {" % locals (), depth )
166
183
for f in product .fields :
167
184
self .visit (f , depth + 1 )
168
185
for field in product .attributes :
@@ -192,9 +209,9 @@ def visitSum(self, sum, name):
192
209
self .visit (t , name , sum .attributes )
193
210
194
211
def get_args (self , fields ):
195
- """Return list of C argument into, one for each field.
212
+ """Return list of Go argument into, one for each field.
196
213
197
- Argument info is 3-tuple of a C type, variable name, and flag
214
+ Argument info is 3-tuple of a Go type, variable name, and flag
198
215
that is true if type can be NULL.
199
216
"""
200
217
args = []
@@ -207,21 +224,21 @@ def get_args(self, fields):
207
224
name = "name%d" % (c - 1 )
208
225
else :
209
226
name = f .name
210
- # XXX should extend get_c_type () to handle this
227
+ # XXX should extend get_go_type () to handle this
211
228
if f .seq :
212
229
if f .type .value in ('cmpop' ,):
213
230
ctype = "[]asdl_int_seq"
214
231
else :
215
232
ctype = "[]asdl_seq"
216
233
else :
217
- ctype = get_c_type (f .type )
234
+ ctype = get_go_type (f .type )
218
235
args .append ((ctype , name , f .opt or f .seq ))
219
236
return args
220
237
221
238
def visitConstructor (self , cons , type , attrs ):
222
239
args = self .get_args (cons .fields )
223
240
attrs = self .get_args (attrs )
224
- ctype = get_c_type (type )
241
+ ctype = get_go_type (type )
225
242
self .emit_function (cons .name , ctype , args , attrs )
226
243
227
244
def emit_function (self , name , ctype , args , attrs , union = True ):
@@ -240,28 +257,28 @@ def emit_function(self, name, ctype, args, attrs, union=True):
240
257
self .emit ("%s %s(%s);" % (ctype , name , argstr ), False )
241
258
242
259
def visitProduct (self , prod , name ):
243
- self .emit_function (name , get_c_type (name ),
260
+ self .emit_function (name , get_go_type (name ),
244
261
self .get_args (prod .fields ), [], union = False )
245
262
246
263
247
264
class FunctionVisitor (PrototypeVisitor ):
248
265
"""Visitor to generate constructor functions for AST."""
249
266
250
267
def emit_function (self , name , ctype , args , attrs , union = True ):
268
+ return # FIXME
251
269
def emit (s , depth = 0 ):
252
270
self .emit (s , depth )
253
- argstr = ", " .join (["%s %s" % (aname , atype )
254
- for atype , aname , opt in args + attrs ])
255
- emit ("func %s(%s) *%s {" % (name , argstr , ctype ))
256
- emit ("var p %s;" % ctype , 1 )
271
+ argl = []
272
+ for atype , aname , opt in args + attrs :
273
+ argl .append ("%s %s" % (go_name (aname ), atype ))
274
+ argstr = ", " .join (argl )
275
+ emit ("func New%s(%s) *%s {" % (name , argstr , name ))
276
+ emit ("var p %s;" % name , 1 )
257
277
for argtype , argname , opt in args :
258
278
if not opt and argtype != "int" :
259
- emit ("if (!%s) {" % argname , 1 )
260
- emit ("PyErr_SetString(PyExc_ValueError," , 2 )
279
+ emit ("if %s == nil {" % argname , 1 )
261
280
msg = "field %s is required for %s" % (argname , name )
262
- emit (' "%s");' % msg ,
263
- 2 )
264
- emit ('return NULL;' , 2 )
281
+ emit ('panic(py.ExceptionNewf(py.ValueError, "%s"))' % msg )
265
282
emit ('}' , 1 )
266
283
267
284
#emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1);
@@ -280,14 +297,17 @@ def emit(s, depth=0):
280
297
self .emit (s , depth )
281
298
emit ("p.kind = %s_kind;" % name , 1 )
282
299
for argtype , argname , opt in args :
283
- emit ("p.v.%s.%s = %s;" % (name , argname , argname ), 1 )
300
+ argname = go_name (argname )
301
+ emit ("p.%s = %s;" % (argname , argname ), 1 )
284
302
for argtype , argname , opt in attrs :
303
+ argname = go_name (argname )
285
304
emit ("p.%s = %s;" % (argname , argname ), 1 )
286
305
287
306
def emit_body_struct (self , name , args , attrs ):
288
307
def emit (s , depth = 0 ):
289
308
self .emit (s , depth )
290
309
for argtype , argname , opt in args :
310
+ argname = go_name (argname )
291
311
emit ("p.%s = %s;" % (argname , argname ), 1 )
292
312
assert not attrs
293
313
@@ -317,14 +337,14 @@ def visitField(self, sum):
317
337
class Obj2ModPrototypeVisitor (PickleVisitor ):
318
338
def visitProduct (self , prod , name ):
319
339
code = "int obj2ast_%s(PyObject* obj, %s* out, PyArena* arena);"
320
- #self.emit(code % (name, get_c_type (name)), 0)
340
+ #self.emit(code % (name, get_go_type (name)), 0)
321
341
322
342
visitSum = visitProduct
323
343
324
344
325
345
class Obj2ModVisitor (PickleVisitor ):
326
346
def funcHeader (self , name ):
327
- ctype = get_c_type (name )
347
+ ctype = get_go_type (name )
328
348
self .emit ("int" , 0 )
329
349
self .emit ("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name , ctype ), 0 )
330
350
self .emit ("{" , 0 )
@@ -395,7 +415,7 @@ def complexSum(self, sum, name):
395
415
self .sumTrailer (name , True )
396
416
397
417
def visitAttributeDeclaration (self , a , name , sum = sum ):
398
- ctype = get_c_type (a .type )
418
+ ctype = get_go_type (a .type )
399
419
self .emit ("%s %s;" % (ctype , a .name ), 1 )
400
420
401
421
def visitSum (self , sum , name ):
@@ -405,7 +425,7 @@ def visitSum(self, sum, name):
405
425
self .complexSum (sum , name )
406
426
407
427
def visitProduct (self , prod , name ):
408
- ctype = get_c_type (name )
428
+ ctype = get_go_type (name )
409
429
self .emit ("int" , 0 )
410
430
self .emit ("obj2ast_%s(PyObject* obj, %s* out, PyArena* arena)" % (name , ctype ), 0 )
411
431
self .emit ("{" , 0 )
@@ -425,14 +445,14 @@ def visitProduct(self, prod, name):
425
445
self .emit ("" , 0 )
426
446
427
447
def visitFieldDeclaration (self , field , name , sum = None , prod = None , depth = 0 ):
428
- ctype = get_c_type (field .type )
448
+ ctype = get_go_type (field .type )
429
449
if field .seq :
430
450
if self .isSimpleType (field ):
431
451
self .emit ("%s []asdl_int_seq;" % field .name , depth )
432
452
else :
433
453
self .emit ("%s []asdl_seq;" % field .name , depth )
434
454
else :
435
- ctype = get_c_type (field .type )
455
+ ctype = get_go_type (field .type )
436
456
self .emit ("%s %s" % (field .name , ctype ), depth )
437
457
438
458
def isSimpleSum (self , field ):
@@ -441,13 +461,13 @@ def isSimpleSum(self, field):
441
461
'unaryop' , 'cmpop' )
442
462
443
463
def isNumeric (self , field ):
444
- return get_c_type (field .type ) in ("int" , "bool" )
464
+ return get_go_type (field .type ) in ("int" , "bool" )
445
465
446
466
def isSimpleType (self , field ):
447
467
return self .isSimpleSum (field ) or self .isNumeric (field )
448
468
449
469
def visitField (self , field , name , sum = None , prod = None , depth = 0 ):
450
- ctype = get_c_type (field .type )
470
+ ctype = get_go_type (field .type )
451
471
if field .opt :
452
472
check = "exists_not_none(obj, &PyId_%s)" % (field .name ,)
453
473
else :
@@ -505,7 +525,7 @@ def visitField(self, field, name, sum=None, prod=None, depth=0):
505
525
class MarshalPrototypeVisitor (PickleVisitor ):
506
526
507
527
def prototype (self , sum , name ):
508
- ctype = get_c_type (name )
528
+ ctype = get_go_type (name )
509
529
self .emit ("int marshal_write_%s(PyObject **, int *, %s);"
510
530
% (name , ctype ), 0 )
511
531
@@ -543,7 +563,7 @@ def visitSum(self, sum, name):
543
563
self .emit ("};" , 0 )
544
564
ptype = "void*"
545
565
if is_simple (sum ):
546
- ptype = get_c_type (name )
566
+ ptype = get_go_type (name )
<
B83A
code>547 567
tnames = []
548
568
for t in sum .types :
549
569
tnames .append (str (t .name )+ "_singleton" )
@@ -1016,7 +1036,7 @@ def visit(self, object):
1016
1036
class ObjVisitor (PickleVisitor ):
1017
1037
1018
1038
def func_begin (self , name ):
1019
- ctype = get_c_type (name )
1039
+ ctype = get_go_type (name )
1020
1040
self .emit ("func ast2obj_%s(void* _o) py.Object" % (name ), 0 )
1021
1041
self .emit ("{" , 0 )
1022
1042
self .emit ("%s o = (%s)_o;" % (ctype , ctype ), 1 )
@@ -1135,7 +1155,7 @@ def set(self, field, value, depth):
1135
1155
else :
1136
1156
self .emit ("value = ast2obj_list(%s, ast2obj_%s);" % (value , field .type ), depth )
1137
1157
else :
1138
- ctype = get_c_type (field .type )
1158
+ ctype = get_go_type (field .type )
1139
1159
self .emit ("value = ast2obj_%s(%s);" % (field .type , value ), depth )
1140
1160
1141
1161
@@ -1210,7 +1230,8 @@ def main(srcfile):
1210
1230
p = "%s-ast.go" % mod .name
1211
1231
f = open (p , "w" )
1212
1232
f .write (auto_gen_msg )
1213
- f .write ('package parser\n ' )
1233
+ f .write ('package ast\n ' )
1234
+ f .write ('import "github.com/ncw/gpython/py"\n ' )
1214
1235
c = ChainOfVisitors (TypeDefVisitor (f ),
1215
1236
StructVisitor (f ),
1216
1237
PrototypeVisitor (f ),
0 commit comments