generic function lookup
							parent
							
								
									0d94e89045
								
							
						
					
					
						commit
						8a3920918c
					
				|  | @ -43,10 +43,12 @@ add_executable( | |||
| 	src/codegen.h | ||||
| 	src/identcheck.h | ||||
| 	src/parser.h | ||||
| 	src/util.h | ||||
|     src/ast.c | ||||
| 	src/codegen.c | ||||
| 	src/identcheck.c | ||||
| 	src/parser.c | ||||
| 	src/util.c | ||||
| 	src/main.c | ||||
| 	# Generated code | ||||
|     ${BISON_Parser_OUTPUTS} | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ | |||
| #include <llvm-c/Transforms/Utils.h> | ||||
| 
 | ||||
| #include "ast.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| typedef struct LocalVariable | ||||
| { | ||||
|  | @ -56,15 +57,11 @@ typedef struct StructTypeFunction | |||
|     uint8_t isStatic; | ||||
| } StructTypeFunction; | ||||
| 
 | ||||
| typedef struct StructTypeGenericFunction | ||||
| { | ||||
|     char *name; | ||||
|     Node *functionDeclarationNode; | ||||
| } StructTypeGenericFunction; | ||||
| 
 | ||||
| typedef struct MonomorphizedGenericFunctionHashEntry | ||||
| { | ||||
|     uint64_t key; | ||||
|     TypeTag **types; | ||||
|     uint32_t typeCount; | ||||
|     StructTypeFunction function; | ||||
| } MonomorphizedGenericFunctionHashEntry; | ||||
| 
 | ||||
|  | @ -74,6 +71,17 @@ typedef struct MonomorphizedGenericFunctionHashArray | |||
|     uint32_t count; | ||||
| } MonomorphizedGenericFunctionHashArray; | ||||
| 
 | ||||
| #define NUM_MONOMORPHIZED_HASH_BUCKETS 1031 | ||||
| 
 | ||||
| typedef struct StructTypeGenericFunction | ||||
| { | ||||
|     char *name; | ||||
|     Node *functionDeclarationNode; | ||||
|     uint8_t isStatic; | ||||
|     MonomorphizedGenericFunctionHashArray | ||||
|         monomorphizedFunctions[NUM_MONOMORPHIZED_HASH_BUCKETS]; | ||||
| } StructTypeGenericFunction; | ||||
| 
 | ||||
| typedef struct StructTypeDeclaration | ||||
| { | ||||
|     char *name; | ||||
|  | @ -87,8 +95,6 @@ typedef struct StructTypeDeclaration | |||
| 
 | ||||
|     StructTypeGenericFunction *genericFunctions; | ||||
|     uint32_t genericFunctionCount; | ||||
| 
 | ||||
|     MonomorphizedGenericFunctionHashArray monomorphizedGenericFunctions; | ||||
| } StructTypeDeclaration; | ||||
| 
 | ||||
