forked from cosmonaut/wraith-lang
				
			Generic Structs (#11)
Reviewed-on: cosmonaut/wraith-lang#11 Co-authored-by: cosmonaut <evan@moonside.games> Co-committed-by: cosmonaut <evan@moonside.games>main
							parent
							
								
									a571edcf6d
								
							
						
					
					
						commit
						9adfaed54c
					
				|  | @ -113,9 +113,13 @@ BaseType                : VOID | |||
|                         { | ||||
|                             $$ = MakePrimitiveTypeNode(MemoryAddress); | ||||
|                         } | ||||
|                         | Identifier GenericArgumentClauseNonEmpty | ||||
|                         { | ||||
|                             $$ = MakeConcreteGenericTypeNode($1, $2); | ||||
|                         } | ||||
|                         | Identifier | ||||
|                         { | ||||
|                             $$ = MakeCustomTypeNode(yytext); | ||||
|                             $$ = MakeCustomTypeNode($1); | ||||
|                         } | ||||
|                         | REFERENCE LESS_THAN Type GREATER_THAN | ||||
|                         { | ||||
|  | @ -157,6 +161,30 @@ Number                  : NUMBER | |||
|                             $$ = MakeNumberNode(yytext); | ||||
|                         } | ||||
| 
 | ||||
| FieldInit               : Identifier COLON Expression | ||||
|                         { | ||||
|                             $$ = MakeFieldInitNode($1, $3); | ||||
|                         } | ||||
| 
 | ||||
| StructInitFields        : FieldInit | ||||
|                         { | ||||
|                             $$ = StartStructInitFieldsNode($1); | ||||
|                         } | ||||
|                         | StructInitFields COMMA FieldInit | ||||
|                         { | ||||
|                             $$ = AddFieldInitNode($1, $3); | ||||
|                         } | ||||
|                         | | ||||
|                         { | ||||
|                             $$ = MakeEmptyFieldInitNode(); | ||||
|                         } | ||||
|                         ; | ||||
| 
 | ||||
| StructInitExpression    : Type LEFT_BRACE StructInitFields RIGHT_BRACE | ||||
|                         { | ||||
|                             $$ = MakeStructInitExpressionNode($1, $3); | ||||
|                         } | ||||
| 
 | ||||
| PrimaryExpression       : Number | ||||
|                         | STRING_LITERAL | ||||
|                         { | ||||
|  | @ -168,6 +196,7 @@ PrimaryExpression       : Number | |||
|                         } | ||||
|                         | FunctionCallExpression | ||||
|                         | AccessExpression | ||||
|                         | StructInitExpression | ||||
|                         ; | ||||
| 
 | ||||
| UnaryExpression         : BANG Expression | ||||
|  | @ -290,11 +319,11 @@ Statements              : Statement | |||
|                             $$ = AddStatement($1, $2); | ||||
|                         } | ||||
| 
 | ||||
| Arguments               : PrimaryExpression | ||||
| Arguments               : Expression | ||||
|                         { | ||||
|                             $$ = StartFunctionArgumentSequenceNode($1); | ||||
|                         } | ||||
|                         | Arguments COMMA PrimaryExpression | ||||
|                         | Arguments COMMA Expression | ||||
|                         { | ||||
|                             $$ = AddFunctionArgumentNode($1, $3); | ||||
|                         } | ||||
|  | @ -359,11 +388,13 @@ GenericArguments        : GenericArgument | |||
|                             $$ = AddGenericArgument($1, $3); | ||||
|                         } | ||||
| 
 | ||||
| GenericArgumentClauseNonEmpty   : LESS_THAN GenericArguments GREATER_THAN | ||||
|                                 { | ||||
|                                     $$ = $2; | ||||
|                                 } | ||||
|                                 ; | ||||
| 
 | ||||
| GenericArgumentClause   : LESS_THAN GenericArguments GREATER_THAN | ||||
|                         { | ||||
|                             $$ = $2; | ||||
|                         } | ||||
| GenericArgumentClause   : GenericArgumentClauseNonEmpty | ||||
|                         | | ||||
|                         { | ||||
|                             $$ = MakeEmptyGenericArgumentsNode(); | ||||
|  |  | |||
							
								
								
									
										38
									
								
								generic.w
								
								
								
								
							
							
						
						
									
										38
									
								
								generic.w
								
								
								
								
							|  | @ -14,9 +14,24 @@ struct MemoryBlock<T> | |||
| 	start: MemoryAddress; | ||||
| 	capacity: uint; | ||||
| 
 | ||||
| 	AddressOf(count: uint): MemoryAddress | ||||
| 	AddressOf(index: uint): MemoryAddress | ||||
|     { | ||||
|         return start + (count * @sizeof<T>()); | ||||
|         return start + (index * @sizeof<T>()); | ||||
|     } | ||||
| 
 | ||||
|     Get(index: uint): T | ||||
|     { | ||||
|         return @dereference<T>(AddressOf(index)); | ||||
|     } | ||||
| 
 | ||||
|     Set(index: uint, value: T): void | ||||
|     { | ||||
|         @memcpy(AddressOf(index), @addr(value), @sizeof<T>()); | ||||
|     } | ||||
| 
 | ||||
|     Free(): void | ||||
|     { | ||||
|         @free(start); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -24,8 +39,21 @@ struct Program { | |||
|     static Main(): int { | ||||
|         x: int = 4; | ||||
|         y: int = Foo.Func(x); | ||||
|         addr: MemoryAddress = @malloc(y); | ||||
|         @free(addr); | ||||
|         return x; | ||||
|         block: MemoryBlock<int> = MemoryBlock<int> | ||||
|         { | ||||
|             capacity: y, | ||||
|             start: @malloc(y * @sizeof<int>()) | ||||
|         }; | ||||
|         block.Set(0, 5); | ||||
|         block.Set(1, 3); | ||||
|         block.Set(2, 9); | ||||
|         block.Set(3, 100); | ||||
|         Console.PrintLine("%p", block.start); | ||||
|         Console.PrintLine("%i", block.Get(0)); | ||||
|         Console.PrintLine("%i", block.Get(1)); | ||||
|         Console.PrintLine("%i", block.Get(2)); | ||||
|         Console.PrintLine("%i", block.Get(3)); | ||||
|         block.Free(); | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										221
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										221
									
								
								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: | ||||
|  | @ -27,6 +29,8 @@ const char *SyntaxKindString(SyntaxKind syntaxKind) | |||
|         return "ForLoop"; | ||||
|     case DeclarationSequence: | ||||
|         return "DeclarationSequence"; | ||||
|     case FieldInit: | ||||
|         return "FieldInit"; | ||||
|     case FunctionArgumentSequence: | ||||
|         return "FunctionArgumentSequence"; | ||||
|     case FunctionCallExpression: | ||||
|  | @ -71,6 +75,10 @@ const char *SyntaxKindString(SyntaxKind syntaxKind) | |||
|         return "StringLiteral"; | ||||
|     case StructDeclaration: | ||||
|         return "StructDeclaration"; | ||||
|     case StructInit: | ||||
|         return "StructInit"; | ||||
|     case StructInitFields: | ||||
|         return "StructInitFields"; | ||||
|     case SystemCall: | ||||
|         return "SystemCall"; | ||||
|     case Type: | ||||
|  | @ -95,11 +103,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 +120,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)); | ||||
|  | @ -542,6 +563,55 @@ Node *MakeForLoopNode( | |||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *MakeFieldInitNode(Node *identifierNode, Node *expressionNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = FieldInit; | ||||
|     node->fieldInit.identifier = identifierNode; | ||||
|     node->fieldInit.expression = expressionNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *StartStructInitFieldsNode(Node *fieldInitNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = StructInitFields; | ||||
|     node->structInitFields.fieldInits = (Node **)malloc(sizeof(Node *)); | ||||
|     node->structInitFields.fieldInits[0] = fieldInitNode; | ||||
|     node->structInitFields.count = 1; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode) | ||||
| { | ||||
|     structInitFieldsNode->structInitFields.fieldInits = realloc( | ||||
|         structInitFieldsNode->structInitFields.fieldInits, | ||||
|         sizeof(Node *) * (structInitFieldsNode->structInitFields.count + 1)); | ||||
|     structInitFieldsNode->structInitFields | ||||
|         .fieldInits[structInitFieldsNode->structInitFields.count] = | ||||
|         fieldInitNode; | ||||
|     structInitFieldsNode->structInitFields.count += 1; | ||||
|     return structInitFieldsNode; | ||||
| } | ||||
| 
 | ||||
| Node *MakeEmptyFieldInitNode() | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = StructInitFields; | ||||
|     node->structInitFields.fieldInits = NULL; | ||||
|     node->structInitFields.count = 0; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = StructInit; | ||||
|     node->structInit.type = typeNode; | ||||
|     node->structInit.initFields = structInitFieldsNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| static const char *PrimitiveTypeToString(PrimitiveType type) | ||||
| { | ||||
|     switch (type) | ||||
|  | @ -624,6 +694,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; | ||||
|  | @ -642,6 +717,12 @@ void PrintNode(Node *node, uint32_t tabCount) | |||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case FieldInit: | ||||
|         printf("\n"); | ||||
|         PrintNode(node->fieldInit.identifier, tabCount + 1); | ||||
|         PrintNode(node->fieldInit.expression, tabCount + 1); | ||||
|         return; | ||||
| 
 | ||||
|     case ForLoop: | ||||
|         printf("\n"); | ||||
|         PrintNode(node->forLoop.declaration, tabCount + 1); | ||||
|  | @ -797,6 +878,20 @@ void PrintNode(Node *node, uint32_t tabCount) | |||
|         PrintNode(node->structDeclaration.declarationSequence, tabCount + 1); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInit: | ||||
|         printf("\n"); | ||||
|         PrintNode(node->structInit.type, tabCount + 1); | ||||
|         PrintNode(node->structInit.initFields, tabCount + 1); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInitFields: | ||||
|         printf("\n"); | ||||
|         for (i = 0; i < node->structInitFields.count; i += 1) | ||||
|         { | ||||
|             PrintNode(node->structInitFields.fieldInits[i], tabCount + 1); | ||||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case SystemCall: | ||||
|         printf("\n"); | ||||
|         PrintNode(node->systemCall.identifier, tabCount + 1); | ||||
|  | @ -843,6 +938,10 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
|     case Comment: | ||||
|         return; | ||||
| 
 | ||||
|     case ConcreteGenericTypeNode: | ||||
|         func(node->concreteGenericType.genericArguments); | ||||
|         return; | ||||
| 
 | ||||
|     case CustomTypeNode: | ||||
|         return; | ||||
| 
 | ||||
|  | @ -858,6 +957,11 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case FieldInit: | ||||
|         func(node->fieldInit.identifier); | ||||
|         func(node->fieldInit.expression); | ||||
|         return; | ||||
| 
 | ||||
|     case ForLoop: | ||||
|         func(node->forLoop.declaration); | ||||
|         func(node->forLoop.startNumber); | ||||
|  | @ -979,6 +1083,18 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
|         func(node->structDeclaration.declarationSequence); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInit: | ||||
|         func(node->structInit.type); | ||||
|         func(node->structInit.initFields); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInitFields: | ||||
|         for (i = 0; i < node->structInitFields.count; i += 1) | ||||
|         { | ||||
|             func(node->structInitFields.fieldInits[i]); | ||||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case SystemCall: | ||||
|         func(node->systemCall.identifier); | ||||
|         func(node->systemCall.argumentSequence); | ||||
|  | @ -1004,6 +1120,8 @@ void Recurse(Node *node, void (*func)(Node *)) | |||
| 
 | ||||
| TypeTag *MakeTypeTag(Node *node) | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     if (node == NULL) | ||||
|     { | ||||
|         fprintf( | ||||
|  | @ -1034,6 +1152,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 +1218,8 @@ TypeTag *MakeTypeTag(Node *node) | |||
| 
 | ||||
| char *TypeTagToString(TypeTag *tag) | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     if (tag == NULL) | ||||
|     { | ||||
|         fprintf( | ||||
|  | @ -1114,6 +1256,64 @@ 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); | ||||
|         len += 2; | ||||
|         result = realloc(result, sizeof(char) * len); | ||||
|         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 + 1)); | ||||
|         strcat(result, ">"); | ||||
|         return result; | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint8_t TypeTagEqual(TypeTag *typeTagA, TypeTag *typeTagB) | ||||
| { | ||||
|     if (typeTagA->type != typeTagB->type) | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     switch (typeTagA->type) | ||||
|     { | ||||
|     case Primitive: | ||||
|         return typeTagA->value.primitiveType == typeTagB->value.primitiveType; | ||||
| 
 | ||||
|     case Reference: | ||||
|         return TypeTagEqual( | ||||
|             typeTagA->value.referenceType, | ||||
|             typeTagB->value.referenceType); | ||||
| 
 | ||||
|     case Custom: | ||||
|         return strcmp(typeTagA->value.customType, typeTagB->value.customType) == | ||||
|                0; | ||||
| 
 | ||||
|     case Generic: | ||||
|         return strcmp( | ||||
|                    typeTagA->value.genericType, | ||||
|                    typeTagB->value.genericType) == 0; | ||||
| 
 | ||||
|     default: | ||||
|         fprintf(stderr, "Invalid type comparison!"); | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -1164,6 +1364,11 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case FieldInit: | ||||
|         LinkParentPointers(node->fieldInit.identifier, node); | ||||
|         LinkParentPointers(node->fieldInit.expression, node); | ||||
|         return; | ||||
| 
 | ||||
|     case ForLoop: | ||||
|         LinkParentPointers(node->forLoop.declaration, node); | ||||
|         LinkParentPointers(node->forLoop.startNumber, node); | ||||
|  | @ -1288,6 +1493,18 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|         LinkParentPointers(node->structDeclaration.declarationSequence, node); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInit: | ||||
|         LinkParentPointers(node->structInit.type, node); | ||||
|         LinkParentPointers(node->structInit.initFields, node); | ||||
|         return; | ||||
| 
 | ||||
|     case StructInitFields: | ||||
|         for (i = 0; i < node->structInitFields.count; i += 1) | ||||
|         { | ||||
|             LinkParentPointers(node->structInitFields.fieldInits[i], node); | ||||
|         } | ||||
|         return; | ||||
| 
 | ||||
|     case SystemCall: | ||||
|         LinkParentPointers(node->systemCall.identifier, node); | ||||
|         LinkParentPointers(node->systemCall.argumentSequence, node); | ||||
|  |  | |||
							
								
								
									
										57
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										57
									
								
								src/ast.h
								
								
								
								
							|  | @ -19,9 +19,11 @@ typedef enum | |||
|     Assignment, | ||||
|     BinaryExpression, | ||||
|     Comment, | ||||
|     ConcreteGenericTypeNode, | ||||
|     CustomTypeNode, | ||||
|     Declaration, | ||||
|     DeclarationSequence, | ||||
|     FieldInit, | ||||
|     ForLoop, | ||||
|     FunctionArgumentSequence, | ||||
|     FunctionCallExpression, | ||||
|  | @ -46,6 +48,8 @@ typedef enum | |||
|     StaticModifier, | ||||
|     StringLiteral, | ||||
|     StructDeclaration, | ||||
|     StructInit, | ||||
|     StructInitFields, | ||||
|     SystemCall, | ||||
|     Type, | ||||
|     UnaryExpression | ||||
|  | @ -86,7 +90,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 +107,8 @@ typedef struct TypeTag | |||
|         Primitive, | ||||
|         Reference, | ||||
|         Custom, | ||||
|         Generic | ||||
|         Generic, | ||||
|         ConcreteGeneric | ||||
|     } type; | ||||
|     union | ||||
|     { | ||||
|  | @ -106,8 +120,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 +162,12 @@ struct Node | |||
| 
 | ||||
|         } comment; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             char *name; | ||||
|             Node *genericArguments; | ||||
|         } concreteGenericType; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             char *name; | ||||
|  | @ -163,6 +185,12 @@ struct Node | |||
|             uint32_t count; | ||||
|         } declarationSequence; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             Node *identifier; | ||||
|             Node *expression; | ||||
|         } fieldInit; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             Node *declaration; | ||||
|  | @ -304,6 +332,18 @@ struct Node | |||
|             Node *genericDeclarations; | ||||
|         } structDeclaration; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             Node *type; | ||||
|             Node *initFields; | ||||
|         } structInit; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             Node **fieldInits; | ||||
|             uint32_t count; | ||||
|         } structInitFields; | ||||
| 
 | ||||
|         struct | ||||
|         { | ||||
|             Node *identifier; | ||||
|  | @ -329,8 +369,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); | ||||
|  | @ -397,6 +440,11 @@ Node *MakeForLoopNode( | |||
|     Node *startNumberNode, | ||||
|     Node *endNumberNode, | ||||
|     Node *statementSequenceNode); | ||||
| Node *MakeFieldInitNode(Node *identifierNode, Node *expressionNode); | ||||
| Node *StartStructInitFieldsNode(Node *fieldInitNode); | ||||
| Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode); | ||||
| Node *MakeEmptyFieldInitNode(); | ||||
| Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); | ||||
| 
 | ||||
| void PrintNode(Node *node, uint32_t tabCount); | ||||
| const char *SyntaxKindString(SyntaxKind syntaxKind); | ||||
|  | @ -412,6 +460,7 @@ void LinkParentPointers(Node *node, Node *prev); | |||
| 
 | ||||
| TypeTag *MakeTypeTag(Node *node); | ||||
| char *TypeTagToString(TypeTag *tag); | ||||
| uint8_t TypeTagEqual(TypeTag *typeTagA, TypeTag *typeTagB); | ||||
| 
 | ||||
| Node *LookupIdNode(Node *current, Node *prev, char *target); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										1069
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										1069
									
								
								src/codegen.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										11
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										11
									
								
								src/util.c
								
								
								
								
							|  | @ -5,7 +5,7 @@ | |||
| char *strdup(const char *s) | ||||
| { | ||||
|     size_t slen = strlen(s); | ||||
|     char *result = (char *)malloc(slen + 1); | ||||
|     char *result = (char *)malloc(sizeof(char) * (slen + 1)); | ||||
|     if (result == NULL) | ||||
|     { | ||||
|         return NULL; | ||||
|  | @ -15,6 +15,15 @@ char *strdup(const char *s) | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| char *w_strcat(char *s, char *s2) | ||||
| { | ||||
|     size_t slen = strlen(s); | ||||
|     size_t slen2 = strlen(s2); | ||||
|     s = realloc(s, sizeof(char) * (slen + slen2 + 1)); | ||||
|     strcat(s, s2); | ||||
|     return s; | ||||
| } | ||||
| 
 | ||||
| uint64_t str_hash(char *str) | ||||
| { | ||||
|     uint64_t hash = 5381; | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <string.h> | ||||
| 
 | ||||
| char *strdup(const char *s); | ||||
| char *w_strcat(char *s, char *s2); | ||||
| uint64_t str_hash(char *str); | ||||
| 
 | ||||
| #endif /* WRAITH_UTIL_H */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue