4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo
9
#include "simodo/interpret/Interpret.h"
10
#include "simodo/interpret/AnalyzeException.h"
12
#include "simodo/bormental/DrBormental.h"
13
#include "simodo/inout/convert/functions.h"
14
#include "simodo/inout/format/fmt.h"
19
#define SemanticFiber_DEBUG_no
21
namespace simodo::interpret
23
loom::FiberStatus Interpret::start()
25
InterpretState state = InterpretState::Flow;
27
for(auto h : _hosts) {
28
if (h->before_start() != InterpretState::Flow) {
29
state = InterpretState::Complete;
36
loom::FiberStatus Interpret::tieKnot()
38
if (_layer_stack.empty())
39
return loom::FiberStatus::Complete;
41
_waiting_for = nullptr;
44
_layer_stack.back().flow_index = _layer_stack.back().next_flow_index;
46
if (_logistics.checkDirection(*this) == Direction::Pause)
47
return loom::FiberStatus::Paused;
49
if (!processOperation()) {
51
return loom::FiberStatus::Paused;
54
if (_layer_stack.empty())
55
return loom::FiberStatus::Complete;
58
return loom::FiberStatus::Delayed;
60
return loom::FiberStatus::Flow;
63
void Interpret::finish()
65
for(auto h : _hosts) {
66
if (h->before_finish(InterpretState::Flow) != InterpretState::Flow)
71
bool Interpret::ready() const
73
return !_layer_stack.empty();
76
const loom::Fiber_interface * Interpret::getWaitingFor()
81
std::u16string Interpret::makeOperatorString(const ast::Node & operation_node)
83
std::u16string semantics_name = operation_node.host();
84
std::u16string operation_code = inout::toU16(std::to_string(static_cast<int>(operation_node.operation())));
85
std::u16string operation_param = operation_node.token().lexeme();
87
return u"{semantics : \"" + semantics_name
88
+ u"\", code : " + operation_code + u", param : \"" + operation_param + u"\"}";
91
/////////////////////////////////////////////////////////////////////////////////////
94
bool Interpret::processOperation()
96
assert(!_layer_stack.empty());
97
assert(flow().flow_index < flow().code_flow.branches().size());
99
size_t flow_layer_position = _layer_stack.size() - 1;
100
const FlowLayerInfo & flow_layer = _layer_stack[flow_layer_position];
102
// Структура АСД не меняется, поэтому ссылка не подвиснет при изменении стека слоёв
103
const ast::Node & op = flow_layer.code_flow.branches()[flow_layer.flow_index];
105
#ifndef SemanticFiber_DEBUG
109
SemanticModule_interface & semantic_module = defineSemanticModule(op);
111
if (flow_layer_position < _layer_stack.size())
112
_layer_stack[flow_layer_position].next_flow_index += 1;
114
semantic_module.performOperation(op);
116
iterateFlowOperation();
118
#ifndef SemanticFiber_DEBUG
120
catch (const AnalyzeException & e)
122
_m.reportError(e.location(), e.what());
125
catch (const bormental::DrBormental & e)
127
_m.reportError( op.token().makeLocation(files()),
128
inout::fmt("Произошло исключение в методе %1 при обработке оператора: %2\nОписание исключения: %3")
130
.arg(makeOperatorString(op))
134
catch (const std::exception & e)
136
_m.reportError( op.token().makeLocation(files()),
137
inout::fmt("Произошло исключение при обработке оператора: %1\nОписание исключения: %2" )
138
.arg(makeOperatorString(op))
144
_m.reportError(op.token().makeLocation(files()),
145
inout::fmt("Произошло исключение при обработке оператора: %1")
146
.arg(makeOperatorString(op)));
153
void Interpret::iterateFlowOperation()
155
assert(!_layer_stack.empty());
158
size_t flow_index = flow().next_flow_index;
160
if (flow_index < flow().code_flow.branches().size())
163
FlowLayerInfo last_flow_info = flow();
165
_layer_stack.pop_back();
167
if (last_flow_info.on_layer_end) {
168
/// \todo Нужно добавить обработку возвращаемого значения, чтобы можно было управлять выполнением
169
/// \todo Нужно убедиться, что в нештатных ситуациях, но при продолжении выполнения,
170
/// вызов функции будет произведён
171
last_flow_info.on_layer_end(last_flow_info);
174
if (_layer_stack.empty())
179
SemanticModule_interface & Interpret::defineSemanticModule(const ast::Node & op)
181
/// \todo Оптимизация на случай большого кол-ва семантических модулей :)
182
/// В данном случае можно было бы упростить
184
const std::u16string & current_host_name = op.host();
186
if (_last_host_name != current_host_name) {
187
auto it_host = std::find_if(_hosts.begin(), _hosts.end(),
188
[current_host_name](SemanticModule_interface *h)
190
return h->checkSemanticName(current_host_name);
193
if (it_host == _hosts.end()) {
194
std::string semantics_name = inout::toU8(current_host_name);
195
if (semantics_name.empty())
196
semantics_name = "SBL";
197
throw bormental::DrBormental("interpret::Interpret::tieKnot",
198
inout::fmt("Владелец семантики '%1' не определён")
199
.arg(semantics_name));
202
_last_host_name = current_host_name;
203
_last_host = *it_host;