Skip to content

Commit

Permalink
Began working on a rudimentary error system (again, cope)
Browse files Browse the repository at this point in the history
  • Loading branch information
Goubermouche committed Dec 22, 2023
1 parent db7b2dc commit 6af3c06
Show file tree
Hide file tree
Showing 20 changed files with 345 additions and 373 deletions.
63 changes: 41 additions & 22 deletions source/compiler/compiler/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,64 @@
#include <utility/string_helper.h>
#include <utility/timer.h>

#define LANG_FILE_EXTENSION ".s"

namespace sigma {
void compiler::compile(const filepath& path, ir::target target) {
compiler(path, target).compile();
auto compiler::compile(const compiler_description& description) -> utility::result<void> {
return compiler(description).compile();
}

compiler::compiler(const filepath& path, ir::target target)
: m_path(path), m_target(target) {}
compiler::compiler(const compiler_description& description)
: m_description(description) {}

void compiler::compile() const {
utility::console::println("compiling file: {}", m_path.string());
verify_file(m_path);
auto compiler::compile() const -> utility::result<void> {
utility::console::println("compiling file: {}", m_description.path.string());
TRY(verify_file(m_description.path));

// declare a global compilation context
// NOTE: it may be a good idea to separate our contexts a bit for when we want to add support
// for multiple files
compilation_context context;

// generate tokens
const std::string file = utility::file::read_text_file(m_path);
auto [tokens, symbols] = tokenizer::tokenize(file);
TRY(const std::string& file, utility::file::read_text_file(m_description.path));
TRY(auto tokenized, tokenizer::tokenize(file));

context.string_table = tokenized.second;
context.tokens = tokenized.first;

// parse the token list
TRY(context.ast, parser::parse(context));

// parse the source code
context.string_table = symbols;
context.tokens = tokens;
context.ast = parser::parse(context);
context.print_ast();
// context.print_ast();

// run analysis on the generated AST
type_checker::type_check(context);
ir::module module = ir_translator::translate(context, m_target);
TRY(type_checker::type_check(context));
TRY(ir::module module, ir_translator::translate(context, m_description.target));

// compile the generated IR
// compile the generated IR module
module.compile();

// emit as an object file
const filepath object_path = get_object_file_path();
emit_object_file(module, object_path);
return SUCCESS;
}

void compiler::verify_file(const filepath& path) {
ASSERT(path.extension() == ".s", "invalid file extension detected");
ASSERT(std::filesystem::is_regular_file(path), "invalid file detected");
auto compiler::verify_file(const filepath& path) -> utility::result<void> {
if(!utility::fs::exists(path)) {
return utility::error::create(utility::error::code::FILE_DOES_NOT_EXIST, path.string());
}

if(!utility::fs::is_file(path)) {
return utility::error::create(utility::error::code::EXPECTED_FILE, path.string());
}

if(path.extension() != LANG_FILE_EXTENSION) {
return utility::error::create(utility::error::code::INVALID_FILE_EXTENSION, path.string(), LANG_FILE_EXTENSION);
}

return SUCCESS;
}

auto compiler::get_object_file_path(const std::string& name) const -> filepath {
Expand All @@ -59,8 +78,8 @@ namespace sigma {
".o" // LINUX
};

const char* format = object_formats[static_cast<u8>(m_target.get_system())];
return m_path.parent_path() / (name + format);
const char* format = object_formats[static_cast<u8>(m_description.target.get_system())];
return m_description.path.parent_path() / (name + format);
}

void compiler::emit_object_file(ir::module& module, const filepath& path) {
Expand Down
20 changes: 13 additions & 7 deletions source/compiler/compiler/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,33 @@

#pragma once
#include <intermediate_representation/target/target.h>
#include <utility/diagnostics.h>
#include <utility/macros.h>

namespace sigma {
using namespace utility::types;

namespace ir {
class module;
}
} // namespace sigma::ir

struct compiler_description {
filepath path;
ir::target target;
};

class compiler {
public:
static void compile(const filepath& path, ir::target target);
static auto compile(const compiler_description& description) -> utility::result<void>;
private:
compiler(const filepath& path, ir::target target);
compiler(const compiler_description& description);

void compile() const;
auto compile() const -> utility::result<void>;
auto get_object_file_path(const std::string& name = "a") const -> filepath;

static void verify_file(const filepath& path);
static auto verify_file(const filepath& path) -> utility::result<void>;
static void emit_object_file(ir::module& module, const filepath& path);
private:
filepath m_path;
ir::target m_target;
compiler_description m_description;
};
} // namespace sigma
231 changes: 7 additions & 224 deletions source/compiler/main.cpp
Original file line number Diff line number Diff line change
@@ -1,234 +1,17 @@
#include "compiler/compiler.h"

#include <utility/macros.h>
#include <utility/filesystem/file.h>
#include <intermediate_representation/builder.h>

using namespace utility::types;

//ast.traverse([&](const handle<ast::node>& node, u16 depth) {
// std::cout << std::string(depth * 2, ' ');
// switch (node->type.type) {
// case ast::node_type::FUNCTION:
// std::cout << "FUNCTION " << utility::detail::escape_string(syntax.symbols.get(node->get<ast::function>().identifier_key)) << '\n';
// return;
// case ast::node_type::FUNCTION_CALL:
// std::cout << "FUNCTION_CALL " << utility::detail::escape_string(syntax.symbols.get(node->get<ast::function_call>().callee_identifier_key)) << '\n';
// return;
// case ast::node_type::VARIABLE_DECLARATION:
// std::cout << utility::detail::escape_string(syntax.symbols.get(node->get<ast::variable>().identifier_key)) << '\n';
// return;
// case ast::node_type::STRING_LITERAL:
// case ast::node_type::NUMERICAL_LITERAL:
// std::cout << '"' << utility::detail::escape_string(syntax.symbols.get(node->get<ast::literal>().value_key)) << "\"\n";
// return;
// }
// std::cout << node->type.to_string() << '\n';
//});

// ./source/compiler/bin/Release/compiler
// ./output/bin/Release/compiler

auto main(i32 argc, char* argv[]) -> i32 {
SUPPRESS_C4100(argc);
SUPPRESS_C4100(argv);

sigma::compiler::compile(argv[1], { sigma::ir::arch::X64, sigma::ir::system::WINDOWS });

return 0;
//
// sigma::ir::target target(sigma::ir::arch::X64, sigma::ir::system::LINUX);
// sigma::ir::module module(target);
// sigma::ir::builder builder(module);
//
// const sigma::ir::function_signature main_func_ty{
// .identifier = "main",
// .returns = { I32_TYPE }
// };
//
// // main
// builder.create_function(main_func_ty, sigma::ir::linkage::PUBLIC);
//
// const sigma::ir::function_signature printf_func_ty{
// .identifier = "printf",
// .parameters = { PTR_TYPE },
// .returns = { I32_TYPE },
// .has_var_args = true
// };
//
// const auto printf_external = builder.create_external(printf_func_ty, sigma::ir::linkage::SO_LOCAL);
//
// const auto message_true = builder.create_string("true\n");
// const auto message_false = builder.create_string("false\n");
//
// const auto true_ctrl = builder.create_region();
// const auto false_ctrl = builder.create_region();
// const auto after_ctrl = builder.create_region();
//
// builder.create_conditional_branch(builder.create_bool(true), true_ctrl, false_ctrl);
//
// builder.set_control(false_ctrl);
// builder.create_call(printf_external, printf_func_ty, { message_false });
// builder.create_branch(after_ctrl);
//
// builder.set_control(true_ctrl);
// builder.create_call(printf_external, printf_func_ty, { message_true });
// builder.create_branch(after_ctrl);
//
//
//
// // end
// builder.set_control(after_ctrl);
// builder.create_return({ builder.create_signed_integer(0, 32) });
// module.compile();
//
// auto object_file = module.generate_object_file();
// utility::file::write(object_file, "./test/a.o");
//
// return 0;

//utility::console::out
// << "compilation finished ("
// << utility::console::precision(3)
// << timer.elapsed<std::chrono::duration<f64>>()
// << "s)\n";

//std::cout << compilation_result.assembly << '\n';

//std::cout << "bytecode:\n";
//for(utility::byte byte : compilation_result.bytecode) {
// std::cout << byte.to_hex() << ' ';
//}
//std::cout << '\n';

// const auto serialization_result_asm = utility::file::write(
// compilation_result.get_value()->assembly_output, "./test/assembly.asm"
// );
//
// ASSERT(!serialization_result_asm.has_error(), "unhandled error encountered");

//const std::vector<utility::byte> bytes = assembly.get_code();

//for (const auto& byte : bytes) {
// utility::console::out << "0x" << byte.to_hex() << '\n';
//}

//code_generator::executable exe("./test/app.exe", bytes);

//sigma::program_options options;
//sigma::command& compile_command = options.add_command(
// "compile", {
// .description = "compile the given source file using the specified arguments",
// .action = [](sigma::argument_list& arguments)->i32 {
// // parse arguments to settings
// const auto settings_parse_result = sigma::compiler_settings::parse_argument_list(
// arguments
// );

// if(settings_parse_result.has_error()) {
// settings_parse_result.get_error()->print();
// }
const sigma::compiler_description description {
.path = argv[1],
.target = { sigma::ir::arch::X64, sigma::ir::system::WINDOWS }
};

// // construct the compiler object
// sigma::compiler compiler;
// const auto compilation_result = compiler.compile(
// settings_parse_result.get_value()
// );
// compile the specified description, check for errors after we finish
PRINT_ERROR(sigma::compiler::compile(description));

// // check for compilation errors
// if (compilation_result.has_error()) {
// compilation_result.get_error()->print();
// return 1;
// }

// return 0;
// }
// }
//);

//compile_command.add_argument(
// "source", {
// .short_tag = "s",
// .description = "specify the input file the compiler should compile",
// .expected = "path",
// .required = true
//});

//compile_command.add_argument(
// "output", {
// .short_tag = "o",
// .description = "specify the output files (.exe, .o, .llvm)",
// .expected = "path",
// .required = true,
// .value_range = { 1, std::numeric_limits<u64>::max() }
//});

//// performance optimization
//compile_command.add_argument("optimize0", {
// .short_tag = "o0",
// .description = "apply no optimization, reduce compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//compile_command.add_argument("optimize1", {
// .short_tag = "o1",
// .description = "apply basic optimization, reduce code size while limiting the impact on compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//compile_command.add_argument("optimize2", {
// .short_tag = "o2",
// .description = "apply medium optimization, greater impact on compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//compile_command.add_argument("optimize3", {
// .short_tag = "o3",
// .description = "apply aggressive optimization, reduce code size, greatest impact on compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//// size optimization
//compile_command.add_argument("size-optimize0", {
// .short_tag = "s0",
// .description = "apply no size optimization, reduce compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//compile_command.add_argument("size-optimize1", {
// .short_tag = "s1",
// .description = "apply medium size optimization, greater impact on compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//compile_command.add_argument("size-optimize2", {
// .short_tag = "s2",
// .description = "apply aggressive size optimization, potentially slower code, greatest impact on compile time",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//// vectorization
//compile_command.add_argument("fslp-vectorize", {
// .short_tag = "v",
// .description = "enable SLP vectorizer, may increase performance in high-data applications",
// .required = false,
// .default_value = false,
// .implicit_value = true,
//});

//return options.parse(argc, argv);
return 0;
}
4 changes: 2 additions & 2 deletions source/intermediate_representation/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace sigma::ir {
utility::byte_buffer bytecode = m_codegen.emit_bytecode(codegen);

// DEBUG
assembly.append(m_codegen.disassemble(bytecode, codegen));
// assembly.append(m_codegen.disassemble(bytecode, codegen));

// finally, emit the compiled function
function->output = {
Expand All @@ -79,7 +79,7 @@ namespace sigma::ir {
}

// DEBUG
utility::console::println("{}", assembly.get_underlying());
// utility::console::println("{}", assembly.get_underlying());
}

auto module::generate_object_file() -> utility::object_file {
Expand Down
Loading

0 comments on commit 6af3c06

Please sign in to comment.