Makes id-tree doubly linked. Fixes id-tree search.
							parent
							
								
									27587d1fb0
								
							
						
					
					
						commit
						8f86392cf3
					
				
							
								
								
									
										35
									
								
								iftest.w
								
								
								
								
							
							
						
						
									
										35
									
								
								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; | ||||
|                         } | ||||
|                     } | ||||
|  |  | |||
							
								
								
									
										132
									
								
								src/identcheck.c
								
								
								
								
							
							
						
						
									
										132
									
								
								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; | ||||
| } | ||||
|  | @ -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);
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue