add static modifier

generics
cosmonaut 2021-04-22 00:35:42 -07:00
parent a75b7a0818
commit c2efcbd7d2
5 changed files with 111 additions and 36 deletions

36
ast.c
View File

@ -30,12 +30,14 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
case FunctionArgumentSequence: return "FunctionArgumentSequence"; case FunctionArgumentSequence: return "FunctionArgumentSequence";
case FunctionCallExpression: return "FunctionCallExpression"; case FunctionCallExpression: return "FunctionCallExpression";
case FunctionDeclaration: return "FunctionDeclaration"; case FunctionDeclaration: return "FunctionDeclaration";
case FunctionModifiers: return "FunctionModifiers";
case FunctionSignature: return "FunctionSignature"; case FunctionSignature: return "FunctionSignature";
case FunctionSignatureArguments: return "FunctionSignatureArguments"; case FunctionSignatureArguments: return "FunctionSignatureArguments";
case Identifier: return "Identifier"; case Identifier: return "Identifier";
case Number: return "Number"; case Number: return "Number";
case Return: return "Return"; case Return: return "Return";
case StatementSequence: return "StatementSequence"; case StatementSequence: return "StatementSequence";
case StaticModifier: return "StaticModifier";
case StringLiteral: return "StringLiteral"; case StringLiteral: return "StringLiteral";
case StructDeclaration: return "StructDeclaration"; case StructDeclaration: return "StructDeclaration";
case Type: return "Type"; case Type: return "Type";
@ -97,6 +99,34 @@ Node* MakeStringNode(
return node; 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( Node* MakeUnaryNode(
UnaryOperator operator, UnaryOperator operator,
Node *child Node *child
@ -208,15 +238,17 @@ Node *MakeFunctionSignatureArgumentsNode(
Node* MakeFunctionSignatureNode( Node* MakeFunctionSignatureNode(
Node *identifierNode, Node *identifierNode,
Node* typeNode, Node* typeNode,
Node* arguments Node* arguments,
Node* modifiersNode
) { ) {
Node* node = (Node*) malloc(sizeof(Node)); Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = FunctionSignature; node->syntaxKind = FunctionSignature;
node->childCount = 3; node->childCount = 4;
node->children = (Node**) malloc(sizeof(Node*) * (node->childCount)); node->children = (Node**) malloc(sizeof(Node*) * (node->childCount));
node->children[0] = identifierNode; node->children[0] = identifierNode;
node->children[1] = typeNode; node->children[1] = typeNode;
node->children[2] = arguments; node->children[2] = arguments;
node->children[3] = modifiersNode;
return node; return node;
} }

10
ast.h
View File

@ -16,6 +16,7 @@ typedef enum
FunctionArgumentSequence, FunctionArgumentSequence,
FunctionCallExpression, FunctionCallExpression,
FunctionDeclaration, FunctionDeclaration,
FunctionModifiers,
FunctionSignature, FunctionSignature,
FunctionSignatureArguments, FunctionSignatureArguments,
Identifier, Identifier,
@ -23,6 +24,7 @@ typedef enum
Return, Return,
ReturnVoid, ReturnVoid,
StatementSequence, StatementSequence,
StaticModifier,
StringLiteral, StringLiteral,
StructDeclaration, StructDeclaration,
Type, Type,
@ -95,6 +97,11 @@ Node* MakeNumberNode(
Node* MakeStringNode( Node* MakeStringNode(
const char *string const char *string
); );
Node* MakeStaticNode();
Node* MakeFunctionModifiersNode(
Node **pModifierNodes,
uint32_t modifierCount
);
Node* MakeUnaryNode( Node* MakeUnaryNode(
UnaryOperator operator, UnaryOperator operator,
Node *child Node *child
@ -127,7 +134,8 @@ Node* MakeFunctionSignatureArgumentsNode(
Node* MakeFunctionSignatureNode( Node* MakeFunctionSignatureNode(
Node *identifierNode, Node *identifierNode,
Node* typeNode, Node* typeNode,
Node* arguments Node* arguments,
Node* modifiersNode
); );
Node* MakeFunctionDeclarationNode( Node* MakeFunctionDeclarationNode(
Node* functionSignatureNode, Node* functionSignatureNode,

View File

@ -5,10 +5,12 @@
#include <llvm-c/Core.h> #include <llvm-c/Core.h>
#include <llvm-c/Analysis.h> #include <llvm-c/Analysis.h>
#include <llvm-c/BitWriter.h> #include <llvm-c/BitWriter.h>
#include <llvm-c/Object.h>
#include <llvm-c/Transforms/PassManagerBuilder.h> #include <llvm-c/Transforms/PassManagerBuilder.h>
#include <llvm-c/Transforms/InstCombine.h> #include <llvm-c/Transforms/InstCombine.h>
#include <llvm-c/Transforms/Scalar.h> #include <llvm-c/Transforms/Scalar.h>
#include <llvm-c/Transforms/Utils.h> #include <llvm-c/Transforms/Utils.h>
#include <llvm-c/TargetMachine.h>
#include "y.tab.h" #include "y.tab.h"
#include "ast.h" #include "ast.h"
@ -240,7 +242,6 @@ static void AddStructVariables(
} }
static LLVMValueRef CompileExpression( static LLVMValueRef CompileExpression(
LLVMValueRef wStructValue,
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef function, LLVMValueRef function,
Node *binaryExpression Node *binaryExpression
@ -306,13 +307,12 @@ static LLVMValueRef CompileNumber(
} }
static LLVMValueRef CompileBinaryExpression( static LLVMValueRef CompileBinaryExpression(
LLVMValueRef wStructValue,
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef function, LLVMValueRef function,
Node *binaryExpression Node *binaryExpression
) { ) {
LLVMValueRef left = CompileExpression(wStructValue, builder, function, binaryExpression->children[0]); LLVMValueRef left = CompileExpression(builder, function, binaryExpression->children[0]);
LLVMValueRef right = CompileExpression(wStructValue, builder, function, binaryExpression->children[1]); LLVMValueRef right = CompileExpression(builder, function, binaryExpression->children[1]);
switch (binaryExpression->operator.binaryOperator) switch (binaryExpression->operator.binaryOperator)
{ {
@ -332,7 +332,6 @@ static LLVMValueRef CompileBinaryExpression(
/* FIXME THIS IS ALL BROKEN */ /* FIXME THIS IS ALL BROKEN */
static LLVMValueRef CompileFunctionCallExpression( static LLVMValueRef CompileFunctionCallExpression(
LLVMValueRef wStructValue,
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef function, LLVMValueRef function,
Node *expression Node *expression
@ -343,7 +342,7 @@ static LLVMValueRef CompileFunctionCallExpression(
for (i = 0; i < argumentCount; i += 1) 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"); //return LLVMBuildCall(builder, FindVariableValueByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp");
@ -352,7 +351,6 @@ static LLVMValueRef CompileFunctionCallExpression(
static LLVMValueRef CompileAccessExpressionForStore( static LLVMValueRef CompileAccessExpressionForStore(
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef wStructValue,
LLVMValueRef function, LLVMValueRef function,
Node *expression Node *expression
) { ) {
@ -364,7 +362,6 @@ static LLVMValueRef CompileAccessExpressionForStore(
static LLVMValueRef CompileAccessExpression( static LLVMValueRef CompileAccessExpression(
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef wStructValue,
LLVMValueRef function, LLVMValueRef function,
Node *expression Node *expression
) { ) {
@ -376,7 +373,6 @@ static LLVMValueRef CompileAccessExpression(
} }
static LLVMValueRef CompileExpression( static LLVMValueRef CompileExpression(
LLVMValueRef wStructValue,
LLVMBuilderRef builder, LLVMBuilderRef builder,
LLVMValueRef function, LLVMValueRef function,
Node *expression Node *expression
@ -384,13 +380,13 @@ static LLVMValueRef CompileExpression(
switch (expression->syntaxKind) switch (expression->syntaxKind)
{ {
case AccessExpression: case AccessExpression:
return CompileAccessExpression(builder, wStructValue, function, expression); return CompileAccessExpression(builder, function, expression);
case BinaryExpression: case BinaryExpression:
return CompileBinaryExpression(wStructValue, builder, function, expression); return CompileBinaryExpression(builder, function, expression);
case FunctionCallExpression: case FunctionCallExpression:
return CompileFunctionCallExpression(wStructValue, builder, function, expression); return CompileFunctionCallExpression(builder, function, expression);
case Identifier: case Identifier:
return FindVariableValue(builder, expression->value.string); return FindVariableValue(builder, expression->value.string);
@ -403,10 +399,9 @@ static LLVMValueRef CompileExpression(
return NULL; return NULL;
} }
/* FIXME: we need a scope structure */ static void CompileReturn(LLVMBuilderRef builder, LLVMValueRef function, Node *returnStatemement)
static void CompileReturn(LLVMValueRef wStructValue, 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); LLVMBuildRet(builder, expression);
} }
@ -415,13 +410,13 @@ static void CompileReturnVoid(LLVMBuilderRef builder)
LLVMBuildRetVoid(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; LLVMValueRef identifier;
if (assignmentStatement->children[0]->syntaxKind == AccessExpression) 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) else if (assignmentStatement->children[0]->syntaxKind == Identifier)
{ {
@ -458,12 +453,12 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var
AddLocalVariable(scope, variable, variableName); 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) switch (statement->syntaxKind)
{ {
case Assignment: case Assignment:
CompileAssignment(wStructValue, builder, function, statement); CompileAssignment(builder, function, statement);
return 0; return 0;
case Declaration: case Declaration:
@ -471,7 +466,7 @@ static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builde
return 0; return 0;
case Return: case Return:
CompileReturn(wStructValue, builder, function, statement); CompileReturn(builder, function, statement);
return 1; return 1;
case ReturnVoid: case ReturnVoid:
@ -492,31 +487,52 @@ static void CompileFunction(
) { ) {
uint32_t i; uint32_t i;
uint8_t hasReturn = 0; uint8_t hasReturn = 0;
uint8_t isStatic = 0;
Node *functionSignature = functionDeclaration->children[0]; Node *functionSignature = functionDeclaration->children[0];
Node *functionBody = functionDeclaration->children[1]; Node *functionBody = functionDeclaration->children[1];
uint32_t argumentCount = functionSignature->children[2]->childCount + 1; /* struct is implicit argument */ uint32_t argumentCount = functionSignature->children[2]->childCount;
LLVMTypeRef paramTypes[argumentCount]; 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); PushScopeFrame(scope);
paramTypes[0] = wStructPointerType;
for (i = 0; i < functionSignature->children[2]->childCount; i += 1) 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 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); LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry); LLVMPositionBuilderAtEnd(builder, entry);
if (!isStatic)
{
LLVMValueRef wStructPointer = LLVMGetParam(function, 0); LLVMValueRef wStructPointer = LLVMGetParam(function, 0);
AddStructVariables(builder, wStructPointer); AddStructVariables(builder, wStructPointer);
}
for (i = 0; i < functionSignature->children[2]->childCount; i += 1) 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) 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) if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn)
@ -645,7 +661,8 @@ int main(int argc, char *argv[])
char *error = NULL; char *error = NULL;
LLVMVerifyModule(module, LLVMAbortProcessAction, &error); LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE);
LLVMPassManagerRef passManager = LLVMCreatePassManager(); LLVMPassManagerRef passManager = LLVMCreatePassManager();
LLVMAddInstructionCombiningPass(passManager); LLVMAddInstructionCombiningPass(passManager);
@ -663,6 +680,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "error writing bitcode to file\n"); fprintf(stderr, "error writing bitcode to file\n");
} }
LLVMMemoryBufferRef memoryBuffer = LLVMWriteBitcodeToMemoryBuffer(module);
LLVMCreateBinary(memoryBuffer, context, &error);
LLVMDisposeMessage(error);
LLVMDisposeMemoryBuffer(memoryBuffer);
LLVMPassManagerBuilderDispose(passManagerBuilder); LLVMPassManagerBuilderDispose(passManagerBuilder);
LLVMDisposePassManager(passManager); LLVMDisposePassManager(passManager);
LLVMDisposeModule(module); LLVMDisposeModule(module);

View File

@ -14,6 +14,7 @@
"bool" return BOOL; "bool" return BOOL;
"struct" return STRUCT; "struct" return STRUCT;
"return" return RETURN; "return" return RETURN;
"static" return STATIC;
[0-9]+ return NUMBER; [0-9]+ return NUMBER;
[a-zA-Z][a-zA-Z0-9]* return ID; [a-zA-Z][a-zA-Z0-9]* return ID;
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL; \"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL;

View File

@ -30,6 +30,7 @@ extern Node *rootNode;
%token BOOL %token BOOL
%token STRUCT %token STRUCT
%token RETURN %token RETURN
%token STATIC
%token NUMBER %token NUMBER
%token ID %token ID
%token STRING_LITERAL %token STRING_LITERAL
@ -265,7 +266,18 @@ FunctionSignature : Type Identifier LEFT_PAREN SignatureArguments RIGHT_PA
uint32_t declarationCount; uint32_t declarationCount;
declarations = GetNodes(stack, &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); PopStackFrame(stack);
} }