diff --git a/CMakeLists.txt b/CMakeLists.txt index c2fa8b7..3697459 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ add_executable(sugar include/molasses/lexer.h src/molasses/parser_primitives.cpp include/molasses/parser_primitives.h - include/molasses/generator_primitives.h) + include/molasses/generator_primitives.h src/molasses/interpreter.cpp) function(add_expect_test [testname filename]) add_test( diff --git a/include/molasses/parser_primitives.h b/include/molasses/parser_primitives.h index 99e98b2..1d31abc 100644 --- a/include/molasses/parser_primitives.h +++ b/include/molasses/parser_primitives.h @@ -214,6 +214,7 @@ namespace molasses { std::vector operator>>(std::vector current_stack, const operation& next_op); std::optional try_parse_int32(const std::string& str); + std::optional try_parse_int64(const std::string& str); struct parser_context { std::vector> types; @@ -229,7 +230,11 @@ namespace molasses { parser_context parser; std::vector> procedures; }; - + + using success_t = bool; + + std::tuple>> interpret(interpreter_stack, generate_context, std::string ); + generate_context parse(parser_context, const lexed_output&); std::vector generate(const generate_context&); diff --git a/src/main.cpp b/src/main.cpp index 56374f1..6c2a56d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -111,6 +111,19 @@ int main(int argc, char** argv) { compile_stack.emplace(lexer_1); } else throw build_system_error("merge-all expects at least 1 lexed outputs\n"); + } else if(elem == "interpret") { + if(not compile_stack.empty() and std::holds_alternative(compile_stack.top())) { + auto context = std::get(compile_stack.top()); + compile_stack.pop(); + molasses::interpreter_stack stack; + while(true) { + std::cout << "%> "; + std::string contents; + std::getline(std::cin, contents); + molasses::interpret(stack, context, contents); + } + } else + throw build_system_error("merge-all expects at least 1 lexed outputs\n"); } else if(elem == "assemble") { if(not compile_stack.empty() and std::holds_alternative(compile_stack.top())) { auto filename = std::get(compile_stack.top()); diff --git a/src/molasses/interpreter.cpp b/src/molasses/interpreter.cpp new file mode 100644 index 0000000..716b922 --- /dev/null +++ b/src/molasses/interpreter.cpp @@ -0,0 +1,30 @@ +#include +#include "molasses/parser_primitives.h" + +namespace molasses { + std::tuple>> interpret(interpreter_stack stack, generate_context context, std::string text){ + auto copy_stack = stack; + auto copy_ctx = context; + + try { + lexed_output new_lex = lex("%interpreter%", text); + context.lexer = concatenate(context.lexer, new_lex); + auto count_to_execute = new_lex.symbols.size(); + auto executable_span = std::span( + context.lexer.symbols.begin()+((intptr_t)context.lexer.symbols.size() - (intptr_t)count_to_execute), + context.lexer.symbols.end() + ); + + for(const auto& l : executable_span) { + auto token = context.lexer.dictionary[l]; + if(auto value_i32 = try_parse_int32(token); value_i32) stack.push(value_i32.value()); + else if(auto value_i64 = try_parse_int64(token); value_i64) stack.push(value_i64.value()); + else context.parser.lookup_operation(token)->execute(context, stack); + } + } catch (std::runtime_error& err) { + return {copy_stack, copy_ctx, std::make_shared(err)}; + } + + return {stack, context, std::nullopt}; + } +}