From 8f86392cf33f31e04886475561532c0269075f6b Mon Sep 17 00:00:00 2001 From: venko Date: Fri, 7 May 2021 13:22:51 -0700 Subject: [PATCH] Makes id-tree doubly linked. Fixes id-tree search. --- iftest.w | 35 +++++++------ src/identcheck.c | 132 ++++++++++++++++++++++++++--------------------- src/identcheck.h | 5 +- src/main.c | 9 +++- 4 files changed, 104 insertions(+), 77 deletions(-) diff --git a/iftest.w b/iftest.w index 90d5d11..73df20c 100644 --- a/iftest.w +++ b/iftest.w @@ -1,20 +1,21 @@ -struct Program { // Scope () - static Main(): int { // | Program : Struct - myInt: int = 54; // | | Main : Function - if (myInt < 0) { // | | | myInt : Variable - signTag: int = 0 - 1; // | | | Scope (if-else) - } else if (myInt == 0) { // | | | | Scope (if) - signTag: int = 0; // | | | | | signTag : Variable - } else { // | | | | Scope (else) - signTag: int = 1; // | | | | | Scope (if) - } // | | | | | | signTag : Variable - // | | | myBool : Variable - myBool: bool; // | | | Scope (if) - if (myBool) { // | | | | Scope (if) - if (myBool) { // | | | | | Scope (if) - if (myBool) { // | | | | | | Scope (if) - if (myBool) { // | | | | | | | Scope (if) - if (myBool) { // | | | | | | | | lol : Variable +struct Program { + static Main(): int { + myInt: int = 54; + if (myInt < 0) { + signTag: int = 0 - 1; + } else if (myInt == 0) { + signTag: int = 0; + } else { + signTag: int = 1; + } + + lol: int = 420; + myBool: bool; + if (myBool) { + if (myBool) { + if (myBool) { + if (myBool) { + if (myBool) { lol: int = 69; } } diff --git a/src/identcheck.c b/src/identcheck.c index 772628b..1796ca6 100644 --- a/src/identcheck.c +++ b/src/identcheck.c @@ -6,10 +6,11 @@ #include "ast.h" #include "identcheck.h" -IdNode* MakeIdNode(NodeType type, char *name) { +IdNode* MakeIdNode(NodeType type, char *name, IdNode *parent) { IdNode *node = (IdNode*)malloc(sizeof(IdNode)); node->type = type; node->name = strdup(name); + node->parent = parent; node->childCount = 0; node->childCapacity = 0; node->children = NULL; @@ -31,51 +32,19 @@ void AddChildToNode(IdNode *node, IdNode *child) { node->childCount += 1; } -IdNode* FindId(IdNode *root, NodeType targetType, char *targetName) { - IdNode *result = NULL; - IdNode **frontier = (IdNode**)malloc(sizeof(IdNode*)); - frontier[0] = root; - uint32_t frontierCount = 1; - - while (frontierCount > 0) { - IdNode *current = frontier[0]; - - if (current->type == targetType && strcmp(current->name, targetName)) { - result = current; - break; - } - - IdNode **temp = - (IdNode**)malloc(sizeof(IdNode*) * (frontierCount - 1 + current->childCount)); - uint32_t i; - for (i = 1; i < frontierCount; i++) { - temp[i - 1] = frontier[i]; - } - uint32_t offset = i; - for (i = 0; i < current->childCount; i++) { - temp[offset + i] = current->children[i]; - } - frontier = temp; - frontierCount += current->childCount - 1; - } - - free(frontier); - return result; -} - -IdNode* MakeIdTree(Node *astNode) { +IdNode* MakeIdTree(Node *astNode, IdNode *parent) { uint32_t i; switch (astNode->syntaxKind) { case Assignment: return (astNode->children[0]->syntaxKind == Declaration) - ? MakeIdTree(astNode->children[0]) + ? MakeIdTree(astNode->children[0], parent) : NULL; case IfStatement: { Node *stmtSeq = astNode->children[1]; - IdNode *ifNode = MakeIdNode(LexicalScope, "if"); + IdNode *ifNode = MakeIdNode(LexicalScope, "if", parent); for (i = 0; i < stmtSeq->childCount; i++) { - AddChildToNode(ifNode, MakeIdTree(stmtSeq->children[i])); + AddChildToNode(ifNode, MakeIdTree(stmtSeq->children[i], ifNode)); } return ifNode; } @@ -83,14 +52,14 @@ IdNode* MakeIdTree(Node *astNode) { case IfElseStatement: { Node *ifNode = astNode->children[0]; Node *elseStmts = astNode->children[1]; - IdNode *ifElseNode = MakeIdNode(LexicalScope, "if-else"); - IdNode *ifBranch = MakeIdTree(ifNode); - IdNode *elseBranch = MakeIdNode(LexicalScope, "else"); + IdNode *ifElseNode = MakeIdNode(LexicalScope, "if-else", parent); + IdNode *ifBranch = MakeIdTree(ifNode, ifElseNode); + IdNode *elseBranch = MakeIdNode(LexicalScope, "else", ifElseNode); AddChildToNode(ifElseNode, ifBranch); AddChildToNode(ifElseNode, elseBranch); for (i = 0; i < elseStmts->childCount; i++) { - AddChildToNode(elseBranch, MakeIdTree(elseStmts->children[i])); + AddChildToNode(elseBranch, MakeIdTree(elseStmts->children[i], elseBranch)); } return ifElseNode; @@ -99,23 +68,23 @@ IdNode* MakeIdTree(Node *astNode) { case ForLoop: { Node *loopDecl = astNode->children[0]; Node *loopBody = astNode->children[3]; - IdNode *loopNode = MakeIdNode(LexicalScope, "for-loop"); - AddChildToNode(loopNode, MakeIdTree(loopDecl)); + IdNode *loopNode = MakeIdNode(LexicalScope, "for-loop", parent); + AddChildToNode(loopNode, MakeIdTree(loopDecl, loopNode)); for (i = 0; i < loopBody->childCount; i++) { - AddChildToNode(loopNode, MakeIdTree(loopBody->children[i])); + AddChildToNode(loopNode, MakeIdTree(loopBody->children[i], loopNode)); } return loopNode; } case Declaration: - return MakeIdNode(Variable, astNode->children[1]->value.string); + return MakeIdNode(Variable, astNode->children[1]->value.string, parent); case StructDeclaration: { Node *idNode = astNode->children[0]; Node *declsNode = astNode->children[1]; - IdNode *structNode = MakeIdNode(Struct, idNode->value.string); + IdNode *structNode = MakeIdNode(Struct, idNode->value.string, parent); for (i = 0; i < declsNode->childCount; i++) { - AddChildToNode(structNode, MakeIdTree(declsNode->children[i])); + AddChildToNode(structNode, MakeIdTree(declsNode->children[i], structNode)); } return structNode; } @@ -125,20 +94,20 @@ IdNode* MakeIdTree(Node *astNode) { Node *funcNameNode = sigNode->children[0]; Node *funcArgsNode = sigNode->children[2]; Node *bodyStatementsNode = astNode->children[1]; - IdNode *funcNode = MakeIdNode(Function, funcNameNode->value.string); + IdNode *funcNode = MakeIdNode(Function, funcNameNode->value.string, parent); for (i = 0; i < funcArgsNode->childCount; i++) { - AddChildToNode(funcNode, MakeIdTree(funcArgsNode->children[i])); + AddChildToNode(funcNode, MakeIdTree(funcArgsNode->children[i], funcNode)); } for (i = 0; i < bodyStatementsNode->childCount; i++) { - AddChildToNode(funcNode, MakeIdTree(bodyStatementsNode->children[i])); + AddChildToNode(funcNode, MakeIdTree(bodyStatementsNode->children[i], funcNode)); } return funcNode; } case DeclarationSequence: { - IdNode *declSeqNode = MakeIdNode(LexicalScope, ""); + IdNode *declSeqNode = MakeIdNode(LexicalScope, "", parent); for (i = 0; i < astNode->childCount; i++) { - AddChildToNode(declSeqNode, MakeIdTree(astNode->children[i])); + AddChildToNode(declSeqNode, MakeIdTree(astNode->children[i], declSeqNode)); } return declSeqNode; } @@ -148,20 +117,67 @@ IdNode* MakeIdTree(Node *astNode) { } } +void PrintIdNode(IdNode *node) { + switch(node->type) { + case LexicalScope: printf("Scope (%s)\n", node->name); break; + case Struct: printf("%s : Struct\n", node->name); break; + case Function: printf("%s : Function\n", node->name); break; + case Variable: printf("%s : Variable\n", node->name); break; + } +} + void PrintIdTree(IdNode *tree, uint32_t tabCount) { uint32_t i; for (i = 0; i < tabCount; i++) { printf("| "); } - switch(tree->type) { - case LexicalScope: printf("Scope (%s)\n", tree->name); break; - case Struct: printf("%s : Struct\n", tree->name); break; - case Function: printf("%s : Function\n", tree->name); break; - case Variable: printf("%s : Variable\n", tree->name); break; - } + PrintIdNode(tree); for (i = 0; i < tree->childCount; i++) { PrintIdTree(tree->children[i], tabCount + 1); } } + + +int PrintAncestors(IdNode *node) { + if (node == NULL) return -1; + + int i; + int indent = 1; + indent += PrintAncestors(node->parent); + for (i = 0; i < indent; i++) { + printf(" "); + } + PrintIdNode(node); + return indent; +} + +IdNode* FindId(IdNode *root, NodeType targetType, char *targetName) { + IdNode *result = NULL; + IdNode **frontier = (IdNode**)malloc(sizeof(IdNode*)); + frontier[0] = root; + uint32_t frontierCount = 1; + uint32_t cursor = 0; + + while (frontierCount > 0 && cursor < frontierCount) { + IdNode *current = frontier[cursor]; + + if (current->type == targetType && strcmp(current->name, targetName) == 0) { + result = current; + break; + } + + int newSize = frontierCount + current->childCount; + frontier = realloc(frontier, sizeof(IdNode*) * newSize); + uint32_t i; + for (i = 0; i < current->childCount; i++) { + frontier[frontierCount + i] = current->children[i]; + } + frontierCount += current->childCount; + cursor += 1; + } + + free(frontier); + return result; +} \ No newline at end of file diff --git a/src/identcheck.h b/src/identcheck.h index 395a73c..0afa6ac 100644 --- a/src/identcheck.h +++ b/src/identcheck.h @@ -16,6 +16,7 @@ typedef enum NodeType { typedef struct IdNode { NodeType type; char *name; + struct IdNode *parent; struct IdNode **children; uint32_t childCount; uint32_t childCapacity; @@ -28,8 +29,10 @@ typedef struct IdStatus { } IdStatus; -IdNode* MakeIdTree(Node *astNode); +IdNode* FindId(IdNode *root, NodeType targetType, char *targetName); +IdNode* MakeIdTree(Node *astNode, IdNode *parent); void PrintIdTree(IdNode *tree, uint32_t tabCount); +int PrintAncestors(IdNode *node); //IdStatus CheckIds(Node *root); diff --git a/src/main.c b/src/main.c index 10668c2..ab08167 100644 --- a/src/main.c +++ b/src/main.c @@ -65,7 +65,14 @@ int main(int argc, char *argv[]) } else { - PrintIdTree(MakeIdTree(rootNode), /*tabCount=*/0); + IdNode *idTree = MakeIdTree(rootNode, NULL); + PrintIdTree(idTree, /*tabCount=*/0); + + { + printf("Searching for a variable named 'lol' and printing its ancestors\n"); + IdNode *deepest = FindId(idTree, Variable, "lol"); + PrintAncestors(deepest); + } exitCode = Codegen(rootNode, optimizationLevel); } }