loom

Форк
0
/
BaseInterpret_abstract.cpp 
197 строк · 6.5 Кб
1
/*
2
MIT License
3

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

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

9
#include "simodo/interpret/builtins/hosts/base/BaseInterpret_abstract.h"
10
#include "simodo/interpret/AnalyzeException.h"
11
#include "simodo/inout/convert/functions.h"
12

13
#include <cassert>
14

15
namespace simodo::interpret::builtins
16
{
17
    namespace 
18
    {
19
        using namespace simodo::parser;
20

21
        inout::uri_set_t null_uri_set {};
22

23
        void initializeOperationSwitchboard(std::vector<BaseOperationParser_t> & switchboard)
24
        {
25
            switchboard.resize(static_cast<size_t>(BaseOperationCode::LastOperation), nullptr);
26

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;
35
        }
36
    }
37

38
BaseInterpret_abstract::BaseInterpret_abstract(Interpret_interface * inter)
39
    : _interpret(inter)
40
    , _machine(inter ? inter->files() : null_uri_set)
41
{
42
    assert(inter);
43
    
44
    initializeOperationSwitchboard(_operation_switchboard);
45
}
46

47
BaseInterpret_abstract::~BaseInterpret_abstract()
48
{
49
}
50

51
void BaseInterpret_abstract::reset()
52
{
53
}
54

55
InterpretState BaseInterpret_abstract::before_start() 
56
{ 
57
    return InterpretState::Flow; 
58
}
59

60
InterpretState BaseInterpret_abstract::before_finish(InterpretState state) 
61
{ 
62
    return state; 
63
}
64

65
// void BaseInterpret_abstract::setFiber(Interpret * inter)
66
// {
67
//     assert(inter);
68
//     _interpret = inter;
69
// }
70

71
bool BaseInterpret_abstract::isOperationExists(simodo::ast::OperationCode operation_code) const
72
{
73
    size_t operation_index = static_cast<size_t>(operation_code);
74

75
    return operation_index < _operation_switchboard.size() && _operation_switchboard[operation_index] != nullptr;
76
}
77

78
InterpretState BaseInterpret_abstract::performOperation(const ast::Node & op) 
79
{
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())));
83

84
    return _operation_switchboard[static_cast<size_t>(op.operation())](*this,op);
85
}
86

87
void BaseInterpret_abstract::importNamespace(const std::u16string & name, const variable::Value & ns, const inout::TokenLocation & location)
88
{
89
    _machine.push({name, ns, location, 
90
                {{  {variable::SPEC_ORIGIN, variable::SPEC_ORIGIN_MODULE}, 
91
                    {variable::SPEC_BUILTIN, true},
92
                }} });
93
}
94

95
InterpretState BaseInterpret_abstract::executeNone()
96
{
97
    return InterpretState::Flow;
98
}
99

100
InterpretState BaseInterpret_abstract::executePushConstant(const inout::Token & constant_value)
101
{
102
    _machine.push(_machine.createVariable_implicit(constant_value));
103

104
    return InterpretState::Flow;
105
}
106

107
InterpretState BaseInterpret_abstract::executePushValue(const inout::Token & variable_name)
108
{
109
    variable::VariableRef v;
110

111
    try {
112
        v = _machine.findVariable(variable_name);
113
    }
114
    catch(...) {
115
        // Перед выходом сохраняем состояние выполнения команды
116
        _machine.push({variable_name.lexeme(), {}, variable_name.location(), {}}); 
117
        throw;
118
    }
119

120
    _machine.pushRef(v);
121

122
    return InterpretState::Flow;
123
}
124

125
InterpretState BaseInterpret_abstract::executeObjectElement(const inout::Token & dot, const inout::Token & variable_name)
126
{
127
    variable::Variable v {variable::null_variable()};
128

129
    try {
130
        v = _machine.getElement_implicit(dot,variable_name);
131
    }
132
    catch(...) {
133
        // Перед выходом сохраняем состояние выполнения команды
134
        _machine.pop();
135
        _machine.push({variable_name.lexeme(), {}, variable_name.location()}); 
136
        throw;
137
    }
138

139
    _machine.pop();
140
    _machine.push(v);
141

142
    return InterpretState::Flow;
143
}
144

145
InterpretState BaseInterpret_abstract::executeFunctionCall(const ast::Node & op)
146
{
147
    size_t args_stack_position = _machine.stack().size();
148

149
    inter().addFlowLayer(
150
                op, 
151
                [this, args_stack_position](FlowLayerInfo flow) {
152
                    variable::Value v;
153

154
                    if (!flow.error_sign /*&& checkInterpretType(InterpretType::Preview)*/) {
155
                        try {
156
                            v = _machine.callFunction_implicit(flow.code_flow.token(), args_stack_position);
157
                        }
158
                        catch(...) {
159
                            // Перед выходом восстанавливаем ожидаемое состояние выполнения команды
160
                            _machine.popAmount(_machine.stack().size() - args_stack_position);
161
                            _machine.pop();
162
                            _machine.push({flow.code_flow.token().lexeme(), {}, flow.code_flow.token().location(), {}}); 
163
                            throw;
164
                        }
165
                    }
166

167
                    // Чистим параметры функции
168
                    _machine.popAmount(_machine.stack().size() - args_stack_position);
169
                    // Чистим функцию
170
                    _machine.pop();
171
                    // Добавляем результат функции
172
                    _machine.push({u"", v, flow.code_flow.token().location()});
173
                });
174
    
175
    return InterpretState::Flow;
176
}
177

178
InterpretState BaseInterpret_abstract::executeProcedureCheck()
179
{
180
    _machine.checkProcedureCalled();
181

182
    return InterpretState::Flow;
183
}
184

185
InterpretState BaseInterpret_abstract::executeBlock(const ast::Node & )
186
{
187
    return InterpretState::Flow;
188
}
189

190
InterpretState BaseInterpret_abstract::executePop()
191
{
192
    _machine.pop();
193

194
    return InterpretState::Flow;
195
}
196

197
}
198

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

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

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

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