scope refactor
parent
e3fd821d8f
commit
c6507fdcb7
14
ast.c
14
ast.c
|
@ -21,6 +21,7 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
|
||||||
{
|
{
|
||||||
switch(syntaxKind)
|
switch(syntaxKind)
|
||||||
{
|
{
|
||||||
|
case AccessExpression: return "AccessExpression";
|
||||||
case Assignment: return "Assignment";
|
case Assignment: return "Assignment";
|
||||||
case BinaryExpression: return "BinaryExpression";
|
case BinaryExpression: return "BinaryExpression";
|
||||||
case Comment: return "Comment";
|
case Comment: return "Comment";
|
||||||
|
@ -292,6 +293,19 @@ Node* MakeFunctionCallExpressionNode(
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node* MakeAccessExpressionNode(
|
||||||
|
Node *accessee,
|
||||||
|
Node *accessor
|
||||||
|
) {
|
||||||
|
Node* node = (Node*) malloc(sizeof(Node));
|
||||||
|
node->syntaxKind = AccessExpression;
|
||||||
|
node->children = (Node**) malloc(sizeof(Node*) * 2);
|
||||||
|
node->childCount = 2;
|
||||||
|
node->children[0] = accessee;
|
||||||
|
node->children[1] = accessor;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* PrimitiveTypeToString(PrimitiveType type)
|
static const char* PrimitiveTypeToString(PrimitiveType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
5
ast.h
5
ast.h
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
AccessExpression,
|
||||||
Assignment,
|
Assignment,
|
||||||
BinaryExpression,
|
BinaryExpression,
|
||||||
Comment,
|
Comment,
|
||||||
|
@ -148,6 +149,10 @@ Node* MakeFunctionCallExpressionNode(
|
||||||
Node *identifierNode,
|
Node *identifierNode,
|
||||||
Node *argumentSequenceNode
|
Node *argumentSequenceNode
|
||||||
);
|
);
|
||||||
|
Node* MakeAccessExpressionNode(
|
||||||
|
Node *accessee,
|
||||||
|
Node *accessor
|
||||||
|
);
|
||||||
|
|
||||||
void PrintTree(Node *node, uint32_t tabCount);
|
void PrintTree(Node *node, uint32_t tabCount);
|
||||||
|
|
||||||
|
|
431
compiler.c
431
compiler.c
|
@ -14,175 +14,259 @@ extern FILE *yyin;
|
||||||
Stack *stack;
|
Stack *stack;
|
||||||
Node *rootNode;
|
Node *rootNode;
|
||||||
|
|
||||||
typedef struct StructFieldMapValue
|
typedef struct LocalVariable
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
LLVMValueRef pointer;
|
||||||
|
} LocalVariable;
|
||||||
|
|
||||||
|
typedef struct FunctionArgument
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
LLVMValueRef value;
|
LLVMValueRef value;
|
||||||
LLVMValueRef valuePointer;
|
} FunctionArgument;
|
||||||
|
|
||||||
|
typedef struct ScopeFrame
|
||||||
|
{
|
||||||
|
LocalVariable *localVariables;
|
||||||
|
uint32_t localVariableCount;
|
||||||
|
|
||||||
|
FunctionArgument *arguments;
|
||||||
|
uint32_t argumentCount;
|
||||||
|
} ScopeFrame;
|
||||||
|
|
||||||
|
typedef struct Scope
|
||||||
|
{
|
||||||
|
ScopeFrame *scopeStack;
|
||||||
|
uint32_t scopeStackCount;
|
||||||
|
} Scope;
|
||||||
|
|
||||||
|
Scope *scope;
|
||||||
|
|
||||||
|
typedef struct StructTypeField
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
uint8_t needsWrite;
|
} StructTypeField;
|
||||||
uint8_t needsRead;
|
|
||||||
} StructFieldMapValue;
|
|
||||||
|
|
||||||
typedef struct StructFieldMap
|
typedef struct StructTypeFieldDeclaration
|
||||||
{
|
{
|
||||||
LLVMValueRef structPointer;
|
LLVMTypeRef structType;
|
||||||
StructFieldMapValue *fields;
|
StructTypeField *fields;
|
||||||
uint32_t fieldCount;
|
uint32_t fieldCount;
|
||||||
} StructFieldMap;
|
|
||||||
|
|
||||||
StructFieldMap *structFieldMaps;
|
} StructTypeFieldDeclaration;
|
||||||
uint32_t structFieldMapCount;
|
|
||||||
|
|
||||||
static void AddStruct(LLVMValueRef wStructPointer)
|
StructTypeFieldDeclaration *structTypeFieldDeclarations;
|
||||||
|
uint32_t structTypeFieldDeclarationCount;
|
||||||
|
|
||||||
|
static Scope* CreateScope()
|
||||||
{
|
{
|
||||||
structFieldMaps = realloc(structFieldMaps, sizeof(StructFieldMap) * (structFieldMapCount + 1));
|
Scope *scope = malloc(sizeof(Scope));
|
||||||
structFieldMaps[structFieldMapCount].structPointer = wStructPointer;
|
|
||||||
structFieldMaps[structFieldMapCount].fields = NULL;
|
scope->scopeStack = malloc(sizeof(ScopeFrame));
|
||||||
structFieldMaps[structFieldMapCount].fieldCount = 0;
|
scope->scopeStack[0].argumentCount = 0;
|
||||||
structFieldMapCount += 1;
|
scope->scopeStack[0].arguments = NULL;
|
||||||
|
scope->scopeStack[0].localVariableCount = 0;
|
||||||
|
scope->scopeStack[0].localVariables = NULL;
|
||||||
|
scope->scopeStackCount = 1;
|
||||||
|
|
||||||
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddStructFieldName(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index)
|
static void PushScopeFrame(Scope *scope)
|
||||||
{
|
{
|
||||||
uint32_t i, fieldCount;
|
uint32_t index = scope->scopeStackCount;
|
||||||
|
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * (scope->scopeStackCount + 1));
|
||||||
|
scope->scopeStack[index].argumentCount = 0;
|
||||||
|
scope->scopeStack[index].arguments = NULL;
|
||||||
|
scope->scopeStack[index].localVariableCount = 0;
|
||||||
|
scope->scopeStack[index].localVariables = NULL;
|
||||||
|
|
||||||
for (i = 0; i < structFieldMapCount; i += 1)
|
scope->scopeStackCount += 1;
|
||||||
{
|
|
||||||
if (structFieldMaps[i].structPointer == wStructPointer)
|
|
||||||
{
|
|
||||||
fieldCount = structFieldMaps[i].fieldCount;
|
|
||||||
|
|
||||||
structFieldMaps[i].fields = realloc(structFieldMaps[i].fields, sizeof(StructFieldMapValue) * (fieldCount + 1));
|
|
||||||
structFieldMaps[i].fields[fieldCount].name = strdup(name);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef CheckStructFieldAndLoad(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name)
|
static void PopScopeFrame(Scope *scope)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i;
|
||||||
|
uint32_t index = scope->scopeStackCount - 1;
|
||||||
|
|
||||||
for (i = 0; i < structFieldMapCount; i += 1)
|
if (scope->scopeStack[index].arguments != NULL)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].structPointer == wStructPointer)
|
for (i = 0; i < scope->scopeStack[index].argumentCount; i += 1)
|
||||||
{
|
{
|
||||||
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1)
|
free(scope->scopeStack[index].arguments[i].name);
|
||||||
|
}
|
||||||
|
free(scope->scopeStack[index].arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope->scopeStack[index].localVariables != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp(structFieldMaps[i].fields[j].name, name) == 0)
|
for (i = 0; i < scope->scopeStack[index].localVariableCount; i += 1)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].fields[j].needsRead)
|
free(scope->scopeStack[index].localVariables[i].name);
|
||||||
|
}
|
||||||
|
free(scope->scopeStack[index].localVariables);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope->scopeStackCount -= 1;
|
||||||
|
|
||||||
|
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * scope->scopeStackCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddLocalVariable(Scope *scope, LLVMValueRef pointer, char *name)
|
||||||
|
{
|
||||||
|
ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1];
|
||||||
|
uint32_t index = scopeFrame->localVariableCount;
|
||||||
|
|
||||||
|
scopeFrame->localVariables = realloc(scopeFrame->localVariables, sizeof(LocalVariable) * (scopeFrame->localVariableCount + 1));
|
||||||
|
scopeFrame->localVariables[index].name = strdup(name);
|
||||||
|
scopeFrame->localVariables[index].pointer = pointer;
|
||||||
|
|
||||||
|
scopeFrame->localVariableCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddFunctionArgument(Scope *scope, LLVMValueRef value, char *name)
|
||||||
|
{
|
||||||
|
ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1];
|
||||||
|
uint32_t index = scopeFrame->argumentCount;
|
||||||
|
|
||||||
|
scopeFrame->arguments = realloc(scopeFrame->arguments, sizeof(FunctionArgument) * (scopeFrame->argumentCount + 1));
|
||||||
|
scopeFrame->arguments[index].name = strdup(name);
|
||||||
|
scopeFrame->arguments[index].value = value;
|
||||||
|
|
||||||
|
scopeFrame->argumentCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef FindStructFieldPointer(LLVMBuilderRef builder, LLVMValueRef structPointer, char *name)
|
||||||
|
{
|
||||||
|
int32_t i, j;
|
||||||
|
|
||||||
|
LLVMTypeRef structType = LLVMTypeOf(structPointer);
|
||||||
|
|
||||||
|
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||||
|
{
|
||||||
|
if (structTypeFieldDeclarations[i].structType == structType)
|
||||||
|
{
|
||||||
|
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
|
||||||
|
{
|
||||||
|
if (strcmp(structTypeFieldDeclarations[i].fields[j].name, name) == 0)
|
||||||
{
|
{
|
||||||
char *ptrName = strdup(name);
|
char *ptrName = strdup(name);
|
||||||
strcat(ptrName, "_ptr");
|
strcat(ptrName, "_ptr");
|
||||||
LLVMValueRef elementPointer = LLVMBuildStructGEP(
|
return LLVMBuildStructGEP(
|
||||||
builder,
|
builder,
|
||||||
wStructPointer,
|
structPointer,
|
||||||
structFieldMaps[i].fields[j].index,
|
structTypeFieldDeclarations[i].fields[j].index,
|
||||||
ptrName
|
ptrName
|
||||||
);
|
);
|
||||||
free(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Failed to find struct field pointer!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MarkStructFieldForWrite(LLVMValueRef wStructPointer, LLVMValueRef value)
|
static LLVMValueRef FindVariablePointer(char *name)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
int32_t i, j;
|
||||||
|
|
||||||
for (i = 0; i < structFieldMapCount; i += 1)
|
for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].structPointer == wStructPointer)
|
for (j = 0; j < scope->scopeStack[i].localVariableCount; j += 1)
|
||||||
{
|
{
|
||||||
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1)
|
if (strcmp(scope->scopeStack[i].localVariables[j].name, name) == 0)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].fields[j].value == value)
|
return scope->scopeStack[i].localVariables[j].pointer;
|
||||||
{
|
|
||||||
structFieldMaps[i].fields[j].needsWrite = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static LLVMValueRef GetStructFieldPointer(LLVMValueRef wStructPointer, LLVMValueRef value)
|
|
||||||
{
|
|
||||||
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 (structFieldMaps[i].fields[j].value == value)
|
|
||||||
{
|
|
||||||
return structFieldMaps[i].fields[j].valuePointer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Failed to find variable pointer!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RemoveStruct(LLVMBuilderRef builder, LLVMValueRef wStructPointer)
|
static LLVMValueRef FindVariableValue(LLVMBuilderRef builder, char *name)
|
||||||
{
|
{
|
||||||
|
int32_t i, j;
|
||||||
|
|
||||||
|
for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
|
||||||
|
{
|
||||||
|
for (j = 0; j < scope->scopeStack[i].argumentCount; j += 1)
|
||||||
|
{
|
||||||
|
if (strcmp(scope->scopeStack[i].arguments[j].name, name) == 0)
|
||||||
|
{
|
||||||
|
return scope->scopeStack[i].arguments[j].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < scope->scopeStack[i].localVariableCount; j += 1)
|
||||||
|
{
|
||||||
|
if (strcmp(scope->scopeStack[i].localVariables[j].name, name) == 0)
|
||||||
|
{
|
||||||
|
return LLVMBuildLoad(builder, scope->scopeStack[i].localVariables[j].pointer, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Failed to find variable value!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddStructDeclaration(
|
||||||
|
LLVMTypeRef wStructType,
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
structTypeFieldDeclarationCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddStructVariables(
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
LLVMValueRef structPointer
|
||||||
|
) {
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
|
|
||||||
for (i = 0; i < structFieldMapCount; i += 1)
|
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].structPointer == wStructPointer)
|
if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
|
||||||
{
|
{
|
||||||
for (j = 0; j < structFieldMaps[i].fieldCount; j += 1)
|
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
|
||||||
{
|
{
|
||||||
if (structFieldMaps[i].fields[j].needsWrite)
|
LLVMValueRef elementPointer = LLVMBuildStructGEP(
|
||||||
{
|
|
||||||
LLVMBuildStore(
|
|
||||||
builder,
|
builder,
|
||||||
structFieldMaps[i].fields[j].value,
|
structPointer,
|
||||||
structFieldMaps[i].fields[j].valuePointer
|
structTypeFieldDeclarations[i].fields[j].index,
|
||||||
|
structTypeFieldDeclarations[i].fields[j].name
|
||||||
|
);
|
||||||
|
|
||||||
|
AddLocalVariable(
|
||||||
|
scope,
|
||||||
|
elementPointer,
|
||||||
|
structTypeFieldDeclarations[i].fields[j].name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(structFieldMaps[i].fields);
|
|
||||||
structFieldMaps[i].fields = NULL;
|
|
||||||
structFieldMaps[i].fieldCount = 0;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct IdentifierMapValue
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
LLVMValueRef value;
|
|
||||||
} IdentifierMapValue;
|
|
||||||
|
|
||||||
IdentifierMapValue *namedVariables;
|
|
||||||
uint32_t namedVariableCount;
|
|
||||||
|
|
||||||
static LLVMValueRef CompileExpression(
|
static LLVMValueRef CompileExpression(
|
||||||
LLVMValueRef wStructValue,
|
LLVMValueRef wStructValue,
|
||||||
|
@ -191,43 +275,6 @@ static LLVMValueRef CompileExpression(
|
||||||
Node *binaryExpression
|
Node *binaryExpression
|
||||||
);
|
);
|
||||||
|
|
||||||
static void AddNamedVariable(char *name, LLVMValueRef variable)
|
|
||||||
{
|
|
||||||
IdentifierMapValue mapValue;
|
|
||||||
mapValue.name = name;
|
|
||||||
mapValue.value = variable;
|
|
||||||
|
|
||||||
namedVariables = realloc(namedVariables, sizeof(IdentifierMapValue) * (namedVariableCount + 1));
|
|
||||||
namedVariables[namedVariableCount] = mapValue;
|
|
||||||
|
|
||||||
namedVariableCount += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (strcmp(namedVariables[i].name, name) == 0)
|
|
||||||
{
|
|
||||||
return namedVariables[i].value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if none exist, search struct vars */
|
|
||||||
searchResult = CheckStructFieldAndLoad(builder, wStructValue, name);
|
|
||||||
|
|
||||||
if (searchResult == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Identifier not found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return searchResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct CustomTypeMap
|
typedef struct CustomTypeMap
|
||||||
{
|
{
|
||||||
LLVMTypeRef type;
|
LLVMTypeRef type;
|
||||||
|
@ -312,6 +359,7 @@ static LLVMValueRef CompileBinaryExpression(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME THIS IS ALL BROKEN */
|
||||||
static LLVMValueRef CompileFunctionCallExpression(
|
static LLVMValueRef CompileFunctionCallExpression(
|
||||||
LLVMValueRef wStructValue,
|
LLVMValueRef wStructValue,
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
|
@ -327,7 +375,33 @@ static LLVMValueRef CompileFunctionCallExpression(
|
||||||
args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]);
|
args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return LLVMBuildCall(builder, FindVariableByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
|
//return LLVMBuildCall(builder, FindVariableValueByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef CompileAccessExpressionForStore(
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
LLVMValueRef wStructValue,
|
||||||
|
LLVMValueRef function,
|
||||||
|
Node *expression
|
||||||
|
) {
|
||||||
|
Node *accessee = expression->children[0];
|
||||||
|
Node *accessor = expression->children[1];
|
||||||
|
LLVMValueRef accesseeValue = FindVariablePointer(accessee->value.string);
|
||||||
|
return FindStructFieldPointer(builder, accesseeValue, accessor->value.string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef CompileAccessExpression(
|
||||||
|
LLVMBuilderRef builder,
|
||||||
|
LLVMValueRef wStructValue,
|
||||||
|
LLVMValueRef function,
|
||||||
|
Node *expression
|
||||||
|
) {
|
||||||
|
Node *accessee = expression->children[0];
|
||||||
|
Node *accessor = expression->children[1];
|
||||||
|
LLVMValueRef accesseeValue = FindVariablePointer(accessee->value.string);
|
||||||
|
LLVMValueRef access = FindStructFieldPointer(builder, accesseeValue, accessor->value.string);
|
||||||
|
return LLVMBuildLoad(builder, access, accessor->value.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef CompileExpression(
|
static LLVMValueRef CompileExpression(
|
||||||
|
@ -340,6 +414,9 @@ static LLVMValueRef CompileExpression(
|
||||||
|
|
||||||
switch (expression->syntaxKind)
|
switch (expression->syntaxKind)
|
||||||
{
|
{
|
||||||
|
case AccessExpression:
|
||||||
|
return CompileAccessExpression(builder, wStructValue, function, expression);
|
||||||
|
|
||||||
case BinaryExpression:
|
case BinaryExpression:
|
||||||
return CompileBinaryExpression(wStructValue, builder, function, expression);
|
return CompileBinaryExpression(wStructValue, builder, function, expression);
|
||||||
|
|
||||||
|
@ -347,7 +424,7 @@ static LLVMValueRef CompileExpression(
|
||||||
return CompileFunctionCallExpression(wStructValue, builder, function, expression);
|
return CompileFunctionCallExpression(wStructValue, builder, function, expression);
|
||||||
|
|
||||||
case Identifier:
|
case Identifier:
|
||||||
return FindVariableByName(builder, wStructValue, expression->value.string);
|
return FindVariableValue(builder, expression->value.string);
|
||||||
|
|
||||||
case Number:
|
case Number:
|
||||||
return CompileNumber(expression);
|
return CompileNumber(expression);
|
||||||
|
@ -357,9 +434,12 @@ static LLVMValueRef CompileExpression(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: we need a scope structure */
|
||||||
static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
|
static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
|
||||||
{
|
{
|
||||||
LLVMBuildRet(builder, CompileExpression(wStructValue, builder, function, returnStatemement->children[0]));
|
uint32_t i, j;
|
||||||
|
LLVMValueRef expression = CompileExpression(wStructValue, builder, function, returnStatemement->children[0]);
|
||||||
|
LLVMBuildRet(builder, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileReturnVoid(LLVMBuilderRef builder)
|
static void CompileReturnVoid(LLVMBuilderRef builder)
|
||||||
|
@ -371,9 +451,17 @@ static void CompileAssignment(LLVMValueRef wStructValue, LLVMBuilderRef builder,
|
||||||
{
|
{
|
||||||
LLVMValueRef fieldPointer;
|
LLVMValueRef fieldPointer;
|
||||||
LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]);
|
LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]);
|
||||||
LLVMValueRef identifier = CompileExpression(wStructValue, builder, function, assignmentStatement->children[0]);
|
LLVMValueRef identifier;
|
||||||
|
if (assignmentStatement->children[0]->syntaxKind == AccessExpression)
|
||||||
|
{
|
||||||
|
identifier = CompileAccessExpressionForStore(builder, wStructValue, function, assignmentStatement->children[0]);
|
||||||
|
}
|
||||||
|
else if (assignmentStatement->children[0]->syntaxKind == Identifier)
|
||||||
|
{
|
||||||
|
identifier = FindVariablePointer(assignmentStatement->children[0]->value.string);
|
||||||
|
}
|
||||||
|
|
||||||
MarkStructFieldForWrite(wStructValue, identifier);
|
LLVMBuildStore(builder, result, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration)
|
static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration)
|
||||||
|
@ -390,7 +478,7 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var
|
||||||
variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), variableName);
|
variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddNamedVariable(variableName, variable);
|
AddLocalVariable(scope, variable, variableName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
|
static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
|
||||||
|
@ -432,6 +520,8 @@ static void CompileFunction(
|
||||||
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */
|
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */
|
||||||
LLVMTypeRef paramTypes[argumentCount];
|
LLVMTypeRef paramTypes[argumentCount];
|
||||||
|
|
||||||
|
PushScopeFrame(scope);
|
||||||
|
|
||||||
paramTypes[0] = wStructPointerType;
|
paramTypes[0] = wStructPointerType;
|
||||||
|
|
||||||
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
||||||
|
@ -443,25 +533,19 @@ static void CompileFunction(
|
||||||
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0);
|
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0);
|
||||||
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
|
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
|
||||||
|
|
||||||
|
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
||||||
|
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||||
|
LLVMPositionBuilderAtEnd(builder, entry);
|
||||||
|
|
||||||
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
|
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
|
||||||
|
|
||||||
|
AddStructVariables(builder, wStructPointer);
|
||||||
|
|
||||||
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
||||||
{
|
{
|
||||||
LLVMValueRef argument = LLVMGetParam(function, i + 1);
|
LLVMValueRef argument = LLVMGetParam(function, i + 1);
|
||||||
AddNamedVariable(functionSignature->children[2]->children[i]->children[1]->value.string, argument);
|
LLVMValueRef argumentCopy = LLVMBuildAlloca(builder, LLVMTypeOf(argument), functionSignature->children[2]->children[i]->children[1]->value.string);
|
||||||
}
|
AddLocalVariable(scope, argumentCopy, functionSignature->children[2]->children[i]->children[1]->value.string);
|
||||||
|
|
||||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
|
||||||
|
|
||||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
|
||||||
LLVMPositionBuilderAtEnd(builder, entry);
|
|
||||||
|
|
||||||
/* FIXME: replace this with a scope abstraction */
|
|
||||||
AddStruct(wStructPointer);
|
|
||||||
|
|
||||||
for (i = 0; i < fieldDeclarationCount; i += 1)
|
|
||||||
{
|
|
||||||
AddStructFieldName(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < functionBody->childCount; i += 1)
|
for (i = 0; i < functionBody->childCount; i += 1)
|
||||||
|
@ -469,8 +553,6 @@ static void CompileFunction(
|
||||||
hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]);
|
hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveStruct(builder, wStructPointer);
|
|
||||||
|
|
||||||
if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
|
if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
|
||||||
{
|
{
|
||||||
LLVMBuildRetVoid(builder);
|
LLVMBuildRetVoid(builder);
|
||||||
|
@ -479,6 +561,8 @@ static void CompileFunction(
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Return statement not provided!");
|
fprintf(stderr, "Return statement not provided!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopScopeFrame(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
||||||
|
@ -491,6 +575,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
||||||
Node *currentDeclarationNode;
|
Node *currentDeclarationNode;
|
||||||
Node *fieldDeclarations[declarationCount];
|
Node *fieldDeclarations[declarationCount];
|
||||||
|
|
||||||
|
PushScopeFrame(scope);
|
||||||
|
|
||||||
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
|
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
|
||||||
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
|
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
|
||||||
|
|
||||||
|
@ -510,6 +596,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMStructSetBody(wStruct, types, fieldCount, packed);
|
LLVMStructSetBody(wStruct, types, fieldCount, packed);
|
||||||
|
AddStructDeclaration(wStructPointerType, fieldDeclarations, fieldCount);
|
||||||
|
RegisterCustomType(wStruct, node->children[0]->value.string);
|
||||||
|
|
||||||
/* now we can wire up the functions */
|
/* now we can wire up the functions */
|
||||||
for (i = 0; i < declarationCount; i += 1)
|
for (i = 0; i < declarationCount; i += 1)
|
||||||
|
@ -524,7 +612,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterCustomType(wStruct, node->children[0]->value.string);
|
PopScopeFrame(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
||||||
|
@ -552,11 +640,10 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
namedVariables = NULL;
|
scope = CreateScope();
|
||||||
namedVariableCount = 0;
|
|
||||||
|
|
||||||
structFieldMaps = NULL;
|
structTypeFieldDeclarations = NULL;
|
||||||
structFieldMapCount = 0;
|
structTypeFieldDeclarationCount = 0;
|
||||||
|
|
||||||
customTypes = NULL;
|
customTypes = NULL;
|
||||||
customTypeCount = 0;
|
customTypeCount = 0;
|
||||||
|
|
17
wraith.y
17
wraith.y
|
@ -115,8 +115,16 @@ Identifier : ID
|
||||||
$$ = MakeIdentifierNode(yytext);
|
$$ = MakeIdentifierNode(yytext);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimaryExpression : Identifier
|
AccessExpression : Identifier POINT AccessExpression
|
||||||
| NUMBER
|
{
|
||||||
|
$$ = MakeAccessExpressionNode($1, $3);
|
||||||
|
}
|
||||||
|
| Identifier
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimaryExpression : NUMBER
|
||||||
{
|
{
|
||||||
$$ = MakeNumberNode(yytext);
|
$$ = MakeNumberNode(yytext);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +137,7 @@ PrimaryExpression : Identifier
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
| FunctionCallExpression
|
| FunctionCallExpression
|
||||||
|
| AccessExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
UnaryExpression : BANG Expression
|
UnaryExpression : BANG Expression
|
||||||
|
@ -164,6 +173,10 @@ VariableDeclaration : Type Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignmentStatement : VariableDeclaration EQUAL Expression
|
AssignmentStatement : VariableDeclaration EQUAL Expression
|
||||||
|
{
|
||||||
|
$$ = MakeAssignmentNode($1, $3);
|
||||||
|
}
|
||||||
|
| AccessExpression EQUAL Expression
|
||||||
{
|
{
|
||||||
$$ = MakeAssignmentNode($1, $3);
|
$$ = MakeAssignmentNode($1, $3);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue