loom

Форк
0
/
ScriptOperationParser.cpp 
518 строк · 17.4 Кб
1
/*
2
MIT License
3

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

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

9
#include "ScriptOperationParser.h"
10
#include "ScriptSemantics_abstract.h"
11
#include "simodo/interpret/AnalyzeException.h"
12
#include "simodo/inout/format/fmt.h"
13

14
namespace simodo::interpret
15
{
16
    InterpretState OperationParser::parseNone(ScriptSemantics_abstract &host, const ast::Node & )
17
    {
18
        // node(None, )
19

20
        return host.executeNone();
21
    }
22

23
    InterpretState OperationParser::parsePushConstant(ScriptSemantics_abstract &host, const ast::Node & op)
24
    {
25
        // node(PushConstant, constant_value)
26
        //    |
27
        //    ---- node(, unit) * 0..n
28

29
        return host.executePushConstant(op);
30
    }
31

32
    InterpretState OperationParser::parsePushVariable(ScriptSemantics_abstract &host, const ast::Node & op)
33
    {
34
        // node(PushVariable, variable_name)
35

36
        return host.executePushVariable(op.token());
37
    }
38

39
    InterpretState OperationParser::parseObjectElement(ScriptSemantics_abstract &host, const ast::Node & op)
40
    {
41
        // node(ObjectElement, variable_name)
42

43
        return host.executeObjectElement(op);
44
    }
45

46
    InterpretState OperationParser::parseFunctionCall(ScriptSemantics_abstract &host, const ast::Node & op)
47
    {
48
        // node(FunctionCall, parenthesis)
49
        //    |
50
        //    ---- node() * 0..n (список выражений)
51

52
        return host.executeFunctionCall(op);
53
    }
54

55
    InterpretState OperationParser::parseProcedureCheck(ScriptSemantics_abstract &host, const ast::Node & )
56
    {
57
        // node(ProcedureCheck, )
58

59
        // Предполагается, что оператор ProcedureCheck выполняется сразу после вызова функции/процедуры
60

61
        return host.executeProcedureCheck();
62
    }
63

64
    InterpretState OperationParser::parsePrint(ScriptSemantics_abstract &host, const ast::Node & op)
65
    {
66
        // node(Print, needDetailedReport)
67

68
        return host.executePrint(op.token().lexeme() == u"all");
69
    }
70

71
    InterpretState OperationParser::parseBlock(ScriptSemantics_abstract &host, const ast::Node & op)
72
    {
73
        // node(Block, isBeginningOfBlock)
74
        //    |
75
        //    ---- node() * 0.. (список операторов)
76

77
        return host.executeBlock(!op.branches().empty(), op);
78
    }
79

80
    InterpretState OperationParser::parsePop(ScriptSemantics_abstract &host, const ast::Node & )
81
    {
82
        // node(Pop, )
83

84
        return host.executePop();
85
    }
86

87
    InterpretState OperationParser::parseReference(ScriptSemantics_abstract &host, const ast::Node & op)
88
    {
89
        // node(Reference, )
90

91
        return host.executeReference(op);
92
    }
93

94
    InterpretState OperationParser::parseArrayElement(ScriptSemantics_abstract &host, const ast::Node & op)
95
    {
96
        // node(ArrayElement, dot)
97
        //    |
98
        //    ---- node(None, name) * 1.. (список выражений, интерпретируемых, как набор индексов)
99

100
        return host.executeArrayElement(op);
101
    }
102

103
    InterpretState OperationParser::parseRecordStructure(ScriptSemantics_abstract &host, const ast::Node & op)
104
    {
105
        // node(RecordStructure, dot)
106
        //    |
107
        //    ---- node(None, name) * 0.. (список именованных выражений)
108

109
        return host.executeObjectStructure(op);
110
    }
111

112
    InterpretState OperationParser::parseArrayStructure(ScriptSemantics_abstract &host, const ast::Node & op)
113
    {
114
        // node(ArrayStructure, dot)
115
        //    |
116
        //    ---- node(None, name) * 0.. (список выражений, интерпретируемых, как значения одномерного массива)
117

118
        return host.executeArrayStructure(op);
119
    }
120

121
    InterpretState OperationParser::parseImport(ScriptSemantics_abstract &host, const ast::Node & op)
122
    {
123
        // node(Import, path)
124

125
        return host.executeImport(op.token());
126
    }
127

128
    InterpretState OperationParser::parseContractDefinition(ScriptSemantics_abstract &host, const ast::Node & op)
129
    {
130
        // node(ContractDefinition, contract_name)
131

132
        return host.executeContract(op);
133
    }
134

135
    InterpretState OperationParser::parseAnnouncement(ScriptSemantics_abstract &host, const ast::Node & )
136
    {
137
        // node(Announcement, )
138

139
        return host.executeAnnouncement();
140
    }
141

142
    InterpretState OperationParser::parseDeclaration(ScriptSemantics_abstract &host, const ast::Node & op)
143
    {
144
        // node(Declaration, ID)
145

146
        return host.executeDeclaration(op);
147
    }
148

149
    InterpretState OperationParser::parseDeclarationOnce(ScriptSemantics_abstract &host, const ast::Node & op)
150
    {
151
        // node(DeclarationOnce, ID)
152

153
        return host.executeDeclarationOnce(op);
154
    }
155

156
    InterpretState OperationParser::parseDeclarationCompletion(ScriptSemantics_abstract &host, const ast::Node & )
157
    {
158
        // node(DeclarationCompletion, )
159

160
        return host.executeDeclarationCompletion();
161
    }
162

163
    InterpretState OperationParser::parseAssignment(ScriptSemantics_abstract &host, const ast::Node & op)
164
    {
165
        // node(<assignment>, )
166
        //    |
167
        //    ---- node(..., ...) * 1.. (выражение)
168
        //
169
        // <assignment>:
170
        //      Initialize
171
        //      Assignment
172
        //      AssignAddition
173
        //      AssignSubtraction
174
        //      AssignMultiplication
175
        //      AssignDivision
176
        //      AssignModulo
177

178
        return host.executeAssignment(op);
179
    }
180

181
    InterpretState OperationParser::parsePostAssignment(ScriptSemantics_abstract &host, const ast::Node & op)
182
    {
183
        return host.executePostAssignment(op);
184
    }
185

186
    InterpretState OperationParser::parseUnary(ScriptSemantics_abstract &host, const ast::Node & op)
187
    {
188
        // node(<unary>, )
189
        // <unary>:
190
        //      Plus
191
        //      Minus
192
        //      Not
193

194
        return host.executeUnary(op);
195
    }
196

197
    InterpretState OperationParser::parseLogical(ScriptSemantics_abstract &host, const ast::Node & op)
198
    {
199
        // node(<logical>, )
200
        // <logical>:
201
        //      Or
202
        //      And
203

204
        return host.executeLogical(op);
205
    }
206

207
    InterpretState OperationParser::parseCompare(ScriptSemantics_abstract &host, const ast::Node & op)
208
    {
209
        // node(<compare>, )
210
        // <compare>:
211
        //      Equal
212
        //      NotEqual
213
        //      Less
214
        //      LessOrEqual
215
        //      More
216
        //      MoreOrEqual
217

218
        return host.executeCompare(op);
219
    }
220

221
    InterpretState OperationParser::parseArithmetic(ScriptSemantics_abstract &host, const ast::Node & op)
222
    {
223
        // node(<arithmetic>, )
224
        // <arithmetic>:
225
        //      Addition
226
        //      Subtraction
227
        //      Multiplication
228
        //      Division
229
        //      Modulo
230
        //      Power
231

232
        return host.executeArithmetic(op);
233
    }
234

235
    InterpretState OperationParser::parseConditional(ScriptSemantics_abstract &host, const ast::Node & op)
236
    {
237
        // node(<conditional>, )
238
        // <conditional>:
239
        //      Ternary
240
        //      If
241

242
        if (op.branches().empty())
243
            throw bormental::DrBormental("OperationParser::parseConditional", 
244
                                inout::fmt("Incorrect group conditional structure"));
245

246
        return host.executeConditional(static_cast<ScriptOperationCode>(op.operation()),
247
                                    op.branches().front(), 
248
                                    op.branches().front().operation() == op.branches().back().operation() ? nullptr : &op.branches().back());
249
    }
250

251
    InterpretState OperationParser::parseFunctionDefinition(ScriptSemantics_abstract &host, const ast::Node & op)
252
    {
253
        // node(Function, fn) #31 fn
254
        // |
255
        // +- Function_Closure #3101 [ // nullable
256
        // |  |
257
        // |  +- Function_Closure_Id #3102 <ID>
258
        // |  +- ...
259
        // |
260
        // +- Function_Params #3103 ( // nullable
261
        // |  |
262
        // |  +- <code> // код из объявления переменных
263
        // |  +- ...
264
        // |
265
        // +- Function_Return_Type #3106 -> // nullable
266
        // |  |
267
        // |  +- <code> // код из объявления переменных
268
        // |  +- ...
269
        // |
270
        // +- Function_Body #3107 { // not nullable
271
        //    |
272
        //    +- <code>
273
        //    +- ...
274
        //    +- #0 }
275

276
        if (op.branches().empty())
277
            throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
278
                                inout::fmt("Incorrect function declaration structure"));
279

280
        const ast::Node *   pop_closure = nullptr;
281
        const ast::Node *   pop_params  = nullptr;
282
        const ast::Node *   pop_return_type= nullptr;
283
        const ast::Node *   pop_body    = nullptr;
284

285
        for(const ast::Node & o : op.branches())
286
            switch (static_cast<ScriptOperationCode>(o.operation()))
287
            {
288
            case ScriptOperationCode::Function_Closure:
289
                if (pop_closure)
290
                    throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
291
                                        inout::fmt("Incorrect function declaration structure"));
292
                pop_closure = &o;
293
                break;
294
            case ScriptOperationCode::Function_Params:
295
                if (pop_params)
296
                    throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
297
                                        inout::fmt("Incorrect function declaration structure"));
298
                pop_params = &o;
299
                break;
300
            case ScriptOperationCode::Function_Return_Type:
301
                if (pop_return_type)
302
                    throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
303
                                        inout::fmt("Incorrect function declaration structure"));
304
                pop_return_type = &o;
305
                break;
306
            case ScriptOperationCode::Function_Body:
307
                if (pop_body)
308
                    throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
309
                                        inout::fmt("Incorrect function declaration structure"));
310
                pop_body = &o;
311
                break;
312
            default:
313
                throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
314
                                        inout::fmt("Incorrect function declaration structure"));
315
            }
316

317
        if (pop_body == nullptr)
318
            throw bormental::DrBormental("OperationParser::parseFunctionDefinition", 
319
                                inout::fmt("Incorrect function declaration structure"));
320

321
        return host.executeFunctionDefinition(pop_closure, pop_params, pop_return_type, *pop_body);
322
    }
323

324
    InterpretState OperationParser::parseFunctionDefinitionEnd(ScriptSemantics_abstract &host, const ast::Node & op)
325
    {
326
        return host.executeFunctionDefinitionEnd(op);
327
    }
328

329
    InterpretState OperationParser::parseFunctionTethered(ScriptSemantics_abstract &host, const ast::Node & op)
330
    {
331
        return host.executeFunctionTethered(op);
332
    }
333

334
    InterpretState OperationParser::parseReturn(ScriptSemantics_abstract &host, const ast::Node & op)
335
    {
336
        return host.executeReturn(op);
337
    }
338

339
    InterpretState OperationParser::parseFor(ScriptSemantics_abstract &host, const ast::Node & op)
340
    {
341
        const ast::Node * pop_variable = nullptr;
342
        const ast::Node * pop_source   = nullptr;
343
        const ast::Node * pop_body     = nullptr;
344
        bool              error        = false;
345

346
        for(const ast::Node & n : op.branches())
347
            switch(ScriptOperationCode(n.operation()))
348
            {
349
            case ScriptOperationCode::For_Variable:
350
                if (pop_variable)
351
                    error = true;
352
                else
353
                    pop_variable = &n;
354
                break;
355
            case ScriptOperationCode::For_Source:
356
                if (pop_source)
357
                    error = true;
358
                else
359
                    pop_source = &n;
360
                break;
361
            case ScriptOperationCode::Cycle_Body:
362
                if (pop_body)
363
                    error = true;
364
                else
365
                    pop_body = &n;
366
                break;
367
            default:
368
                error = true;
369
                break;
370
            }
371

372
        if (error || pop_variable == nullptr || pop_source == nullptr || pop_body == nullptr)
373
            throw bormental::DrBormental("OperationParser::parseFor", 
374
                                inout::fmt("Incorrect operator 'for' structure"));
375

376
        return host.executeFor(op.token(), pop_variable, pop_source, pop_body);
377
    }
378

379
    InterpretState OperationParser::parseWhile(ScriptSemantics_abstract &host, const ast::Node & op)
380
    {
381
        const ast::Node * pop_expression = nullptr;
382
        const ast::Node * pop_body       = nullptr;
383
        bool              error          = false;
384

385
        for(const ast::Node & n : op.branches())
386
            switch(ScriptOperationCode(n.operation()))
387
            {
388
            case ScriptOperationCode::While_Condition:
389
                if (pop_expression)
390
                    error = true;
391
                else
392
                    pop_expression = &n;
393
                break;
394
            case ScriptOperationCode::Cycle_Body:
395
                if (pop_body)
396
                    error = true;
397
                else
398
                    pop_body = &n;
399
                break;
400
            default:
401
                error = true;
402
                break;
403
            }
404

405
        if (error || pop_expression == nullptr || pop_body == nullptr)
406
            throw bormental::DrBormental("OperationParser::parseWhile", 
407
                                inout::fmt("Incorrect operator 'while' structure"));
408

409
        return host.executeWhile(op.token(), pop_expression, pop_body);
410
    }
411

412
    InterpretState OperationParser::parseDoWhile(ScriptSemantics_abstract &host, const ast::Node & op)
413
    {
414
        const ast::Node * pop_expression = nullptr;
415
        const ast::Node * pop_body       = nullptr;
416
        bool              error          = false;
417

418
        for(const ast::Node & n : op.branches())
419
            switch(ScriptOperationCode(n.operation()))
420
            {
421
            case ScriptOperationCode::While_Condition:
422
                if (pop_expression)
423
                    error = true;
424
                else
425
                    pop_expression = &n;
426
                break;
427
            case ScriptOperationCode::Cycle_Body:
428
                if (pop_body)
429
                    error = true;
430
                else
431
                    pop_body = &n;
432
                break;
433
            default:
434
                error = true;
435
                break;
436
            }
437

438
        if (error || pop_expression == nullptr || pop_body == nullptr)
439
            throw bormental::DrBormental("OperationParser::parseDoWhile", 
440
                                inout::fmt("Incorrect operator 'do-while' structure"));
441

442
        return host.executeDoWhile(op.token(), pop_body, pop_expression);
443
    }
444

445
    InterpretState OperationParser::parseBreak(ScriptSemantics_abstract &host, const ast::Node & op)
446
    {
447
        return host.executeBreak(op);
448
    }
449

450
    InterpretState OperationParser::parseContinue(ScriptSemantics_abstract &host, const ast::Node & op)
451
    {
452
        return host.executeContinue(op);
453
    }
454

455
    InterpretState OperationParser::parseCommon(ScriptSemantics_abstract &host, const ast::Node & op)
456
    {
457
        std::vector<inout::Token> names;
458

459
        if (op.branches().empty())
460
            throw bormental::DrBormental("OperationParser::parseCommon", 
461
                                inout::fmt("Incorrect operator 'common' structure"));
462

463
        for(const ast::Node & n : op.branches())
464
            names.push_back(n.token());
465

466
        return host.executeCommon(op, names);
467
    }
468

469
    InterpretState OperationParser::parseUsing(ScriptSemantics_abstract &host, const ast::Node & op)
470
    {
471
        if (op.branches().empty())
472
            throw bormental::DrBormental("OperationParser::parseUsing", 
473
                                inout::fmt("Incorrect operator 'using' structure"));
474

475
        return host.executeUsing(op, op.branches().front());
476
    }
477

478
    InterpretState OperationParser::parseFiberOperations(ScriptSemantics_abstract &host, const ast::Node & op)
479
    {
480
        switch (ScriptOperationCode(op.operation()))
481
        {
482
        case ScriptOperationCode::FiberMake:
483
            return host.executeFiberMake(op);
484
        
485
        case ScriptOperationCode::FiberWait:
486
            return host.executeFiberWait(op);
487

488
        case ScriptOperationCode::FiberPull:
489
        case ScriptOperationCode::FiberPush:
490
            return host.executeFiberPushPull(op);
491

492
        case ScriptOperationCode::FiberFlow:
493
            return host.executeFiberFlow(op);
494

495
        default:
496
            break;
497
        }
498

499
        throw bormental::DrBormental("OperationParser::parseFiberOperations", 
500
                            inout::fmt("Incorrect inter operation structure"));
501
    }
502

503
    InterpretState OperationParser::parseCheckState(ScriptSemantics_abstract &host, const ast::Node & op)
504
    {
505
        return host.executeCheckState(op);
506
    }
507

508
    InterpretState OperationParser::parseArrayPush(ScriptSemantics_abstract &host, const ast::Node & op)
509
    {
510
        return host.executeArrayPush(op);
511
    }
512

513
    InterpretState OperationParser::parseArrayPop(ScriptSemantics_abstract &host, const ast::Node & op)
514
    {
515
        return host.executeArrayPop(op);
516
    }
517

518
}

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

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

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

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