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
void initializeOperationSwitchboard(std::vector<BaseOperationParser_t> & switchboard)
23
switchboard.resize(static_cast<size_t>(BaseOperationCode::LastOperation), nullptr);
25
switchboard[static_cast<size_t>(BaseOperationCode::None)] = BaseOperationParser::parseNone;
26
switchboard[static_cast<size_t>(BaseOperationCode::PushConstant)] = BaseOperationParser::parsePushConstant;
27
switchboard[static_cast<size_t>(BaseOperationCode::PushVariable)] = BaseOperationParser::parsePushVariable;
28
switchboard[static_cast<size_t>(BaseOperationCode::ObjectElement)] = BaseOperationParser::parseObjectElement;
29
switchboard[static_cast<size_t>(BaseOperationCode::FunctionCall)] = BaseOperationParser::parseFunctionCall;
30
switchboard[static_cast<size_t>(BaseOperationCode::ProcedureCheck)] = BaseOperationParser::parseProcedureCheck;
31
switchboard[static_cast<size_t>(BaseOperationCode::Block)] = BaseOperationParser::parseBlock;
32
switchboard[static_cast<size_t>(BaseOperationCode::Pop)] = BaseOperationParser::parsePop;
36
BaseInterpret_abstract::BaseInterpret_abstract(Interpret_interface * inter)
38
, _machine(inter->files())
40
initializeOperationSwitchboard(_operation_switchboard);
43
BaseInterpret_abstract::~BaseInterpret_abstract()
47
void BaseInterpret_abstract::reset()
51
InterpretState BaseInterpret_abstract::before_start()
53
return InterpretState::Flow;
56
InterpretState BaseInterpret_abstract::before_finish(InterpretState state)
61
// void BaseInterpret_abstract::setFiber(Interpret * inter)
67
bool BaseInterpret_abstract::isOperationExists(simodo::ast::OperationCode operation_code) const
69
size_t operation_index = static_cast<size_t>(operation_code);
71
return operation_index < _operation_switchboard.size() && _operation_switchboard[operation_index] != nullptr;
74
InterpretState BaseInterpret_abstract::performOperation(const ast::Node & op)
76
if (!isOperationExists(op.operation()))
77
throw bormental::DrBormental("BaseInterpret_abstract::performOperation",
78
"Invalid operation index " + std::to_string(static_cast<size_t>(op.operation())));
80
return _operation_switchboard[static_cast<size_t>(op.operation())](*this,op);
83
void BaseInterpret_abstract::importNamespace(std::u16string name, variable::Object ns, inout::TokenLocation location)
85
_machine.push({name, ns, location,
86
{{ {variable::SPEC_ORIGIN, variable::SPEC_ORIGIN_MODULE},
87
{variable::SPEC_BUILTIN, true},
91
InterpretState BaseInterpret_abstract::executeNone()
93
return InterpretState::Flow;
96
InterpretState BaseInterpret_abstract::executePushConstant(const inout::Token & constant_value)
98
_machine.push(_machine.createVariable_implicit(constant_value));
100
return InterpretState::Flow;
103
InterpretState BaseInterpret_abstract::executePushValue(const inout::Token & variable_name)
105
variable::VariableRef v;
108
v = _machine.findVariable(variable_name);
111
// Перед выходом сохраняем состояние выполнения команды
112
_machine.push({variable_name.lexeme(), {}, variable_name.location(), {}});
118
return InterpretState::Flow;
121
InterpretState BaseInterpret_abstract::executeObjectElement(const inout::Token & dot, const inout::Token & variable_name)
123
variable::Variable v {variable::null_variable()};
126
v = _machine.getElement_implicit(dot,variable_name);
129
// Перед выходом сохраняем состояние выполнения команды
131
_machine.push({variable_name.lexeme(), {}, variable_name.location()});
138
return InterpretState::Flow;
141
InterpretState BaseInterpret_abstract::executeFunctionCall(const ast::Node & op)
143
size_t args_stack_position = _machine.stack().size();
145
inter().addFlowLayer(
147
[this, args_stack_position](FlowLayerInfo flow) {
150
if (!flow.error_sign /*&& checkInterpretType(InterpretType::Preview)*/) {
152
v = _machine.callFunction_implicit(flow.code.token(), args_stack_position);
155
// Перед выходом восстанавливаем ожидаемое состояние выполнения команды
156
_machine.popAmount(_machine.stack().size() - args_stack_position);
158
_machine.push({flow.code.token().lexeme(), {}, flow.code.token().location(), {}});
163
// Чистим параметры функции
164
_machine.popAmount(_machine.stack().size() - args_stack_position);
167
// Добавляем результат функции
168
_machine.push({u"", v, flow.code.token().location()});
171
return InterpretState::Flow;
174
InterpretState BaseInterpret_abstract::executeProcedureCheck()
176
_machine.checkProcedureCalled();
178
return InterpretState::Flow;
181
InterpretState BaseInterpret_abstract::executeBlock(const ast::Node & )
183
return InterpretState::Flow;
186
InterpretState BaseInterpret_abstract::executePop()
190
return InterpretState::Flow;