From eb1ab91e1a12520d825cae60ee49655a0e8c4b94 Mon Sep 17 00:00:00 2001 From: Tuowen Zhao Date: Mon, 26 Sep 2016 08:51:47 -0600 Subject: Node cleanup --- src/ast/node.cpp | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 src/ast/node.cpp (limited to 'src/ast') diff --git a/src/ast/node.cpp b/src/ast/node.cpp new file mode 100644 index 0000000..ea74159 --- /dev/null +++ b/src/ast/node.cpp @@ -0,0 +1,263 @@ +// +// Created by ztuowen on 9/26/16. +// + +#include "chillAST.h" +#include "printer/dump.h" +#include "printer/cfamily.h" + +void chillAST_Node::mergeChildInfo(chillAST_Node) { + // TODO if (par) par->add to definition for vardecl/typedecl + // TODO if (par) par->getSourceFile()->addFunc(this); for FuncDecl + // TODO if (par) par->getSourceFile()->addMacro(this); For MacroDecl + // TODO if (parent) parent->addVariableToSymbolTable(this); // should percolate up until something has a symbol table +} + +void chillAST_Node::addChild(chillAST_Node *c) { + c->parent = this; + // check to see if it's already there + for (int i = 0; i < children.size(); i++) { + if (c == children[i]) { + CHILL_ERROR("addchild ALREADY THERE\n"); + return; // already there + } + } + children.push_back(c); +}; // not usually useful + +void chillAST_Node::addChildren(const chillAST_NodeList &c) { + for (int i = 0; i < c.size(); ++i) { + addChild(c[i]); + } +} + +void chillAST_Node::insertChild(int i, chillAST_Node *node) { + //fprintf(stderr, "%s inserting child of type %s at location %d\n", getTypeString(), node->getTypeString(), i); + node->parent = this; + children.insert(children.begin() + i, node); +}; + +void chillAST_Node::removeChild(int i) { + children.erase(children.begin() + i); +}; + +int chillAST_Node::findChild(chillAST_Node *c) { + for (int i = 0; i < children.size(); i++) { + if (children[i] == c) return i; + } + return -1; +} + +void chillAST_Node::replaceChild(chillAST_Node *old, chillAST_Node *newchild) { + CHILL_DEBUG_PRINT("(%s) forgot to implement replaceChild() ... using generic\n", getTypeString()); + CHILL_DEBUG_PRINT("%d children\n", children.size()); + for (int i = 0; i < children.size(); i++) { + if (children[i] == old) { + children[i] = newchild; + newchild->setParent(this); + return; + } + } + CHILL_ERROR("%s %p generic replaceChild called with oldchild that was not a child\n", + getTypeString(), this); + CHILL_DEBUG_BEGIN + fprintf(stderr, "printing\n"); + print(); + fprintf(stderr, "\nchild: "); + if (!old) fprintf(stderr, "oldchild NULL!\n"); + old->print(); + fprintf(stderr, "\nnew: "); + newchild->print(); + fprintf(stderr, "\n"); + CHILL_DEBUG_END + exit(-1); +}; + +void chillAST_Node::loseLoopWithLoopVar(char *var) { + std::vector dupe = children; // simple enough? + for (int i = 0; i < dupe.size(); i++) { // recurse on all children + dupe[i]->loseLoopWithLoopVar(var); + } +} + +//! recursive walk parent links, looking for loops, and grabbing the declRefExpr in the loop init and cond. +void chillAST_Node::gatherLoopIndeces( + std::vector &indeces) { + // you can quit when you get to certain nodes + + CHILL_DEBUG_PRINT("%s::gatherLoopIndeces()\n", getTypeString()); + + if (isSourceFile() || isFunctionDecl()) return; // end of the line + + if (!parent) return; // should not happen, but be careful + + // for most nodes, this just recurses upwards + parent->gatherLoopIndeces(indeces); +} + +//! recursive walk parent links, looking for loops +chillAST_ForStmt *chillAST_Node::findContainingLoop() { + CHILL_DEBUG_PRINT("%s::findContainingLoop() ", getTypeString()); + if (!parent) return NULL; + if (parent->isForStmt()) return (chillAST_ForStmt *) parent; + return parent->findContainingLoop(); // recurse upwards +} + +chillAST_Node *chillAST_Node::findContainingNonLoop() { + fprintf(stderr, "%s::findContainingNonLoop() ", getTypeString()); + if (!parent) return NULL; + if (parent->isCompoundStmt() && parent->getParent()->isForStmt()) + return parent->getParent()->findContainingNonLoop(); // keep recursing + if (parent->isForStmt()) return parent->findContainingNonLoop(); // keep recursing + return (chillAST_Node *) parent; // return non-loop +} + +void chillAST_Node::getTopLevelLoops(std::vector &loops) { + int n = children.size(); + for (int i = 0; i < n; i++) { + if (children[i]->isForStmt()) { + loops.push_back(((chillAST_ForStmt *) (children[i]))); + } + } +} + + +void chillAST_Node::repairParentChild() { // for nodes where all subnodes are children + int n = children.size(); + for (int i = 0; i < n; i++) { + if (children[i]->parent != this) { + fprintf(stderr, "fixing child %s that didn't know its parent\n", children[i]->getTypeString()); + children[i]->parent = this; + } + } +} + + +void chillAST_Node::get_deep_loops( + std::vector &loops) { // this is probably broken - returns ALL loops under it + int n = children.size(); + //fprintf(stderr, "get_deep_loops of a %s with %d children\n", getTypeString(), n); + for (int i = 0; i < n; i++) { + //fprintf(stderr, "child %d is a %s\n", i, children[i]->getTypeString()); + children[i]->get_deep_loops(loops); + } + //fprintf(stderr, "found %d deep loops\n", loops.size()); +} + + +// generic for chillAST_Node with children +void chillAST_Node::find_deepest_loops(std::vector &loops) { // returns DEEPEST nesting of loops + std::vector deepest; // deepest below here + + int n = children.size(); + //fprintf(stderr, "find_deepest_loops of a %s with %d children\n", getTypeString(), n); + for (int i = 0; i < n; i++) { + std::vector subloops; // loops below here among a child of mine + + //fprintf(stderr, "child %d is a %s\n", i, children[i]->getTypeString()); + children[i]->find_deepest_loops(subloops); + + if (subloops.size() > deepest.size()) { + deepest = subloops; + } + } + + // append deepest we see at this level to loops + for (int i = 0; i < deepest.size(); i++) { + loops.push_back(deepest[i]); + } + + //fprintf(stderr, "found %d deep loops\n", loops.size()); + +} + +chillAST_SourceFile *chillAST_Node::getSourceFile() { + if (isSourceFile()) return ((chillAST_SourceFile *) this); + if (parent != NULL) return parent->getSourceFile(); + CHILL_ERROR("UHOH, getSourceFile() called on node %p %s that does not have a parent and is not a source file\n", + this, this->getTypeString()); + this->print(); + exit(-1); +} + +void chillAST_Node::addVariableToScope(chillAST_VarDecl *vd) { + CHILL_DEBUG_PRINT("addVariableToScope( %s )\n", vd->varname); + if (!symbolTable) return; + symbolTable = addSymbolToTable(symbolTable, vd); + vd->parent = this; +} + +void chillAST_Node::addTypedefToScope(chillAST_TypedefDecl *tdd) { + if (!typedefTable) return; + typedefTable = addTypedefToTable(typedefTable, tdd); + tdd->parent = this; +} + +chillAST_TypedefDecl *chillAST_Node::findTypeDecleration(const char *t) { + fprintf(stderr, " %s \n", t); + chillAST_TypedefDecl *td = getTypeDeclaration(t); + if (!td && parent) return parent->findTypeDecleration(t); + return td; // should not happen +} + +chillAST_VarDecl *chillAST_Node::findVariableDecleration(const char *t) { + fprintf(stderr, " %s \n", t); + chillAST_VarDecl *td = getVariableDeclaration(t); + if (!td && parent) return parent->findVariableDecleration(t); + return td; // should not happen +} + +chillAST_VarDecl *chillAST_Node::getVariableDeclaration(const char *t) { + chillAST_VarDecl *vd = symbolTableFindName(getSymbolTable(), t); + if (!vd) vd = getParameter(t); + return vd; +} + +chillAST_TypedefDecl *chillAST_Node::getTypeDeclaration(const char *t) { + return typedefTableFindName(getTypedefTable(), t); +} + +void chillAST_Node::addParameter(chillAST_VarDecl *vd) { + if (!parameters) { + CHILL_ERROR("Calling addParameter on construct without parameters"); + exit(-1); + } + + if (symbolTableFindName(getParameters(), vd->varname)) { // NOT recursive. just in FunctionDecl + CHILL_ERROR("parameter %s already exists?\n", vd->varname); + return; + } + + CHILL_DEBUG_PRINT("setting %s isAParameter\n", vd->varname); + getParameters()->push_back(vd); + vd->isAParameter = true; + vd->setParent(this); // this is a combined list! +} + +chillAST_VarDecl *chillAST_Node::getParameter(const char *t) { + return symbolTableFindName(getParameters(), t); +} + +void chillAST_Node::dump(int indent, FILE *fp) { + if (fp == stderr) { + chill::printer::Dump d; + d.printErr("", this); + fprintf(stderr, "\n"); + } else { + chill::printer::Dump d; + d.printOut("", this); + fprintf(stdout, "\n"); + } +} + +void chillAST_Node::print(int indent, FILE *fp) { + if (fp == stderr) { + chill::printer::CFamily d; + d.printErr("", this); + fprintf(stderr, "\n"); + } else { + chill::printer::CFamily d; + d.printOut("", this); + fprintf(stdout, "\n"); + } +} -- cgit v1.2.3-70-g09d2