wraith-lang/compiler.c

671 lines
20 KiB
C
Raw Normal View History

2021-04-18 22:29:54 +00:00
#include <stdio.h>
2021-04-20 01:18:45 +00:00
#include <stdlib.h>
#include <string.h>
2021-04-18 22:29:54 +00:00
#include <llvm-c/Core.h>
2021-04-20 01:18:45 +00:00
#include <llvm-c/Analysis.h>
#include <llvm-c/BitWriter.h>
2021-04-22 05:48:55 +00:00
#include <llvm-c/Transforms/PassManagerBuilder.h>
#include <llvm-c/Transforms/InstCombine.h>
#include <llvm-c/Transforms/Scalar.h>
#include <llvm-c/Transforms/Utils.h>
2021-04-18 22:45:06 +00:00
2021-04-18 22:29:54 +00:00
#include "y.tab.h"
2021-04-18 22:45:06 +00:00
#include "ast.h"
2021-04-18 22:29:54 +00:00
#include "stack.h"
extern FILE *yyin;
Stack *stack;
2021-04-18 22:45:06 +00:00
Node *rootNode;
2021-04-22 04:29:38 +00:00
typedef struct LocalVariable
{
char *name;
LLVMValueRef pointer;
} LocalVariable;
typedef struct FunctionArgument
2021-04-21 02:00:18 +00:00
{
char *name;
LLVMValueRef value;
2021-04-22 04:29:38 +00:00
} FunctionArgument;
typedef struct ScopeFrame
{
LocalVariable *localVariables;
uint32_t localVariableCount;
} ScopeFrame;
typedef struct Scope
{
ScopeFrame *scopeStack;
uint32_t scopeStackCount;
} Scope;
Scope *scope;
typedef struct StructTypeField
{
char *name;
2021-04-21 02:40:39 +00:00
uint32_t index;
2021-04-22 04:29:38 +00:00
} StructTypeField;
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
typedef struct StructTypeFieldDeclaration
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
LLVMTypeRef structType;
StructTypeField *fields;
2021-04-21 02:00:18 +00:00
uint32_t fieldCount;
2021-04-22 04:29:38 +00:00
} StructTypeFieldDeclaration;
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
StructTypeFieldDeclaration *structTypeFieldDeclarations;
uint32_t structTypeFieldDeclarationCount;
static Scope* CreateScope()
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
Scope *scope = malloc(sizeof(Scope));
scope->scopeStack = malloc(sizeof(ScopeFrame));
scope->scopeStack[0].localVariableCount = 0;
scope->scopeStack[0].localVariables = NULL;
scope->scopeStackCount = 1;
return scope;
2021-04-21 02:00:18 +00:00
}
2021-04-22 04:29:38 +00:00
static void PushScopeFrame(Scope *scope)
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
uint32_t index = scope->scopeStackCount;
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * (scope->scopeStackCount + 1));
scope->scopeStack[index].localVariableCount = 0;
scope->scopeStack[index].localVariables = NULL;
scope->scopeStackCount += 1;
}
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
static void PopScopeFrame(Scope *scope)
{
uint32_t i;
uint32_t index = scope->scopeStackCount - 1;
if (scope->scopeStack[index].localVariables != NULL)
{
for (i = 0; i < scope->scopeStack[index].localVariableCount; i += 1)
{
free(scope->scopeStack[index].localVariables[i].name);
2021-04-21 02:00:18 +00:00
}
2021-04-22 04:29:38 +00:00
free(scope->scopeStack[index].localVariables);
2021-04-21 02:00:18 +00:00
}
2021-04-22 04:29:38 +00:00
scope->scopeStackCount -= 1;
scope->scopeStack = realloc(scope->scopeStack, sizeof(ScopeFrame) * scope->scopeStackCount);
2021-04-21 02:00:18 +00:00
}
2021-04-22 04:29:38 +00:00
static void AddLocalVariable(Scope *scope, LLVMValueRef pointer, char *name)
2021-04-21 02:40:39 +00:00
{
2021-04-22 04:29:38 +00:00
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;
}
2021-04-21 02:40:39 +00:00
2021-04-22 04:29:38 +00:00
static LLVMValueRef FindStructFieldPointer(LLVMBuilderRef builder, LLVMValueRef structPointer, char *name)
{
int32_t i, j;
LLVMTypeRef structType = LLVMTypeOf(structPointer);
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
2021-04-21 02:40:39 +00:00
{
2021-04-22 04:29:38 +00:00
if (structTypeFieldDeclarations[i].structType == structType)
2021-04-21 02:40:39 +00:00
{
2021-04-22 04:29:38 +00:00
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
2021-04-21 02:40:39 +00:00
{
2021-04-22 04:29:38 +00:00
if (strcmp(structTypeFieldDeclarations[i].fields[j].name, name) == 0)
2021-04-21 02:40:39 +00:00
{
2021-04-22 04:29:38 +00:00
char *ptrName = strdup(name);
strcat(ptrName, "_ptr");
return LLVMBuildStructGEP(
builder,
structPointer,
structTypeFieldDeclarations[i].fields[j].index,
ptrName
);
free(ptrName);
2021-04-21 02:40:39 +00:00
}
}
}
}
2021-04-22 04:29:38 +00:00
printf("Failed to find struct field pointer!");
2021-04-21 02:40:39 +00:00
return NULL;
}
2021-04-22 04:29:38 +00:00
static LLVMValueRef FindVariablePointer(char *name)
2021-04-21 02:07:11 +00:00
{
2021-04-22 04:29:38 +00:00
int32_t i, j;
2021-04-21 02:07:11 +00:00
2021-04-22 04:29:38 +00:00
for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
2021-04-21 02:07:11 +00:00
{
2021-04-22 04:29:38 +00:00
for (j = 0; j < scope->scopeStack[i].localVariableCount; j += 1)
2021-04-21 02:07:11 +00:00
{
2021-04-22 04:29:38 +00:00
if (strcmp(scope->scopeStack[i].localVariables[j].name, name) == 0)
2021-04-21 02:07:11 +00:00
{
2021-04-22 04:29:38 +00:00
return scope->scopeStack[i].localVariables[j].pointer;
2021-04-21 02:07:11 +00:00
}
}
}
2021-04-22 04:29:38 +00:00
printf("Failed to find variable pointer!");
return NULL;
2021-04-21 02:07:11 +00:00
}
2021-04-22 04:29:38 +00:00
static LLVMValueRef FindVariableValue(LLVMBuilderRef builder, char *name)
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
int32_t i, j;
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
for (i = scope->scopeStackCount - 1; i >= 0; i -= 1)
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
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);
2021-04-21 02:00:18 +00:00
}
}
}
2021-04-22 04:29:38 +00:00
printf("Failed to find variable value!");
2021-04-21 02:00:18 +00:00
return NULL;
}
2021-04-22 04:29:38 +00:00
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
) {
2021-04-21 02:07:11 +00:00
uint32_t i, j;
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
2021-04-21 02:00:18 +00:00
{
2021-04-22 04:29:38 +00:00
for (j = 0; j < structTypeFieldDeclarations[i].fieldCount; j += 1)
2021-04-21 02:07:11 +00:00
{
char *ptrName = strdup(structTypeFieldDeclarations[i].fields[j].name);
strcat(ptrName, "_ptr");
2021-04-22 04:29:38 +00:00
LLVMValueRef elementPointer = LLVMBuildStructGEP(
builder,
structPointer,
structTypeFieldDeclarations[i].fields[j].index,
ptrName
2021-04-22 04:29:38 +00:00
);
free(ptrName);
2021-04-22 04:29:38 +00:00
AddLocalVariable(
scope,
elementPointer,
structTypeFieldDeclarations[i].fields[j].name
);
2021-04-21 02:07:11 +00:00
}
2021-04-21 02:00:18 +00:00
}
}
}
2021-04-20 01:18:45 +00:00
static LLVMValueRef CompileExpression(
2021-04-21 02:00:18 +00:00
LLVMValueRef wStructValue,
2021-04-20 01:18:45 +00:00
LLVMBuilderRef builder,
LLVMValueRef function,
Node *binaryExpression
);
2021-04-21 06:51:26 +00:00
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;
}
2021-04-20 01:18:45 +00:00
static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type)
2021-04-18 22:45:06 +00:00
{
switch (type)
{
case Int:
return LLVMInt64Type();
case UInt:
return LLVMInt64Type();
2021-04-21 02:00:18 +00:00
case Bool:
return LLVMInt1Type();
case Void:
return LLVMVoidType();
2021-04-18 22:45:06 +00:00
}
2021-04-21 02:00:18 +00:00
fprintf(stderr, "Unrecognized type!");
2021-04-18 22:45:06 +00:00
return NULL;
}
2021-04-20 01:18:45 +00:00
static LLVMValueRef CompileNumber(
Node *numberExpression
2021-04-20 17:47:40 +00:00
) {
2021-04-20 01:18:45 +00:00
return LLVMConstInt(LLVMInt64Type(), numberExpression->value.number, 0);
}
static LLVMValueRef CompileBinaryExpression(
2021-04-21 02:00:18 +00:00
LLVMValueRef wStructValue,
2021-04-20 01:18:45 +00:00
LLVMBuilderRef builder,
LLVMValueRef function,
Node *binaryExpression
) {
2021-04-21 02:00:18 +00:00
LLVMValueRef left = CompileExpression(wStructValue, builder, function, binaryExpression->children[0]);
LLVMValueRef right = CompileExpression(wStructValue, builder, function, binaryExpression->children[1]);
2021-04-20 01:18:45 +00:00
switch (binaryExpression->operator.binaryOperator)
{
case Add:
return LLVMBuildAdd(builder, left, right, "tmp");
2021-04-20 17:47:40 +00:00
case Subtract:
return LLVMBuildSub(builder, left, right, "tmp");
case Multiply:
return LLVMBuildMul(builder, left, right, "tmp");
2021-04-20 01:18:45 +00:00
}
return NULL;
}
2021-04-22 04:29:38 +00:00
/* FIXME THIS IS ALL BROKEN */
2021-04-20 17:47:40 +00:00
static LLVMValueRef CompileFunctionCallExpression(
2021-04-21 02:00:18 +00:00
LLVMValueRef wStructValue,
2021-04-20 17:47:40 +00:00
LLVMBuilderRef builder,
LLVMValueRef function,
Node *expression
) {
uint32_t i;
uint32_t argumentCount = expression->children[1]->childCount;
LLVMValueRef args[argumentCount];
for (i = 0; i < argumentCount; i += 1)
{
2021-04-21 02:00:18 +00:00
args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]);
2021-04-20 17:47:40 +00:00
}
2021-04-22 04:29:38 +00:00
//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);
2021-04-20 17:47:40 +00:00
}
2021-04-20 01:18:45 +00:00
static LLVMValueRef CompileExpression(
2021-04-21 02:00:18 +00:00
LLVMValueRef wStructValue,
2021-04-20 01:18:45 +00:00
LLVMBuilderRef builder,
LLVMValueRef function,
Node *expression
) {
switch (expression->syntaxKind)
{
2021-04-22 04:29:38 +00:00
case AccessExpression:
return CompileAccessExpression(builder, wStructValue, function, expression);
2021-04-20 01:18:45 +00:00
case BinaryExpression:
2021-04-21 02:00:18 +00:00
return CompileBinaryExpression(wStructValue, builder, function, expression);
2021-04-20 01:18:45 +00:00
2021-04-20 17:47:40 +00:00
case FunctionCallExpression:
2021-04-21 02:00:18 +00:00
return CompileFunctionCallExpression(wStructValue, builder, function, expression);
2021-04-20 17:47:40 +00:00
2021-04-20 01:18:45 +00:00
case Identifier:
2021-04-22 04:29:38 +00:00
return FindVariableValue(builder, expression->value.string);
2021-04-20 01:18:45 +00:00
case Number:
2021-04-21 02:00:18 +00:00
return CompileNumber(expression);
2021-04-20 01:18:45 +00:00
}
2021-04-21 02:00:18 +00:00
fprintf(stderr, "Unknown expression kind!\n");
2021-04-20 01:18:45 +00:00
return NULL;
}
2021-04-22 04:29:38 +00:00
/* FIXME: we need a scope structure */
2021-04-21 02:00:18 +00:00
static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
2021-04-20 01:18:45 +00:00
{
2021-04-22 04:29:38 +00:00
LLVMValueRef expression = CompileExpression(wStructValue, builder, function, returnStatemement->children[0]);
LLVMBuildRet(builder, expression);
2021-04-21 02:00:18 +00:00
}
static void CompileReturnVoid(LLVMBuilderRef builder)
{
LLVMBuildRetVoid(builder);
}
static void CompileAssignment(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *assignmentStatement)
{
LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]);
2021-04-22 04:29:38 +00:00
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);
}
2021-04-22 05:26:34 +00:00
else
{
printf("Identifier not found!");
return;
}
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
LLVMBuildStore(builder, result, identifier);
2021-04-20 01:18:45 +00:00
}
2021-04-21 06:51:26 +00:00
static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration)
{
LLVMValueRef variable;
char *variableName = variableDeclaration->children[1]->value.string;
char *ptrName = strdup(variableName);
strcat(ptrName, "_ptr");
2021-04-21 06:51:26 +00:00
if (variableDeclaration->children[0]->type == CustomType)
{
char *customTypeName = variableDeclaration->children[0]->children[0]->value.string;
variable = LLVMBuildAlloca(builder, LookupCustomType(customTypeName), ptrName);
2021-04-21 06:51:26 +00:00
}
else
{
variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), ptrName);
2021-04-21 06:51:26 +00:00
}
free(ptrName);
2021-04-22 04:29:38 +00:00
AddLocalVariable(scope, variable, variableName);
2021-04-21 06:51:26 +00:00
}
2021-04-21 02:00:18 +00:00
static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
2021-04-20 01:18:45 +00:00
{
switch (statement->syntaxKind)
{
2021-04-21 02:00:18 +00:00
case Assignment:
CompileAssignment(wStructValue, builder, function, statement);
return 0;
2021-04-21 06:51:26 +00:00
case Declaration:
CompileFunctionVariableDeclaration(builder, statement);
return 0;
2021-04-20 01:18:45 +00:00
case Return:
2021-04-21 02:00:18 +00:00
CompileReturn(wStructValue, builder, function, statement);
return 1;
case ReturnVoid:
CompileReturnVoid(builder);
return 1;
2021-04-20 01:18:45 +00:00
}
2021-04-21 02:00:18 +00:00
fprintf(stderr, "Unknown statement kind!\n");
return 0;
2021-04-20 01:18:45 +00:00
}
2021-04-21 02:00:18 +00:00
static void CompileFunction(
LLVMModuleRef module,
LLVMTypeRef wStructPointerType,
Node **fieldDeclarations,
uint32_t fieldDeclarationCount,
Node *functionDeclaration
) {
2021-04-18 22:45:06 +00:00
uint32_t i;
2021-04-21 02:00:18 +00:00
uint8_t hasReturn = 0;
2021-04-18 22:45:06 +00:00
Node *functionSignature = functionDeclaration->children[0];
2021-04-20 01:18:45 +00:00
Node *functionBody = functionDeclaration->children[1];
2021-04-21 02:00:18 +00:00
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */
LLVMTypeRef paramTypes[argumentCount];
2021-04-22 04:29:38 +00:00
PushScopeFrame(scope);
2021-04-21 02:00:18 +00:00
paramTypes[0] = wStructPointerType;
2021-04-18 22:45:06 +00:00
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
{
2021-04-21 02:00:18 +00:00
paramTypes[i + 1] = WraithTypeToLLVMType(functionSignature->children[2]->children[i]->children[0]->type);
2021-04-20 01:18:45 +00:00
}
2021-04-21 02:00:18 +00:00
LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type);
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0);
2021-04-20 01:18:45 +00:00
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
2021-04-22 04:29:38 +00:00
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
2021-04-21 02:00:18 +00:00
2021-04-22 04:29:38 +00:00
AddStructVariables(builder, wStructPointer);
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
2021-04-21 02:00:18 +00:00
{
char *ptrName = strdup(functionSignature->children[2]->children[i]->children[1]->value.string);
strcat(ptrName, "_ptr");
2021-04-22 04:29:38 +00:00
LLVMValueRef argument = LLVMGetParam(function, i + 1);
LLVMValueRef argumentCopy = LLVMBuildAlloca(builder, LLVMTypeOf(argument), ptrName);
LLVMBuildStore(builder, argument, argumentCopy);
free(ptrName);
2021-04-22 04:29:38 +00:00
AddLocalVariable(scope, argumentCopy, functionSignature->children[2]->children[i]->children[1]->value.string);
2021-04-21 02:00:18 +00:00
}
2021-04-20 01:18:45 +00:00
for (i = 0; i < functionBody->childCount; i += 1)
{
2021-04-21 02:00:18 +00:00
hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]);
2021-04-20 01:18:45 +00:00
}
2021-04-20 17:47:40 +00:00
2021-04-21 02:00:18 +00:00
if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
{
LLVMBuildRetVoid(builder);
}
else if (LLVMGetTypeKind(returnType) != LLVMVoidTypeKind && !hasReturn)
{
fprintf(stderr, "Return statement not provided!");
}
2021-04-22 04:29:38 +00:00
PopScopeFrame(scope);
2021-04-21 02:00:18 +00:00
}
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
{
uint32_t i;
uint32_t fieldCount = 0;
uint32_t declarationCount = node->children[1]->childCount;
uint8_t packed = 1;
LLVMTypeRef types[declarationCount];
Node *currentDeclarationNode;
Node *fieldDeclarations[declarationCount];
2021-04-22 04:29:38 +00:00
PushScopeFrame(scope);
2021-04-21 02:00:18 +00:00
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string);
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
/* first, build the structure definition */
for (i = 0; i < declarationCount; i += 1)
{
currentDeclarationNode = node->children[1]->children[i];
switch (currentDeclarationNode->syntaxKind)
{
case Declaration: /* this is badly named */
types[fieldCount] = WraithTypeToLLVMType(currentDeclarationNode->children[0]->type);
fieldDeclarations[fieldCount] = currentDeclarationNode;
fieldCount += 1;
break;
}
}
LLVMStructSetBody(wStruct, types, fieldCount, packed);
2021-04-22 04:29:38 +00:00
AddStructDeclaration(wStructPointerType, fieldDeclarations, fieldCount);
RegisterCustomType(wStruct, node->children[0]->value.string);
2021-04-21 02:00:18 +00:00
/* now we can wire up the functions */
for (i = 0; i < declarationCount; i += 1)
{
currentDeclarationNode = node->children[1]->children[i];
switch (currentDeclarationNode->syntaxKind)
{
case FunctionDeclaration:
CompileFunction(module, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
break;
}
}
2021-04-21 06:51:26 +00:00
2021-04-22 04:29:38 +00:00
PopScopeFrame(scope);
2021-04-18 22:45:06 +00:00
}
2021-04-21 02:00:18 +00:00
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
2021-04-18 22:45:06 +00:00
{
uint32_t i;
switch (node->syntaxKind)
{
2021-04-21 02:00:18 +00:00
case StructDeclaration:
CompileStruct(module, context, node);
2021-04-18 22:45:06 +00:00
break;
}
for (i = 0; i < node->childCount; i += 1)
{
2021-04-21 02:00:18 +00:00
Compile(module, context, node->children[i]);
2021-04-18 22:45:06 +00:00
}
}
2021-04-18 22:29:54 +00:00
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Please provide a file.\n");
return 1;
}
2021-04-22 04:29:38 +00:00
scope = CreateScope();
2021-04-20 01:18:45 +00:00
2021-04-22 04:29:38 +00:00
structTypeFieldDeclarations = NULL;
structTypeFieldDeclarationCount = 0;
2021-04-21 02:00:18 +00:00
2021-04-21 06:51:26 +00:00
customTypes = NULL;
customTypeCount = 0;
2021-04-18 22:29:54 +00:00
stack = CreateStack();
FILE *fp = fopen(argv[1], "r");
yyin = fp;
yyparse(fp, stack);
fclose(fp);
2021-04-18 22:45:06 +00:00
PrintTree(rootNode, 0);
LLVMModuleRef module = LLVMModuleCreateWithName("my_module");
2021-04-21 02:00:18 +00:00
LLVMContextRef context = LLVMGetGlobalContext();
2021-04-18 22:45:06 +00:00
2021-04-21 02:00:18 +00:00
Compile(module, context, rootNode);
2021-04-18 22:29:54 +00:00
2021-04-20 01:18:45 +00:00
char *error = NULL;
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
2021-04-22 05:48:55 +00:00
LLVMPassManagerRef passManager = LLVMCreatePassManager();
LLVMAddInstructionCombiningPass(passManager);
LLVMAddCFGSimplificationPass(passManager);
LLVMAddReassociatePass(passManager);
LLVMAddPromoteMemoryToRegisterPass(passManager);
LLVMPassManagerBuilderRef passManagerBuilder = LLVMPassManagerBuilderCreate();
LLVMPassManagerBuilderSetOptLevel(passManagerBuilder, 3);
LLVMPassManagerBuilderPopulateModulePassManager(passManagerBuilder, passManager);
LLVMRunPassManager(passManager, module);
2021-04-20 01:18:45 +00:00
if (LLVMWriteBitcodeToFile(module, "test.bc") != 0) {
fprintf(stderr, "error writing bitcode to file\n");
}
2021-04-22 05:48:55 +00:00
LLVMPassManagerBuilderDispose(passManagerBuilder);
LLVMDisposePassManager(passManager);
LLVMDisposeModule(module);
2021-04-18 22:29:54 +00:00
return 0;
}