| StructTypeDeclaration *structTypeDeclarations; | ||||
|  | @ -296,8 +302,6 @@ static void AddStructDeclaration( | |||
|     structTypeDeclarations[index].functionCount = 0; | ||||
|     structTypeDeclarations[index].genericFunctions = NULL; | ||||
|     structTypeDeclarations[index].genericFunctionCount = 0; | ||||
|     structTypeDeclarations[index].monomorphizedGenericFunctions.elements = NULL; | ||||
|     structTypeDeclarations[index].monomorphizedGenericFunctions.count = 0; | ||||
| 
 | ||||
|     for (i = 0; i < fieldDeclarationCount; i += 1) | ||||
|     { | ||||
|  | @ -350,9 +354,10 @@ static void DeclareStructFunction( | |||
| static void DeclareGenericStructFunction( | ||||
|     LLVMTypeRef wStructPointerType, | ||||
|     Node *functionDeclarationNode, | ||||
|     uint8_t isStatic, | ||||
|     char *name) | ||||
| { | ||||
|     uint32_t i, index; | ||||
|     uint32_t i, j, index; | ||||
| 
 | ||||
|     for (i = 0; i < structTypeDeclarationCount; i += 1) | ||||
|     { | ||||
|  | @ -364,6 +369,21 @@ static void DeclareGenericStructFunction( | |||
|             structTypeDeclarations[i] | ||||
|                 .genericFunctions[index] | ||||
|                 .functionDeclarationNode = functionDeclarationNode; | ||||
|             structTypeDeclarations[i].genericFunctions[index].isStatic = | ||||
|                 isStatic; | ||||
| 
 | ||||
|             for (j = 0; j < NUM_MONOMORPHIZED_HASH_BUCKETS; j += 1) | ||||
|             { | ||||
|                 structTypeDeclarations[i] | ||||
|                     .genericFunctions[index] | ||||
|                     .monomorphizedFunctions[j] | ||||
|                     .elements = NULL; | ||||
|                 structTypeDeclarations[i] | ||||
|                     .genericFunctions[index] | ||||
|                     .monomorphizedFunctions[j] | ||||
|                     .count = 0; | ||||
|             } | ||||
| 
 | ||||
|             structTypeDeclarations[i].genericFunctionCount += 1; | ||||
| 
 | ||||
|             return; | ||||
|  | @ -411,6 +431,20 @@ static LLVMTypeRef ResolveType(Node *typeNode) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static inline uint64_t HashTypeTags(TypeTag **tags, uint32_t count) | ||||
| { | ||||
|     const uint64_t HASH_FACTOR = 97; | ||||
|     uint64_t result = 1; | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     for (i = 0; i < count; i += 1) | ||||
|     { | ||||
|         result *= HASH_FACTOR + str_hash(TypeTagToString(tags[i])); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef LookupGenericFunction( | ||||
|     StructTypeGenericFunction *genericFunction, | ||||
|     TypeTag **genericArgumentTypes, | ||||
|  | @ -418,8 +452,46 @@ static LLVMValueRef LookupGenericFunction( | |||
|     LLVMTypeRef *pReturnType, | ||||
|     uint8_t *pStatic) | ||||
| { | ||||
|     /* TODO: hash the argument types */ | ||||
|     /* TODO: compile the monomorphism if doesnt exist */ | ||||
|     uint32_t i, j; | ||||
|     uint64_t typeHash = | ||||
|         HashTypeTags(genericArgumentTypes, genericArgumentTypeCount); | ||||
|     uint8_t match = 0; | ||||
| 
 | ||||
|     MonomorphizedGenericFunctionHashArray *hashArray = | ||||
|         &genericFunction->monomorphizedFunctions | ||||
|              [typeHash % NUM_MONOMORPHIZED_HASH_BUCKETS]; | ||||
| 
 | ||||
|     MonomorphizedGenericFunctionHashEntry *hashEntry = NULL; | ||||
|     for (i = 0; i < hashArray->count; i += 1) | ||||
|     { | ||||
|         match = 1; | ||||
| 
 | ||||
|         for (j = 0; j < hashArray->elements[i].typeCount; j += 1) | ||||
|         { | ||||
|             if (hashArray->elements[i].types[j] != genericArgumentTypes[j]) | ||||
|             { | ||||
|                 match = 0; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (match) | ||||
|         { | ||||
|             hashEntry = &hashArray->elements[i]; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (hashEntry == NULL) | ||||
|     { | ||||
| 
 | ||||
|         /* TODO: compile */ | ||||
|     } | ||||
| 
 | ||||
|     *pReturnType = hashEntry->function.returnType; | ||||
|     *pStatic = hashEntry->function.isStatic; | ||||
| 
 | ||||
|     return hashEntry->function.function; | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef LookupFunctionByType( | ||||
|  | @ -1257,6 +1329,7 @@ static void CompileFunction( | |||
|         DeclareGenericStructFunction( | ||||
|             wStructPointerType, | ||||
|             functionDeclaration, | ||||
|             isStatic, | ||||
|             functionName); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										14
									
								
								src/util.c
								
								
								
								
							|  | @ -1,7 +1,6 @@ | |||
| #include "util.h" | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| char *strdup(const char *s) | ||||
| { | ||||
|  | @ -15,3 +14,16 @@ char *strdup(const char *s) | |||
|     memcpy(result, s, slen + 1); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| uint64_t str_hash(char *str) | ||||
| { | ||||
|     uint64_t hash = 5381; | ||||
|     size_t c; | ||||
| 
 | ||||
|     while (c = *str++) | ||||
|     { | ||||
|         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ | ||||
|     } | ||||
| 
 | ||||
|     return hash; | ||||
| } | ||||
|  |  | |||
|  | @ -1,8 +1,10 @@ | |||
| #ifndef WRAITH_UTIL_H | ||||
| #define WRAITH_UTIL_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| char *strdup(const char *s); | ||||
| uint64_t str_hash(char *str); | ||||
| 
 | ||||
| #endif /* WRAITH_UTIL_H */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue