diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/ast.c | 42 | ||||
-rw-r--r-- | src/ast.h | 15 | ||||
-rw-r--r-- | src/gas_assembly_generator.c | 102 | ||||
-rw-r--r-- | src/gas_assembly_generator.h | 7 | ||||
-rw-r--r-- | src/pipac.c | 3 |
6 files changed, 66 insertions, 105 deletions
@@ -1,7 +1,7 @@ TARGET := pipac SRC_DIR := src BUILD_DIR := build -CFLAGS := -Wall -Wextra -pedantic -std=c11 -ggdb +CFLAGS := -Werror -Wall -Wextra -pedantic -std=c11 -ggdb SRCS := $(wildcard $(SRC_DIR)/*.c) HEADERS := $(wildcard $(SRC_DIR)/*.h) @@ -19,42 +19,6 @@ #include <stdio.h> #include <stdlib.h> -void -ast_node_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) -{ - assert(node); - assert(node->accept_visitor); - node->accept_visitor(node, visitor); -} - -static void -ast_node_function_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) -{ - assert(visitor->visit_function && "unimplemented visit_function"); - visitor->visit_function(visitor, &node->data.function); -} - -static void -ast_node_return_stmt_accept_visitor(ast_node_t *node, ast_visitor_t *visitor) -{ - assert(visitor->visit_return_stmt && "unimplemented visit_return_stmt"); - visitor->visit_return_stmt(visitor, &node->data.return_stmt); -} - -static void -ast_node_literal_visitor(ast_node_t *node, ast_visitor_t *visitor) -{ - assert(visitor->visit_literal && "unimplemented visit_literal"); - visitor->visit_literal(visitor, &node->data.literal); -} - -static void -ast_node_binary_operation_visitor(ast_node_t *node, ast_visitor_t *visitor) -{ - assert(visitor->visit_binary_operation && "unimplemented visit_binary_operation"); - visitor->visit_binary_operation(visitor, &node->data.binary_operation); -} - ast_node_t * ast_node_new() { @@ -108,7 +72,6 @@ ast_node_destroy(ast_node_t *node) void ast_node_init_return_stmt(ast_node_t *node, ast_node_t *argument) { - node->accept_visitor = &ast_node_return_stmt_accept_visitor; node->kind = AST_RETURN_STMT; node->data.return_stmt = (ast_return_stmt_t){ .argument = argument }; } @@ -116,7 +79,6 @@ ast_node_init_return_stmt(ast_node_t *node, ast_node_t *argument) void ast_node_init_function_declaration(ast_node_t *node, string_view_t name, type_t return_type, vector_t *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 } }; } @@ -124,7 +86,6 @@ ast_node_init_function_declaration(ast_node_t *node, string_view_t name, type_t void ast_literal_integer_create(ast_node_t *node, uint32_t number) { - node->accept_visitor = &ast_node_literal_visitor; node->kind = AST_LITERAL; node->data.literal = (ast_literal_t){ .kind = AST_LITERAL_INTEGER, .value = { .integer = number } }; } @@ -132,7 +93,6 @@ ast_literal_integer_create(ast_node_t *node, uint32_t number) void ast_node_init_binary_operation(ast_node_t *node, ast_binary_operation_kind_t kind, ast_node_t *left, ast_node_t *right) { - node->accept_visitor = &ast_node_binary_operation_visitor; node->kind = AST_BINARY_OPERATION; node->data = (ast_node_data_t){ .binary_operation = { .kind = kind, .left = left, .right = right } }; } @@ -140,7 +100,6 @@ ast_node_init_binary_operation(ast_node_t *node, ast_binary_operation_kind_t kin void ast_node_init_variable_declaration(ast_node_t *node, string_view_t variable_name, type_t type, ast_node_t *value) { - // FIXME: define the visitor strategy node->kind = AST_VARIABLE_DECLARATION; node->data = (ast_node_data_t){ .variable = { .name = variable_name, .type = type, .value = value } }; } @@ -148,7 +107,6 @@ ast_node_init_variable_declaration(ast_node_t *node, string_view_t variable_name void ast_node_init_identifier(ast_node_t *node, string_view_t name) { - // FIXME: define the visitor strategy node->kind = AST_IDENTIFIER; node->data.identifier = (ast_identifier_t){ .name = name }; } @@ -20,14 +20,11 @@ #include "vector.h" #include <stdint.h> -#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 ast_node_t; typedef struct ast_return_stmt_t @@ -85,14 +82,6 @@ typedef struct ast_variable_declaration_t ast_node_t *value; } ast_variable_declaration_t; -typedef struct ast_visitor_t -{ - void (*visit_function)(struct ast_visitor_t *, ast_function_declaration_t *); - void (*visit_return_stmt)(struct ast_visitor_t *, ast_return_stmt_t *); - void (*visit_literal)(struct ast_visitor_t *, ast_literal_t *); - void (*visit_binary_operation)(struct ast_visitor_t *, ast_binary_operation_t *); -} ast_visitor_t; - typedef enum { AST_BINARY_OPERATION, @@ -116,14 +105,10 @@ typedef union 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_node_t * ast_node_new(); void diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c index bf98255..34864dd 100644 --- a/src/gas_assembly_generator.c +++ b/src/gas_assembly_generator.c @@ -21,66 +21,88 @@ #include <stdlib.h> static void -gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func); +gas_assembly_generator_binary_operation(gas_assembly_generator_t *gen, ast_binary_operation_t *binary_operation); + static void -gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt_t *return_stmt); +gas_assembly_generator_compile_function(gas_assembly_generator_t *gen, ast_function_declaration_t *func); + static void -gas_assembly_generator_visit_literal(ast_visitor_t *visitor, ast_literal_t *literal); +gas_assembly_generator_compile_literal(gas_assembly_generator_t *gen, ast_literal_t *literal); + static void -gas_assembly_generator_binary_operation(ast_visitor_t *visitor, ast_binary_operation_t *binary_operation); +gas_assembly_generator_compile_return_stmt(gas_assembly_generator_t *gen, ast_return_stmt_t *return_stmt); + +void +gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *stream) +{ + assert(gen && stream); + gen->stream = stream; +} void -gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *out) +gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast) { - assert(gen && out); - gen->super = (ast_visitor_t){ .visit_function = &gas_assembly_generator_visit_function, - .visit_literal = &gas_assembly_generator_visit_literal, - .visit_return_stmt = &gas_assembly_generator_visit_return_stmt, - .visit_binary_operation = &gas_assembly_generator_binary_operation }; - gen->out = out; + switch (ast->kind) { + case AST_BINARY_OPERATION: + gas_assembly_generator_binary_operation(gen, &ast->data.binary_operation); + break; + case AST_FUNCTION_DECLARATION: + gas_assembly_generator_compile_function(gen, &ast->data.function); + break; + case AST_LITERAL: + gas_assembly_generator_compile_literal(gen, &ast->data.literal); + break; + case AST_RETURN_STMT: + gas_assembly_generator_compile_return_stmt(gen, &ast->data.return_stmt); + break; + case AST_IDENTIFIER: + assert(false && "TODO: ast identifier not implemented yet"); + break; + case AST_VARIABLE_DECLARATION: + assert(false && "TODO: ast variable declaration not implemented yet"); + break; + case AST_UNKOWN_NODE: + assert(false && "unreachable"); + } } static void -gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func) +gas_assembly_generator_compile_function(gas_assembly_generator_t *gen, ast_function_declaration_t *func) { - assert(visitor && func); + assert(func); if (!string_view_eq(func->name, string_view_from_str("main"))) { fprintf(stderr, "[ERROR]: no main function has been defined!\n"); exit(EXIT_FAILURE); } - gas_assembly_generator_t *gen = (gas_assembly_generator_t *)visitor; - - fprintf(gen->out, ".global _start\n"); - fprintf(gen->out, ".text\n"); - fprintf(gen->out, "_start:\n"); + fprintf(gen->stream, ".global _start\n"); + fprintf(gen->stream, ".text\n"); + fprintf(gen->stream, "_start:\n"); for (size_t i = 0; i < func->body->size; i++) { - ast_visitor_visit(visitor, vector_at(func->body, i)); + gas_assembly_generator_compile(gen, vector_at(func->body, i)); } } static void -gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt_t *return_stmt) +gas_assembly_generator_compile_return_stmt(gas_assembly_generator_t *gen, ast_return_stmt_t *return_stmt) { - assert(visitor && return_stmt); - gas_assembly_generator_t *gen = (gas_assembly_generator_t *)visitor; + assert(gen && return_stmt); - ast_visitor_visit(visitor, return_stmt->argument); + gas_assembly_generator_compile(gen, return_stmt->argument); - fprintf(gen->out, " mov %%rax, %%rbx\n"); - fprintf(gen->out, " mov $1, %%al\n"); - fprintf(gen->out, " int $0x80\n"); + fprintf(gen->stream, " mov %%rax, %%rbx\n"); + fprintf(gen->stream, " mov $1, %%al\n"); + fprintf(gen->stream, " int $0x80\n"); } static void -gas_assembly_generator_visit_literal(ast_visitor_t *visitor, ast_literal_t *literal) +gas_assembly_generator_compile_literal(gas_assembly_generator_t *gen, ast_literal_t *literal) { - gas_assembly_generator_t *gen = (gas_assembly_generator_t *)visitor; switch (literal->kind) { case AST_LITERAL_INTEGER: - fprintf(gen->out, " mov $%d, %%rax\n", literal->value.integer); + fprintf(gen->stream, " mov $%d, %%rax\n", literal->value.integer); return; default: assert(false && "no code generation strategy."); @@ -88,36 +110,34 @@ gas_assembly_generator_visit_literal(ast_visitor_t *visitor, ast_literal_t *lite } static void -gas_assembly_generator_binary_operation(ast_visitor_t *visitor, ast_binary_operation_t *binary_operation) +gas_assembly_generator_binary_operation(gas_assembly_generator_t *gen, ast_binary_operation_t *binary_operation) { - gas_assembly_generator_t *gen = (gas_assembly_generator_t *)visitor; - - ast_visitor_visit(visitor, binary_operation->right); + gas_assembly_generator_compile(gen, binary_operation->right); - fprintf(gen->out, " push %%rax\n"); + fprintf(gen->stream, " push %%rax\n"); - ast_visitor_visit(visitor, binary_operation->left); + gas_assembly_generator_compile(gen, binary_operation->left); - fprintf(gen->out, " pop %%rcx\n"); + fprintf(gen->stream, " pop %%rcx\n"); if (binary_operation->kind == AST_BINOP_ADITION) { - fprintf(gen->out, " add %%rcx, %%rax\n"); + fprintf(gen->stream, " add %%rcx, %%rax\n"); return; } if (binary_operation->kind == AST_BINOP_SUBTRACTION) { - fprintf(gen->out, " sub %%rcx, %%rax\n"); + fprintf(gen->stream, " sub %%rcx, %%rax\n"); return; } if (binary_operation->kind == AST_BINOP_MULTIPLICATION) { - fprintf(gen->out, " mul %%rcx\n"); + fprintf(gen->stream, " mul %%rcx\n"); return; } if (binary_operation->kind == AST_BINOP_DIVISION) { - fprintf(gen->out, " xor %%rdx, %%rdx\n"); - fprintf(gen->out, " div %%rcx\n"); + fprintf(gen->stream, " xor %%rdx, %%rdx\n"); + fprintf(gen->stream, " div %%rcx\n"); return; } diff --git a/src/gas_assembly_generator.h b/src/gas_assembly_generator.h index c3192b7..4d4b28e 100644 --- a/src/gas_assembly_generator.h +++ b/src/gas_assembly_generator.h @@ -22,14 +22,13 @@ typedef struct gas_assembly_generator_t { - ast_visitor_t super; - FILE *out; + FILE *stream; } gas_assembly_generator_t; void -gas_assembly_generator_init(gas_assembly_generator_t *, FILE *); +gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *stream); void -gas_assembly_generator_visit(gas_assembly_generator_t *gen, ast_node_t *ast); +gas_assembly_generator_compile(gas_assembly_generator_t *gen, ast_node_t *ast); #endif /* GAS_ASSEMBLY_GENERATOR_H */ diff --git a/src/pipac.c b/src/pipac.c index 1acb4b6..d5781a5 100644 --- a/src/pipac.c +++ b/src/pipac.c @@ -29,8 +29,7 @@ generate_gas_x86_64_linux(ast_node_t *func) { gas_assembly_generator_t gen; gas_assembly_generator_init(&gen, stdout); - - ast_visitor_visit(&gen, func); + gas_assembly_generator_compile(&gen, func); } void |