forked from cosmonaut/wraith-lang
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