diff options
Diffstat (limited to 'source/Plugins/ExpressionParser/Go/gen_go_ast.py')
-rw-r--r-- | source/Plugins/ExpressionParser/Go/gen_go_ast.py | 356 |
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 +""" |