diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast.c | 73 | ||||
-rw-r--r-- | src/ast.h | 41 | ||||
-rw-r--r-- | src/gas_assembly_generator.c | 6 | ||||
-rw-r--r-- | src/parser.c | 20 | ||||
-rw-r--r-- | src/parser.h | 2 | ||||
-rw-r--r-- | src/pipac.c | 10 |
6 files changed, 104 insertions, 48 deletions
@@ -15,6 +15,8 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include <assert.h> +#include <stdio.h> +#include <stdlib.h> #include "ast.h" void @@ -26,38 +28,69 @@ ast_node_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) } static void -ast_function_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) +ast_node_function_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) { - visitor->visit_function(visitor, (ast_function_t *) node); + visitor->visit_function(visitor, &node->data.function); } static void -ast_return_stmt_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) +ast_node_return_stmt_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) { - visitor->visit_return_stmt(visitor, (ast_return_stmt_t *) node); + visitor->visit_return_stmt(visitor, &node->data.return_stmt); } -ast_return_stmt_t -ast_return_stmt_create(uint32_t number) +ast_node_t* +ast_node_new() { - return (ast_return_stmt_t) { - .super = (ast_node_t) { - .accept_visitor = &ast_return_stmt_accept_visitor - }, - .number = number + ast_node_t *node = (ast_node_t*) malloc(sizeof(ast_node_t)); + if (node == NULL) { + printf("OOO: could no allocate a node"); + exit(EXIT_FAILURE); + } + node->kind = AST_UNKOWN_NODE; + return node; +} + +void +ast_node_destroy(ast_node_t *node) +{ + switch (node->kind) { + case AST_FUNCTION_DECLARATION: + ast_node_destroy(node->data.function.body); + break; + case AST_RETURN_STMT: + break; + case AST_UNKOWN_NODE: + break; + default: + assert(false && "unmapped free strategy"); + } + free(node); +} + +void +ast_node_init_return_stmt(ast_node_t *node, uint32_t number) +{ + node->accept_visitor = &ast_node_return_stmt_accept_visitor, + node->kind = AST_RETURN_STMT; + node->data = (ast_node_data_t) { + .return_stmt = { + .number = number + } }; } -ast_function_t -ast_function_create(string_view_t name, type_t return_type, ast_return_stmt_t body) +void +ast_node_init_function_declaration(ast_node_t *node, string_view_t name, type_t return_type, ast_node_t* body) { - return (ast_function_t) { - .super = (ast_node_t) { - .accept_visitor = &ast_function_accept_visitor - }, - .name = name, - .return_type = return_type, - .body = body + node->accept_visitor = &ast_node_function_accept_visitor, + node->kind = AST_FUNCTION_DECLARATION; + node->data = (ast_node_data_t) { + .function = { + .name = name, + .return_type = return_type, + .body = body + } }; } @@ -19,39 +19,54 @@ #include <stdint.h> #include "string_view.h" -#define ast_visitor_visit(visitor, node) ast_node_accept_visitor((ast_node_t *) node, (ast_visitor_t *) visitor); +#define ast_visitor_visit(visitor, node) ast_node_accept_visitor(node, (ast_visitor_t *) visitor); typedef enum { TYPE_I32 } type_t; typedef struct ast_visitor_t ast_visitor_t; - -typedef struct ast_node_t { - void (*accept_visitor)(struct ast_node_t *, ast_visitor_t *); -} ast_node_t; +typedef struct ast_node_t ast_node_t; typedef struct ast_return_stmt_t { - struct ast_node_t super; uint32_t number; } ast_return_stmt_t; -typedef struct ast_function_t { - struct ast_node_t super; +typedef struct ast_function_declaration_t { string_view_t name; type_t return_type; - ast_return_stmt_t body; -} ast_function_t; + ast_node_t* body; +} ast_function_declaration_t; typedef struct ast_visitor_t { - void (*visit_function)(struct ast_visitor_t *, ast_function_t *); + void (*visit_function)(struct ast_visitor_t *, ast_function_declaration_t *); void (*visit_return_stmt)(struct ast_visitor_t *, ast_return_stmt_t *); } ast_visitor_t; +typedef enum { + AST_UNKOWN_NODE, + AST_FUNCTION_DECLARATION, + AST_RETURN_STMT +} ast_node_kind_t; + +typedef union { + ast_function_declaration_t function; + ast_return_stmt_t return_stmt; +} ast_node_data_t; + +typedef struct ast_node_t { + void (*accept_visitor)(ast_node_t *, ast_visitor_t *); + ast_node_kind_t kind; + ast_node_data_t data; +} ast_node_t; + void ast_node_accept_visitor(ast_node_t *node, ast_visitor_t *visitor); -ast_function_t ast_function_create(string_view_t name, type_t return_type, ast_return_stmt_t body); -ast_return_stmt_t ast_return_stmt_create(uint32_t number); +ast_node_t* ast_node_new(); +void ast_node_destroy(ast_node_t *node); + +void ast_node_init_function_declaration(ast_node_t* node, string_view_t name, type_t return_type, ast_node_t *body); +void ast_node_init_return_stmt(ast_node_t* node, uint32_t number); #endif /* AST_H */ diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c index d164b7d..afbfebd 100644 --- a/src/gas_assembly_generator.c +++ b/src/gas_assembly_generator.c @@ -20,7 +20,7 @@ #include <stdio.h> #include <stdlib.h> -static void gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_t *func); +static void gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func); static void gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt_t *return_stmt); void @@ -35,7 +35,7 @@ gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *out) } static void -gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_t *func) +gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func) { assert(visitor && func); @@ -50,7 +50,7 @@ gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_t *fu fprintf(gen->out,".text\n"); fprintf(gen->out,"_start:\n"); - ast_visitor_visit(visitor, &func->body); + ast_visitor_visit(visitor, func->body); } static void diff --git a/src/parser.c b/src/parser.c index b956c4e..b1e6a1f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -70,12 +70,12 @@ parser_parse_type(parser_t *parser) return TYPE_I32; } - fprintf(stderr, "[ERROR]: expected type 'i32' but got '"SVFMT"'\n", SVARG(&token.value)); + fprintf(stderr, "[ERROR]: expected type 'i32' but got '"SVFMT"'\n", SVARG(&token.value)); exit(EXIT_FAILURE); } -static ast_return_stmt_t -parser_parse_return_stmt(parser_t *parser) +void +parser_parse_return_stmt(parser_t *parser, ast_node_t *node) { expected_token(parser, TOKEN_OCURLY); token_t return_keyword_token = expected_token(parser, TOKEN_NAME); @@ -93,11 +93,11 @@ parser_parse_return_stmt(parser_t *parser) char number_as_str[number_token.value.size]; string_view_to_str(&number_token.value, number_as_str); - return ast_return_stmt_create(atoi(number_as_str)); + ast_node_init_return_stmt(node, atoi(number_as_str)); } -ast_function_t -parser_parse_function(parser_t *parser) +void +parser_parse_function_declaration(parser_t *parser, ast_node_t *node) { token_t func_name_token = expected_token(parser, TOKEN_NAME); expected_token(parser, TOKEN_OPAREN); @@ -105,9 +105,13 @@ parser_parse_function(parser_t *parser) expected_token(parser, TOKEN_COLON); type_t return_type = parser_parse_type(parser); - return ast_function_create( + ast_node_t *return_node = ast_node_new(); + parser_parse_return_stmt(parser, return_node); + + ast_node_init_function_declaration( + node, func_name_token.value, return_type, - parser_parse_return_stmt(parser) + return_node ); } diff --git a/src/parser.h b/src/parser.h index b846ae1..988006e 100644 --- a/src/parser.h +++ b/src/parser.h @@ -27,7 +27,7 @@ typedef struct parser_t { void parser_init(parser_t *parser, lexer_t *lexer); -ast_function_t parser_parse_function(parser_t *parser); +void parser_parse_function_declaration(parser_t *parser, ast_node_t *node); #endif /* PARSER_H */ diff --git a/src/pipac.c b/src/pipac.c index e56d8a1..41294c4 100644 --- a/src/pipac.c +++ b/src/pipac.c @@ -19,12 +19,13 @@ #include <string.h> #include "lexer.h" +#include "ast.h" #include "parser.h" #include "string_view.h" #include "gas_assembly_generator.h" void -generate_gas_x86_64_linux(ast_function_t *func) +generate_gas_x86_64_linux(ast_node_t *func) { gas_assembly_generator_t gen; gas_assembly_generator_init(&gen, stdout); @@ -61,9 +62,12 @@ main(int argc, char **argv) parser_t parser; parser_init(&parser, &lexer); - ast_function_t func = parser_parse_function(&parser); - generate_gas_x86_64_linux(&func); + ast_node_t* func = ast_node_new(); + parser_parse_function_declaration(&parser, func); + generate_gas_x86_64_linux(func); + + ast_node_destroy(func); return EXIT_SUCCESS; } |