#include "elna/cli/cl.hpp" #include "elna/backend/target.hpp" #include "elna/source/semantic.hpp" #include "elna/source/optimizer.hpp" #include "elna/source/types.hpp" #include namespace elna::cli { void print_error(const std::unique_ptr& compile_error) { std::cerr << compile_error->path().string() << ":" << compile_error->line() << ':' << compile_error->column() << ": " << compile_error->what() << std::endl; } constexpr std::size_t pointer_size = 4; static std::shared_ptr add_builtin_symbols() { source::symbol_table result; std::vector> intrinsic_arguments; auto boolean_info = std::make_shared(source::boolean_type); auto int_info = std::make_shared(source::int_type); result.enter("Boolean", boolean_info); result.enter("Int", int_info); intrinsic_arguments.push_back(int_info->type()); auto writei = std::make_shared( source::procedure_type{ intrinsic_arguments, pointer_size }); result.enter("writei", writei); intrinsic_arguments.clear(); intrinsic_arguments.push_back(boolean_info->type()); auto writeb = std::make_shared( source::procedure_type{ intrinsic_arguments, pointer_size }); result.enter("writeb", writeb); intrinsic_arguments.clear(); return std::make_shared(std::move(result)); } int compile(const std::filesystem::path& in_file, const std::filesystem::path& out_file) { try { source::result lex_result = source::tokenize(in_file); if (lex_result.has_errors()) { print_errors(lex_result.errors().cbegin(), lex_result.errors().cend()); return 1; } source::parser parser{ std::move(lex_result.success()) }; auto ast = parser.parse(); if (ast == nullptr) { print_errors(parser.errors().cbegin(), parser.errors().cend()); return 2; } auto global_scope = add_builtin_symbols(); source::name_analysis_visitor(global_scope, in_file, pointer_size).visit(ast.get()); source::type_analysis_visitor(global_scope, in_file, pointer_size).visit(ast.get()); source::allocator_visitor(global_scope).visit(ast.get()); source::intermediate_code_generator intermediate_code_generator{ global_scope }; intermediate_code_generator.visit(ast.get()); riscv::riscv32_elf(ast.get(), intermediate_code_generator, global_scope, out_file); } catch (std::ios_base::failure&) { return 3; } return 0; } }