fix compilation structure
							parent
							
								
									a849fa73c4
								
							
						
					
					
						commit
						545a010e58
					
				| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,293 @@
 | 
			
		|||
#include "ast.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										264
									
								
								ast.h
								
								
								
								
							
							
						
						
									
										264
									
								
								ast.h
								
								
								
								
							| 
						 | 
				
			
			@ -2,9 +2,6 @@
 | 
			
		|||
#define WRAITH_AST_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <llvm-c/Core.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								stack.h
								
								
								
								
							
							
						
						
									
										73
									
								
								stack.h
								
								
								
								
							| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
#ifndef WRAITH_STACK_H
 | 
			
		||||
#define WRAITH_STACK_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#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 */
 | 
			
		||||
							
								
								
									
										29
									
								
								wraith.y
								
								
								
								
							
							
						
						
									
										29
									
								
								wraith.y
								
								
								
								
							| 
						 | 
				
			
			@ -1,14 +1,17 @@
 | 
			
		|||
%code requires {
 | 
			
		||||
    #include "stack.h"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%{
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue