/* * Copyright (C) 2023 Johnny Richard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gas_assembly_generator.h" #include #include #include 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 gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *out) { assert(gen && out); gen->super = (ast_visitor_t) { .visit_function = &gas_assembly_generator_visit_function, .visit_return_stmt = &gas_assembly_generator_visit_return_stmt }; gen->out = out; } static void gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func) { assert(visitor && 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"); ast_visitor_visit(visitor, func->body); } static void gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt_t *return_stmt) { assert(visitor && return_stmt); gas_assembly_generator_t *gen = (gas_assembly_generator_t *) visitor; fprintf(gen->out, " mov $1, %%al\n"); fprintf(gen->out, " mov $%d, %%ebx\n", return_stmt->number); fprintf(gen->out, " int $0x80\n"); }