summaryrefslogtreecommitdiff
path: root/source/Plugins/ExpressionParser/Go/gen_go_ast.py
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/ExpressionParser/Go/gen_go_ast.py')
-rw-r--r--source/Plugins/ExpressionParser/Go/gen_go_ast.py356
1 files changed, 356 insertions, 0 deletions
diff --git a/source/Plugins/ExpressionParser/Go/gen_go_ast.py b/source/Plugins/ExpressionParser/Go/gen_go_ast.py
new file mode 100644
index 0000000000000..05b589a9976cb
--- /dev/null
+++ b/source/Plugins/ExpressionParser/Go/gen_go_ast.py
@@ -0,0 +1,356 @@
+import StringIO
+
+def addNodes():
+ addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
+ addNode("AssignStmt", "Stmt", "lhs", "[]Expr", "rhs", "[]Expr", "define", "bool")
+ addNode("BadDecl", "Decl")
+ addNode("BadExpr", "Expr")
+ addNode("BadStmt", "Stmt")
+ addNode("BasicLit", "Expr", "value", "Token")
+ addNode("BinaryExpr", "Expr", "x", "Expr", "y", "Expr", "op", "TokenType")
+ addNode("BlockStmt", "Stmt", "list", "[]Stmt")
+ addNode("Ident", "Expr", "name", "Token")
+ addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
+ addNode("CallExpr", "Expr", "fun", "Expr", "args", "[]Expr", "ellipsis", "bool")
+ addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
+ addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
+ addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
+ addNode("CompositeLit", "Expr", "type", "Expr", "elts", "[]Expr")
+ addNode("DeclStmt", "Stmt", "decl", "Decl")
+ addNode("DeferStmt", "Stmt", "call", "CallExpr")
+ addNode("Ellipsis", "Expr", "elt", "Expr")
+ addNode("EmptyStmt", "Stmt")
+ addNode("ExprStmt", "Stmt", "x", "Expr")
+ addNode("Field", "Node", "names", "[]Ident", "type", "Expr", "tag", "BasicLit")
+ addNode("FieldList", "Node", "list", "[]Field")
+ addNode("ForStmt", "Stmt", "init", "Stmt", "cond", "Expr", "post", "Stmt", "body", "BlockStmt")
+ addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
+ addNode("FuncDecl", "Decl", "recv", "FieldList", "name", "Ident", "type", "FuncType", "body", "BlockStmt")
+ addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
+ addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
+ addNode("GoStmt", "Stmt", "call", "CallExpr")
+ addNode("IfStmt", "Stmt", "init", "Stmt", "cond", "Expr", "body", "BlockStmt", "els", "Stmt")
+ addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
+ addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
+ addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
+ addNode("InterfaceType", "Expr", "methods", "FieldList")
+ addNode("KeyValueExpr", "Expr", "key", "Expr", "value", "Expr")
+ addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
+ addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
+ addNode("ParenExpr", "Expr", "x", "Expr")
+ addNode("RangeStmt", "Stmt", "key", "Expr", "value", "Expr", "define", "bool", "x", "Expr", "body", "BlockStmt")
+ addNode("ReturnStmt", "Stmt", "results", "[]Expr")
+ addNode("SelectStmt", "Stmt", "body", "BlockStmt")
+ addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
+ addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
+ addNode("SliceExpr", "Expr", "x", "Expr", "low", "Expr", "high", "Expr", "max", "Expr", "slice3", "bool")
+ addNode("StarExpr", "Expr", "x", "Expr")
+ addNode("StructType", "Expr", "fields", "FieldList")
+ addNode("SwitchStmt", "Stmt", "init", "Stmt", "tag", "Expr", "body", "BlockStmt")
+ addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
+ addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
+ addNode("TypeSwitchStmt", "Stmt", "init", "Stmt", "assign", "Stmt", "body", "BlockStmt")
+ addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
+ addNode("ValueSpec", "Spec", "names", "[]Ident", "type", "Expr", "values", "[]Expr")
+ addParent("Decl", "Node")
+ addParent("Expr", "Node")
+ addParent("Spec", "Node")
+ addParent("Stmt", "Node")
+
+
+class Member(object):
+ def __init__(self, name, typename):
+ self.title = name.title()
+ self.sname = name
+ self.mname = 'm_' + name
+ self.is_list = typename.startswith("[]")
+ self.is_value = isValueType(typename)
+ if self.is_value:
+ self.argtype = typename
+ self.mtype = typename
+ elif self.is_list:
+ self.argtype = 'GoAST' + typename[2:]
+ self.mtype = 'std::vector<std::unique_ptr<%s> >' % self.argtype
+ else:
+ self.argtype = 'GoAST' + typename
+ self.mtype = 'std::unique_ptr<%s>' % self.argtype
+ self.mname = self.mname + '_up'
+
+
+kinds = {}
+parentClasses = StringIO.StringIO()
+childClasses = StringIO.StringIO()
+walker = StringIO.StringIO()
+
+def startClass(name, parent, out):
+ out.write("""
+class GoAST%s : public GoAST%s
+{
+ public:
+""" % (name, parent))
+
+def endClass(name, out):
+ out.write("""
+ %(name)s(const %(name)s &) = delete;
+ const %(name)s &operator=(const %(name)s &) = delete;
+};
+""" % {'name': 'GoAST' + name})
+
+def addNode(name, parent, *children):
+ startClass(name, parent, childClasses)
+ l = kinds.setdefault(parent, [])
+ l.append(name)
+ children = createMembers(name, children)
+ addConstructor(name, parent, children)
+ childClasses.write("""
+ const char *
+ GetKindName() const override
+ {
+ return "%(name)s";
+ }
+
+ static bool
+ classof(const GoASTNode *n)
+ {
+ return n->GetKind() == e%(name)s;
+ }
+ """ % {'name':name})
+ addChildren(name, children)
+ endClass(name, childClasses)
+
+def isValueType(typename):
+ if typename[0].islower():
+ return True
+ if typename[0].isupper():
+ return typename.startswith('Token') or typename == 'ChanDir'
+ return False
+
+
+def createMembers(name, children):
+ l = len(children)
+ if (l % 2) != 0:
+ raise Exception("Invalid children for %s: %s" % (name, children))
+ return [Member(children[i], children[i + 1]) for i in xrange(0, l, 2)]
+
+
+def addConstructor(name, parent, children):
+ for c in children:
+ if c.is_list:
+ children = [x for x in children if x.is_value]
+ break
+ childClasses.write(' ')
+ if len(children) == 1:
+ childClasses.write('explicit ')
+ childClasses.write('GoAST%s(' % name)
+ for i in xrange(len(children)):
+ if i > 0:
+ childClasses.write(', ')
+
+ c = children[i]
+ if c.is_value:
+ childClasses.write(c.argtype)
+ childClasses.write(' ')
+ else:
+ childClasses.write('%s *' % c.argtype)
+ childClasses.write(c.sname)
+ childClasses.write(') : GoAST%s(e%s)' % (parent, name))
+ for c in children:
+ childClasses.write(', ')
+ childClasses.write('%(mname)s(%(sname)s)' % c.__dict__)
+ childClasses.write(""" {}
+ ~GoAST%s() override = default;
+""" % name)
+
+
+def addChildren(name, children):
+ if len(children) == 0:
+ return
+ walker.write("""
+ case e%(n)s:
+ {
+ GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
+ (void)n;""" % {'n':name})
+ for c in children:
+ if c.is_list:
+ childClasses.write("""
+ size_t
+ Num%(title)s() const
+ {
+ return %(mname)s.size();
+ }
+ const %(argtype)s *
+ Get%(title)s(int i) const
+ {
+ return %(mname)s[i].get();
+ }
+ void
+ Add%(title)s(%(argtype)s *%(sname)s)
+ {
+ %(mname)s.push_back(std::unique_ptr<%(argtype)s>(%(sname)s));
+ }
+""" % c.__dict__)
+ walker.write("""
+ for (auto& e : n->%s) { v(e.get()); }""" % c.mname)
+ else:
+ const = ''
+ get = ''
+ set = ''
+ t = c.argtype
+ if isValueType(t):
+ set = '%(mname)s = %(sname)s' % c.__dict__
+ t = t + ' '
+ else:
+ t = t + ' *'
+ const = 'const '
+ get = '.get()'
+ set = '%(mname)s.reset(%(sname)s)' % c.__dict__
+ walker.write("""
+ v(n->%s.get());""" % c.mname)
+ childClasses.write("""
+ %(const)s%(type)s
+ Get%(title)s() const
+ {
+ return %(mname)s%(get)s;
+ }
+ void
+ Set%(title)s(%(type)s%(sname)s)
+ {
+ %(set)s;
+ }
+""" % {'const':const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
+ childClasses.write('\n private:\n friend class GoASTNode;\n')
+ walker.write("""
+ return;
+ }""")
+ for c in children:
+ childClasses.write(' %s %s;\n' %(c.mtype, c.mname))
+
+
+def addParent(name, parent):
+ startClass(name, parent, parentClasses)
+ l = kinds[name]
+ minName = l[0]
+ maxName = l[-1]
+ parentClasses.write(""" template <typename R, typename V> R Visit(V *v) const;
+
+ static bool
+ classof(const GoASTNode *n)
+ {
+ return n->GetKind() >= e%s && n->GetKind() <= e%s;
+ }
+
+ protected:
+ explicit GoAST%s(NodeKind kind) : GoASTNode(kind) { }
+ private:
+""" % (minName, maxName, name))
+ endClass(name, parentClasses)
+
+addNodes()
+
+print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// DO NOT EDIT.
+// Generated by gen_go_ast.py
+
+#ifndef liblldb_GoAST_h
+#define liblldb_GoAST_h
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "llvm/Support/Casting.h"
+#include "Plugins/ExpressionParser/Go/GoLexer.h"
+
+namespace lldb_private
+{
+
+class GoASTNode
+{
+ public:
+ typedef GoLexer::TokenType TokenType;
+ typedef GoLexer::Token Token;
+ enum ChanDir
+ {
+ eChanBidir,
+ eChanSend,
+ eChanRecv,
+ };
+ enum NodeKind
+ {"""
+for l in kinds.itervalues():
+ for x in l:
+ print " e%s," % x
+print """ };
+
+ virtual ~GoASTNode() = default;
+
+ NodeKind
+ GetKind() const
+ {
+ return m_kind;
+ }
+
+ virtual const char *GetKindName() const = 0;
+
+ template <typename V> void WalkChildren(V &v);
+
+ protected:
+ explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
+
+ private:
+ const NodeKind m_kind;
+
+ GoASTNode(const GoASTNode &) = delete;
+ const GoASTNode &operator=(const GoASTNode &) = delete;
+};
+"""
+
+
+print parentClasses.getvalue()
+print childClasses.getvalue()
+
+for k, l in kinds.iteritems():
+ if k == 'Node':
+ continue
+ print """
+template <typename R, typename V>
+R GoAST%s::Visit(V* v) const
+{
+ switch(GetKind())
+ {""" % k
+ for subtype in l:
+ print """ case e%(n)s:
+ return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n':subtype}
+
+ print """ default:
+ assert(false && "Invalid kind");
+ }
+}"""
+
+print """
+template <typename V>
+void GoASTNode::WalkChildren(V &v)
+{
+ switch (m_kind)
+ {
+"""
+print walker.getvalue()
+print"""
+ case eEmptyStmt:
+ case eBadDecl:
+ case eBadExpr:
+ case eBadStmt:
+ break;
+ }
+}
+
+} // namespace lldb_private
+
+#endif
+"""