loom

Форк
0
/
Interpret_Fiber.cpp 
211 строк · 7.1 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo
7
*/
8

9
#include "simodo/interpret/Interpret.h"
10
#include "simodo/interpret/AnalyzeException.h"
11

12
#include "simodo/bormental/DrBormental.h"
13
#include "simodo/inout/convert/functions.h"
14
#include "simodo/inout/format/fmt.h"
15

16
#include <algorithm>
17
#include <cassert>
18

19
#define SemanticFiber_DEBUG_no
20

21
namespace simodo::interpret
22
{
23
    loom::FiberStatus Interpret::start()
24
    {
25
        InterpretState state = InterpretState::Flow;
26

27
        for(auto h : _hosts) {
28
            if (h->before_start() != InterpretState::Flow) {
29
                state = InterpretState::Complete;
30
            }
31
        }
32

33
        return state;
34
    }
35

36
    loom::FiberStatus Interpret::tieKnot()
37
    {
38
        if (_layer_stack.empty())
39
            return loom::FiberStatus::Complete;
40

41
        _waiting_for = nullptr;
42
        _errors = false;
43

44
        _layer_stack.back().flow_index = _layer_stack.back().next_flow_index;
45

46
        if (_logistics.checkDirection(*this) == Direction::Pause)
47
            return loom::FiberStatus::Paused;
48

49
        if (!processOperation()) {
50
            _errors = true;
51
            return loom::FiberStatus::Paused;
52
        }
53

54
        if (_layer_stack.empty())
55
            return loom::FiberStatus::Complete;
56

57
        if (_waiting_for)
58
            return loom::FiberStatus::Delayed;
59

60
        return loom::FiberStatus::Flow;
61
    }
62

63
    void Interpret::finish()
64
    {
65
        for(auto h : _hosts) {
66
            if (h->before_finish(InterpretState::Flow) != InterpretState::Flow)
67
                _errors = true;
68
        }
69
    }
70

71
    bool Interpret::ready() const
72
    {
73
        return !_layer_stack.empty();
74
    }
75

76
    const loom::Fiber_interface * Interpret::getWaitingFor()
77
    {
78
        return _waiting_for;
79
    }
80

81
    std::u16string Interpret::makeOperatorString(const ast::Node & operation_node)
82
    {
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();
86

87
        return u"{semantics : \"" + semantics_name 
88
                + u"\", code : " + operation_code + u", param : \"" + operation_param + u"\"}";
89
    }
90

91
    /////////////////////////////////////////////////////////////////////////////////////
92
    // protected
93

94
    bool Interpret::processOperation()
95
    {
96
        assert(!_layer_stack.empty());
97
        assert(flow().flow_index < flow().code_flow.branches().size());
98

99
        size_t                  flow_layer_position = _layer_stack.size() - 1;
100
        const FlowLayerInfo &   flow_layer          = _layer_stack[flow_layer_position];
101

102
        // Структура АСД не меняется, поэтому ссылка не подвиснет при изменении стека слоёв
103
        const ast::Node &       op                  = flow_layer.code_flow.branches()[flow_layer.flow_index];
104

105
#ifndef SemanticFiber_DEBUG
106
        try
107
        {
108
#endif
109
            SemanticModule_interface & semantic_module = defineSemanticModule(op);
110

111
            if (flow_layer_position < _layer_stack.size())
112
                _layer_stack[flow_layer_position].next_flow_index += 1;
113

114
            semantic_module.performOperation(op);
115

116
            iterateFlowOperation();
117

118
#ifndef SemanticFiber_DEBUG
119
        }
120
        catch (const AnalyzeException & e)
121
        {
122
            _m.reportError(e.location(), e.what());
123
            return false;
124
        }
125
        catch (const bormental::DrBormental & e)
126
        {
127
            _m.reportError( op.token().makeLocation(files()),
128
                            inout::fmt("Произошло исключение в методе %1 при обработке оператора: %2\nОписание исключения: %3")
129
                            .arg(e.where())
130
                            .arg(makeOperatorString(op))                        
131
                            .arg(e.what()));
132
            return false;
133
        }
134
        catch (const std::exception & e)
135
        {
136
            _m.reportError( op.token().makeLocation(files()),
137
                            inout::fmt("Произошло исключение при обработке оператора: %1\nОписание исключения: %2" )
138
                            .arg(makeOperatorString(op))
139
                            .arg(e.what()));
140
            return false;
141
        }
142
        catch (...)
143
        {
144
            _m.reportError(op.token().makeLocation(files()),
145
                            inout::fmt("Произошло исключение при обработке оператора: %1")
146
                            .arg(makeOperatorString(op)));
147
            return false;
148
        }
149
#endif
150
        return true;
151
    }
152

153
    void Interpret::iterateFlowOperation()
154
    {
155
        assert(!_layer_stack.empty());
156

157
        while(true) {
158
            size_t flow_index = flow().next_flow_index;
159
            
160
            if (flow_index < flow().code_flow.branches().size())
161
                break;
162
                
163
            FlowLayerInfo last_flow_info = flow();
164

165
            _layer_stack.pop_back();
166

167
            if (last_flow_info.on_layer_end) {
168
                /// \todo Нужно добавить обработку возвращаемого значения, чтобы можно было управлять выполнением
169
                /// \todo Нужно убедиться, что в нештатных ситуациях, но при продолжении выполнения,
170
                /// вызов функции будет произведён
171
                last_flow_info.on_layer_end(last_flow_info);
172
            }
173

174
            if (_layer_stack.empty())
175
                break;
176
        }
177
    }
178

179
    SemanticModule_interface & Interpret::defineSemanticModule(const ast::Node & op)
180
    {
181
        /// \todo Оптимизация на случай большого кол-ва семантических модулей :)
182
        /// В данном случае можно было бы упростить
183

184
        const std::u16string & current_host_name = op.host();
185

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)
189
                            { 
190
                                return h->checkSemanticName(current_host_name);
191
                            });
192

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));
200
            }
201

202
            _last_host_name = current_host_name;
203
            _last_host      = *it_host;
204
        }
205

206
        assert(_last_host);
207

208
        return *_last_host;
209
    }
210

211
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.