diff --git a/CMakeLists.txt b/CMakeLists.txt index 26ee1cc..f1a1640 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(CMAKE_C_STANDARD 99) find_package(BISON) find_package(FLEX) +find_package(LLVM) include_directories(${CMAKE_SOURCE_DIR}) @@ -14,8 +15,14 @@ FLEX_TARGET(Scanner wraith.lex ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) ADD_FLEX_BISON_DEPENDENCY(Scanner Parser) include_directories(${CMAKE_CURRENT_BINARY_DIR}) + add_executable( wraith_compile + ast.c + stack.c ${BISON_Parser_OUTPUTS} ${FLEX_Scanner_OUTPUTS} + compiler.c ) + +target_link_libraries(wraith_compile PUBLIC LLVM) diff --git a/ast.c b/ast.c new file mode 100644 index 0000000..6468cb6 --- /dev/null +++ b/ast.c @@ -0,0 +1,293 @@ +#include "ast.h" + +#include +#include +#include + +char* strdup (const char* s) +{ + size_t slen = strlen(s); + char* result = malloc(slen + 1); + if(result == NULL) + { + return NULL; + } + + memcpy(result, s, slen+1); + return result; +} + +const char* SyntaxKindString(SyntaxKind syntaxKind) +{ + switch(syntaxKind) + { + case Assignment: return "Assignment"; + case BinaryExpression: return "BinaryExpression"; + case Comment: return "Comment"; + case Declaration: return "Declaration"; + case DeclarationSequence: return "DeclarationSequence"; + case FunctionDeclaration: return "FunctionDeclaration"; + case FunctionSignature: return "FunctionSignature"; + case Identifier: return "Identifier"; + case Number: return "Number"; + case Return: return "Return"; + case StatementSequence: return "StatementSequence"; + case StringLiteral: return "StringLiteral"; + case StructDeclaration: return "StructDeclaration"; + case Type: return "Type"; + case UnaryExpression: return "UnaryExpression"; + default: return "Unknown"; + } +} + +Node* MakeTypeNode( + PrimitiveType type +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Type; + node->type = type; + node->childCount = 0; + return node; +} + +Node* MakeIdentifierNode( + const char *id +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Identifier; + node->value.string = strdup(id); + node->childCount = 0; + return node; +} + +Node* MakeNumberNode( + const char *numberString +) { + char *ptr; + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Number; + node->value.number = strtoul(numberString, &ptr, 10); + node->childCount = 0; + return node; +} + +Node* MakeStringNode( + const char *string +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = StringLiteral; + node->value.string = strdup(string); + node->childCount = 0; + return node; +} + +Node* MakeUnaryNode( + UnaryOperator operator, + Node *child +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = UnaryExpression; + node->operator.unaryOperator = operator; + node->children = malloc(sizeof(Node*)); + node->children[0] = child; + node->childCount = 1; + return node; +} + +Node* MakeBinaryNode( + BinaryOperator operator, + Node *left, + Node *right +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = BinaryExpression; + node->operator.binaryOperator = operator; + node->children = malloc(sizeof(Node*) * 2); + node->children[0] = left; + node->children[1] = right; + node->childCount = 2; + return node; +} + +Node* MakeDeclarationNode( + Node* typeNode, + Node* identifierNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Declaration; + node->children = (Node**) malloc(sizeof(Node*) * 2); + node->childCount = 2; + node->children[0] = typeNode; + node->children[1] = identifierNode; + return node; +} + +Node* MakeAssignmentNode( + Node *left, + Node *right +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Assignment; + node->childCount = 2; + node->children = malloc(sizeof(Node*) * 2); + node->children[0] = left; + node->children[1] = right; + return node; +} + +Node* MakeStatementSequenceNode( + Node** pNodes, + uint32_t nodeCount +) { + int32_t i; + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = StatementSequence; + node->children = (Node**) malloc(sizeof(Node*) * nodeCount); + node->childCount = nodeCount; + for (i = nodeCount - 1; i >= 0; i -= 1) + { + node->children[nodeCount - 1 - i] = pNodes[i]; + } + return node; +} + +Node* MakeReturnStatementNode( + Node *expressionNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = Return; + node->children = (Node**) malloc(sizeof(Node*)); + node->childCount = 1; + node->children[0] = expressionNode; + return node; +} + +Node* MakeFunctionSignatureNode( + Node *identifierNode, + Node* typeNode, + Node* arguments +) { + uint32_t i; + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = FunctionSignature; + node->childCount = 3; + node->children = (Node**) malloc(sizeof(Node*) * (node->childCount)); + node->children[0] = identifierNode; + node->children[1] = typeNode; + node->children[2] = arguments; + return node; +} + +Node* MakeFunctionDeclarationNode( + Node* functionSignatureNode, + Node* functionBodyNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = FunctionDeclaration; + node->childCount = 2; + node->children = (Node**) malloc(sizeof(Node*) * 2); + node->children[0] = functionSignatureNode; + node->children[1] = functionBodyNode; + return node; +} + +Node* MakeStructDeclarationNode( + Node *identifierNode, + Node *declarationSequenceNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = StructDeclaration; + node->childCount = 2; + node->children = (Node**) malloc(sizeof(Node*) * 2); + node->children[0] = identifierNode; + node->children[1] = declarationSequenceNode; + return node; +} + +Node* MakeDeclarationSequenceNode( + Node **pNodes, + uint32_t nodeCount +) { + int32_t i; + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = DeclarationSequence; + node->children = (Node**) malloc(sizeof(Node*) * nodeCount); + node->childCount = nodeCount; + for (i = nodeCount - 1; i >= 0; i -= 1) + { + node->children[nodeCount - 1 - i] = pNodes[i]; + } + return node; +} + +static const char* PrimitiveTypeToString(PrimitiveType type) +{ + switch (type) + { + case Int: return "Int"; + case UInt: return "UInt"; + case Bool: return "Bool"; + } + + return "Unknown"; +} + +static void PrintBinaryOperator(BinaryOperator expression) +{ + switch (expression) + { + case Add: + printf("+"); + break; + + case Subtract: + printf("-"); + break; + } +} + +static void PrintNode(Node *node, int tabCount) +{ + uint32_t i; + for (i = 0; i < tabCount; i += 1) + { + printf(" "); + } + + printf("%s: ", SyntaxKindString(node->syntaxKind)); + switch (node->syntaxKind) + { + case BinaryExpression: + PrintBinaryOperator(node->operator.binaryOperator); + break; + + case Declaration: + break; + + case Type: + printf("%s", PrimitiveTypeToString(node->type)); + break; + + case Identifier: + printf("%s", node->value.string); + break; + + case Number: + printf("%lu", node->value.number); + break; + } + + printf("\n"); +} + +void PrintTree(Node *node, uint32_t tabCount) +{ + uint32_t i; + PrintNode(node, tabCount); + for (i = 0; i < node->childCount; i += 1) + { + PrintTree(node->children[i], tabCount + 1); + } +} + + diff --git a/ast.h b/ast.h index d0fbbb4..b98e77e 100644 --- a/ast.h +++ b/ast.h @@ -2,9 +2,6 @@ #define WRAITH_AST_H #include -#include -#include -#include typedef enum { @@ -72,290 +69,63 @@ typedef struct Node PrimitiveType type; } Node; -char* strdup (const char* s) -{ - size_t slen = strlen(s); - char* result = malloc(slen + 1); - if(result == NULL) - { - return NULL; - } - - memcpy(result, s, slen+1); - return result; -} - -const char* SyntaxKindString(SyntaxKind syntaxKind) -{ - switch(syntaxKind) - { - case Assignment: return "Assignment"; - case BinaryExpression: return "BinaryExpression"; - case Comment: return "Comment"; - case Declaration: return "Declaration"; - case DeclarationSequence: return "DeclarationSequence"; - case FunctionDeclaration: return "FunctionDeclaration"; - case FunctionSignature: return "FunctionSignature"; - case Identifier: return "Identifier"; - case Number: return "Number"; - case Return: return "Return"; - case StatementSequence: return "StatementSequence"; - case StringLiteral: return "StringLiteral"; - case StructDeclaration: return "StructDeclaration"; - case Type: return "Type"; - case UnaryExpression: return "UnaryExpression"; - default: return "Unknown"; - } -} +char* strdup (const char* s); +const char* SyntaxKindString(SyntaxKind syntaxKind); Node* MakeTypeNode( PrimitiveType type -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Type; - node->type = type; - node->childCount = 0; - return node; -} - +); Node* MakeIdentifierNode( const char *id -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Identifier; - node->value.string = strdup(id); - node->childCount = 0; - return node; -} - +); Node* MakeNumberNode( const char *numberString -) { - char *ptr; - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Number; - node->value.number = strtoul(numberString, &ptr, 10); - node->childCount = 0; - return node; -} - +); Node* MakeStringNode( const char *string -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = StringLiteral; - node->value.string = strdup(string); - node->childCount = 0; - return node; -} - +); Node* MakeUnaryNode( UnaryOperator operator, Node *child -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = UnaryExpression; - node->operator.unaryOperator = operator; - node->children = malloc(sizeof(Node*)); - node->children[0] = child; - node->childCount = 1; - return node; -} - +); Node* MakeBinaryNode( BinaryOperator operator, Node *left, Node *right -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = BinaryExpression; - node->operator.binaryOperator = operator; - node->children = malloc(sizeof(Node*) * 2); - node->children[0] = left; - node->children[1] = right; - node->childCount = 2; - return node; -} - +); Node* MakeDeclarationNode( Node* typeNode, Node* identifierNode -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Declaration; - node->children = (Node**) malloc(sizeof(Node*) * 2); - node->childCount = 2; - node->children[0] = typeNode; - node->children[1] = identifierNode; - return node; -} - +); Node* MakeAssignmentNode( Node *left, Node *right -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Assignment; - node->childCount = 2; - node->children = malloc(sizeof(Node*) * 2); - node->children[0] = left; - node->children[1] = right; - return node; -} - +); Node* MakeStatementSequenceNode( Node** pNodes, uint32_t nodeCount -) { - int32_t i; - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = StatementSequence; - node->children = (Node**) malloc(sizeof(Node*) * nodeCount); - node->childCount = nodeCount; - for (i = nodeCount - 1; i >= 0; i -= 1) - { - node->children[nodeCount - 1 - i] = pNodes[i]; - } - return node; -} - +); Node* MakeReturnStatementNode( Node *expressionNode -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Return; - node->children = (Node**) malloc(sizeof(Node*)); - node->childCount = 1; - node->children[0] = expressionNode; - return node; -} - +); Node* MakeFunctionSignatureNode( Node *identifierNode, Node* typeNode, Node* arguments -) { - uint32_t i; - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = FunctionSignature; - node->childCount = 3; - node->children = (Node**) malloc(sizeof(Node*) * (node->childCount)); - node->children[0] = identifierNode; - node->children[1] = typeNode; - node->children[2] = arguments; - return node; -} - +); Node* MakeFunctionDeclarationNode( Node* functionSignatureNode, Node* functionBodyNode -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = FunctionDeclaration; - node->childCount = 2; - node->children = (Node**) malloc(sizeof(Node*) * 2); - node->children[0] = functionSignatureNode; - node->children[1] = functionBodyNode; - return node; -} - +); Node* MakeStructDeclarationNode( Node *identifierNode, Node *declarationSequenceNode -) { - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = StructDeclaration; - node->childCount = 2; - node->children = (Node**) malloc(sizeof(Node*) * 2); - node->children[0] = identifierNode; - node->children[1] = declarationSequenceNode; - return node; -} - +); Node* MakeDeclarationSequenceNode( Node **pNodes, uint32_t nodeCount -) { - int32_t i; - Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = DeclarationSequence; - node->children = (Node**) malloc(sizeof(Node*) * nodeCount); - node->childCount = nodeCount; - for (i = nodeCount - 1; i >= 0; i -= 1) - { - node->children[nodeCount - 1 - i] = pNodes[i]; - } - return node; -} +); -static const char* PrimitiveTypeToString(PrimitiveType type) -{ - switch (type) - { - case Int: return "Int"; - case UInt: return "UInt"; - case Bool: return "Bool"; - } - - return "Unknown"; -} - -static void PrintBinaryOperator(BinaryOperator expression) -{ - switch (expression) - { - case Add: - printf("+"); - break; - - case Subtract: - printf("-"); - break; - } -} - -static void PrintNode(Node *node, int tabCount) -{ - uint32_t i; - for (i = 0; i < tabCount; i += 1) - { - printf(" "); - } - - printf("%s: ", SyntaxKindString(node->syntaxKind)); - switch (node->syntaxKind) - { - case BinaryExpression: - PrintBinaryOperator(node->operator.binaryOperator); - break; - - case Declaration: - break; - - case Type: - printf("%s", PrimitiveTypeToString(node->type)); - break; - - case Identifier: - printf("%s", node->value.string); - break; - - case Number: - printf("%lu", node->value.number); - break; - } - - printf("\n"); -} - -void PrintTree(Node *node, uint32_t tabCount) -{ - uint32_t i; - PrintNode(node, tabCount); - for (i = 0; i < node->childCount; i += 1) - { - PrintTree(node->children[i], tabCount + 1); - } -} +void PrintTree(Node *node, uint32_t tabCount); #endif /* WRAITH_AST_H */ diff --git a/compiler.c b/compiler.c new file mode 100644 index 0000000..e3bac9a --- /dev/null +++ b/compiler.c @@ -0,0 +1,28 @@ +#include + +#include +#include "y.tab.h" +#include "stack.h" + +extern FILE *yyin; +Stack *stack; + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + printf("Please provide a file.\n"); + return 1; + } + + stack = CreateStack(); + + FILE *fp = fopen(argv[1], "r"); + yyin = fp; + yyparse(fp, stack); + fclose(fp); + + LLVMModuleRef mod = LLVMModuleCreateWithName("my_module"); + + return 0; +} diff --git a/stack.c b/stack.c new file mode 100644 index 0000000..570b1aa --- /dev/null +++ b/stack.c @@ -0,0 +1,80 @@ +#include +#include +#include "stack.h" + +Stack* CreateStack() +{ + uint32_t i; + Stack *stack = (Stack*) malloc(sizeof(Stack)); + stack->stackCapacity = 4; + stack->stackFrames = (StackFrame*) malloc(sizeof(StackFrame) * stack->stackCapacity); + for (i = 0; i < stack->stackCapacity; i += 1) + { + stack->stackFrames[i].statements = NULL; + stack->stackFrames[i].statementCapacity = 0; + stack->stackFrames[i].statementCount = 0; + stack->stackFrames[i].declarations = NULL; + stack->stackFrames[i].declarationCapacity = 0; + stack->stackFrames[i].declarationCount = 0; + } + stack->stackIndex = 0; + return stack; +} + +void PushStackFrame(Stack *stack) +{ + stack->stackIndex += 1; + + if (stack->stackIndex == stack->stackCapacity) + { + stack->stackCapacity += 1; + stack->stackFrames = (StackFrame*) realloc(stack->stackFrames, sizeof(StackFrame) * stack->stackCapacity); + + stack->stackFrames[stack->stackIndex].statementCapacity = 0; + stack->stackFrames[stack->stackIndex].declarationCapacity = 0; + } + + stack->stackFrames[stack->stackIndex].statementCount = 0; + stack->stackFrames[stack->stackIndex].declarationCount = 0; +} + +void PopStackFrame(Stack *stack) +{ + stack->stackIndex -= 1; +} + +void AddStatement(Stack *stack, Node *statementNode) +{ + StackFrame *stackFrame = &stack->stackFrames[stack->stackIndex]; + if (stackFrame->statementCount == stackFrame->statementCapacity) + { + stackFrame->statementCapacity += 1; + stackFrame->statements = (Node**) realloc(stackFrame->statements, stackFrame->statementCapacity); + } + stackFrame->statements[stackFrame->statementCount] = statementNode; + stackFrame->statementCount += 1; +} + +Node** GetStatements(Stack *stack, uint32_t *pCount) +{ + *pCount = stack->stackFrames[stack->stackIndex].statementCount; + return stack->stackFrames[stack->stackIndex].statements; +} + +void AddDeclaration(Stack *stack, Node *declarationNode) +{ + StackFrame *stackFrame = &stack->stackFrames[stack->stackIndex]; + if (stackFrame->declarationCount == stackFrame->declarationCapacity) + { + stackFrame->declarationCapacity += 1; + stackFrame->declarations = (Node**) realloc(stackFrame->declarations, stackFrame->declarationCapacity); + } + stackFrame->declarations[stackFrame->declarationCount] = declarationNode; + stackFrame->declarationCount += 1; +} + +Node** GetDeclarations(Stack *stack, uint32_t *pCount) +{ + *pCount = stack->stackFrames[stack->stackIndex].declarationCount; + return stack->stackFrames[stack->stackIndex].declarations; +} diff --git a/stack.h b/stack.h index deea3d9..3d118b9 100644 --- a/stack.h +++ b/stack.h @@ -1,7 +1,6 @@ #ifndef WRAITH_STACK_H #define WRAITH_STACK_H -#include #include "ast.h" typedef struct StackFrame @@ -22,71 +21,13 @@ typedef struct Stack uint32_t stackIndex; } Stack; -Stack* CreateStack() -{ - Stack *stack = (Stack*) malloc(sizeof(Stack)); - stack->stackCapacity = 4; - stack->stackFrames = (StackFrame*) malloc(sizeof(StackFrame) * stack->stackCapacity); - stack->stackIndex = 0; - return stack; -} +Stack* CreateStack(); +void PushStackFrame(Stack *stack); +void PopStackFrame(Stack *stack); -void PushStackFrame(Stack *stack) -{ - stack->stackIndex += 1; - - if (stack->stackIndex == stack->stackCapacity) - { - stack->stackCapacity += 1; - stack->stackFrames = (StackFrame*) realloc(stack->stackFrames, sizeof(StackFrame) * stack->stackCapacity); - - stack->stackFrames[stack->stackIndex].statementCapacity = 0; - stack->stackFrames[stack->stackIndex].declarationCapacity = 0; - } - - stack->stackFrames[stack->stackIndex].statementCount = 0; - stack->stackFrames[stack->stackIndex].declarationCount = 0; -} - -void PopStackFrame(Stack *stack) -{ - stack->stackIndex -= 1; -} - -void AddStatement(Stack *stack, Node *statementNode) -{ - StackFrame *stackFrame = &stack->stackFrames[stack->stackIndex]; - if (stackFrame->statementCount == stackFrame->statementCapacity) - { - stackFrame->statementCapacity += 1; - stackFrame->statements = (Node**) realloc(stackFrame->statements, stackFrame->statementCapacity); - } - stackFrame->statements[stackFrame->statementCount] = statementNode; - stackFrame->statementCount += 1; -} - -Node** GetStatements(Stack *stack, uint32_t *pCount) -{ - *pCount = stack->stackFrames[stack->stackIndex].statementCount; - return stack->stackFrames[stack->stackIndex].statements; -} - -void AddDeclaration(Stack *stack, Node *declarationNode) -{ - StackFrame *stackFrame = &stack->stackFrames[stack->stackIndex]; - if (stackFrame->declarationCount == stackFrame->declarationCapacity) - { - stackFrame->declarationCapacity += 1; - stackFrame->declarations = (Node**) realloc(stackFrame->declarations, stackFrame->declarationCapacity); - } - stackFrame->declarations[stackFrame->declarationCount] = declarationNode; - stackFrame->declarationCount += 1; -} - -Node** GetDeclarations(Stack *stack, uint32_t *pCount) -{ - *pCount = stack->stackFrames[stack->stackIndex].declarationCount; - return stack->stackFrames[stack->stackIndex].declarations; -} +void AddStatement(Stack *stack, Node *statementNode); +Node** GetStatements(Stack *stack, uint32_t *pCount); +void AddDeclaration(Stack *stack, Node *declarationNode); +Node** GetDeclarations(Stack *stack, uint32_t *pCount); #endif /* WRAITH_STACK_H */ \ No newline at end of file diff --git a/wraith.y b/wraith.y index 2020b6a..bfad84f 100644 --- a/wraith.y +++ b/wraith.y @@ -1,14 +1,17 @@ +%code requires { + #include "stack.h" +} + %{ #include #include "ast.h" #include "stack.h" -void yyerror(FILE *fp, char *s) + +void yyerror(FILE *fp, Stack *stack, char *s) { fprintf (stderr, "%s\n", s); } -Stack *stack; - extern char *yytext; extern int yylex (void); extern FILE *yyin; @@ -53,7 +56,7 @@ extern FILE *yyin; %token COMMENT %token NEWLINE -%parse-param { FILE* fp } +%parse-param { FILE* fp } { Stack *stack } %left PLUS MINUS %left BANG @@ -235,21 +238,3 @@ Declarations : Declaration Declarations PushStackFrame(stack); } %% - -int main(int argc, char *argv[]) -{ - if (argc < 2) - { - printf("Please provide a file.\n"); - return 1; - } - - stack = CreateStack(); - - FILE *fp = fopen(argv[1], "r"); - yyin = fp; - yyparse(fp); - fclose(fp); - - return 0; -}