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