diff --git a/compiler.c b/compiler.c index b15ceae..8738413 100644 --- a/compiler.c +++ b/compiler.c @@ -19,7 +19,9 @@ typedef struct StructFieldMapValue char *name; LLVMValueRef value; LLVMValueRef valuePointer; + uint32_t index; uint8_t needsWrite; + uint8_t needsRead; } StructFieldMapValue; typedef struct StructFieldMap @@ -41,7 +43,7 @@ static void AddStruct(LLVMValueRef wStructPointer) structFieldMapCount += 1; } -static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index) +static void AddStructFieldName(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index) { uint32_t i, fieldCount; @@ -51,18 +53,13 @@ static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, { fieldCount = structFieldMaps[i].fieldCount; - LLVMValueRef elementPointer = LLVMBuildStructGEP( - builder, - wStructPointer, - fieldCount, - "ptr" - ); - structFieldMaps[i].fields = realloc(structFieldMaps[i].fields, sizeof(StructFieldMapValue) * (fieldCount + 1)); structFieldMaps[i].fields[fieldCount].name = strdup(name); - structFieldMaps[i].fields[fieldCount].value = LLVMBuildLoad(builder, elementPointer, name); - structFieldMaps[i].fields[fieldCount].valuePointer = elementPointer; + structFieldMaps[i].fields[fieldCount].value = NULL; + structFieldMaps[i].fields[fieldCount].valuePointer = NULL; + structFieldMaps[i].fields[fieldCount].index = index; structFieldMaps[i].fields[fieldCount].needsWrite = 0; + structFieldMaps[i].fields[fieldCount].needsRead = 1; structFieldMaps[i].fieldCount += 1; break; @@ -70,6 +67,44 @@ static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, } } +static LLVMValueRef CheckStructFieldAndLoad(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name) +{ + uint32_t i, j; + + for (i = 0; i < structFieldMapCount; i += 1) + { + if (structFieldMaps[i].structPointer == wStructPointer) + { + for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) + { + if (strcmp(structFieldMaps[i].fields[j].name, name) == 0) + { + if (structFieldMaps[i].fields[j].needsRead) + { + char *ptrName = strdup(name); + strcat(ptrName, "_ptr"); + LLVMValueRef elementPointer = LLVMBuildStructGEP( + builder, + wStructPointer, + structFieldMaps[i].fields[j].index, + ptrName + ); + free(ptrName); + + structFieldMaps[i].fields[j].value = LLVMBuildLoad(builder, elementPointer, name); + structFieldMaps[i].fields[j].valuePointer = elementPointer; + structFieldMaps[i].fields[j].needsRead = 0; + } + + return structFieldMaps[i].fields[j].value; + } + } + } + } + + return NULL; +} + static void MarkStructFieldForWrite(LLVMValueRef wStructPointer, LLVMValueRef value) { uint32_t i, j; @@ -168,9 +203,10 @@ static void AddNamedVariable(char *name, LLVMValueRef variable) namedVariableCount += 1; } -static LLVMValueRef FindVariableByName(LLVMValueRef wStructValue, LLVMBuilderRef builder, char *name) +static LLVMValueRef FindVariableByName(LLVMBuilderRef builder, LLVMValueRef wStructValue, char *name) { uint32_t i, j; + LLVMValueRef searchResult; /* first, search scoped vars */ for (i = 0; i < namedVariableCount; i += 1) @@ -182,22 +218,14 @@ static LLVMValueRef FindVariableByName(LLVMValueRef wStructValue, LLVMBuilderRef } /* if none exist, search struct vars */ - for (i = 0; i < structFieldMapCount; i += 1) + searchResult = CheckStructFieldAndLoad(builder, wStructValue, name); + + if (searchResult == NULL) { - if (structFieldMaps[i].structPointer == wStructValue) - { - for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) - { - if (strcmp(structFieldMaps[i].fields[j].name, name) == 0) - { - return structFieldMaps[i].fields[j].value; - } - } - } + fprintf(stderr, "Identifier not found!"); } - fprintf(stderr, "Identifier not found!"); - return NULL; + return searchResult; } static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) @@ -267,7 +295,7 @@ static LLVMValueRef CompileFunctionCallExpression( args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]); } - return LLVMBuildCall(builder, FindVariableByName(wStructValue, builder, expression->children[0]->value.string), args, argumentCount, "tmp"); + return LLVMBuildCall(builder, FindVariableByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp"); } static LLVMValueRef CompileExpression( @@ -287,7 +315,7 @@ static LLVMValueRef CompileExpression( return CompileFunctionCallExpression(wStructValue, builder, function, expression); case Identifier: - return FindVariableByName(wStructValue, builder, expression->value.string); + return FindVariableByName(builder, wStructValue, expression->value.string); case Number: return CompileNumber(expression); @@ -380,7 +408,7 @@ static void CompileFunction( for (i = 0; i < fieldDeclarationCount; i += 1) { - AddStructField(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i); + AddStructFieldName(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i); } for (i = 0; i < functionBody->childCount; i += 1)