diff --git a/CMakeLists.txt b/CMakeLists.txt index f1638ac..8bab386 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,18 @@ enable_testing() include_directories(include) add_executable(sugar - src/main.cpp - src/molasses/lexer.cpp - src/molasses/generator_primitives_x86_64_linux.cpp + include/generalized_parsing.h + include/molasses/errors.h + include/molasses/generator_primitives.h include/molasses/lexer.h - src/molasses/parser_primitives.cpp include/molasses/parser_primitives.h - include/molasses/generator_primitives.h include/molasses/errors.h include/molasses/parser_types.h src/molasses/generator_primitives.cpp include/generalized_parsing.h) + include/molasses/parser_types.h + src/main.cpp + src/molasses/generator_primitives.cpp + src/molasses/generator_primitives_x86_64_linux.cpp + src/molasses/interpreter.cpp + src/molasses/lexer.cpp + src/molasses/parser_primitives.cpp) function(add_expect_test [testname filename]) add_test( diff --git a/include/molasses/parser_primitives.h b/include/molasses/parser_primitives.h index 72bd07e..04eaaf9 100644 --- a/include/molasses/parser_primitives.h +++ b/include/molasses/parser_primitives.h @@ -31,7 +31,10 @@ constexpr size_t architecture_ptr_size = 4; 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; std::vector> operations; @@ -47,8 +50,11 @@ namespace molasses { std::vector> procedures; }; + using success_t = bool; + + std::tuple>> interpret(interpreter_stack, generate_context, std::string ); + std::optional try_parse_int32(const std::string& str); - 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 728fbbd..b3cc26f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -106,6 +106,19 @@ int main(int argc, char** argv) { compile_stack.emplace(lexer_1); } else throw molasses::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 molasses::build_system_error("interpreter expects 1 generated context\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}; + } +} diff --git a/src/molasses/parser_primitives.cpp b/src/molasses/parser_primitives.cpp index 40ce4dc..57480eb 100644 --- a/src/molasses/parser_primitives.cpp +++ b/src/molasses/parser_primitives.cpp @@ -358,7 +358,17 @@ namespace molasses { } void procedure_operation::execute(const generate_context& ctx, interpreter_stack& stack) const { + for(const auto& elem : _body) { + if(auto n = ctx.parser.lookup_operation(ctx.lexer.dictionary.at(elem)); n) + n->execute(ctx, stack); + else if(auto maybe_i64 = try_parse_int64(ctx.lexer.dictionary.at(elem)); maybe_i64) + stack.emplace(int64_t(maybe_i64.value())); + else if(auto maybe_i32 = try_parse_int32(ctx.lexer.dictionary.at(elem)); maybe_i32) + stack.emplace(int32_t(maybe_i32.value())); + else + std::cerr << "OPERATION NOT FOUND: " << elem <<"\n"; + } } } diff --git a/tests/004.exp b/tests/004.exp index d504d34..8305117 100644 --- a/tests/004.exp +++ b/tests/004.exp @@ -86,7 +86,7 @@ expect eof spawn -noecho $SUGAR_EXECUTABLE tests/004/incomplete-07.mol lex parse expect { eof { abort "should display failure line" } - {incomplete-07.mol:2} + {incomplete-07.mol:1} } expect { eof { abort "should display failure in incomplete-07" }