From e3fd821d8fc840d3c1c87df068fec9fcec8e3826 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 20 Apr 2021 23:51:26 -0700 Subject: [PATCH] add custom types and local allocation --- ast.c | 13 ++++++++++++ ast.h | 6 +++++- compiler.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ stack.c | 12 +++++++++-- stack.h | 4 ++-- wraith.y | 4 ++++ 6 files changed, 92 insertions(+), 5 deletions(-) diff --git a/ast.c b/ast.c index daafae9..f968623 100644 --- a/ast.c +++ b/ast.c @@ -53,6 +53,18 @@ Node* MakeTypeNode( return node; } +Node* MakeCustomTypeNode( + Node *identifierNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Type; + node->type = CustomType; + node->childCount = 1; + node->children = (Node**) malloc(sizeof(Node*)); + node->children[0] = identifierNode; + return node; +} + Node* MakeIdentifierNode( const char *id ) { @@ -288,6 +300,7 @@ static const char* PrimitiveTypeToString(PrimitiveType type) case UInt: return "UInt"; case Bool: return "Bool"; case Void: return "Void"; + case CustomType: return "CustomType"; } return "Unknown"; diff --git a/ast.h b/ast.h index a8c80bd..d96cf74 100644 --- a/ast.h +++ b/ast.h @@ -48,7 +48,8 @@ typedef enum UInt, Float, Double, - String + String, + CustomType } PrimitiveType; typedef union @@ -81,6 +82,9 @@ const char* SyntaxKindString(SyntaxKind syntaxKind); Node* MakeTypeNode( PrimitiveType type ); +Node* MakeCustomTypeNode( + Node *identifierNode +); Node* MakeIdentifierNode( const char *id ); diff --git a/compiler.c b/compiler.c index 8738413..d68cde3 100644 --- a/compiler.c +++ b/compiler.c @@ -228,6 +228,38 @@ static LLVMValueRef FindVariableByName(LLVMBuilderRef builder, LLVMValueRef wStr return searchResult; } +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; +} + static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) { switch (type) @@ -344,6 +376,23 @@ static void CompileAssignment(LLVMValueRef wStructValue, LLVMBuilderRef builder, MarkStructFieldForWrite(wStructValue, identifier); } +static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration) +{ + char *variableName = variableDeclaration->children[1]->value.string; + LLVMValueRef variable; + if (variableDeclaration->children[0]->type == CustomType) + { + char *customTypeName = variableDeclaration->children[0]->children[0]->value.string; + variable = LLVMBuildAlloca(builder, LookupCustomType(customTypeName), variableName); + } + else + { + variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), variableName); + } + + AddNamedVariable(variableName, variable); +} + static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builder, LLVMValueRef function, Node *statement) { switch (statement->syntaxKind) @@ -352,6 +401,10 @@ static uint8_t CompileStatement(LLVMValueRef wStructValue, LLVMBuilderRef builde CompileAssignment(wStructValue, builder, function, statement); return 0; + case Declaration: + CompileFunctionVariableDeclaration(builder, statement); + return 0; + case Return: CompileReturn(wStructValue, builder, function, statement); return 1; @@ -470,6 +523,8 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no break; } } + + RegisterCustomType(wStruct, node->children[0]->value.string); } static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node) @@ -503,6 +558,9 @@ int main(int argc, char *argv[]) structFieldMaps = NULL; structFieldMapCount = 0; + customTypes = NULL; + customTypeCount = 0; + stack = CreateStack(); FILE *fp = fopen(argv[1], "r"); diff --git a/stack.c b/stack.c index 1fe7fe0..43c48ab 100644 --- a/stack.c +++ b/stack.c @@ -4,7 +4,7 @@ Stack* CreateStack() { - uint32_t i; + int32_t i; Stack *stack = (Stack*) malloc(sizeof(Stack)); stack->stackCapacity = 4; stack->stackFrames = (StackFrame*) malloc(sizeof(StackFrame) * stack->stackCapacity); @@ -15,6 +15,8 @@ Stack* CreateStack() stack->stackFrames[i].nodeCount = 0; } stack->stackIndex = 0; + + PushStackFrame(stack); return stack; } @@ -26,8 +28,9 @@ void PushStackFrame(Stack *stack) { stack->stackCapacity += 1; stack->stackFrames = (StackFrame*) realloc(stack->stackFrames, sizeof(StackFrame) * stack->stackCapacity); - + stack->stackFrames[stack->stackIndex].nodes = NULL; stack->stackFrames[stack->stackIndex].nodeCapacity = 0; + stack->stackFrames[stack->stackIndex].nodeCount = 0; } stack->stackFrames[stack->stackIndex].nodeCount = 0; @@ -52,6 +55,11 @@ void AddNode(Stack *stack, Node *statementNode) Node** GetNodes(Stack *stack, uint32_t *pCount) { + if (stack->stackIndex < 0) { + *pCount= 0; + return NULL; + } + *pCount = stack->stackFrames[stack->stackIndex].nodeCount; return stack->stackFrames[stack->stackIndex].nodes; } diff --git a/stack.h b/stack.h index 09c8892..549e72e 100644 --- a/stack.h +++ b/stack.h @@ -13,8 +13,8 @@ typedef struct StackFrame typedef struct Stack { StackFrame *stackFrames; - uint32_t stackCapacity; - uint32_t stackIndex; + int32_t stackCapacity; + int32_t stackIndex; } Stack; Stack* CreateStack(); diff --git a/wraith.y b/wraith.y index 96a53f9..d2a0b17 100644 --- a/wraith.y +++ b/wraith.y @@ -158,6 +158,10 @@ VariableDeclaration : Type Identifier { $$ = MakeDeclarationNode($1, $2); } + | Identifier Identifier + { + $$ = MakeDeclarationNode(MakeCustomTypeNode($1), $2); + } AssignmentStatement : VariableDeclaration EQUAL Expression {