4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
#include "simodo/interpret/builtins/hosts/base/BaseInterpret_abstract.h"
10
#include "simodo/interpret/AnalyzeException.h"
11
#include "simodo/inout/convert/functions.h"
15
namespace simodo::interpret::builtins
19
using namespace simodo::parser;
21
inout::uri_set_t null_uri_set {};
23
void initializeOperationSwitchboard(std::vector<BaseOperationParser_t> & switchboard)
25
switchboard.resize(static_cast<size_t>(BaseOperationCode::LastOperation), nullptr);
27
switchboard[static_cast<size_t>(BaseOperationCode::None)] = BaseOperationParser::parseNone;
28
switchboard[static_cast<size_t>(BaseOperationCode::PushConstant)] = BaseOperationParser::parsePushConstant;
29
switchboard[static_cast<size_t>(BaseOperationCode::PushVariable)] = BaseOperationParser::parsePushVariable;
30
switchboard[static_cast<size_t>(BaseOperationCode::ObjectElement)] = BaseOperationParser::parseObjectElement;
31
switchboard[static_cast<size_t>(BaseOperationCode::FunctionCall)] = BaseOperationParser::parseFunctionCall;
32
switchboard[static_cast<size_t>(BaseOperationCode::ProcedureCheck)] = BaseOperationParser::parseProcedureCheck;
33
switchboard[static_cast<size_t>(BaseOperationCode::Block)] = BaseOperationParser::parseBlock;
34
switchboard[static_cast<size_t>(BaseOperationCode::Pop)] = BaseOperationParser::parsePop;
38
BaseInterpret_abstract::BaseInterpret_abstract(Interpret_interface * inter)
40
, _machine(inter ? inter->files() : null_uri_set)
44
initializeOperationSwitchboard(_operation_switchboard);
47
BaseInterpret_abstract::~BaseInterpret_abstract()
51
void BaseInterpret_abstract::reset()
55
InterpretState BaseInterpret_abstract::before_start()
57
return InterpretState::Flow;
60
InterpretState BaseInterpret_abstract::before_finish(InterpretState state)
65
// void BaseInterpret_abstract::setFiber(Interpret * inter)
71
bool BaseInterpret_abstract::isOperationExists(simodo::ast::OperationCode operation_code) const
73
size_t operation_index = static_cast<size_t>(operation_code);
75
return operation_index < _operation_switchboard.size() && _operation_switchboard[operation_index] != nullptr;
78
InterpretState BaseInterpret_abstract::performOperation(const ast::Node & op)
80
if (!isOperationExists(op.operation()))
81
throw bormental::DrBormental("BaseInterpret_abstract::performOperation",
82
"Invalid operation index " + std::to_string(static_cast<size_t>(op.operation())));
84
return _operation_switchboard[static_cast<size_t>(op.operation())](*this,op);
87
void BaseInterpret_abstract::importNamespace(const std::u16string & name, const variable::Value & ns, const inout::TokenLocation & location)
89
_machine.push({name, ns, location,
90
{{ {variable::SPEC_ORIGIN, variable::SPEC_ORIGIN_MODULE},
91
{variable::SPEC_BUILTIN, true},
95
InterpretState BaseInterpret_abstract::executeNone()
97
return InterpretState::Flow;
100
InterpretState BaseInterpret_abstract::executePushConstant(const inout::Token & constant_value)
102
_machine.push(_machine.createVariable_implicit(constant_value));
104
return InterpretState::Flow;
107
InterpretState BaseInterpret_abstract::executePushValue(const inout::Token & variable_name)
109
variable::VariableRef v;
112
v = _machine.findVariable(variable_name);
115
// Перед выходом сохраняем состояние выполнения команды
116
_machine.push({variable_name.lexeme(), {}, variable_name.location(), {}});
122
return InterpretState::Flow;
125
InterpretState BaseInterpret_abstract::executeObjectElement(const inout::Token & dot, const inout::Token & variable_name)
127
variable::Variable v {variable::null_variable()};
130
v = _machine.getElement_implicit(dot,variable_name);
133
// Перед выходом сохраняем состояние выполнения команды
135
_machine.push({variable_name.lexeme(), {}, variable_name.location()});
142
return InterpretState::Flow;
145
InterpretState BaseInterpret_abstract::executeFunctionCall(const ast::Node & op)
147
size_t args_stack_position = _machine.stack().size();
149
inter().addFlowLayer(
151
[this, args_stack_position](FlowLayerInfo flow) {
154
if (!flow.error_sign /*&& checkInterpretType(InterpretType::Preview)*/) {
156
v = _machine.callFunction_implicit(flow.code_flow.token(), args_stack_position);
159
// Перед выходом восстанавливаем ожидаемое состояние выполнения команды
160
_machine.popAmount(_machine.stack().size() - args_stack_position);
162
_machine.push({flow.code_flow.token().lexeme(), {}, flow.code_flow.token().location(), {}});
167
// Чистим параметры функции
168
_machine.popAmount(_machine.stack().size() - args_stack_position);
171
// Добавляем результат функции
172
_machine.push({u"", v, flow.code_flow.token().location()});
175
return InterpretState::Flow;
178
InterpretState BaseInterpret_abstract::executeProcedureCheck()
180
_machine.checkProcedureCalled();
182
return InterpretState::Flow;
185
InterpretState BaseInterpret_abstract::executeBlock(const ast::Node & )
187
return InterpretState::Flow;
190
InterpretState BaseInterpret_abstract::executePop()
194
return InterpretState::Flow;