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/loom/Loom_interface.h"
13
#include "simodo/bormental/DrBormental.h"
14
#include "simodo/inout/convert/functions.h"
15
#include "simodo/inout/format/fmt.h"
20
#define SemanticFiber_DEBUG_no
22
namespace simodo::interpret
24
bool Interpret::wait(const variable::Variable & var)
26
const ChildFlowInfo * info = findChildFlowInfo(var);
30
if (var.origin().type() != variable::ValueType::Object)
33
_waiting_for = info->child->fiber();
38
bool Interpret::push(const variable::Variable & var)
40
const ChildFlowInfo * info = findChildFlowInfo(var);
44
if (var.origin().type() != variable::ValueType::Object)
47
if (info->child->ready())
48
throw bormental::DrBormental("ScriptSemantics_abstract::executeFunctionCall",
49
inout::fmt("Unacceptable use of an already working fiber"));
51
std::shared_ptr<variable::Object> source_object = var.origin().value().getObject();
52
auto [begin,end] = info->child->stack().boundaryLowAndTop(info->child_bound);
54
for(name_index_t i=begin; i < end; ++i) {
55
variable::Variable & target_variable = info->child->stack().variable(i);
56
if (!target_variable.value().isFunction()) {
57
const variable::Variable & source_element = source_object->getVariableByName(target_variable.name());
58
assert(!source_element.name().empty());
59
target_variable.value() = source_element.value().copy();
66
bool Interpret::pull(variable::Variable & var)
68
const ChildFlowInfo * info = findChildFlowInfo(var);
72
if (var.origin().type() != variable::ValueType::Object)
75
if (info->child->ready())
76
throw bormental::DrBormental("ScriptSemantics_abstract::executeFunctionCall",
77
inout::fmt("Unacceptable use of an already working fiber"));
79
std::shared_ptr<variable::Object> target_object = var.origin().value().getObject();
80
auto [begin,end] = info->child->stack().boundaryLowAndTop(info->child_bound);
82
for(name_index_t i=begin; i < end; ++i) {
83
const variable::Variable & source_element = info->child->stack().variable(i);
84
if (!source_element.value().isFunction()) {
85
variable::Variable & target_variable = const_cast<variable::Variable &>(target_object->getVariableByName(source_element.name()));
86
assert(!target_variable.name().empty());
87
target_variable.value().setValueRecursively(source_element.value());
94
// bool Interpret::cut()
100
bool Interpret::addChildFiber(const variable::Variable & var)
102
const ChildFlowInfo * info = findChildFlowInfo(var);
106
if (var.origin().type() != variable::ValueType::Object)
109
std::shared_ptr<variable::Object> obj = var.origin().value().getObject();
111
Interpret * child = new Interpret(_type, _m, _loom, _semantic_factories);
113
boundary_index_t child_bound = child->copyBaseBounds(stack());
115
child->stack().fillFromObject(obj);
116
child->stack().startBoundary();
118
/// \todo Это одноразовое копирование не годится для общего случая, особенно для итеративной отладки!
120
child->_files = _files;
121
// child->_breakpoints = _breakpoints;
124
const variable::Value & name_value = obj->find(u"name");
126
if (name_value.isString())
127
name = inout::toU8(name_value.getString());
129
name = inout::toU8(var.origin().name());
131
if (!_loom.dock(child,true,this,loom::FiberStatus::Delayed,name)) {
136
_childs.push_back({obj,child,child_bound});
140
const ChildFlowInfo * Interpret::findChildFlowInfo(const variable::Variable & var) const
142
if (var.origin().type() != variable::ValueType::Object)
145
std::shared_ptr<variable::Object> obj = var.origin().value().getObject();
147
auto it = std::find_if( _childs.begin(), _childs.end(),
148
[obj](const ChildFlowInfo & info)
150
return info.our_object.get() == obj.get();
153
if (it == _childs.end())