forked from cosmonaut/wraith-lang
function calls
parent
e4cf57ef74
commit
acb6c61922
|
@ -23,7 +23,7 @@ find_package(LLVM)
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR})
|
include_directories(${CMAKE_SOURCE_DIR})
|
||||||
|
|
||||||
BISON_TARGET(Parser wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS -d)
|
BISON_TARGET(Parser wraith.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c COMPILE_FLAGS "-d -v -t")
|
||||||
FLEX_TARGET(Scanner wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c)
|
FLEX_TARGET(Scanner wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c)
|
||||||
|
|
||||||
ADD_FLEX_BISON_DEPENDENCY(Scanner Parser)
|
ADD_FLEX_BISON_DEPENDENCY(Scanner Parser)
|
||||||
|
|
165
compiler.c
165
compiler.c
|
@ -53,12 +53,22 @@ typedef struct StructTypeField
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
} StructTypeField;
|
} StructTypeField;
|
||||||
|
|
||||||
|
typedef struct StructTypeFunction
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
LLVMValueRef function;
|
||||||
|
LLVMTypeRef returnType;
|
||||||
|
uint8_t isStatic;
|
||||||
|
} StructTypeFunction;
|
||||||
|
|
||||||
typedef struct StructTypeFieldDeclaration
|
typedef struct StructTypeFieldDeclaration
|
||||||
{
|
{
|
||||||
LLVMTypeRef structType;
|
LLVMTypeRef structType;
|
||||||
StructTypeField *fields;
|
StructTypeField *fields;
|
||||||
uint32_t fieldCount;
|
uint32_t fieldCount;
|
||||||
|
|
||||||
|
StructTypeFunction *functions;
|
||||||
|
uint32_t functionCount;
|
||||||
} StructTypeFieldDeclaration;
|
} StructTypeFieldDeclaration;
|
||||||
|
|
||||||
StructTypeFieldDeclaration *structTypeFieldDeclarations;
|
StructTypeFieldDeclaration *structTypeFieldDeclarations;
|
||||||
|
@ -198,6 +208,8 @@ static void AddStructDeclaration(
|
||||||
structTypeFieldDeclarations[index].structType = wStructType;
|
structTypeFieldDeclarations[index].structType = wStructType;
|
||||||
structTypeFieldDeclarations[index].fields = NULL;
|
structTypeFieldDeclarations[index].fields = NULL;
|
||||||
structTypeFieldDeclarations[index].fieldCount = 0;
|
structTypeFieldDeclarations[index].fieldCount = 0;
|
||||||
|
structTypeFieldDeclarations[index].functions = NULL;
|
||||||
|
structTypeFieldDeclarations[index].functionCount = 0;
|
||||||
|
|
||||||
for (i = 0; i < fieldDeclarationCount; i += 1)
|
for (i = 0; i < fieldDeclarationCount; i += 1)
|
||||||
{
|
{
|
||||||
|
@ -210,7 +222,63 @@ static void AddStructDeclaration(
|
||||||
structTypeFieldDeclarationCount += 1;
|
structTypeFieldDeclarationCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddStructVariables(
|
static void DeclareStructFunction(
|
||||||
|
LLVMTypeRef wStructType,
|
||||||
|
LLVMValueRef function,
|
||||||
|
LLVMTypeRef returnType,
|
||||||
|
uint8_t isStatic,
|
||||||
|
char *name
|
||||||
|
) {
|
||||||
|
uint32_t i, index;
|
||||||
|
|
||||||
|
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||||
|
{
|
||||||
|
if (structTypeFieldDeclarations[i].structType == wStructType)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Could not find struct type for function!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static LLVMValueRef LookupFunction(
|
||||||
|
LLVMValueRef structPointer,
|
||||||
|
char *name,
|
||||||
|
LLVMTypeRef *pReturnType,
|
||||||
|
uint8_t *pStatic
|
||||||
|
) {
|
||||||
|
uint32_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < structTypeFieldDeclarationCount; i += 1)
|
||||||
|
{
|
||||||
|
if (structTypeFieldDeclarations[i].structType == LLVMTypeOf(structPointer))
|
||||||
|
{
|
||||||
|
for (j = 0; j < structTypeFieldDeclarations[i].functionCount; j += 1)
|
||||||
|
{
|
||||||
|
if (strcmp(structTypeFieldDeclarations[i].functions[j].name, name) == 0)
|
||||||
|
{
|
||||||
|
*pReturnType = structTypeFieldDeclarations[i].functions[j].returnType;
|
||||||
|
*pStatic = structTypeFieldDeclarations[i].functions[j].isStatic;
|
||||||
|
return structTypeFieldDeclarations[i].functions[j].function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Could not find struct function!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddStructVariablesToScope(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef structPointer
|
LLVMValueRef structPointer
|
||||||
) {
|
) {
|
||||||
|
@ -244,7 +312,6 @@ static void AddStructVariables(
|
||||||
|
|
||||||
static LLVMValueRef CompileExpression(
|
static LLVMValueRef CompileExpression(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *binaryExpression
|
Node *binaryExpression
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -309,11 +376,10 @@ static LLVMValueRef CompileNumber(
|
||||||
|
|
||||||
static LLVMValueRef CompileBinaryExpression(
|
static LLVMValueRef CompileBinaryExpression(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *binaryExpression
|
Node *binaryExpression
|
||||||
) {
|
) {
|
||||||
LLVMValueRef left = CompileExpression(builder, function, binaryExpression->children[0]);
|
LLVMValueRef left = CompileExpression(builder, binaryExpression->children[0]);
|
||||||
LLVMValueRef right = CompileExpression(builder, function, binaryExpression->children[1]);
|
LLVMValueRef right = CompileExpression(builder, binaryExpression->children[1]);
|
||||||
|
|
||||||
switch (binaryExpression->operator.binaryOperator)
|
switch (binaryExpression->operator.binaryOperator)
|
||||||
{
|
{
|
||||||
|
@ -334,25 +400,51 @@ static LLVMValueRef CompileBinaryExpression(
|
||||||
/* FIXME THIS IS ALL BROKEN */
|
/* FIXME THIS IS ALL BROKEN */
|
||||||
static LLVMValueRef CompileFunctionCallExpression(
|
static LLVMValueRef CompileFunctionCallExpression(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *expression
|
Node *expression
|
||||||
) {
|
) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t argumentCount = expression->children[1]->childCount;
|
uint32_t argumentCount = 0;
|
||||||
LLVMValueRef args[argumentCount];
|
LLVMValueRef args[argumentCount];
|
||||||
|
LLVMValueRef function;
|
||||||
|
uint8_t isStatic;
|
||||||
|
LLVMValueRef structInstance;
|
||||||
|
LLVMTypeRef functionReturnType;
|
||||||
|
char *returnName = "";
|
||||||
|
|
||||||
for (i = 0; i < argumentCount; i += 1)
|
/* FIXME: this needs to be recursive on access chains */
|
||||||
|
if (expression->children[0]->syntaxKind == AccessExpression)
|
||||||
{
|
{
|
||||||
args[i] = CompileExpression(builder, function, expression->children[1]->children[i]);
|
structInstance = FindVariablePointer(expression->children[0]->children[0]->value.string);
|
||||||
|
function = LookupFunction(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to find function!\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return LLVMBuildCall(builder, FindVariableValueByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
|
if (!isStatic)
|
||||||
return NULL;
|
{
|
||||||
|
args[argumentCount] = structInstance;
|
||||||
|
argumentCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < expression->children[1]->childCount; i += 1)
|
||||||
|
{
|
||||||
|
args[argumentCount] = CompileExpression(builder, expression->children[1]->children[i]);
|
||||||
|
argumentCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LLVMGetTypeKind(functionReturnType) != LLVMVoidTypeKind)
|
||||||
|
{
|
||||||
|
returnName = "callReturn";
|
||||||
|
}
|
||||||
|
|
||||||
|
return LLVMBuildCall(builder, function, args, argumentCount, returnName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef CompileAccessExpressionForStore(
|
static LLVMValueRef CompileAccessExpressionForStore(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *expression
|
Node *expression
|
||||||
) {
|
) {
|
||||||
Node *accessee = expression->children[0];
|
Node *accessee = expression->children[0];
|
||||||
|
@ -363,7 +455,6 @@ static LLVMValueRef CompileAccessExpressionForStore(
|
||||||
|
|
||||||
static LLVMValueRef CompileAccessExpression(
|
static LLVMValueRef CompileAccessExpression(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *expression
|
Node *expression
|
||||||
) {
|
) {
|
||||||
Node *accessee = expression->children[0];
|
Node *accessee = expression->children[0];
|
||||||
|
@ -375,19 +466,18 @@ static LLVMValueRef CompileAccessExpression(
|
||||||
|
|
||||||
static LLVMValueRef CompileExpression(
|
static LLVMValueRef CompileExpression(
|
||||||
LLVMBuilderRef builder,
|
LLVMBuilderRef builder,
|
||||||
LLVMValueRef function,
|
|
||||||
Node *expression
|
Node *expression
|
||||||
) {
|
) {
|
||||||
switch (expression->syntaxKind)
|
switch (expression->syntaxKind)
|
||||||
{
|
{
|
||||||
case AccessExpression:
|
case AccessExpression:
|
||||||
return CompileAccessExpression(builder, function, expression);
|
return CompileAccessExpression(builder, expression);
|
||||||
|
|
||||||
case BinaryExpression:
|
case BinaryExpression:
|
||||||
return CompileBinaryExpression(builder, function, expression);
|
return CompileBinaryExpression(builder, expression);
|
||||||
|
|
||||||
case FunctionCallExpression:
|
case FunctionCallExpression:
|
||||||
return CompileFunctionCallExpression(builder, function, expression);
|
return CompileFunctionCallExpression(builder, expression);
|
||||||
|
|
||||||
case Identifier:
|
case Identifier:
|
||||||
return FindVariableValue(builder, expression->value.string);
|
return FindVariableValue(builder, expression->value.string);
|
||||||
|
@ -400,9 +490,9 @@ static LLVMValueRef CompileExpression(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileReturn(LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
|
static void CompileReturn(LLVMBuilderRef builder, Node *returnStatemement)
|
||||||
{
|
{
|
||||||
LLVMValueRef expression = CompileExpression(builder, function, returnStatemement->children[0]);
|
LLVMValueRef expression = CompileExpression(builder, returnStatemement->children[0]);
|
||||||
LLVMBuildRet(builder, expression);
|
LLVMBuildRet(builder, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,13 +501,13 @@ static void CompileReturnVoid(LLVMBuilderRef builder)
|
||||||
LLVMBuildRetVoid(builder);
|
LLVMBuildRetVoid(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CompileAssignment(LLVMBuilderRef builder, LLVMValueRef function, Node *assignmentStatement)
|
static void CompileAssignment(LLVMBuilderRef builder, Node *assignmentStatement)
|
||||||
{
|
{
|
||||||
LLVMValueRef result = CompileExpression(builder, function, assignmentStatement->children[1]);
|
LLVMValueRef result = CompileExpression(builder, assignmentStatement->children[1]);
|
||||||
LLVMValueRef identifier;
|
LLVMValueRef identifier;
|
||||||
if (assignmentStatement->children[0]->syntaxKind == AccessExpression)
|
if (assignmentStatement->children[0]->syntaxKind == AccessExpression)
|
||||||
{
|
{
|
||||||
identifier = CompileAccessExpressionForStore(builder, function, assignmentStatement->children[0]);
|
identifier = CompileAccessExpressionForStore(builder, assignmentStatement->children[0]);
|
||||||
}
|
}
|
||||||
else if (assignmentStatement->children[0]->syntaxKind == Identifier)
|
else if (assignmentStatement->children[0]->syntaxKind == Identifier)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +549,11 @@ static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, N
|
||||||
switch (statement->syntaxKind)
|
switch (statement->syntaxKind)
|
||||||
{
|
{
|
||||||
case Assignment:
|
case Assignment:
|
||||||
CompileAssignment(builder, function, statement);
|
CompileAssignment(builder, statement);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case FunctionCallExpression:
|
||||||
|
CompileFunctionCallExpression(builder, statement);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case Declaration:
|
case Declaration:
|
||||||
|
@ -467,7 +561,7 @@ static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, N
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case Return:
|
case Return:
|
||||||
CompileReturn(builder, function, statement);
|
CompileReturn(builder, statement);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case ReturnVoid:
|
case ReturnVoid:
|
||||||
|
@ -531,6 +625,8 @@ static void CompileFunction(
|
||||||
LLVMValueRef function = LLVMAddFunction(module, functionName, functionType);
|
LLVMValueRef function = LLVMAddFunction(module, functionName, functionType);
|
||||||
free(functionName);
|
free(functionName);
|
||||||
|
|
||||||
|
DeclareStructFunction(wStructPointerType, function, returnType, isStatic, functionSignature->children[0]->value.string);
|
||||||
|
|
||||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
||||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||||
LLVMPositionBuilderAtEnd(builder, entry);
|
LLVMPositionBuilderAtEnd(builder, entry);
|
||||||
|
@ -538,7 +634,7 @@ static void CompileFunction(
|
||||||
if (!isStatic)
|
if (!isStatic)
|
||||||
{
|
{
|
||||||
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
|
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
|
||||||
AddStructVariables(builder, wStructPointer);
|
AddStructVariablesToScope(builder, wStructPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
||||||
|
@ -626,16 +722,16 @@ static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
switch (node->syntaxKind)
|
|
||||||
{
|
|
||||||
case StructDeclaration:
|
|
||||||
CompileStruct(module, context, node);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < node->childCount; i += 1)
|
for (i = 0; i < node->childCount; i += 1)
|
||||||
{
|
{
|
||||||
Compile(module, context, node->children[i]);
|
if (node->children[i]->syntaxKind == StructDeclaration)
|
||||||
|
{
|
||||||
|
CompileStruct(module, context, node->children[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "top level declarations that are not structs are forbidden!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,6 +743,9 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int yydebug;
|
||||||
|
yydebug = 1;
|
||||||
|
|
||||||
scope = CreateScope();
|
scope = CreateScope();
|
||||||
|
|
||||||
structTypeFieldDeclarations = NULL;
|
structTypeFieldDeclarations = NULL;
|
||||||
|
|
11
wraith.y
11
wraith.y
|
@ -62,6 +62,8 @@ extern Node *rootNode;
|
||||||
|
|
||||||
%parse-param { FILE* fp } { Stack *stack }
|
%parse-param { FILE* fp } { Stack *stack }
|
||||||
|
|
||||||
|
%define parse.error verbose
|
||||||
|
|
||||||
%left PLUS MINUS
|
%left PLUS MINUS
|
||||||
%left BANG
|
%left BANG
|
||||||
%left LEFT_PAREN RIGHT_PAREN
|
%left LEFT_PAREN RIGHT_PAREN
|
||||||
|
@ -195,7 +197,7 @@ ReturnStatement : RETURN Expression
|
||||||
$$ = MakeReturnVoidStatementNode();
|
$$ = MakeReturnVoidStatementNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCallExpression : Identifier LEFT_PAREN Arguments RIGHT_PAREN
|
FunctionCallExpression : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN
|
||||||
{
|
{
|
||||||
Node **arguments;
|
Node **arguments;
|
||||||
uint32_t argumentCount;
|
uint32_t argumentCount;
|
||||||
|
@ -206,9 +208,9 @@ FunctionCallExpression : Identifier LEFT_PAREN Arguments RIGHT_PAREN
|
||||||
PopStackFrame(stack);
|
PopStackFrame(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialStatement : AssignmentStatement
|
PartialStatement : FunctionCallExpression
|
||||||
|
| AssignmentStatement
|
||||||
| VariableDeclaration
|
| VariableDeclaration
|
||||||
| FunctionCallExpression
|
|
||||||
| ReturnStatement
|
| ReturnStatement
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -233,6 +235,9 @@ Arguments : PrimaryExpression COMMA Arguments
|
||||||
AddNode(stack, $1);
|
AddNode(stack, $1);
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
|
{
|
||||||
|
PushStackFrame(stack);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
SignatureArguments : VariableDeclaration COMMA SignatureArguments
|
SignatureArguments : VariableDeclaration COMMA SignatureArguments
|
||||||
|
|
Loading…
Reference in New Issue