diff --git a/include/molasses/generator_primitives.h b/include/molasses/generator_primitives.h index e6ea0f7..e03ee0c 100644 --- a/include/molasses/generator_primitives.h +++ b/include/molasses/generator_primitives.h @@ -2,21 +2,30 @@ #include "molasses/parser_primitives.h" namespace molasses { + template std::vector initialize_stack(); - + + template std::vector generate_return(); - + + template std::vector generate_label(const std::string& target); - + + template std::vector generate_push_int32(int32_t target); + template std::vector generate_push_int64(int64_t target); - + + template std::vector generate_call(const std::string& target); - + + template std::vector generate_enter(); + template std::vector generate_push_string_ptr(const symbol&); + template std::vector generate_string(const symbol&, const std::string&); } \ No newline at end of file diff --git a/include/molasses/parser_primitives.h b/include/molasses/parser_primitives.h index b7abd52..800cf68 100644 --- a/include/molasses/parser_primitives.h +++ b/include/molasses/parser_primitives.h @@ -211,6 +211,8 @@ namespace molasses { std::vector generate(const generate_context&); parser_context register_integers(parser_context); + + template 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/molasses/generator_primitives_x86_64_linux.cpp b/src/molasses/generator_primitives_x86_64_linux.cpp index f330615..6c56ca4 100644 --- a/src/molasses/generator_primitives_x86_64_linux.cpp +++ b/src/molasses/generator_primitives_x86_64_linux.cpp @@ -46,7 +46,8 @@ namespace molasses { return builder.str(); } - parser_context register_integers(parser_context ctx) requires(architecture == architecture_t::x86_64_linux) + // TODO: move to a platform independent file + 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)); @@ -60,8 +61,8 @@ namespace molasses { return ctx; } - parser_context register_i32_operations(parser_context ctx) - requires (architecture == architecture_t::x86_64_linux) { + template<> + parser_context register_i32_operations(parser_context ctx) { ctx.operations.emplace_back( std::make_shared( std::string{"+"}, @@ -261,51 +262,52 @@ namespace molasses { return ctx; } - - std::vector generate_call(const std::string& target) - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector generate_call(const std::string& target) { return { " call "+marshal(target)+"\n", }; } - std::vector generate_string(const symbol& representation, const std::string& string_value) - requires (architecture == architecture_t::x86_64_linux) { + template<> + std::vector generate_string(const symbol& representation, const std::string& string_value) { return { "__EMITED_STRING_____"+std::to_string(representation.id)+"___:\n", " .asciz \""+escape(string_value)+"\"\n", }; } - std::vector generate_push_string_ptr(const symbol& representation) { + template<> + std::vector generate_push_string_ptr(const symbol& representation) { return { " pushq $__EMITED_STRING_____"+std::to_string(representation.id)+"___\n" }; } - - std::vector generate_push_int32(int32_t target) - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector generate_push_int32(int32_t target) { return { " pushq $" +std::to_string(target)+ "\n" }; } - std::vector generate_push_int64(int64_t target) - requires (architecture == architecture_t::x86_64_linux) { + template<> + std::vector generate_push_int64(int64_t target) { return { " pushq $" +std::to_string(target)+ "\n" }; } - - std::vector generate_label(const std::string& target) - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector generate_label(const std::string& target) { return { marshal(target)+":\n" }; } - - std::vector generate_return() - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector generate_return() { return { " // Return to caller\n", " addq $-8, %r10\n", @@ -313,18 +315,18 @@ namespace molasses { " retq\n" }; } - - std::vector generate_enter() - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector generate_enter() { return { " // Prepare the function stack\n", " popq (%r10)\n" " addq $8, %r10\n", }; } - - std::vector initialize_stack() - requires (architecture == architecture_t::x86_64_linux) { + + template<> + std::vector initialize_stack() { std::vector operations = { "code:\n", " .skip 1000000\n", diff --git a/src/molasses/lexer.cpp b/src/molasses/lexer.cpp index e1d7bd5..d593212 100644 --- a/src/molasses/lexer.cpp +++ b/src/molasses/lexer.cpp @@ -60,7 +60,7 @@ namespace molasses { continue; } if(character == '\"') { - if(builder.view().empty() && state == state_machine_t::normal) { + if(builder.str().empty() && state == state_machine_t::normal) { state = state_machine_t::string; continue; } else if (state == state_machine_t::string) { diff --git a/tests/001.exp b/tests/001.exp index a4cf4cb..fb1c131 100644 --- a/tests/001.exp +++ b/tests/001.exp @@ -1,6 +1,7 @@ #!/usr/bin/expect set SUGAR_EXECUTABLE $::env(SUGAR_EXECUTABLE) +set BUILD_NAME 001. proc abort {reason} { puts "test failed $reason" @@ -20,7 +21,7 @@ if {$value != 0} { } -spawn -noecho $SUGAR_EXECUTABLE tests/001/exit-with-1.mol lex parse /tmp/sugar.generated generate assemble +spawn -noecho $SUGAR_EXECUTABLE tests/001/exit-with-1.mol lex parse "/tmp/sugar.generated.$BUILD_NAME" generate assemble expect { error { abort "failed to compile" } eof { abort "didn't run clang" } @@ -37,7 +38,7 @@ if {$value != 0} { abort "compiler crashed" } -spawn -noecho /tmp/sugar.generated +spawn -noecho /tmp/sugar.generated.$BUILD_NAME expect eof lassign [wait] pid spawnid os_error_flag value if {$value != 1} { diff --git a/tests/002.exp b/tests/002.exp index fbc7caf..0799ba5 100644 --- a/tests/002.exp +++ b/tests/002.exp @@ -1,6 +1,7 @@ #!/usr/bin/expect set SUGAR_EXECUTABLE $::env(SUGAR_EXECUTABLE) +set BUILD_NAME 002. proc abort {reason} { puts "test failed $reason" @@ -20,7 +21,7 @@ if {$value != 0} { } -spawn -noecho $SUGAR_EXECUTABLE tests/002/exit-with-1.mol lex parse /tmp/sugar.generated generate assemble +spawn -noecho $SUGAR_EXECUTABLE tests/002/exit-with-1.mol lex parse /tmp/sugar.generated.$BUILD_NAME generate assemble expect { error { abort "failed to compile" } eof { abort "didn't run clang" } @@ -37,7 +38,7 @@ if {$value != 0} { abort "compiler crashed" } -spawn -noecho /tmp/sugar.generated +spawn -noecho /tmp/sugar.generated.$BUILD_NAME expect eof lassign [wait] pid spawnid os_error_flag value if {$value != 1} { diff --git a/tests/003.exp b/tests/003.exp index 2b61900..bfa55ce 100644 --- a/tests/003.exp +++ b/tests/003.exp @@ -1,6 +1,7 @@ #!/usr/bin/expect set SUGAR_EXECUTABLE $::env(SUGAR_EXECUTABLE) +set BUILD_NAME 003. proc abort {reason} { puts "test failed $reason" @@ -25,7 +26,7 @@ if {$value != 0} { } -spawn -noecho $SUGAR_EXECUTABLE tests/003/exit-with-1.mol lex tests/003/library.mol lex merge parse /tmp/sugar.generated generate assemble +spawn -noecho $SUGAR_EXECUTABLE tests/003/exit-with-1.mol lex tests/003/library.mol lex merge parse /tmp/sugar.generated.$BUILD_NAME generate assemble expect { error { abort "failed to compile" } eof { abort "didn't run clang" } @@ -42,7 +43,7 @@ if {$value != 0} { abort "compiler crashed" } -spawn -noecho /tmp/sugar.generated +spawn -noecho /tmp/sugar.generated.$BUILD_NAME expect { error { abort "failed to compile" } eof { abort "didn't output" }