forked from cosmonaut/wraith-lang
				
			Possibly implements full type annotation of the AST
							parent
							
								
									32541d4794
								
							
						
					
					
						commit
						f441e5bede
					
				|  | @ -0,0 +1,11 @@ | ||||||
|  | struct MyStruct { | ||||||
|  |     foo: int; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct Program { | ||||||
|  |     static Main(): int { | ||||||
|  |         myStruct: Reference<MyStruct>; | ||||||
|  |         myStruct = alloc MyStruct; | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										15
									
								
								src/ast.c
								
								
								
								
							|  | @ -97,6 +97,7 @@ Node* MakeIdentifierNode( | ||||||
|     node->syntaxKind = Identifier; |     node->syntaxKind = Identifier; | ||||||
|     node->value.string = strdup(id); |     node->value.string = strdup(id); | ||||||
|     node->childCount = 0; |     node->childCount = 0; | ||||||
|  |     node->typeTag = NULL; | ||||||
|     return node; |     return node; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -506,7 +507,12 @@ static void PrintNode(Node *node, int tabCount) | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case Identifier: |         case Identifier: | ||||||
|             printf("%s", node->value.string); |             if (node->typeTag == NULL) { | ||||||
|  |                 printf("%s", node->value.string); | ||||||
|  |             } else { | ||||||
|  |                 char *type = TypeTagToString(node->typeTag); | ||||||
|  |                 printf("%s<%s>", node->value.string, type); | ||||||
|  |             } | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case Number: |         case Number: | ||||||
|  | @ -561,6 +567,7 @@ TypeTag* MakeTypeTag(Node *node) { | ||||||
|         case StructDeclaration: |         case StructDeclaration: | ||||||
|             tag->type = Custom; |             tag->type = Custom; | ||||||
|             tag->value.customType = strdup(node->children[0]->value.string); |             tag->value.customType = strdup(node->children[0]->value.string); | ||||||
|  |             printf("Struct tag: %s\n", TypeTagToString(tag)); | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case FunctionDeclaration: |         case FunctionDeclaration: | ||||||
|  | @ -593,15 +600,9 @@ char* TypeTagToString(TypeTag *tag) { | ||||||
|             size_t innerStrLen = strlen(inner); |             size_t innerStrLen = strlen(inner); | ||||||
|             char *result = malloc(sizeof(char) * (innerStrLen + 5)); |             char *result = malloc(sizeof(char) * (innerStrLen + 5)); | ||||||
|             sprintf(result, "Ref<%s>", inner); |             sprintf(result, "Ref<%s>", inner); | ||||||
|             free(inner); |  | ||||||
|             return result; |             return result; | ||||||
|         } |         } | ||||||
|         case Custom: |         case Custom: | ||||||
|             return tag->value.customType; |             return tag->value.customType; | ||||||
|     } |     } | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void AddTypeTags(Node *ast)  |  | ||||||
| { |  | ||||||
|     fprintf(stderr, "wraith: AddTypeTags not implemented yet.\n"); |  | ||||||
| } | } | ||||||
|  | @ -2,6 +2,7 @@ | ||||||
| #define WRAITH_AST_H | #define WRAITH_AST_H | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
|  | #include "identcheck.h" | ||||||
| 
 | 
 | ||||||
| typedef enum | typedef enum | ||||||
| { | { | ||||||
|  | @ -108,6 +109,7 @@ typedef struct Node | ||||||
|     } value; |     } value; | ||||||
|     PrimitiveType primitiveType; |     PrimitiveType primitiveType; | ||||||
|     TypeTag *typeTag;  |     TypeTag *typeTag;  | ||||||
|  |     IdNode *idLink; | ||||||
| } Node; | } Node; | ||||||
| 
 | 
 | ||||||
| const char* SyntaxKindString(SyntaxKind syntaxKind); | const char* SyntaxKindString(SyntaxKind syntaxKind); | ||||||
|  | @ -231,9 +233,9 @@ Node* MakeForLoopNode( | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| void PrintTree(Node *node, uint32_t tabCount); | void PrintTree(Node *node, uint32_t tabCount); | ||||||
|  | const char* SyntaxKindString(SyntaxKind syntaxKind); | ||||||
| 
 | 
 | ||||||
| TypeTag* MakeTypeTag(Node *node); | TypeTag* MakeTypeTag(Node *node); | ||||||
| char* TypeTagToString(TypeTag *tag); | char* TypeTagToString(TypeTag *tag); | ||||||
| void AddTypeTags(Node *ast); |  | ||||||
| 
 | 
 | ||||||
| #endif /* WRAITH_AST_H */ | #endif /* WRAITH_AST_H */ | ||||||
|  |  | ||||||
							
								
								
									
										114
									
								
								src/identcheck.c
								
								
								
								
							
							
						
						
									
										114
									
								
								src/identcheck.c
								
								
								
								
							|  | @ -36,63 +36,74 @@ void AddChildToNode(IdNode *node, IdNode *child) { | ||||||
| 
 | 
 | ||||||
| IdNode* MakeIdTree(Node *astNode, IdNode *parent) { | IdNode* MakeIdTree(Node *astNode, IdNode *parent) { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|  |     IdNode *mainNode; | ||||||
|     switch (astNode->syntaxKind) { |     switch (astNode->syntaxKind) { | ||||||
|         case Assignment: |         case Assignment: { | ||||||
|             return (astNode->children[0]->syntaxKind == Declaration) |             if (astNode->children[0]->syntaxKind == Declaration) { | ||||||
|                 ? MakeIdTree(astNode->children[0], parent) |                 return MakeIdTree(astNode->children[0], parent); | ||||||
|                 : NULL; |             } else { | ||||||
|  |                 for (i = 0; i < astNode->childCount; i++) { | ||||||
|  |                     AddChildToNode(parent, MakeIdTree(astNode->children[i], parent)); | ||||||
|  |                 } | ||||||
|  |                 return NULL; | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         case IfStatement: { |         case IfStatement: { | ||||||
|  |             mainNode = MakeIdNode(OrderedScope, "if", parent); | ||||||
|  |             Node *clause = astNode->children[0]; | ||||||
|             Node *stmtSeq = astNode->children[1]; |             Node *stmtSeq = astNode->children[1]; | ||||||
|             IdNode *ifNode = MakeIdNode(OrderedScope, "if", parent); |             for (i = 0; i < clause->childCount; i++) { | ||||||
|             for (i = 0; i < stmtSeq->childCount; i++) { |                 AddChildToNode(mainNode, MakeIdTree(clause->children[i], mainNode)); | ||||||
|                 AddChildToNode(ifNode, MakeIdTree(stmtSeq->children[i], ifNode)); |  | ||||||
|             } |             } | ||||||
|             return ifNode; |             for (i = 0; i < stmtSeq->childCount; i++) { | ||||||
|  |                 AddChildToNode(mainNode, MakeIdTree(stmtSeq->children[i], mainNode)); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case IfElseStatement: { |         case IfElseStatement: { | ||||||
|             Node *ifNode = astNode->children[0]; |             Node *ifNode = astNode->children[0]; | ||||||
|             Node *elseStmts = astNode->children[1]; |             Node *elseStmts = astNode->children[1]; | ||||||
|             IdNode *ifElseNode = MakeIdNode(OrderedScope, "if-else", parent); |             mainNode = MakeIdNode(OrderedScope, "if-else", parent); | ||||||
|             IdNode *ifBranch = MakeIdTree(ifNode, ifElseNode); |             IdNode *ifBranch = MakeIdTree(ifNode, mainNode); | ||||||
|             IdNode *elseBranch = MakeIdNode(OrderedScope, "else", ifElseNode); |             IdNode *elseBranch = MakeIdNode(OrderedScope, "else", mainNode); | ||||||
| 
 | 
 | ||||||
|             AddChildToNode(ifElseNode, ifBranch); |             AddChildToNode(mainNode, ifBranch); | ||||||
|             for (i = 0; i < elseStmts->childCount; i++) { |             for (i = 0; i < elseStmts->childCount; i++) { | ||||||
|                 AddChildToNode(elseBranch, MakeIdTree(elseStmts->children[i], elseBranch)); |                 AddChildToNode(elseBranch, MakeIdTree(elseStmts->children[i], elseBranch)); | ||||||
|             } |             } | ||||||
|             AddChildToNode(ifElseNode, elseBranch); |             AddChildToNode(mainNode, elseBranch); | ||||||
| 
 |             break; | ||||||
|             return ifElseNode; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case ForLoop: { |         case ForLoop: { | ||||||
|             Node *loopDecl = astNode->children[0]; |             Node *loopDecl = astNode->children[0]; | ||||||
|             Node *loopBody = astNode->children[3]; |             Node *loopBody = astNode->children[3]; | ||||||
|             IdNode *loopNode = MakeIdNode(OrderedScope, "for-loop", parent); |             mainNode = MakeIdNode(OrderedScope, "for-loop", parent); | ||||||
|             AddChildToNode(loopNode, MakeIdTree(loopDecl, loopNode)); |             AddChildToNode(mainNode, MakeIdTree(loopDecl, mainNode)); | ||||||
|             for (i = 0; i < loopBody->childCount; i++) { |             for (i = 0; i < loopBody->childCount; i++) { | ||||||
|                 AddChildToNode(loopNode, MakeIdTree(loopBody->children[i], loopNode)); |                 AddChildToNode(mainNode, MakeIdTree(loopBody->children[i], mainNode)); | ||||||
|             } |             } | ||||||
|             return loopNode; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case Declaration: { |         case Declaration: { | ||||||
|             IdNode *declNode = MakeIdNode(Variable, astNode->children[1]->value.string, parent); |             mainNode = MakeIdNode(Variable, astNode->children[1]->value.string, parent); | ||||||
|             declNode->typeTag = MakeTypeTag(astNode); |             mainNode->typeTag = MakeTypeTag(astNode); | ||||||
|             return declNode; |             astNode->children[1]->typeTag = mainNode->typeTag; | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case StructDeclaration: { |         case StructDeclaration: { | ||||||
|             Node *idNode = astNode->children[0]; |             Node *idNode = astNode->children[0]; | ||||||
|             Node *declsNode = astNode->children[1]; |             Node *declsNode = astNode->children[1]; | ||||||
|             IdNode *structNode = MakeIdNode(Struct, idNode->value.string, parent); |             mainNode = MakeIdNode(Struct, idNode->value.string, parent); | ||||||
|             structNode->typeTag = MakeTypeTag(astNode); |             mainNode->typeTag = MakeTypeTag(astNode); | ||||||
|             for (i = 0; i < declsNode->childCount; i++) { |             for (i = 0; i < declsNode->childCount; i++) { | ||||||
|                 AddChildToNode(structNode, MakeIdTree(declsNode->children[i], structNode)); |                 AddChildToNode(mainNode, MakeIdTree(declsNode->children[i], mainNode)); | ||||||
|             } |             } | ||||||
|             return structNode; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case FunctionDeclaration: { |         case FunctionDeclaration: { | ||||||
|  | @ -100,28 +111,50 @@ IdNode* MakeIdTree(Node *astNode, IdNode *parent) { | ||||||
|             Node *funcNameNode = sigNode->children[0]; |             Node *funcNameNode = sigNode->children[0]; | ||||||
|             Node *funcArgsNode = sigNode->children[2]; |             Node *funcArgsNode = sigNode->children[2]; | ||||||
|             Node *bodyStatementsNode = astNode->children[1]; |             Node *bodyStatementsNode = astNode->children[1]; | ||||||
|             IdNode *funcNode = MakeIdNode(Function, funcNameNode->value.string, parent); |             mainNode = MakeIdNode(Function, funcNameNode->value.string, parent); | ||||||
|             funcNode->typeTag = MakeTypeTag(astNode); |             mainNode->typeTag = MakeTypeTag(astNode); | ||||||
|  |             astNode->children[0]->children[0]->typeTag = mainNode->typeTag; | ||||||
|             for (i = 0; i < funcArgsNode->childCount; i++) { |             for (i = 0; i < funcArgsNode->childCount; i++) { | ||||||
|                 AddChildToNode(funcNode, MakeIdTree(funcArgsNode->children[i], funcNode)); |                 AddChildToNode(mainNode, MakeIdTree(funcArgsNode->children[i], mainNode)); | ||||||
|             } |             } | ||||||
|             for (i = 0; i < bodyStatementsNode->childCount; i++) { |             for (i = 0; i < bodyStatementsNode->childCount; i++) { | ||||||
|                 AddChildToNode(funcNode, MakeIdTree(bodyStatementsNode->children[i], funcNode)); |                 AddChildToNode(mainNode, MakeIdTree(bodyStatementsNode->children[i], mainNode)); | ||||||
|             } |             } | ||||||
|             return funcNode; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case DeclarationSequence: { |         case DeclarationSequence: { | ||||||
|             IdNode *declSeqNode = MakeIdNode(UnorderedScope, "", parent); |             mainNode = MakeIdNode(UnorderedScope, "", parent); | ||||||
|             for (i = 0; i < astNode->childCount; i++) { |             for (i = 0; i < astNode->childCount; i++) { | ||||||
|                 AddChildToNode(declSeqNode, MakeIdTree(astNode->children[i], declSeqNode)); |                 AddChildToNode(mainNode, MakeIdTree(astNode->children[i], mainNode)); | ||||||
|             } |             } | ||||||
|             return declSeqNode; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         default: |         case Identifier: { | ||||||
|  |             mainNode = MakeIdNode(Placeholder, astNode->value.string, parent); | ||||||
|  |             IdNode *lookupNode = LookupId(mainNode, NULL, astNode->value.string); | ||||||
|  |             if (lookupNode == NULL) { | ||||||
|  |                 fprintf(stderr, "wraith: Could not find IdNode for id %s\n", astNode->value.string); | ||||||
|  |                 TypeTag *tag = (TypeTag*)malloc(sizeof(TypeTag)); | ||||||
|  |                 tag->type = Unknown; | ||||||
|  |                 astNode->typeTag = tag; | ||||||
|  |             } else { | ||||||
|  |                 astNode->typeTag = lookupNode->typeTag; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         default: { | ||||||
|  |             for (i = 0; i < astNode->childCount; i++) { | ||||||
|  |                 AddChildToNode(parent, MakeIdTree(astNode->children[i], parent)); | ||||||
|  |             } | ||||||
|             return NULL; |             return NULL; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     astNode->idLink = mainNode; | ||||||
|  |     return mainNode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void PrintIdNode(IdNode *node) { | void PrintIdNode(IdNode *node) { | ||||||
|  | @ -131,6 +164,9 @@ void PrintIdNode(IdNode *node) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch(node->type) { |     switch(node->type) { | ||||||
|  |         case Placeholder: | ||||||
|  |             printf("Placeholder (%s)\n", node->name); | ||||||
|  |             break; | ||||||
|         case OrderedScope:  |         case OrderedScope:  | ||||||
|             printf("OrderedScope (%s)\n", node->name);  |             printf("OrderedScope (%s)\n", node->name);  | ||||||
|             break; |             break; | ||||||
|  | @ -234,7 +270,7 @@ IdNode* LookupId(IdNode *node, IdNode *prev, char *target) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (strcmp(node->name, target) == 0) { |     if (strcmp(node->name, target) == 0 && node->type != Placeholder) { | ||||||
|         return node; |         return node; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -266,8 +302,8 @@ IdNode* LookupId(IdNode *node, IdNode *prev, char *target) { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|     for (i = 0; i < idxLimit; i++) { |     for (i = 0; i < idxLimit; i++) { | ||||||
|         IdNode *child = node->children[i]; |         IdNode *child = node->children[i]; | ||||||
|         if (child == prev) { |         if (child == prev || child->type == Placeholder) { | ||||||
|             // Do not inspect the node we just came from.
 |             // Do not inspect the node we just came from or placeholders.
 | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -287,4 +323,4 @@ IdNode* LookupId(IdNode *node, IdNode *prev, char *target) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return LookupId(node->parent, node, target); |     return LookupId(node->parent, node, target); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,7 +6,11 @@ | ||||||
| 
 | 
 | ||||||
| #include "ast.h" | #include "ast.h" | ||||||
| 
 | 
 | ||||||
|  | struct TypeTag; | ||||||
|  | struct Node; | ||||||
|  | 
 | ||||||
| typedef enum NodeType { | typedef enum NodeType { | ||||||
|  |     Placeholder, | ||||||
|     UnorderedScope, |     UnorderedScope, | ||||||
|     OrderedScope, |     OrderedScope, | ||||||
|     Struct, |     Struct, | ||||||
|  | @ -17,7 +21,7 @@ typedef enum NodeType { | ||||||
| typedef struct IdNode { | typedef struct IdNode { | ||||||
|     NodeType type; |     NodeType type; | ||||||
|     char *name; |     char *name; | ||||||
|     TypeTag *typeTag; |     struct TypeTag *typeTag; | ||||||
|     struct IdNode *parent; |     struct IdNode *parent; | ||||||
|     struct IdNode **children; |     struct IdNode **children; | ||||||
|     uint32_t childCount; |     uint32_t childCount; | ||||||
|  | @ -31,7 +35,7 @@ typedef struct IdStatus { | ||||||
| } IdStatus; | } IdStatus; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| IdNode* MakeIdTree(Node *astNode, IdNode *parent); | IdNode* MakeIdTree(struct Node *astNode, IdNode *parent); | ||||||
| void PrintIdNode(IdNode *node); | void PrintIdNode(IdNode *node); | ||||||
| void PrintIdTree(IdNode *tree, uint32_t tabCount); | void PrintIdTree(IdNode *tree, uint32_t tabCount); | ||||||
| int PrintAncestors(IdNode *node); | int PrintAncestors(IdNode *node); | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										44
									
								
								src/main.c
								
								
								
								
							|  | @ -65,49 +65,11 @@ int main(int argc, char *argv[]) | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     { // This shit only works if you're using iftest.w
 |                     { | ||||||
|                         IdNode *idTree = MakeIdTree(rootNode, NULL); |                         IdNode *idTree = MakeIdTree(rootNode, NULL); | ||||||
|                         PrintIdTree(idTree, /*tabCount=*/0); |                         PrintIdTree(idTree, /*tabCount=*/0); | ||||||
| 
 |                         printf("\n"); | ||||||
|                         printf("\nSeeking to struct 'Program'\n"); |                         PrintTree(rootNode, /*tabCount=*/0); | ||||||
|                         IdNode *node = LookdownId(idTree, Struct, "Program"); |  | ||||||
|                         if (node == NULL) printf("Failed.\n"); |  | ||||||
| 
 |  | ||||||
|                         printf("\n[attempting to look up MyStruct]: \n"); |  | ||||||
|                         PrintIdNode(LookupId(node, /*prev=*/NULL, "MyStruct")); |  | ||||||
| 
 |  | ||||||
|                             printf("\n[attempting to look up MyFunc]: \n"); |  | ||||||
|                             PrintIdNode(LookupId(node, /*prev=*/NULL, "MyFunc")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up myStructInt]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "myStructInt")); |  | ||||||
| 
 |  | ||||||
|                         printf("\n[attempting to look up Program]: \n"); |  | ||||||
|                         PrintIdNode(LookupId(node, /*prev=*/NULL, "Program")); |  | ||||||
| 
 |  | ||||||
|                             printf("\n[attempting to look up Foo]: \n"); |  | ||||||
|                             PrintIdNode(LookupId(node, /*prev=*/NULL, "Foo")); |  | ||||||
| 
 |  | ||||||
|                             printf("\n[attempting to look up Main]: \n"); |  | ||||||
|                             PrintIdNode(LookupId(node, /*prev=*/NULL, "Main")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up myInt]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "myInt")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up signTag]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "signTag")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up myBool]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "myBool")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up lol]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "lol")); |  | ||||||
| 
 |  | ||||||
|                                 printf("\n[attempting to look up someInt]: \n"); |  | ||||||
|                                 PrintIdNode(LookupId(node, /*prev=*/NULL, "someInt")); |  | ||||||
| 
 |  | ||||||
|                             printf("\n[attempting to look up Bar]: \n"); |  | ||||||
|                             PrintIdNode(LookupId(node, /*prev=*/NULL, "Bar")); |  | ||||||
|                     } |                     } | ||||||
|                     exitCode = Codegen(rootNode, optimizationLevel); |                     exitCode = Codegen(rootNode, optimizationLevel); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue