|
#include <span>
|
|
#include "molasses/parser_primitives.h"
|
|
|
|
namespace molasses {
|
|
std::tuple<interpreter_stack, generate_context, std::optional<std::shared_ptr<std::runtime_error>>> 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<std::runtime_error>(err)};
|
|
}
|
|
|
|
return {stack, context, std::nullopt};
|
|
}
|
|
}
|