]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py
MFC r345703:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / ExpressionParser / Go / gen_go_ast.py
1 import StringIO
2
3
4 def addNodes():
5     addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
6     addNode(
7         "AssignStmt",
8         "Stmt",
9         "lhs",
10         "[]Expr",
11         "rhs",
12         "[]Expr",
13         "define",
14         "bool")
15     addNode("BadDecl", "Decl")
16     addNode("BadExpr", "Expr")
17     addNode("BadStmt", "Stmt")
18     addNode("BasicLit", "Expr", "value", "Token")
19     addNode("BinaryExpr", "Expr", "x", "Expr", "y", "Expr", "op", "TokenType")
20     addNode("BlockStmt", "Stmt", "list", "[]Stmt")
21     addNode("Ident", "Expr", "name", "Token")
22     addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
23     addNode(
24         "CallExpr",
25         "Expr",
26         "fun",
27         "Expr",
28         "args",
29         "[]Expr",
30         "ellipsis",
31         "bool")
32     addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
33     addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
34     addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
35     addNode("CompositeLit", "Expr", "type", "Expr", "elts", "[]Expr")
36     addNode("DeclStmt", "Stmt", "decl", "Decl")
37     addNode("DeferStmt", "Stmt", "call", "CallExpr")
38     addNode("Ellipsis", "Expr", "elt", "Expr")
39     addNode("EmptyStmt", "Stmt")
40     addNode("ExprStmt", "Stmt", "x", "Expr")
41     addNode(
42         "Field",
43         "Node",
44         "names",
45         "[]Ident",
46         "type",
47         "Expr",
48         "tag",
49         "BasicLit")
50     addNode("FieldList", "Node", "list", "[]Field")
51     addNode(
52         "ForStmt",
53         "Stmt",
54         "init",
55         "Stmt",
56         "cond",
57         "Expr",
58         "post",
59         "Stmt",
60         "body",
61         "BlockStmt")
62     addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
63     addNode(
64         "FuncDecl",
65         "Decl",
66         "recv",
67         "FieldList",
68         "name",
69         "Ident",
70         "type",
71         "FuncType",
72         "body",
73         "BlockStmt")
74     addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
75     addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
76     addNode("GoStmt", "Stmt", "call", "CallExpr")
77     addNode(
78         "IfStmt",
79         "Stmt",
80         "init",
81         "Stmt",
82         "cond",
83         "Expr",
84         "body",
85         "BlockStmt",
86         "els",
87         "Stmt")
88     addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
89     addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
90     addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
91     addNode("InterfaceType", "Expr", "methods", "FieldList")
92     addNode("KeyValueExpr", "Expr", "key", "Expr", "value", "Expr")
93     addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
94     addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
95     addNode("ParenExpr", "Expr", "x", "Expr")
96     addNode(
97         "RangeStmt",
98         "Stmt",
99         "key",
100         "Expr",
101         "value",
102         "Expr",
103         "define",
104         "bool",
105         "x",
106         "Expr",
107         "body",
108         "BlockStmt")
109     addNode("ReturnStmt", "Stmt", "results", "[]Expr")
110     addNode("SelectStmt", "Stmt", "body", "BlockStmt")
111     addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
112     addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
113     addNode(
114         "SliceExpr",
115         "Expr",
116         "x",
117         "Expr",
118         "low",
119         "Expr",
120         "high",
121         "Expr",
122         "max",
123         "Expr",
124         "slice3",
125         "bool")
126     addNode("StarExpr", "Expr", "x", "Expr")
127     addNode("StructType", "Expr", "fields", "FieldList")
128     addNode(
129         "SwitchStmt",
130         "Stmt",
131         "init",
132         "Stmt",
133         "tag",
134         "Expr",
135         "body",
136         "BlockStmt")
137     addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
138     addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
139     addNode(
140         "TypeSwitchStmt",
141         "Stmt",
142         "init",
143         "Stmt",
144         "assign",
145         "Stmt",
146         "body",
147         "BlockStmt")
148     addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
149     addNode(
150         "ValueSpec",
151         "Spec",
152         "names",
153         "[]Ident",
154         "type",
155         "Expr",
156         "values",
157         "[]Expr")
158     addParent("Decl", "Node")
159     addParent("Expr", "Node")
160     addParent("Spec", "Node")
161     addParent("Stmt", "Node")
162
163
164 class Member(object):
165
166     def __init__(self, name, typename):
167         self.title = name.title()
168         self.sname = name
169         self.mname = 'm_' + name
170         self.is_list = typename.startswith("[]")
171         self.is_value = isValueType(typename)
172         if self.is_value:
173             self.argtype = typename
174             self.mtype = typename
175         elif self.is_list:
176             self.argtype = 'GoAST' + typename[2:]
177             self.mtype = 'std::vector<std::unique_ptr<%s> >' % self.argtype
178         else:
179             self.argtype = 'GoAST' + typename
180             self.mtype = 'std::unique_ptr<%s>' % self.argtype
181             self.mname = self.mname + '_up'
182
183
184 kinds = {}
185 parentClasses = StringIO.StringIO()
186 childClasses = StringIO.StringIO()
187 walker = StringIO.StringIO()
188
189
190 def startClass(name, parent, out):
191     out.write("""
192 class GoAST%s : public GoAST%s
193 {
194   public:
195 """ % (name, parent))
196
197
198 def endClass(name, out):
199     out.write("""
200     %(name)s(const %(name)s &) = delete;
201     const %(name)s &operator=(const %(name)s &) = delete;
202 };
203 """ % {'name': 'GoAST' + name})
204
205
206 def addNode(name, parent, *children):
207     startClass(name, parent, childClasses)
208     l = kinds.setdefault(parent, [])
209     l.append(name)
210     children = createMembers(name, children)
211     addConstructor(name, parent, children)
212     childClasses.write("""
213     const char *
214     GetKindName() const override
215     {
216         return "%(name)s";
217     }
218
219     static bool
220     classof(const GoASTNode *n)
221     {
222         return n->GetKind() == e%(name)s;
223     }
224     """ % {'name': name})
225     addChildren(name, children)
226     endClass(name, childClasses)
227
228
229 def isValueType(typename):
230     if typename[0].islower():
231         return True
232     if typename[0].isupper():
233         return typename.startswith('Token') or typename == 'ChanDir'
234     return False
235
236
237 def createMembers(name, children):
238     l = len(children)
239     if (l % 2) != 0:
240         raise Exception("Invalid children for %s: %s" % (name, children))
241     return [Member(children[i], children[i + 1]) for i in xrange(0, l, 2)]
242
243
244 def addConstructor(name, parent, children):
245     for c in children:
246         if c.is_list:
247             children = [x for x in children if x.is_value]
248             break
249     childClasses.write('    ')
250     if len(children) == 1:
251         childClasses.write('explicit ')
252     childClasses.write('GoAST%s(' % name)
253     for i in xrange(len(children)):
254         if i > 0:
255             childClasses.write(', ')
256
257         c = children[i]
258         if c.is_value:
259             childClasses.write(c.argtype)
260             childClasses.write(' ')
261         else:
262             childClasses.write('%s *' % c.argtype)
263         childClasses.write(c.sname)
264     childClasses.write(') : GoAST%s(e%s)' % (parent, name))
265     for c in children:
266         childClasses.write(', ')
267         childClasses.write('%(mname)s(%(sname)s)' % c.__dict__)
268     childClasses.write(""" {}
269     ~GoAST%s() override = default;
270 """ % name)
271
272
273 def addChildren(name, children):
274     if len(children) == 0:
275         return
276     walker.write("""
277     case e%(n)s:
278         {
279             GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
280             (void)n;""" % {'n': name})
281     for c in children:
282         if c.is_list:
283             childClasses.write("""
284     size_t
285     Num%(title)s() const
286     {
287         return %(mname)s.size();
288     }
289     const %(argtype)s *
290     Get%(title)s(int i) const
291     {
292         return %(mname)s[i].get();
293     }
294     void
295     Add%(title)s(%(argtype)s *%(sname)s)
296     {
297         %(mname)s.push_back(std::unique_ptr<%(argtype)s>(%(sname)s));
298     }
299 """ % c.__dict__)
300             walker.write("""
301             for (auto& e : n->%s) { v(e.get()); }""" % c.mname)
302         else:
303             const = ''
304             get = ''
305             set = ''
306             t = c.argtype
307             if isValueType(t):
308                 set = '%(mname)s = %(sname)s' % c.__dict__
309                 t = t + ' '
310             else:
311                 t = t + ' *'
312                 const = 'const '
313                 get = '.get()'
314                 set = '%(mname)s.reset(%(sname)s)' % c.__dict__
315                 walker.write("""
316             v(n->%s.get());""" % c.mname)
317             childClasses.write("""
318     %(const)s%(type)s
319     Get%(title)s() const
320     {
321         return %(mname)s%(get)s;
322     }
323     void
324     Set%(title)s(%(type)s%(sname)s)
325     {
326         %(set)s;
327     }
328 """ % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
329     childClasses.write('\n  private:\n    friend class GoASTNode;\n')
330     walker.write("""
331             return;
332         }""")
333     for c in children:
334         childClasses.write('    %s %s;\n' % (c.mtype, c.mname))
335
336
337 def addParent(name, parent):
338     startClass(name, parent, parentClasses)
339     l = kinds[name]
340     minName = l[0]
341     maxName = l[-1]
342     parentClasses.write("""    template <typename R, typename V> R Visit(V *v) const;
343
344     static bool
345     classof(const GoASTNode *n)
346     {
347         return n->GetKind() >= e%s && n->GetKind() <= e%s;
348     }
349
350   protected:
351     explicit GoAST%s(NodeKind kind) : GoASTNode(kind) { }
352   private:
353 """ % (minName, maxName, name))
354     endClass(name, parentClasses)
355
356 addNodes()
357
358 print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
359 //
360 //                     The LLVM Compiler Infrastructure
361 //
362 // This file is distributed under the University of Illinois Open Source
363 // License. See LICENSE.TXT for details.
364 //
365 //===----------------------------------------------------------------------===//
366
367 // DO NOT EDIT.
368 // Generated by gen_go_ast.py
369
370 #ifndef liblldb_GoAST_h
371 #define liblldb_GoAST_h
372
373 #include "lldb/lldb-forward.h"
374 #include "lldb/lldb-private.h"
375 #include "llvm/Support/Casting.h"
376 #include "Plugins/ExpressionParser/Go/GoLexer.h"
377
378 namespace lldb_private
379 {
380
381 class GoASTNode
382 {
383   public:
384     typedef GoLexer::TokenType TokenType;
385     typedef GoLexer::Token Token;
386     enum ChanDir
387     {
388         eChanBidir,
389         eChanSend,
390         eChanRecv,
391     };
392     enum NodeKind
393     {"""
394 for l in kinds.itervalues():
395     for x in l:
396         print "        e%s," % x
397 print """    };
398
399     virtual ~GoASTNode() = default;
400
401     NodeKind
402     GetKind() const
403     {
404         return m_kind;
405     }
406
407     virtual const char *GetKindName() const = 0;
408
409     template <typename V> void WalkChildren(V &v);
410
411   protected:
412     explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
413
414   private:
415     const NodeKind m_kind;
416
417     GoASTNode(const GoASTNode &) = delete;
418     const GoASTNode &operator=(const GoASTNode &) = delete;
419 };
420 """
421
422
423 print parentClasses.getvalue()
424 print childClasses.getvalue()
425
426 for k, l in kinds.iteritems():
427     if k == 'Node':
428         continue
429     print """
430 template <typename R, typename V>
431 R GoAST%s::Visit(V* v) const
432 {
433     switch(GetKind())
434     {""" % k
435     for subtype in l:
436         print """    case e%(n)s:
437         return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
438
439     print """    default:
440         assert(false && "Invalid kind");
441     }
442 }"""
443
444 print """
445 template <typename V>
446 void GoASTNode::WalkChildren(V &v)
447 {
448     switch (m_kind)
449     {
450 """
451 print walker.getvalue()
452 print"""
453         case eEmptyStmt:
454         case eBadDecl:
455         case eBadExpr:
456         case eBadStmt:
457           break;
458     }
459 }
460
461 }  // namespace lldb_private
462
463 #endif
464 """