forked from cosmonaut/wraith-lang
add static modifier
parent
a75b7a0818
commit
c2efcbd7d2
36
ast.c
36
ast.c
|
@ -30,12 +30,14 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
|
|||
case FunctionArgumentSequence: return "FunctionArgumentSequence";
|
||||
case FunctionCallExpression: return "FunctionCallExpression";
|
||||
case FunctionDeclaration: return "FunctionDeclaration";
|
||||
case FunctionModifiers: return "FunctionModifiers";
|
||||
case FunctionSignature: return "FunctionSignature";
|
||||
case FunctionSignatureArguments: return "FunctionSignatureArguments";
|
||||
case Identifier: return "Identifier";
|
||||
case Number: return "Number";
|
||||
case Return: return "Return";
|
||||
case StatementSequence: return "StatementSequence";
|
||||
case StaticModifier: return "StaticModifier";
|
||||
case StringLiteral: return "StringLiteral";
|
||||
case StructDeclaration: return "StructDeclaration";
|
||||
case Type: return "Type";
|
||||
|
@ -97,6 +99,34 @@ Node* MakeStringNode(
|
|||
return node;
|
||||
}
|
||||
|
||||
Node* MakeStaticNode()
|
||||
{
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = StaticModifier;
|
||||
node->childCount = 0;
|
||||
return node;
|
||||
}
|
||||
|
||||
Node* MakeFunctionModifiersNode(
|
||||
Node **pModifierNodes,
|
||||
uint32_t modifierCount
|
||||
) {
|
||||
uint32_t i;
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = FunctionModifiers;
|
||||
node->childCount = modifierCount;
|
||||
if (modifierCount > 0)
|
||||
{
|
||||
node->children = malloc(sizeof(Node*) * node->childCount);
|
||||
for (i = 0; i < modifierCount; i += 1)
|
||||
{
|
||||
node->children[i] = pModifierNodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
Node* MakeUnaryNode(
|
||||
UnaryOperator operator,
|
||||
Node *child
|
||||
|
@ -208,15 +238,17 @@ Node *MakeFunctionSignatureArgumentsNode(
|
|||
Node* MakeFunctionSignatureNode(
|
||||
Node *identifierNode,
|
||||
Node* typeNode,
|
||||
Node* arguments
|
||||
Node* arguments,
|
||||
Node* modifiersNode
|
||||
) {
|
||||
Node* node = (Node*) malloc(sizeof(Node));
|
||||
node->syntaxKind = FunctionSignature;
|
||||
node->childCount = 3;
|
||||
node->childCount = 4;
|
||||
node->children = (Node**) malloc(sizeof(Node*) * (node->childCount));
|
||||
node->children[0] = identifierNode;
|
||||
node->children[1] = typeNode;
|
||||
node->children[2] = arguments;
|
||||
node->children[3] = modifiersNode;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
|
10
ast.h
10
ast.h
|
@ -16,6 +16,7 @@ typedef enum
|
|||
FunctionArgumentSequence,
|
||||
FunctionCallExpression,
|
||||
FunctionDeclaration,
|
||||
FunctionModifiers,
|
||||
FunctionSignature,
|
||||
FunctionSignatureArguments,
|
||||
Identifier,
|
||||
|
@ -23,6 +24,7 @@ typedef enum
|
|||
Return,
|
||||
ReturnVoid,
|
||||
StatementSequence,
|
||||
StaticModifier,
|
||||
StringLiteral,
|
||||
StructDeclaration,
|
||||
Type,
|
||||
|
@ -95,6 +97,11 @@ Node* MakeNumberNode(
|
|||
Node* MakeStringNode(
|
||||
const char *string
|
||||
);
|
||||
Node* MakeStaticNode();
|
||||
Node* MakeFunctionModifiersNode(
|
||||
Node **pModifierNodes,
|
||||
uint32_t modifierCount
|
||||
);
|
||||
Node* MakeUnaryNode(
|
||||
UnaryOperator operator,
|
||||
Node *child
|
||||
|
@ -127,7 +134,8 @@ Node* MakeFunctionSignatureArgumentsNode(
|
|||
Node* MakeFunctionSignatureNode(
|
||||
Node *identifierNode,
|
||||
Node* typeNode,
|
||||
Node* arguments
|
||||
Node* arguments,
|
||||
Node* modifiersNode
|
||||
);
|
||||
Node* MakeFunctionDeclarationNode(
|
||||
Node* functionSignatureNode,
|
||||
|
|
82
compiler.c
82
compiler.c
|
@ -5,10 +5,12 @@
|
|||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/BitWriter.h>
|
||||
#include <llvm-c/Object.h>
|
||||
#include <llvm-c/Transforms/PassManagerBuilder.h>
|
||||
#include <llvm-c/Transforms/InstCombine.h>
|
||||
#include <llvm-c/Transforms/Scalar.h>
|
||||
#include <llvm-c/Transforms/Utils.h>
|
||||
#include <llvm-c/TargetMachine.h>
|
||||
|
||||
#include "y.tab.h"
|
||||
#include "ast.h"
|
||||
|
@ -240,7 +242,6 @@ static void AddStructVariables(
|
|||
}
|
||||
|
||||
static LLVMValueRef CompileExpression(
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef function,
|
||||
Node *binaryExpression
|
||||
|
@ -306,13 +307,12 @@ static LLVMValueRef CompileNumber(
|
|||
}
|
||||
|
||||
static LLVMValueRef CompileBinaryExpression(
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef function,
|
||||
Node *binaryExpression
|
||||
) {
|
||||
LLVMValueRef left = CompileExpression(wStructValue, builder, function, binaryExpression->children[0]);
|
||||
LLVMValueRef right = CompileExpression(wStructValue, builder, function, binaryExpression->children[1]);
|
||||
LLVMValueRef left = CompileExpression(builder, function, binaryExpression->children[0]);
|
||||
LLVMValueRef right = CompileExpression(builder, function, binaryExpression->children[1]);
|
||||
|
||||
switch (binaryExpression->operator.binaryOperator)
|
||||
{
|
||||
|
@ -332,7 +332,6 @@ static LLVMValueRef CompileBinaryExpression(
|
|||
|
||||
/* FIXME THIS IS ALL BROKEN */
|
||||
static LLVMValueRef CompileFunctionCallExpression(
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef function,
|
||||
Node *expression
|
||||
|
@ -343,7 +342,7 @@ static LLVMValueRef CompileFunctionCallExpression(
|
|||
|
||||
for (i = 0; i < argumentCount; i += 1)
|
||||
{
|
||||
args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]);
|
||||
args[i] = CompileExpression(builder, function, expression->children[1]->children[i]);
|
||||
}
|
||||
|
||||
//return LLVMBuildCall(builder, FindVariableValueByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
|
||||
|
@ -352,7 +351,6 @@ static LLVMValueRef CompileFunctionCallExpression(
|
|||
|
||||
static LLVMValueRef CompileAccessExpressionForStore(
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMValueRef function,
|
||||
Node *expression
|
||||
) {
|
||||
|
@ -364,7 +362,6 @@ static LLVMValueRef CompileAccessExpressionForStore(
|
|||
|
||||
static LLVMValueRef CompileAccessExpression(
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMValueRef function,
|
||||
Node *expression
|
||||
) {
|
||||
|
@ -376,7 +373,6 @@ static LLVMValueRef CompileAccessExpression(
|
|||
}
|
||||
|
||||
static LLVMValueRef CompileExpression(
|
||||
LLVMValueRef wStructValue,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef function,
|
||||
Node *expression
|
||||
|
@ -384,13 +380,13 @@ static LLVMValueRef CompileExpression(
|
|||
switch (expression->syntaxKind)
|
||||
{
|
||||
case AccessExpression:
|
||||
return CompileAccessExpression(builder, wStructValue, function, expression);
|
||||
return CompileAccessExpression(builder, function, expression);
|
||||
|
||||
case BinaryExpression:
|
||||
return CompileBinaryExpression(wStructValue, builder, function, expression);
|
||||
return CompileBinaryExpression(builder, function, expression);
|
||||
|
||||
case FunctionCallExpression:
|
||||
return CompileFunctionCallExpression(wStructValue, builder, function, expression);
|
||||
return CompileFunctionCallExpression(builder, function, expression);
|
||||
|
||||
case Identifier:
|
||||
return FindVariableValue(builder, expression->value.string);
|
||||
|
@ -403,10 +399,9 @@ static LLVMValueRef CompileExpression(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: we need a scope structure */
|
||||
static void CompileReturn(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
|
||||
static void CompileReturn(LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
|
||||
{
|
||||
LLVMValueRef expression = CompileExpression(wStructValue, builder, function, returnStatemement->children[0]);
|
||||
LLVMValueRef expression = CompileExpression(builder, function, returnStatemement->children[0]);
|
||||
LLVMBuildRet(builder, expression);
|
||||
}
|
||||
|
||||
|
@ -415,13 +410,13 @@ static void CompileReturnVoid(LLVMBuilderRef builder)
|
|||
LLVMBuildRetVoid(builder);
|
||||
}
|
||||
|
||||
static void CompileAssignment(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *assignmentStatement)
|
||||
static void CompileAssignment(LLVMBuilderRef builder, LLVMValueRef function, Node *assignmentStatement)
|
||||
{
|
||||
LLVMValueRef result = CompileExpression(wStructValue, builder, function, assignmentStatement->children[1]);
|
||||
LLVMValueRef result = CompileExpression(builder, function, assignmentStatement->children[1]);
|
||||
LLVMValueRef identifier;
|
||||
if (assignmentStatement->children[0]->syntaxKind == AccessExpression)
|
||||
{
|
||||
identifier = CompileAccessExpressionForStore(builder, wStructValue, function, assignmentStatement->children[0]);
|
||||
identifier = CompileAccessExpressionForStore(builder, function, assignmentStatement->children[0]);
|
||||
}
|
||||
else if (assignmentStatement->children[0]->syntaxKind == Identifier)
|
||||
{
|
||||
|
@ -458,12 +453,12 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var
|
|||
AddLocalVariable(scope, variable, variableName);
|
||||
}
|
||||
|
||||
static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
|
||||
static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, Node *statement)
|
||||
{
|
||||
switch (statement->syntaxKind)
|
||||
{
|
||||
case Assignment:
|
||||
CompileAssignment(wStructValue, builder, function, statement);
|
||||
CompileAssignment(builder, function, statement);
|
||||
return 0;
|
||||
|
||||
case Declaration:
|
||||
|
@ -471,7 +466,7 @@ static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builde
|
|||
return 0;
|
||||
|
||||
case Return:
|
||||
CompileReturn(wStructValue, builder, function, statement);
|
||||
CompileReturn(builder, function, statement);
|
||||
return 1;
|
||||
|
||||
case ReturnVoid:
|
||||
|
@ -492,31 +487,52 @@ static void CompileFunction(
|
|||
) {
|
||||
uint32_t i;
|
||||
uint8_t hasReturn = 0;
|
||||
uint8_t isStatic = 0;
|
||||
Node *functionSignature = functionDeclaration->children[0];
|
||||
Node *functionBody = functionDeclaration->children[1];
|
||||
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */
|
||||
LLVMTypeRef paramTypes[argumentCount];
|
||||
uint32_t argumentCount = functionSignature->children[2]->childCount;
|
||||
LLVMTypeRef paramTypes[argumentCount + 1];
|
||||
uint32_t paramIndex = 0;
|
||||
|
||||
if (functionSignature->children[3]->childCount > 0)
|
||||
{
|
||||
for (i = 0; i < functionSignature->children[3]->childCount; i += 1)
|
||||
{
|
||||
if (functionSignature->children[3]->children[i]->syntaxKind == StaticModifier)
|
||||
{
|
||||
isStatic = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStatic)
|
||||
{
|
||||
paramTypes[paramIndex] = wStructPointerType;
|
||||
paramIndex += 1;
|
||||
}
|
||||
|
||||
PushScopeFrame(scope);
|
||||
|
||||
paramTypes[0] = wStructPointerType;
|
||||
|
||||
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
||||
{
|
||||
paramTypes[i + 1] = WraithTypeToLLVMType(functionSignature->children[2]->children[i]->children[0]->type);
|
||||
paramTypes[paramIndex] = WraithTypeToLLVMType(functionSignature->children[2]->children[i]->children[0]->type);
|
||||
paramIndex += 1;
|
||||
}
|
||||
|
||||
LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type);
|
||||
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, argumentCount, 0);
|
||||
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0);
|
||||
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
|
||||
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
|
||||
if (!isStatic)
|
||||
{
|
||||
LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
|
||||
|
||||
AddStructVariables(builder, wStructPointer);
|
||||
}
|
||||
|
||||
for (i = 0; i < functionSignature->children[2]->childCount; i += 1)
|
||||
{
|
||||
|
@ -531,7 +547,7 @@ static void CompileFunction(
|
|||
|
||||
for (i = 0; i < functionBody->childCount; i += 1)
|
||||
{
|
||||
hasReturn |= CompileStatement(wStructPointer, builder, function, functionBody->children[i]);
|
||||
hasReturn |= CompileStatement(builder, function, functionBody->children[i]);
|
||||
}
|
||||
|
||||
if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
|
||||
|
@ -645,7 +661,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
char *error = NULL;
|
||||
LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE);
|
||||
|
||||
LLVMPassManagerRef passManager = LLVMCreatePassManager();
|
||||
LLVMAddInstructionCombiningPass(passManager);
|
||||
|
@ -663,6 +680,11 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "error writing bitcode to file\n");
|
||||
}
|
||||
|
||||
LLVMMemoryBufferRef memoryBuffer = LLVMWriteBitcodeToMemoryBuffer(module);
|
||||
LLVMCreateBinary(memoryBuffer, context, &error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeMemoryBuffer(memoryBuffer);
|
||||
|
||||
LLVMPassManagerBuilderDispose(passManagerBuilder);
|
||||
LLVMDisposePassManager(passManager);
|
||||
LLVMDisposeModule(module);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"bool" return BOOL;
|
||||
"struct" return STRUCT;
|
||||
"return" return RETURN;
|
||||
"static" return STATIC;
|
||||
[0-9]+ return NUMBER;
|
||||
[a-zA-Z][a-zA-Z0-9]* return ID;
|
||||
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL;
|
||||
|
|
14
wraith.y
14
wraith.y
|
@ -30,6 +30,7 @@ extern Node *rootNode;
|
|||
%token BOOL
|
||||
%token STRUCT
|
||||
%token RETURN
|
||||
%token STATIC
|
||||
%token NUMBER
|
||||
%token ID
|
||||
%token STRING_LITERAL
|
||||
|
@ -265,7 +266,18 @@ FunctionSignature : Type Identifier LEFT_PAREN SignatureArguments RIGHT_PA
|
|||
uint32_t declarationCount;
|
||||
|
||||
declarations = GetNodes(stack, &declarationCount);
|
||||
$$ = MakeFunctionSignatureNode($2, $1, MakeFunctionSignatureArgumentsNode(declarations, declarationCount));
|
||||
$$ = MakeFunctionSignatureNode($2, $1, MakeFunctionSignatureArgumentsNode(declarations, declarationCount), MakeFunctionModifiersNode(NULL, 0));
|
||||
|
||||
PopStackFrame(stack);
|
||||
}
|
||||
| STATIC Type Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN
|
||||
{
|
||||
Node **declarations;
|
||||
uint32_t declarationCount;
|
||||
Node *modifier = MakeStaticNode();
|
||||
|
||||
declarations = GetNodes(stack, &declarationCount);
|
||||
$$ = MakeFunctionSignatureNode($3, $2, MakeFunctionSignatureArgumentsNode(declarations, declarationCount), MakeFunctionModifiersNode(&modifier, 1));
|
||||
|
||||
PopStackFrame(stack);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue