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