generic function lookup

pull/4/head
cosmonaut 2021-05-20 13:18:57 -07:00
parent 0d94e89045
commit 8a3920918c
4 changed files with 103 additions and 14 deletions

View File

@ -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}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 */