groundwork for struct generics
							parent
							
								
									a571edcf6d
								
							
						
					
					
						commit
						f3435f8659
					
				|  | @ -113,9 +113,13 @@ BaseType                : VOID | |||
|                         { | ||||
|                             $$ = MakePrimitiveTypeNode(MemoryAddress); | ||||
|                         } | ||||
|                         | Identifier GenericArgumentClauseNonEmpty | ||||
|                         { | ||||
|                             $$ = MakeConcreteGenericTypeNode($1, $2); | ||||
|                         } | ||||
|                         | Identifier | ||||
|                         { | ||||
|                             $$ = MakeCustomTypeNode(yytext); | ||||
|                             $$ = MakeCustomTypeNode($1); | ||||
|                         } | ||||
|                         | REFERENCE LESS_THAN Type GREATER_THAN | ||||
|                         { | ||||
|  | @ -359,11 +363,13 @@ GenericArguments        : GenericArgument | |||
|                             $$ = AddGenericArgument($1, $3); | ||||
|                         } | ||||
| 
 | ||||
| GenericArgumentClauseNonEmpty   : LESS_THAN GenericArguments GREATER_THAN | ||||
|                                 { | ||||
|                                     $$ = $2; | ||||
|                                 } | ||||
|                                 ; | ||||
| 
 | ||||
| GenericArgumentClause   : LESS_THAN GenericArguments GREATER_THAN | ||||
|                         { | ||||
|                             $$ = $2; | ||||
|                         } | ||||
| GenericArgumentClause   : GenericArgumentClauseNonEmpty | ||||
|                         | | ||||
|                         { | ||||
|                             $$ = MakeEmptyGenericArgumentsNode(); | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ struct Program { | |||
|     static Main(): int { | ||||
|         x: int = 4; | ||||
|         y: int = Foo.Func(x); | ||||
|         block: MemoryBlock<int>; | ||||
|         addr: MemoryAddress = @malloc(y); | ||||
|         @free(addr); | ||||
|         return x; | ||||
|  |  | |||
							
								
								
									
										79
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										79
									
								
								src/ast.c
								
								
								
								
							|  | @ -19,6 +19,8 @@ const char *SyntaxKindString(SyntaxKind syntaxKind) | |||
|         return "BinaryExpression"; | ||||
|     case Comment: | ||||
|         return "Comment"; | ||||
|     case ConcreteGenericTypeNode: | ||||
|         return "ConcreteGenericTypeNode"; | ||||
|     case CustomTypeNode: | ||||
|         return "CustomTypeNode"; | ||||
|     case Declaration: | ||||
|  | @ -95,11 +97,12 @@ Node *MakePrimitiveTypeNode(PrimitiveType type) | |||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *MakeCustomTypeNode(char *name) | ||||
| Node *MakeCustomTypeNode(Node *identifierNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = CustomTypeNode; | ||||
|     node->customType.name = strdup(name); | ||||
|     node->customType.name = strdup(identifierNode->identifier.name); | ||||
|     free(identifierNode); | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
|  | @ -111,6 +114,18 @@ Node *MakeReferenceTypeNode(Node *typeNode) | |||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *MakeConcreteGenericTypeNode( | ||||
|     Node *identifierNode, | ||||
|     Node *genericArgumentsNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = ConcreteGenericTypeNode; | ||||
|     node->concreteGenericType.name = strdup(identifierNode->identifier.name); | ||||
|     node->concreteGenericType.genericArguments = genericArgumentsNode; | ||||
|     free(identifierNode); | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *MakeTypeNode(Node *typeNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|  | @ -624,6 +639,11 @@ void PrintNode(Node *node, uint32_t tabCount) | |||
|         PrintNode(node->binaryExpression.right, tabCount + 1); | ||||
|         return; | ||||
| 
 | ||||
|     case ConcreteGenericTypeNode: | ||||
|         printf("%s\n", node->concreteGenericType.name); | ||||
|         PrintNode(node->concreteGenericType.genericArguments, tabCount + 1); | ||||
|         return; | ||||
| 
 | ||||
|     case CustomTypeNode: | ||||
|         printf("%s\n", node->customType.name); | ||||
|         return; | ||||
|  | @ -843,6 +863,10 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
|     case Comment: | ||||
|         return; | ||||
| 
 | ||||
|     case ConcreteGenericTypeNode: | ||||
|         func(node->concreteGenericType.genericArguments); | ||||
|         return; | ||||
| 
 | ||||
|     case CustomTypeNode: | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1004,6 +1028,8 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
| 
 | ||||
| TypeTag *MakeTypeTag(Node *node) | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     if (node == NULL) | ||||
|     { | ||||
|         fprintf( | ||||
|  | @ -1034,6 +1060,28 @@ TypeTag *MakeTypeTag(Node *node) | |||
|         tag->value.customType = strdup(node->customType.name); | ||||
|         break; | ||||
| 
 | ||||
|     case ConcreteGenericTypeNode: | ||||
|         tag->type = ConcreteGeneric; | ||||
|         tag->value.concreteGenericType.name = | ||||
|             strdup(node->concreteGenericType.name); | ||||
|         tag->value.concreteGenericType.genericArgumentCount = | ||||
|             node->concreteGenericType.genericArguments->genericArguments.count; | ||||
|         tag->value.concreteGenericType.genericArguments = malloc( | ||||
|             sizeof(TypeTag *) * | ||||
|             tag->value.concreteGenericType.genericArgumentCount); | ||||
| 
 | ||||
|         for (i = 0; | ||||
|              i < | ||||
|              node->concreteGenericType.genericArguments->genericArguments.count; | ||||
|              i += 1) | ||||
|         { | ||||
|             tag->value.concreteGenericType.genericArguments[i] = MakeTypeTag( | ||||
|                 node->concreteGenericType.genericArguments->genericArguments | ||||
|                     .arguments[i] | ||||
|                     ->genericArgument.type); | ||||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case Declaration: | ||||
|         tag = MakeTypeTag(node->declaration.type); | ||||
|         break; | ||||
|  | @ -1078,6 +1126,8 @@ TypeTag *MakeTypeTag(Node *node) | |||
| 
 | ||||
| char *TypeTagToString(TypeTag *tag) | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     if (tag == NULL) | ||||
|     { | ||||
|         fprintf( | ||||
|  | @ -1114,6 +1164,31 @@ char *TypeTagToString(TypeTag *tag) | |||
|         sprintf(result, "Generic<%s>", tag->value.genericType); | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     case ConcreteGeneric: | ||||
|     { | ||||
|         char *result = strdup(tag->value.concreteGenericType.name); | ||||
|         uint32_t len = strlen(result); | ||||
|         result = realloc(result, len + 2); | ||||
|         strcat(result, "<"); | ||||
| 
 | ||||
|         for (i = 0; i < tag->value.concreteGenericType.genericArgumentCount; | ||||
|              i += 1) | ||||
|         { | ||||
|             char *inner = TypeTagToString( | ||||
|                 tag->value.concreteGenericType.genericArguments[i]); | ||||
|             len += strlen(inner); | ||||
|             result = realloc(result, sizeof(char) * (len + 3)); | ||||
|             if (i != tag->value.concreteGenericType.genericArgumentCount - 1) | ||||
|             { | ||||
|                 strcat(result, ", "); | ||||
|             } | ||||
|             strcat(result, inner); | ||||
|         } | ||||
|         result = realloc(result, sizeof(char) * (len + 2)); | ||||
|         strcat(result, ">"); | ||||
|         return result; | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										30
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										30
									
								
								src/ast.h
								
								
								
								
							|  | @ -19,6 +19,7 @@ typedef enum | |||
|     Assignment, | ||||
|     BinaryExpression, | ||||
|     Comment, | ||||
|     ConcreteGenericTypeNode, | ||||
|     CustomTypeNode, | ||||
|     Declaration, | ||||
|     DeclarationSequence, | ||||
|  | @ -86,7 +87,16 @@ typedef union | |||
|     BinaryOperator binaryOperator; | ||||
| } Operator; | ||||
| 
 | ||||
| typedef struct TypeTag | ||||
| typedef struct TypeTag TypeTag; | ||||
| 
 | ||||
| typedef struct ConcreteGenericTypeTag | ||||
| { | ||||
|     char *name; | ||||
|     TypeTag **genericArguments; | ||||
|     uint32_t genericArgumentCount; | ||||
| } ConcreteGenericTypeTag; | ||||
| 
 | ||||
| struct TypeTag | ||||
| { | ||||
|     enum Type | ||||
|     { | ||||
|  | @ -94,7 +104,8 @@ typedef struct TypeTag | |||
|         Primitive, | ||||
|         Reference, | ||||
|         Custom, | ||||
|         Generic | ||||
|         Generic, | ||||
|         ConcreteGeneric | ||||
|     } type; | ||||
|     union | ||||
|     { | ||||
|  | @ -106,8 +117,10 @@ typedef struct TypeTag | |||
|         char *customType; | ||||
|         /* Valid when type = Generic. */ | ||||
|         char *genericType; | ||||
|         /* Valid when type = ConcreteGeneric */ | ||||
|         ConcreteGenericTypeTag concreteGenericType; | ||||
|     } value; | ||||
| } TypeTag; | ||||
| }; | ||||
| 
 | ||||
| typedef struct Node Node; | ||||
| 
 | ||||
|  | @ -146,6 +159,12 @@ struct Node | |||
| 
 | ||||
|         } comment; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             char *name; | ||||
|             Node *genericArguments; | ||||
|         } concreteGenericType; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             char *name; | ||||
|  | @ -329,8 +348,11 @@ const char *SyntaxKindString(SyntaxKind syntaxKind); | |||
| 
 | ||||
| uint8_t IsPrimitiveType(Node *typeNode); | ||||
| Node *MakePrimitiveTypeNode(PrimitiveType type); | ||||
| Node *MakeCustomTypeNode(char *string); | ||||
| Node *MakeCustomTypeNode(Node *identifierNode); | ||||
| Node *MakeReferenceTypeNode(Node *typeNode); | ||||
| Node *MakeConcreteGenericTypeNode( | ||||
|     Node *identifierNode, | ||||
|     Node *genericArgumentsNode); | ||||
| Node *MakeTypeNode(Node *typeNode); | ||||
| Node *MakeIdentifierNode(const char *id); | ||||
| Node *MakeNumberNode(const char *numberString); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue