progress on nested generic compile
							parent
							
								
									45004f83e0
								
							
						
					
					
						commit
						ff5011b813
					
				|  | @ -151,6 +151,11 @@ AccessExpression        : Identifier POINT AccessExpression | |||
|                         { | ||||
|                             $$ = $1; | ||||
|                         } | ||||
| 						| BaseType POINT AccessExpression | ||||
| 						{ | ||||
| 							$$ = MakeAccessExpressionNode($1, $3); | ||||
| 						} | ||||
| 						; | ||||
| 
 | ||||
| SystemCallExpression    : AT Identifier | ||||
|                         { | ||||
|  | @ -452,9 +457,9 @@ InterfaceMembers        : InterfaceMember | |||
|                             $$ = AddInterfaceMemberNode($1, $2); | ||||
|                         } | ||||
| 
 | ||||
| InterfaceDeclaration    : INTERFACE Identifier LEFT_BRACE InterfaceMembers RIGHT_BRACE | ||||
| InterfaceDeclaration    : INTERFACE Identifier GenericDeclarationClause LEFT_BRACE InterfaceMembers RIGHT_BRACE | ||||
|                         { | ||||
|                             $$ = MakeInterfaceDeclarationNode($2, $4); | ||||
|                             $$ = MakeInterfaceDeclarationNode($2, $5, $3); | ||||
|                         } | ||||
| 
 | ||||
| TopLevelDeclaration     : StructDeclaration | ||||
|  |  | |||
							
								
								
									
										25
									
								
								generic.w
								
								
								
								
							
							
						
						
									
										25
									
								
								generic.w
								
								
								
								
							|  | @ -35,8 +35,33 @@ struct MemoryBlock<T> | |||
|     } | ||||
| } | ||||
| 
 | ||||
| struct Array<T> | ||||
| { | ||||
|     memoryBlock: MemoryBlock<T>; | ||||
| 
 | ||||
|     static Init(capacity: uint): Array<T> | ||||
|     { | ||||
|         return Array<T> | ||||
|         { | ||||
|             memoryBlock: MemoryBlock<T> { capacity: capacity, start: @malloc(capacity * @sizeof<T>()) } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     Get(index: uint): T | ||||
|     { | ||||
|         return memoryBlock.Get(index); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| interface Iterable<T> | ||||
| { | ||||
|     HasNext(): bool; | ||||
|     Next(): T; | ||||
| } | ||||
| 
 | ||||
| struct Program { | ||||
|     static Main(): int { | ||||
|         array: Array<int> = Array<int>.Init(4); | ||||
|         x: int = 4; | ||||
|         y: int = Foo.Func(x); | ||||
|         block: MemoryBlock<int> = MemoryBlock<int> | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										15
									
								
								src/ast.c
								
								
								
								
							|  | @ -614,12 +614,14 @@ Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode) | |||
| 
 | ||||
| Node *MakeInterfaceDeclarationNode( | ||||
|     Node *identifierNode, | ||||
|     Node *interfaceMembersNode) | ||||
|     Node *interfaceMembersNode, | ||||
|     Node *genericDeclarationsNode) | ||||
| { | ||||
|     Node *node = (Node *)malloc(sizeof(Node)); | ||||
|     node->syntaxKind = Interface; | ||||
|     node->interface.identifier = identifierNode; | ||||
|     node->interface.interfaceMembers = interfaceMembersNode; | ||||
|     node->interface.genericDeclarations = genericDeclarationsNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
|  | @ -1384,6 +1386,10 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|     case Comment: | ||||
|         return; | ||||
| 
 | ||||
| 	case ConcreteGenericTypeNode: | ||||
| 		LinkParentPointers(node->concreteGenericType.genericArguments, node); | ||||
| 		return; | ||||
| 
 | ||||
|     case CustomTypeNode: | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1423,6 +1429,7 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|     case FunctionCallExpression: | ||||
|         LinkParentPointers(node->functionCallExpression.identifier, node); | ||||
|         LinkParentPointers(node->functionCallExpression.argumentSequence, node); | ||||
| 		LinkParentPointers(node->functionCallExpression.genericArguments, node); | ||||
|         return; | ||||
| 
 | ||||
|     case FunctionDeclaration: | ||||
|  | @ -1493,6 +1500,11 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|         LinkParentPointers(node->ifElseStatement.elseStatement, node); | ||||
|         return; | ||||
| 
 | ||||
| 	case Interface: | ||||
| 		LinkParentPointers(node->interface.genericDeclarations, node); | ||||
| 		LinkParentPointers(node->interface.interfaceMembers, node); | ||||
| 		return; | ||||
| 
 | ||||
|     case Number: | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1547,6 +1559,7 @@ void LinkParentPointers(Node *node, Node *prev) | |||
|         return; | ||||
| 
 | ||||
|     case Type: | ||||
| 		LinkParentPointers(node->type.typeNode, node); | ||||
|         return; | ||||
| 
 | ||||
|     case UnaryExpression: | ||||
|  |  | |||
|  | @ -290,6 +290,7 @@ struct Node | |||
|         { | ||||
|             Node *identifier; | ||||
|             Node *interfaceMembers; | ||||
|             Node *genericDeclarations; | ||||
|         } interface; | ||||
| 
 | ||||
|         struct | ||||
|  | @ -461,7 +462,8 @@ Node *MakeEmptyFieldInitNode(); | |||
| Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); | ||||
| Node *MakeInterfaceDeclarationNode( | ||||
|     Node *identifierNode, | ||||
|     Node *interfaceMembersNode); | ||||
|     Node *interfaceMembersNode, | ||||
|     Node *genericDeclarationsNode); | ||||
| Node *StartInterfaceMembersNode(Node *interfaceMemberNode); | ||||
| Node *AddInterfaceMemberNode( | ||||
|     Node *interfaceMembersNode, | ||||
|  |  | |||
|  | @ -1370,36 +1370,62 @@ static LLVMValueRef CompileFunctionCallExpression( | |||
|     if (functionCallExpression->functionCallExpression.identifier->syntaxKind == | ||||
|         AccessExpression) | ||||
|     { | ||||
|         LLVMTypeRef typeReference = LookupStructTypeByName( | ||||
|             functionCallExpression->functionCallExpression.identifier | ||||
|                 ->accessExpression.accessee->identifier.name); | ||||
| 		if (functionCallExpression->functionCallExpression.identifier->accessExpression.accessee->syntaxKind == | ||||
| 			ConcreteGenericTypeNode) | ||||
| 		{ | ||||
| 			TypeTag *typeTag = | ||||
| 				MakeTypeTag( | ||||
| 					functionCallExpression->functionCallExpression.identifier->accessExpression.accessee | ||||
| 				); | ||||
| 			LLVMTypeRef typeReference = ResolveType(typeTag); | ||||
| 
 | ||||
|         char *functionName = | ||||
|             functionCallExpression->functionCallExpression.identifier | ||||
|                 ->accessExpression.accessor->identifier.name; | ||||
| 			char *functionName = | ||||
| 				functionCallExpression->functionCallExpression.identifier | ||||
| 					->accessExpression.accessor->identifier.name; | ||||
| 
 | ||||
|         if (typeReference != NULL) | ||||
|         { | ||||
|             function = LookupFunctionByType( | ||||
|                 typeReference, | ||||
|                 functionName, | ||||
|                 functionCallExpression, | ||||
|                 &functionReturnType, | ||||
|                 &isStatic); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             structInstance = FindVariablePointer( | ||||
|                 functionCallExpression->functionCallExpression.identifier | ||||
|                     ->accessExpression.accessee->identifier.name); | ||||
| 			function = LookupFunctionByType( | ||||
| 				typeReference, | ||||
| 				functionName, | ||||
| 				functionCallExpression, | ||||
| 				&functionReturnType, | ||||
| 				&isStatic | ||||
| 			); | ||||
| 
 | ||||
|             function = LookupFunctionByInstance( | ||||
|                 structInstance, | ||||
|                 functionName, | ||||
|                 functionCallExpression, | ||||
|                 &functionReturnType, | ||||
|                 &isStatic); | ||||
|         } | ||||
| 			free(typeTag); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			LLVMTypeRef typeReference = LookupStructTypeByName( | ||||
| 				functionCallExpression->functionCallExpression.identifier | ||||
| 					->accessExpression.accessee->identifier.name); | ||||
| 
 | ||||
| 			char *functionName = | ||||
| 				functionCallExpression->functionCallExpression.identifier | ||||
| 					->accessExpression.accessor->identifier.name; | ||||
| 
 | ||||
| 			if (typeReference != NULL) | ||||
| 			{ | ||||
| 				function = LookupFunctionByType( | ||||
| 					typeReference, | ||||
| 					functionName, | ||||
| 					functionCallExpression, | ||||
| 					&functionReturnType, | ||||
| 					&isStatic); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				structInstance = FindVariablePointer( | ||||
| 					functionCallExpression->functionCallExpression.identifier | ||||
| 						->accessExpression.accessee->identifier.name); | ||||
| 
 | ||||
| 				function = LookupFunctionByInstance( | ||||
| 					structInstance, | ||||
| 					functionName, | ||||
| 					functionCallExpression, | ||||
| 					&functionReturnType, | ||||
| 					&isStatic); | ||||
| 			} | ||||
| 		} | ||||
|     } | ||||
|     else if ( | ||||
|         functionCallExpression->functionCallExpression.identifier->syntaxKind == | ||||
|  |  | |||
|  | @ -449,6 +449,22 @@ void ConvertCustomsToGenerics(Node *node) | |||
|                     MakeGenericTypeNode(id->typeTag->value.genericType); | ||||
|             } | ||||
|         } | ||||
| 		else if (type->syntaxKind == ConcreteGenericTypeNode) | ||||
| 		{ | ||||
| 			for (int32_t i = 0; i < id->typeTag->value.concreteGenericType.genericArgumentCount; i += 1) | ||||
| 			{ | ||||
| 				if (id->typeTag->value.concreteGenericType.genericArguments[i]->type == Custom) | ||||
| 				{ | ||||
| 					char *target = id->typeTag->value.concreteGenericType.genericArguments[i]->value.customType; | ||||
| 					Node *typeLookup = LookupType(node, target); | ||||
| 					if (typeLookup != NULL && | ||||
| 						typeLookup->syntaxKind == GenericDeclaration) | ||||
| 					{ | ||||
| 						id->typeTag->value.concreteGenericType.genericArguments[i]->type = Generic; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -469,6 +485,22 @@ void ConvertCustomsToGenerics(Node *node) | |||
|                     MakeGenericTypeNode(id->typeTag->value.genericType); | ||||
|             } | ||||
|         } | ||||
| 		else if (type->syntaxKind == ConcreteGenericTypeNode) | ||||
| 		{ | ||||
| 			for (int32_t i = 0; i < id->typeTag->value.concreteGenericType.genericArgumentCount; i += 1) | ||||
| 			{ | ||||
| 				if (id->typeTag->value.concreteGenericType.genericArguments[i]->type == Custom) | ||||
| 				{ | ||||
| 					char *target = id->typeTag->value.concreteGenericType.genericArguments[i]->value.customType; | ||||
| 					Node *typeLookup = LookupType(node, target); | ||||
| 					if (typeLookup != NULL && | ||||
| 						typeLookup->syntaxKind == GenericDeclaration) | ||||
| 					{ | ||||
| 						id->typeTag->value.concreteGenericType.genericArguments[i]->type = Generic; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue