Adds type for validating identifiers
							parent
							
								
									6ec5479db1
								
							
						
					
					
						commit
						aeb36f9540
					
				|  | @ -23,7 +23,7 @@ find_package(LLVM) | |||
| 
 | ||||
| include_directories(${CMAKE_SOURCE_DIR}) | ||||
| 
 | ||||
| BISON_TARGET(Parser generators/wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS "-d -v -t -Wcounterexamples") | ||||
| BISON_TARGET(Parser generators/wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS "-d -v -t") | ||||
| FLEX_TARGET(Scanner generators/wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) | ||||
| 
 | ||||
| ADD_FLEX_BISON_DEPENDENCY(Scanner Parser) | ||||
|  | @ -41,9 +41,11 @@ add_executable( | |||
| 	# Source | ||||
| 	src/ast.h | ||||
| 	src/codegen.h | ||||
| 	src/identcheck.h | ||||
| 	src/parser.h | ||||
|     src/ast.c | ||||
| 	src/codegen.c | ||||
| 	src/identcheck.c | ||||
| 	src/parser.c | ||||
| 	src/main.c | ||||
| 	# Generated code | ||||
|  |  | |||
|  | @ -0,0 +1,130 @@ | |||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "ast.h" | ||||
| #include "identcheck.h" | ||||
| 
 | ||||
| IdNode* MakeIdNode(NodeType type, char *name) { | ||||
|     IdNode *node = (IdNode*)malloc(sizeof(IdNode)); | ||||
|     node->type = type; | ||||
|     node->name = strdup(name); | ||||
|     node->childCount = 0; | ||||
|     node->childCapacity = 0; | ||||
|     node->children = NULL; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| void AddChildToNode(IdNode *node, IdNode *child) { | ||||
|     if (child == NULL) return; | ||||
| 
 | ||||
|     if (node->children == NULL) { | ||||
|         node->childCapacity = 2; | ||||
|         node->children = (IdNode**)malloc(sizeof(IdNode*) * node->childCapacity); | ||||
|     } else if (node->childCount == node->childCapacity) { | ||||
|         node->childCapacity *= 2; | ||||
|         node->children = realloc(node->children, sizeof(IdNode*) * node->childCapacity); | ||||
|     } | ||||
| 
 | ||||
|     node->children[node->childCount] = 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) { | ||||
|     switch (astNode->syntaxKind) { | ||||
|         case Declaration: | ||||
|             return MakeIdNode(Variable, astNode->children[1]->value.string); | ||||
| 
 | ||||
|         case DeclarationSequence:  { | ||||
|             IdNode *declSeqNode = MakeIdNode(LexicalScope, ""); | ||||
|             uint32_t i; | ||||
|             for (i = 0; i < astNode->childCount; i++) { | ||||
|                 AddChildToNode(declSeqNode, MakeIdTree(astNode->children[i])); | ||||
|             } | ||||
|             return declSeqNode; | ||||
|         } | ||||
| 
 | ||||
|         case StructDeclaration: { | ||||
|             Node *idNode = astNode->children[0]; | ||||
|             Node *declsNode = astNode->children[1]; | ||||
|             IdNode *structNode = MakeIdNode(Struct, idNode->value.string); | ||||
|             uint32_t i; | ||||
|             for (i = 0; i < declsNode->childCount; i++) { | ||||
|                 AddChildToNode(structNode, MakeIdTree(declsNode->children[i])); | ||||
|             } | ||||
|             return structNode; | ||||
|         } | ||||
| 
 | ||||
|         case FunctionDeclaration: { | ||||
|             Node *sigNode = astNode->children[0]; | ||||
|             Node *funcNameNode = sigNode->children[0]; | ||||
|             Node *funcArgsNode = sigNode->children[2]; | ||||
| 
 | ||||
|             Node *bodyStatementsNode = astNode->children[1]; | ||||
| 
 | ||||
|             IdNode *funcNode = MakeIdNode(Function, funcNameNode->value.string); | ||||
|             uint32_t i; | ||||
|             for (i = 0; i < funcArgsNode->childCount; i++) { | ||||
|                 AddChildToNode(funcNode, MakeIdTree(funcArgsNode->children[i])); | ||||
|             } | ||||
|             for (i = 0; i < bodyStatementsNode->childCount; i++) { | ||||
|                 AddChildToNode(funcNode, MakeIdTree(bodyStatementsNode->children[i])); | ||||
|             } | ||||
|             return funcNode; | ||||
|         } | ||||
| 
 | ||||
|         default: | ||||
|             return NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void PrintIdTree(IdNode *tree, uint32_t tabCount) { | ||||
|     uint32_t i; | ||||
|     for (i = 0; i < tabCount; i++) { | ||||
|         printf("| "); | ||||
|     } | ||||
| 
 | ||||
|     switch(tree->type) { | ||||
|         case LexicalScope: printf("Scope\n"); 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; | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < tree->childCount; i++) { | ||||
|         PrintIdTree(tree->children[i], tabCount + 1); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,36 @@ | |||
| // Validates identifier usage in an AST.
 | ||||
| #ifndef WRAITH_IDENTCHECK_H | ||||
| #define WRAITH_IDENTCHECK_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "ast.h" | ||||
| 
 | ||||
| typedef enum NodeType { | ||||
|     LexicalScope, | ||||
|     Struct, | ||||
|     Function, | ||||
|     Variable | ||||
| } NodeType; | ||||
| 
 | ||||
| typedef struct IdNode { | ||||
|     NodeType type; | ||||
|     char *name; | ||||
|     struct IdNode **children; | ||||
|     uint32_t childCount; | ||||
|     uint32_t childCapacity; | ||||
| } IdNode; | ||||
| 
 | ||||
| typedef struct IdStatus { | ||||
|     enum StatusCode { | ||||
|         Valid, | ||||
|     } StatusCode; | ||||
| } IdStatus; | ||||
| 
 | ||||
| 
 | ||||
| IdNode* MakeIdTree(Node *astNode); | ||||
| void PrintIdTree(IdNode *tree, uint32_t tabCount); | ||||
| 
 | ||||
| //IdStatus CheckIds(Node *root);
 | ||||
| 
 | ||||
| #endif /* WRAITH_IDENTCHECK_H */ | ||||
		Loading…
	
		Reference in New Issue