From 1e4141f737a2642ff80fef3e34ba0db1056962af Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Wed, 25 Jan 2023 13:22:06 +0100 Subject: [PATCH] Added more instructions to get closer to the hello world --- include/molasses/parser_primitives.h | 5 +- src/main.cpp | 15 +-- src/molasses/parser_primitives.cpp | 194 ++++++++++++++++++++++++--- 3 files changed, 182 insertions(+), 32 deletions(-) diff --git a/include/molasses/parser_primitives.h b/include/molasses/parser_primitives.h index dd8bb7b..39eaa96 100644 --- a/include/molasses/parser_primitives.h +++ b/include/molasses/parser_primitives.h @@ -144,8 +144,9 @@ namespace molasses { }; parser_context parse(parser_context, const lexed_output&); - - parser_context register_integers(parser_context); + + parser_context register_integers(parser_context); + parser_context register_i32_operations(parser_context); bool type_check(const parser_context&, const lexed_output&, const std::vector&, std::vector execution_input, const std::vector& execution_output); } diff --git a/src/main.cpp b/src/main.cpp index 80c7929..181c8b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,20 +44,7 @@ int main() { molasses::parser_context ctx; ctx = molasses::register_integers(ctx); - ctx.operations.emplace_back( - std::make_shared( - std::string{"+"}, - std::vector({"i32", "i32"}), - std::vector({"i32"}), - std::vector({ - " popq %rax\n", - " popq %rbx\n", - " addl %ebx, %eax\n", - " andl $0xFFFFFFFF, %eax\n", - " pushq %rax\n" - }) - ) - ); + ctx = molasses::register_i32_operations(ctx); molasses::parse(ctx, lexed); } diff --git a/src/molasses/parser_primitives.cpp b/src/molasses/parser_primitives.cpp index 3503ef8..06e9189 100644 --- a/src/molasses/parser_primitives.cpp +++ b/src/molasses/parser_primitives.cpp @@ -3,19 +3,178 @@ #include #include "molasses/parser_primitives.h" +enum class architecture_t { + x86_64 +}; + +constexpr architecture_t architecture = architecture_t::x86_64; + namespace molasses { - parser_context register_integers(parser_context ctx) { - ctx.types.push_back(std::make_shared("i8",1)); - ctx.types.push_back(std::make_shared("i16",2)); - ctx.types.push_back(std::make_shared("i32",4)); - ctx.types.push_back(std::make_shared("i64",8)); - ctx.types.push_back(std::make_shared("u8",1)); - ctx.types.push_back(std::make_shared("u16",2)); - ctx.types.push_back(std::make_shared("u32",4)); - ctx.types.push_back(std::make_shared("u64",8)); - - return ctx; - } + parser_context register_integers(parser_context ctx) { + ctx.types.push_back(std::make_shared("i8",1)); + ctx.types.push_back(std::make_shared("i16",2)); + ctx.types.push_back(std::make_shared("i32",4)); + ctx.types.push_back(std::make_shared("i64",8)); + ctx.types.push_back(std::make_shared("u8",1)); + ctx.types.push_back(std::make_shared("u16",2)); + ctx.types.push_back(std::make_shared("u32",4)); + ctx.types.push_back(std::make_shared("u64",8)); + + return ctx; + } + + parser_context register_i32_operations(parser_context ctx) { + ctx.operations.emplace_back( + std::make_shared( + std::string{"+"}, + std::vector({"i32", "i32"}), + std::vector({"i32"}), + std::vector({ + " popq %rax\n", + " popq %rbx\n", + " addl %ebx, %eax\n", + " andl $0xFFFFFFFF, %eax\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"*"}, + std::vector({"i32", "i32"}), + std::vector({"i32"}), + std::vector({ + " popq %rax\n", + " popq %rbx\n", + " multl %ebx, %eax\n", + " andl $0xFFFFFFFF, %eax\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"-"}, + std::vector({"i32", "i32"}), + std::vector({"i32"}), + std::vector({ + " popq %rax\n", + " popq %rbx\n", + " subl %ebx, %eax\n", + " andl $0xFFFFFFFF, %eax\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"i32-to-i64"}, + std::vector({"i32"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " movslq %rax\n", + " pushq %rax\n" + }) + ) + ); + + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall1"}, + std::vector({"i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall2"}, + std::vector({"i64", "i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " popq %rsi\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall3"}, + std::vector({"i64", "i64", "i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " popq %rsi\n", + " popq %rdx\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall4"}, + std::vector({"i64", "i64", "i64", "i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " popq %rsi\n", + " popq %rdx\n", + " popq %r10\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall5"}, + std::vector({"i64", "i64", "i64", "i64", "i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " popq %rsi\n", + " popq %rdx\n", + " popq %r10\n", + " popq %r8\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + ctx.operations.emplace_back( + std::make_shared( + std::string{"syscall6"}, + std::vector({"i64", "i64", "i64", "i64", "i64", "i64", "i64"}), + std::vector({"i64"}), + std::vector({ + " popq %rax\n", + " popq %rdi\n", + " popq %rsi\n", + " popq %rdx\n", + " popq %r10\n", + " popq %r8\n", + " popq %r9\n", + " syscall\n", + " pushq %rax\n" + }) + ) + ); + + return ctx; + } std::vector operator>>(std::vector current_stack, const operation& next_op) { { @@ -90,7 +249,8 @@ namespace molasses { return type_stack == execution_output; } - std::vector initialize_stack() { + std::vector initialize_stack() + requires (architecture == architecture_t::x86_64) { return { ".bss\n",// TODO: make threadlocal "stack_instruction:\n", @@ -215,7 +375,8 @@ namespace molasses { return ctx; } - std::vector generate_call(std::string target) { + std::vector generate_call(std::string target) + requires (architecture == architecture_t::x86_64) { static uint64_t label_count= 0; return { " movq return_label_n"+std::to_string(label_count)+", (stack_instruction)\n", @@ -225,13 +386,14 @@ namespace molasses { }; } - std::vector generate_push_int32(int32_t target) { + std::vector generate_push_int32(int32_t target) requires (architecture == architecture_t::x86_64) { return { " pushq $" +std::to_string(target)+ "\n" }; } - std::vector procedure_operation::generate(const parser_context& ctx, const lexed_output& lexer_data) const { + std::vector procedure_operation::generate(const parser_context& ctx, const lexed_output& lexer_data) const + requires (architecture == architecture_t::x86_64) { std::vector ops; ops.emplace_back(name()+":\n");