loom

Форк
0
/
BaseInterpret_abstract.cpp 
193 строки · 6.3 Кб
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
        void initializeOperationSwitchboard(std::vector<BaseOperationParser_t> & switchboard)
22
        {
23
            switchboard.resize(static_cast<size_t>(BaseOperationCode::LastOperation), nullptr);
24

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;
33
        }
34
    }
35

36
BaseInterpret_abstract::BaseInterpret_abstract(Interpret_interface * inter)
37
    : _interpret(inter)
38
    , _machine(inter->files())
39
{
40
    initializeOperationSwitchboard(_operation_switchboard);
41
}
42

43
BaseInterpret_abstract::~BaseInterpret_abstract()
44
{
45
}
46

47
void BaseInterpret_abstract::reset()
48
{
49
}
50

51
InterpretState BaseInterpret_abstract::before_start() 
52
{ 
53
    return InterpretState::Flow; 
54
}
55

56
InterpretState BaseInterpret_abstract::before_finish(InterpretState state) 
57
{ 
58
    return state; 
59
}
60

61
// void BaseInterpret_abstract::setFiber(Interpret * inter)
62
// {
63
//     assert(inter);
64
//     _interpret = inter;
65
// }
66

67
bool BaseInterpret_abstract::isOperationExists(simodo::ast::OperationCode operation_code) const
68
{
69
    size_t operation_index = static_cast<size_t>(operation_code);
70

71
    return operation_index < _operation_switchboard.size() && _operation_switchboard[operation_index] != nullptr;
72
}
73

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

80
    return _operation_switchboard[static_cast<size_t>(op.operation())](*this,op);
81
}
82

83
void BaseInterpret_abstract::importNamespace(std::u16string name, variable::Object ns, inout::TokenLocation location)
84
{
85
    _machine.push({name, ns, location, 
86
                {{  {variable::SPEC_ORIGIN, variable::SPEC_ORIGIN_MODULE}, 
87
                    {variable::SPEC_BUILTIN, true},
88
                }} });
89
}
90

91
InterpretState BaseInterpret_abstract::executeNone()
92
{
93
    return InterpretState::Flow;
94
}
95

96
InterpretState BaseInterpret_abstract::executePushConstant(const inout::Token & constant_value)
97
{
98
    _machine.push(_machine.createVariable_implicit(constant_value));
99

100
    return InterpretState::Flow;
101
}
102

103
InterpretState BaseInterpret_abstract::executePushValue(const inout::Token & variable_name)
104
{
105
    variable::VariableRef v;
106

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

116
    _machine.pushRef(v);
117

118
    return InterpretState::Flow;
119
}
120

121
InterpretState BaseInterpret_abstract::executeObjectElement(const inout::Token & dot, const inout::Token & variable_name)
122
{
123
    variable::Variable v {variable::null_variable()};
124

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

135
    _machine.pop();
136
    _machine.push(v);
137

138
    return InterpretState::Flow;
139
}
140

141
InterpretState BaseInterpret_abstract::executeFunctionCall(const ast::Node & op)
142
{
143
    size_t args_stack_position = _machine.stack().size();
144

145
    inter().addFlowLayer(
146
                op, 
147
                [this, args_stack_position](FlowLayerInfo flow) {
148
                    variable::Value v;
149

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

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

174
InterpretState BaseInterpret_abstract::executeProcedureCheck()
175
{
176
    _machine.checkProcedureCalled();
177

178
    return InterpretState::Flow;
179
}
180

181
InterpretState BaseInterpret_abstract::executeBlock(const ast::Node & )
182
{
183
    return InterpretState::Flow;
184
}
185

186
InterpretState BaseInterpret_abstract::executePop()
187
{
188
    _machine.pop();
189

190
    return InterpretState::Flow;
191
}
192

193
}
194

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

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

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

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