diff --git a/ast.h b/ast.h index 67aab6d..bf58d26 100644 --- a/ast.h +++ b/ast.h @@ -1,3 +1,6 @@ +#ifndef WRAITH_AST_H +#define WRAITH_AST_H + #include #include #include @@ -9,12 +12,18 @@ typedef enum BinaryExpression, Comment, Declaration, + DeclarationSequence, Expression, ForLoop, + FunctionDeclaration, + FunctionSignature, Identifier, Number, Return, + StatementSequence, StringLiteral, + StructDeclaration, + Type, UnaryExpression } SyntaxKind; @@ -82,15 +91,33 @@ const char* SyntaxKindString(SyntaxKind 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 ) { @@ -151,14 +178,15 @@ Node* MakeBinaryNode( } Node* MakeDeclarationNode( - PrimitiveType type, - const char *id + Node* typeNode, + Node* identifierNode ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = Declaration; - node->type = type; - node->value.string = strdup(id); - node->childCount = 0; + node->children = (Node**) malloc(sizeof(Node*) * 2); + node->childCount = 2; + node->children[0] = typeNode; + node->children[1] = identifierNode; return node; } @@ -175,6 +203,80 @@ Node* MakeAssignmentNode( 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* 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) @@ -199,8 +301,6 @@ static void PrintBinaryOperator(BinaryOperator expression) printf("-"); break; } - - printf("\n"); } static void PrintNode(Node *node, int tabCount) @@ -219,7 +319,10 @@ static void PrintNode(Node *node, int tabCount) break; case Declaration: - printf("%s %s", PrimitiveTypeToString(node->type), node->value.string); + break; + + case Type: + printf("%s", PrimitiveTypeToString(node->type)); break; case Identifier: @@ -243,3 +346,5 @@ void PrintTree(Node *node, uint32_t tabCount) PrintTree(node->children[i], tabCount + 1); } } + +#endif /* WRAITH_AST_H */ diff --git a/stack.h b/stack.h new file mode 100644 index 0000000..deea3d9 --- /dev/null +++ b/stack.h @@ -0,0 +1,92 @@ +#ifndef WRAITH_STACK_H +#define WRAITH_STACK_H + +#include +#include "ast.h" + +typedef struct StackFrame +{ + Node **statements; + uint32_t statementCount; + uint32_t statementCapacity; + + Node **declarations; + uint32_t declarationCount; + uint32_t declarationCapacity; +} StackFrame; + +typedef struct Stack +{ + StackFrame *stackFrames; + uint32_t stackCapacity; + 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; +} + +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; +} + +#endif /* WRAITH_STACK_H */ \ No newline at end of file diff --git a/wraith.lex b/wraith.lex index 4ed8a6b..e8f3d36 100644 --- a/wraith.lex +++ b/wraith.lex @@ -8,6 +8,7 @@ "double" return DOUBLE; "string" return STRING; "bool" return BOOL; +"struct" return STRUCT; [a-zA-Z][a-zA-Z0-9]* return ID; \"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL; "+" return PLUS; diff --git a/wraith.y b/wraith.y index 52ec75e..3a0e040 100644 --- a/wraith.y +++ b/wraith.y @@ -1,14 +1,17 @@ %{ #include #include "ast.h" +#include "stack.h" #define YYSTYPE struct Node* void yyerror(FILE *fp, char *s) { fprintf (stderr, "%s\n", s); } -Node **statements; -uint32_t statementCount; -uint32_t i; + +Stack *stack; + +#define YYDEBUG 1 +int yydebug=1; %} %token NUMBER @@ -18,6 +21,7 @@ uint32_t i; %token DOUBLE %token STRING %token BOOL +%token STRUCT %token ID %token STRING_LITERAL %token PLUS @@ -53,14 +57,45 @@ uint32_t i; %left LEFT_PAREN RIGHT_PAREN %% -Program : Statements +Program : Declarations { - for (i = 0; i < statementCount; i += 1) - { - PrintTree(statements[i], 0); - } + Node **declarations; + Node *declarationSequence; + uint32_t declarationCount; + + declarations = GetDeclarations(stack, &declarationCount); + declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); + + PopStackFrame(stack); + PrintTree(declarationSequence, 0); } +Type : INT + { + $$ = MakeTypeNode(Int); + } + | UINT + { + $$ = MakeTypeNode(UInt); + } + | FLOAT + { + $$ = MakeTypeNode(Float); + } + | DOUBLE + { + $$ = MakeTypeNode(Double); + } + | STRING + { + $$ = MakeTypeNode(String); + } + | BOOL + { + $$ = MakeTypeNode(Bool); + } + ; + Identifier : ID { $$ = MakeIdentifierNode(yytext); @@ -76,6 +111,9 @@ PrimaryExpression : Identifier $$ = MakeStringNode(yytext); } | LEFT_PAREN Expression RIGHT_PAREN + { + $$ = $2; + } ; UnaryExpression : BANG Expression @@ -97,29 +135,9 @@ Expression : PrimaryExpression | BinaryExpression ; -VariableDeclaration : INT ID +VariableDeclaration : Type Identifier SEMICOLON { - $$ = MakeDeclarationNode(Int, yytext); - } - | UINT ID - { - $$ = MakeDeclarationNode(UInt, yytext); - } - | FLOAT ID - { - $$ = MakeDeclarationNode(Float, yytext); - } - | DOUBLE ID - { - $$ = MakeDeclarationNode(Double, yytext); - } - | STRING ID - { - $$ = MakeDeclarationNode(String, yytext); - } - | BOOL ID - { - $$ = MakeDeclarationNode(Bool, yytext); + $$ = MakeDeclarationNode($1, $2); } AssignmentStatement : VariableDeclaration EQUAL Expression @@ -131,20 +149,80 @@ AssignmentStatement : VariableDeclaration EQUAL Expression $$ = MakeAssignmentNode($1, $3); } -Statement : AssignmentStatement +PartialStatement : AssignmentStatement + | VariableDeclaration ; -CompleteStatement : Statement SEMICOLON; +Statement : PartialStatement SEMICOLON; -Statements : Statements CompleteStatement +Statements : Statement { - statements = realloc(statements, statementCount + 1); - statements[statementCount] = $2; - statementCount += 1; + Node **statements; + uint32_t statementCount; + + AddStatement(stack, $1); + + statements = GetStatements(stack, &statementCount); + $$ = MakeStatementSequenceNode(statements, statementCount); + PopStackFrame(stack); + } + | Statement Statements + { + AddStatement(stack, $2); + } + +Arguments : Arguments COMMA VariableDeclaration + | VariableDeclaration + ; + +Body : LEFT_BRACE Statements RIGHT_BRACE + { + $$ = $2; + } + +FunctionSignature : Type Identifier LEFT_PAREN Arguments RIGHT_PAREN + { + $$ = MakeFunctionSignatureNode($2, $1, $4); + } + +FunctionDeclaration : FunctionSignature Body + { + $$ = MakeFunctionDeclarationNode($1, $2); + } + +VariableDeclarations : VariableDeclaration VariableDeclarations + { + AddDeclaration(stack, $1); } | { - $$ = NULL; + PushStackFrame(stack); + } + +StructDeclaration : STRUCT Identifier LEFT_BRACE VariableDeclarations RIGHT_BRACE + { + Node **declarations; + Node *declarationSequence; + uint32_t declarationCount; + + declarations = GetDeclarations(stack, &declarationCount); + declarationSequence = MakeDeclarationSequenceNode(declarations, declarationCount); + $$ = MakeStructDeclarationNode($2, declarationSequence); + + PopStackFrame(stack); + } + +Declaration : StructDeclaration + | FunctionDeclaration + ; + +Declarations : Declaration Declarations + { + AddDeclaration(stack, $1); + } + | + { + PushStackFrame(stack); } %% @@ -158,9 +236,12 @@ int main(int argc, char *argv[]) return 1; } + stack = CreateStack(); + FILE *fp = fopen(argv[1], "r"); yyin = fp; yyparse(fp); fclose(fp); + return 0; }