forked from cosmonaut/wraith-lang
static function lookup
parent
b344635c8d
commit
c4c916a2de
242
compiler.c
242
compiler.c
|
@ -61,18 +61,20 @@ typedef struct StructTypeFunction
|
|||
uint8_t isStatic;
|
||||
} StructTypeFunction;
|
||||
|
||||
typedef struct StructTypeFieldDeclaration
|
||||
typedef struct StructTypeDeclaration
|
||||
{
|
||||
char *name;
|
||||
LLVMTypeRef structType;
|
||||
LLVMTypeRef structPointerType;
|
||||
StructTypeField *fields;
|
||||
uint32_t fieldCount;
|
||||
|
||||
StructTypeFunction *functions;
|
||||
uint32_t functionCount;
|
||||
} StructTypeFieldDeclaration;
|
||||
} StructTypeDeclaration;
|
||||
|
||||
StructTypeFieldDeclaration *structTypeFieldDeclarations;
|
||||
uint32_t structTypeFieldDeclarationCount;
|
||||
StructTypeDeclaration *structTypeDeclarations;
|
||||
uint32_t structTypeDeclarationCount;
|
||||
|
||||
static Scope* CreateScope()
|
||||
{
|
||||
|
@ -127,26 +129,41 @@ static void AddLocalVariable(Scope *scope, LLVMValueRef pointer, char *name)
|
|||
scopeFrame->localVariableCount += 1;
|
||||
}
|
||||
|
||||
static LLVMTypeRef FindStructType(char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (strcmp(structTypeDeclarations[i].name, name) == 0)
|
||||
{
|
||||
return structTypeDeclarations[i].structType;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMValueRef FindStructFieldPointer(LLVMBuilderRef builder, LLVMValueRef structPointer, char *name)
|
||||
{
|
||||
int32_t i, j;
|
||||
|
||||
LLVMTypeRef structType = LLVMTypeOf(structPointer);
|
||||
LLVMTypeRef structPointerType = LLVMTypeOf(structPointer);
|
||||
|
||||
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (structTypeFieldDeclarations[i].structType == structType)
|
||||
if (structTypeDeclarations[i].structPointerType == structPointerType)
|
||||
{
|
||||
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
|
||||
for (j = 0; j < structTypeDeclarations[i].fieldCount; j += 1)
|
||||
{
|
||||
if (strcmp(structTypeFieldDeclarations[i].fields[j].name, name) == 0)
|
||||
if (strcmp(structTypeDeclarations[i].fields[j].name, name) == 0)
|
||||
{
|
||||
char *ptrName = strdup(name);
|
||||
strcat(ptrName, "_ptr");
|
||||
return LLVMBuildStructGEP(
|
||||
builder,
|
||||
structPointer,
|
||||
structTypeFieldDeclarations[i].fields[j].index,
|
||||
structTypeDeclarations[i].fields[j].index,
|
||||
ptrName
|
||||
);
|
||||
free(ptrName);
|
||||
|
@ -199,31 +216,35 @@ static LLVMValueRef FindVariableValue(LLVMBuilderRef builder, char *name)
|
|||
|
||||
static void AddStructDeclaration(
|
||||
LLVMTypeRef wStructType,
|
||||
LLVMTypeRef wStructPointerType,
|
||||
char *name,
|
||||
Node **fieldDeclarations,
|
||||
uint32_t fieldDeclarationCount
|
||||
) {
|
||||
uint32_t i;
|
||||
uint32_t index = structTypeFieldDeclarationCount;
|
||||
structTypeFieldDeclarations = realloc(structTypeFieldDeclarations, sizeof(StructTypeFieldDeclaration) * (structTypeFieldDeclarationCount + 1));
|
||||
structTypeFieldDeclarations[index].structType = wStructType;
|
||||
structTypeFieldDeclarations[index].fields = NULL;
|
||||
structTypeFieldDeclarations[index].fieldCount = 0;
|
||||
structTypeFieldDeclarations[index].functions = NULL;
|
||||
structTypeFieldDeclarations[index].functionCount = 0;
|
||||
uint32_t index = structTypeDeclarationCount;
|
||||
structTypeDeclarations = realloc(structTypeDeclarations, sizeof(StructTypeDeclaration) * (structTypeDeclarationCount + 1));
|
||||
structTypeDeclarations[index].structType = wStructType;
|
||||
structTypeDeclarations[index].structPointerType = wStructPointerType;
|
||||
structTypeDeclarations[index].name = strdup(name);
|
||||
structTypeDeclarations[index].fields = NULL;
|
||||
structTypeDeclarations[index].fieldCount = 0;
|
||||
structTypeDeclarations[index].functions = NULL;
|
||||
structTypeDeclarations[index].functionCount = 0;
|
||||
|
||||
for (i = 0; i < fieldDeclarationCount; i += 1)
|
||||
{
|
||||
structTypeFieldDeclarations[index].fields = realloc(structTypeFieldDeclarations[index].fields, sizeof(StructTypeField) * (structTypeFieldDeclarations[index].fieldCount + 1));
|
||||
structTypeFieldDeclarations[index].fields[i].name = strdup(fieldDeclarations[i]->children[1]->value.string);
|
||||
structTypeFieldDeclarations[index].fields[i].index = i;
|
||||
structTypeFieldDeclarations[index].fieldCount += 1;
|
||||
structTypeDeclarations[index].fields = realloc(structTypeDeclarations[index].fields, sizeof(StructTypeField) * (structTypeDeclarations[index].fieldCount + 1));
|
||||
structTypeDeclarations[index].fields[i].name = strdup(fieldDeclarations[i]->children[1]->value.string);
|
||||
structTypeDeclarations[index].fields[i].index = i;
|
||||
structTypeDeclarations[index].fieldCount += 1;
|
||||
}
|
||||
|
||||
structTypeFieldDeclarationCount += 1;
|
||||
structTypeDeclarationCount += 1;
|
||||
}
|
||||
|
||||
static void DeclareStructFunction(
|
||||
LLVMTypeRef wStructType,
|
||||
LLVMTypeRef wStructPointerType,
|
||||
LLVMValueRef function,
|
||||
LLVMTypeRef returnType,
|
||||
uint8_t isStatic,
|
||||
|
@ -231,71 +252,124 @@ static void DeclareStructFunction(
|
|||
) {
|
||||
uint32_t i, index;
|
||||
|
||||
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (structTypeFieldDeclarations[i].structType == wStructType)
|
||||
if (structTypeDeclarations[i].structPointerType == wStructPointerType)
|
||||
{
|
||||
index = structTypeFieldDeclarations[i].functionCount;
|
||||
structTypeFieldDeclarations[i].functions = realloc(structTypeFieldDeclarations[i].functions, sizeof(StructTypeFunction) * (structTypeFieldDeclarations[i].functionCount + 1));
|
||||
structTypeFieldDeclarations[i].functions[index].name = strdup(name);
|
||||
structTypeFieldDeclarations[i].functions[index].function = function;
|
||||
structTypeFieldDeclarations[i].functions[index].returnType = returnType;
|
||||
structTypeFieldDeclarations[i].functions[index].isStatic = isStatic;
|
||||
structTypeFieldDeclarations[i].functionCount += 1;
|
||||
index = structTypeDeclarations[i].functionCount;
|
||||
structTypeDeclarations[i].functions = realloc(structTypeDeclarations[i].functions, sizeof(StructTypeFunction) * (structTypeDeclarations[i].functionCount + 1));
|
||||
structTypeDeclarations[i].functions[index].name = strdup(name);
|
||||
structTypeDeclarations[i].functions[index].function = function;
|
||||
structTypeDeclarations[i].functions[index].returnType = returnType;
|
||||
structTypeDeclarations[i].functions[index].isStatic = isStatic;
|
||||
structTypeDeclarations[i].functionCount += 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Could not find struct type for function!");
|
||||
fprintf(stderr, "Could not find struct type for function!\n");
|
||||
}
|
||||
|
||||
static LLVMValueRef LookupFunction(
|
||||
LLVMValueRef structPointer,
|
||||
static LLVMTypeRef LookupCustomType(char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (strcmp(structTypeDeclarations[i].name, name) == 0)
|
||||
{
|
||||
return structTypeDeclarations[i].structType;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Could not find struct type!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMValueRef LookupFunctionByType(
|
||||
LLVMTypeRef structType,
|
||||
char *name,
|
||||
LLVMTypeRef *pReturnType,
|
||||
uint8_t *pStatic
|
||||
) {
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
|
||||
if (structTypeDeclarations[i].structType == structType)
|
||||
{
|
||||
for (j = 0; j < structTypeFieldDeclarations[i].functionCount; j += 1)
|
||||
for (j = 0; j < structTypeDeclarations[i].functionCount; j += 1)
|
||||
{
|
||||
if (strcmp(structTypeFieldDeclarations[i].functions[j].name, name) == 0)
|
||||
if (strcmp(structTypeDeclarations[i].functions[j].name, name) == 0)
|
||||
{
|
||||
*pReturnType = structTypeFieldDeclarations[i].functions[j].returnType;
|
||||
*pStatic = structTypeFieldDeclarations[i].functions[j].isStatic;
|
||||
return structTypeFieldDeclarations[i].functions[j].function;
|
||||
*pReturnType = structTypeDeclarations[i].functions[j].returnType;
|
||||
*pStatic = structTypeDeclarations[i].functions[j].isStatic;
|
||||
return structTypeDeclarations[i].functions[j].function;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Could not find struct function!");
|
||||
fprintf(stderr, "Could not find struct function!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMValueRef LookupFunctionByPointerType(
|
||||
LLVMTypeRef structPointerType,
|
||||
char *name,
|
||||
LLVMTypeRef *pReturnType,
|
||||
uint8_t *pStatic
|
||||
) {
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (structTypeDeclarations[i].structPointerType == structPointerType)
|
||||
{
|
||||
for (j = 0; j < structTypeDeclarations[i].functionCount; j += 1)
|
||||
{
|
||||
if (strcmp(structTypeDeclarations[i].functions[j].name, name) == 0)
|
||||
{
|
||||
*pReturnType = structTypeDeclarations[i].functions[j].returnType;
|
||||
*pStatic = structTypeDeclarations[i].functions[j].isStatic;
|
||||
return structTypeDeclarations[i].functions[j].function;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Could not find struct function!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMValueRef LookupFunctionByInstance(
|
||||
LLVMValueRef structPointer,
|
||||
char *name,
|
||||
LLVMTypeRef *pReturnType,
|
||||
uint8_t *pStatic
|
||||
) {
|
||||
return LookupFunctionByPointerType(LLVMTypeOf(structPointer), name, pReturnType, pStatic);
|
||||
}
|
||||
|
||||
static void AddStructVariablesToScope(
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef structPointer
|
||||
) {
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||
for (i = 0; i < structTypeDeclarationCount; i += 1)
|
||||
{
|
||||
if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
|
||||
if (structTypeDeclarations[i].structPointerType == LLVMTypeOf(structPointer))
|
||||
{
|
||||
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
|
||||
for (j = 0; j < structTypeDeclarations[i].fieldCount; j += 1)
|
||||
{
|
||||
char *ptrName = strdup(structTypeFieldDeclarations[i].fields[j].name);
|
||||
char *ptrName = strdup(structTypeDeclarations[i].fields[j].name);
|
||||
strcat(ptrName, "_ptr");
|
||||
LLVMValueRef elementPointer = LLVMBuildStructGEP(
|
||||
builder,
|
||||
structPointer,
|
||||
structTypeFieldDeclarations[i].fields[j].index,
|
||||
structTypeDeclarations[i].fields[j].index,
|
||||
ptrName
|
||||
);
|
||||
free(ptrName);
|
||||
|
@ -303,7 +377,7 @@ static void AddStructVariablesToScope(
|
|||
AddLocalVariable(
|
||||
scope,
|
||||
elementPointer,
|
||||
structTypeFieldDeclarations[i].fields[j].name
|
||||
structTypeDeclarations[i].fields[j].name
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -315,38 +389,6 @@ static LLVMValueRef CompileExpression(
|
|||
Node *binaryExpression
|
||||
);
|
||||
|
||||
typedef struct CustomTypeMap
|
||||
{
|
||||
LLVMTypeRef type;
|
||||
char *name;
|
||||
} CustomTypeMap;
|
||||
|
||||
CustomTypeMap *customTypes;
|
||||
uint32_t customTypeCount;
|
||||
|
||||
static void RegisterCustomType(LLVMTypeRef type, char *name)
|
||||
{
|
||||
customTypes = realloc(customTypes, sizeof(CustomType) * (customTypeCount + 1));
|
||||
customTypes[customTypeCount].type = type;
|
||||
customTypes[customTypeCount].name = strdup(name);
|
||||
customTypeCount += 1;
|
||||
}
|
||||
|
||||
static LLVMTypeRef LookupCustomType(char *name)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < customTypeCount; i += 1)
|
||||
{
|
||||
if (strcmp(customTypes[i].name, name) == 0)
|
||||
{
|
||||
return customTypes[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -404,7 +446,7 @@ static LLVMValueRef CompileFunctionCallExpression(
|
|||
) {
|
||||
uint32_t i;
|
||||
uint32_t argumentCount = 0;
|
||||
LLVMValueRef args[argumentCount];
|
||||
LLVMValueRef args[expression->children[1]->childCount + 1];
|
||||
LLVMValueRef function;
|
||||
uint8_t isStatic;
|
||||
LLVMValueRef structInstance;
|
||||
|
@ -413,9 +455,25 @@ static LLVMValueRef CompileFunctionCallExpression(
|
|||
|
||||
/* FIXME: this needs to be recursive on access chains */
|
||||
if (expression->children[0]->syntaxKind == AccessExpression)
|
||||
{
|
||||
LLVMTypeRef typeReference = FindStructType(
|
||||
expression->children[0]->children[0]->value.string
|
||||
);
|
||||
|
||||
if (typeReference != NULL)
|
||||
{
|
||||
function = LookupFunctionByType(
|
||||
typeReference,
|
||||
expression->children[0]->children[1]->value.string,
|
||||
&functionReturnType,
|
||||
&isStatic
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
structInstance = FindVariablePointer(expression->children[0]->children[0]->value.string);
|
||||
function = LookupFunction(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic);
|
||||
function = LookupFunctionByInstance(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -641,7 +699,7 @@ static void CompileFunction(
|
|||
{
|
||||
char *ptrName = strdup(functionSignature->children[2]->children[i]->children[1]->value.string);
|
||||
strcat(ptrName, "_ptr");
|
||||
LLVMValueRef argument = LLVMGetParam(function, i + 1);
|
||||
LLVMValueRef argument = LLVMGetParam(function, i + !isStatic);
|
||||
LLVMValueRef argumentCopy = LLVMBuildAlloca(builder, LLVMTypeOf(argument), ptrName);
|
||||
LLVMBuildStore(builder, argument, argumentCopy);
|
||||
free(ptrName);
|
||||
|
@ -680,8 +738,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
|||
|
||||
PushScopeFrame(scope);
|
||||
|
||||
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, structName);
|
||||
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
|
||||
LLVMTypeRef wStructType = LLVMStructCreateNamed(context, structName);
|
||||
LLVMTypeRef wStructPointerType = LLVMPointerType(wStructType, 0); /* FIXME: is this address space correct? */
|
||||
|
||||
/* first, build the structure definition */
|
||||
for (i = 0; i < declarationCount; i += 1)
|
||||
|
@ -698,9 +756,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
|||
}
|
||||
}
|
||||
|
||||
LLVMStructSetBody(wStruct, types, fieldCount, packed);
|
||||
AddStructDeclaration(wStructPointerType, fieldDeclarations, fieldCount);
|
||||
RegisterCustomType(wStruct, node->children[0]->value.string);
|
||||
LLVMStructSetBody(wStructType, types, fieldCount, packed);
|
||||
AddStructDeclaration(wStructType, wStructPointerType, node->children[0]->value.string, fieldDeclarations, fieldCount);
|
||||
|
||||
/* now we can wire up the functions */
|
||||
for (i = 0; i < declarationCount; i += 1)
|
||||
|
@ -748,11 +805,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
scope = CreateScope();
|
||||
|
||||
structTypeFieldDeclarations = NULL;
|
||||
structTypeFieldDeclarationCount = 0;
|
||||
|
||||
customTypes = NULL;
|
||||
customTypeCount = 0;
|
||||
structTypeDeclarations = NULL;
|
||||
structTypeDeclarationCount = 0;
|
||||
|
||||
stack = CreateStack();
|
||||
|
||||
|
|
Loading…
Reference in New Issue