4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
#include "ScriptOperationParser.h"
10
#include "ScriptSemantics_abstract.h"
11
#include "simodo/interpret/AnalyzeException.h"
12
#include "simodo/inout/format/fmt.h"
14
namespace simodo::interpret
16
InterpretState OperationParser::parseNone(ScriptSemantics_abstract &host, const ast::Node & )
20
return host.executeNone();
23
InterpretState OperationParser::parsePushConstant(ScriptSemantics_abstract &host, const ast::Node & op)
25
// node(PushConstant, constant_value)
27
// ---- node(, unit) * 0..n
29
return host.executePushConstant(op);
32
InterpretState OperationParser::parsePushVariable(ScriptSemantics_abstract &host, const ast::Node & op)
34
// node(PushVariable, variable_name)
36
return host.executePushVariable(op.token());
39
InterpretState OperationParser::parseObjectElement(ScriptSemantics_abstract &host, const ast::Node & op)
41
// node(ObjectElement, variable_name)
43
return host.executeObjectElement(op);
46
InterpretState OperationParser::parseFunctionCall(ScriptSemantics_abstract &host, const ast::Node & op)
48
// node(FunctionCall, parenthesis)
50
// ---- node() * 0..n (список выражений)
52
return host.executeFunctionCall(op);
55
InterpretState OperationParser::parseProcedureCheck(ScriptSemantics_abstract &host, const ast::Node & )
57
// node(ProcedureCheck, )
59
// Предполагается, что оператор ProcedureCheck выполняется сразу после вызова функции/процедуры
61
return host.executeProcedureCheck();
64
InterpretState OperationParser::parsePrint(ScriptSemantics_abstract &host, const ast::Node & op)
66
// node(Print, needDetailedReport)
68
return host.executePrint(op.token().lexeme() == u"all");
71
InterpretState OperationParser::parseBlock(ScriptSemantics_abstract &host, const ast::Node & op)
73
// node(Block, isBeginningOfBlock)
75
// ---- node() * 0.. (список операторов)
77
return host.executeBlock(!op.branches().empty(), op);
80
InterpretState OperationParser::parsePop(ScriptSemantics_abstract &host, const ast::Node & )
84
return host.executePop();
87
InterpretState OperationParser::parseReference(ScriptSemantics_abstract &host, const ast::Node & op)
91
return host.executeReference(op);
94
InterpretState OperationParser::parseArrayElement(ScriptSemantics_abstract &host, const ast::Node & op)
96
// node(ArrayElement, dot)
98
// ---- node(None, name) * 1.. (список выражений, интерпретируемых, как набор индексов)
100
return host.executeArrayElement(op);
103
InterpretState OperationParser::parseRecordStructure(ScriptSemantics_abstract &host, const ast::Node & op)
105
// node(RecordStructure, dot)
107
// ---- node(None, name) * 0.. (список именованных выражений)
109
return host.executeObjectStructure(op);
112
InterpretState OperationParser::parseArrayStructure(ScriptSemantics_abstract &host, const ast::Node & op)
114
// node(ArrayStructure, dot)
116
// ---- node(None, name) * 0.. (список выражений, интерпретируемых, как значения одномерного массива)
118
return host.executeArrayStructure(op);
121
InterpretState OperationParser::parseImport(ScriptSemantics_abstract &host, const ast::Node & op)
123
// node(Import, path)
125
return host.executeImport(op.token());
128
InterpretState OperationParser::parseContractDefinition(ScriptSemantics_abstract &host, const ast::Node & op)
130
// node(ContractDefinition, contract_name)
132
return host.executeContract(op);
135
InterpretState OperationParser::parseAnnouncement(ScriptSemantics_abstract &host, const ast::Node & )
137
// node(Announcement, )
139
return host.executeAnnouncement();
142
InterpretState OperationParser::parseDeclaration(ScriptSemantics_abstract &host, const ast::Node & op)
144
// node(Declaration, ID)
146
return host.executeDeclaration(op);
149
InterpretState OperationParser::parseDeclarationOnce(ScriptSemantics_abstract &host, const ast::Node & op)
151
// node(DeclarationOnce, ID)
153
return host.executeDeclarationOnce(op);
156
InterpretState OperationParser::parseDeclarationCompletion(ScriptSemantics_abstract &host, const ast::Node & )
158
// node(DeclarationCompletion, )
160
return host.executeDeclarationCompletion();
163
InterpretState OperationParser::parseAssignment(ScriptSemantics_abstract &host, const ast::Node & op)
165
// node(<assignment>, )
167
// ---- node(..., ...) * 1.. (выражение)
174
// AssignMultiplication
178
return host.executeAssignment(op);
181
InterpretState OperationParser::parsePostAssignment(ScriptSemantics_abstract &host, const ast::Node & op)
183
return host.executePostAssignment(op);
186
InterpretState OperationParser::parseUnary(ScriptSemantics_abstract &host, const ast::Node & op)
194
return host.executeUnary(op);
197
InterpretState OperationParser::parseLogical(ScriptSemantics_abstract &host, const ast::Node & op)
204
return host.executeLogical(op);
207
InterpretState OperationParser::parseCompare(ScriptSemantics_abstract &host, const ast::Node & op)
218
return host.executeCompare(op);
221
InterpretState OperationParser::parseArithmetic(ScriptSemantics_abstract &host, const ast::Node & op)
223
// node(<arithmetic>, )
232
return host.executeArithmetic(op);
235
InterpretState OperationParser::parseConditional(ScriptSemantics_abstract &host, const ast::Node & op)
237
// node(<conditional>, )
242
if (op.branches().empty())
243
throw bormental::DrBormental("OperationParser::parseConditional",
244
inout::fmt("Incorrect group conditional structure"));
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());
251
InterpretState OperationParser::parseFunctionDefinition(ScriptSemantics_abstract &host, const ast::Node & op)
253
// node(Function, fn) #31 fn
255
// +- Function_Closure #3101 [ // nullable
257
// | +- Function_Closure_Id #3102 <ID>
260
// +- Function_Params #3103 ( // nullable
262
// | +- <code> // код из объявления переменных
265
// +- Function_Return_Type #3106 -> // nullable
267
// | +- <code> // код из объявления переменных
270
// +- Function_Body #3107 { // not nullable
276
if (op.branches().empty())
277
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
278
inout::fmt("Incorrect function declaration structure"));
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;
285
for(const ast::Node & o : op.branches())
286
switch (static_cast<ScriptOperationCode>(o.operation()))
288
case ScriptOperationCode::Function_Closure:
290
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
291
inout::fmt("Incorrect function declaration structure"));
294
case ScriptOperationCode::Function_Params:
296
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
297
inout::fmt("Incorrect function declaration structure"));
300
case ScriptOperationCode::Function_Return_Type:
302
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
303
inout::fmt("Incorrect function declaration structure"));
304
pop_return_type = &o;
306
case ScriptOperationCode::Function_Body:
308
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
309
inout::fmt("Incorrect function declaration structure"));
313
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
314
inout::fmt("Incorrect function declaration structure"));
317
if (pop_body == nullptr)
318
throw bormental::DrBormental("OperationParser::parseFunctionDefinition",
319
inout::fmt("Incorrect function declaration structure"));
321
return host.executeFunctionDefinition(pop_closure, pop_params, pop_return_type, *pop_body);
324
InterpretState OperationParser::parseFunctionDefinitionEnd(ScriptSemantics_abstract &host, const ast::Node & op)
326
return host.executeFunctionDefinitionEnd(op);
329
InterpretState OperationParser::parseFunctionTethered(ScriptSemantics_abstract &host, const ast::Node & op)
331
return host.executeFunctionTethered(op);
334
InterpretState OperationParser::parseReturn(ScriptSemantics_abstract &host, const ast::Node & op)
336
return host.executeReturn(op);
339
InterpretState OperationParser::parseFor(ScriptSemantics_abstract &host, const ast::Node & op)
341
const ast::Node * pop_variable = nullptr;
342
const ast::Node * pop_source = nullptr;
343
const ast::Node * pop_body = nullptr;
346
for(const ast::Node & n : op.branches())
347
switch(ScriptOperationCode(n.operation()))
349
case ScriptOperationCode::For_Variable:
355
case ScriptOperationCode::For_Source:
361
case ScriptOperationCode::Cycle_Body:
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"));
376
return host.executeFor(op.token(), pop_variable, pop_source, pop_body);
379
InterpretState OperationParser::parseWhile(ScriptSemantics_abstract &host, const ast::Node & op)
381
const ast::Node * pop_expression = nullptr;
382
const ast::Node * pop_body = nullptr;
385
for(const ast::Node & n : op.branches())
386
switch(ScriptOperationCode(n.operation()))
388
case ScriptOperationCode::While_Condition:
394
case ScriptOperationCode::Cycle_Body:
405
if (error || pop_expression == nullptr || pop_body == nullptr)
406
throw bormental::DrBormental("OperationParser::parseWhile",
407
inout::fmt("Incorrect operator 'while' structure"));
409
return host.executeWhile(op.token(), pop_expression, pop_body);
412
InterpretState OperationParser::parseDoWhile(ScriptSemantics_abstract &host, const ast::Node & op)
414
const ast::Node * pop_expression = nullptr;
415
const ast::Node * pop_body = nullptr;
418
for(const ast::Node & n : op.branches())
419
switch(ScriptOperationCode(n.operation()))
421
case ScriptOperationCode::While_Condition:
427
case ScriptOperationCode::Cycle_Body:
438
if (error || pop_expression == nullptr || pop_body == nullptr)
439
throw bormental::DrBormental("OperationParser::parseDoWhile",
440
inout::fmt("Incorrect operator 'do-while' structure"));
442
return host.executeDoWhile(op.token(), pop_body, pop_expression);
445
InterpretState OperationParser::parseBreak(ScriptSemantics_abstract &host, const ast::Node & op)
447
return host.executeBreak(op);
450
InterpretState OperationParser::parseContinue(ScriptSemantics_abstract &host, const ast::Node & op)
452
return host.executeContinue(op);
455
InterpretState OperationParser::parseCommon(ScriptSemantics_abstract &host, const ast::Node & op)
457
std::vector<inout::Token> names;
459
if (op.branches().empty())
460
throw bormental::DrBormental("OperationParser::parseCommon",
461
inout::fmt("Incorrect operator 'common' structure"));
463
for(const ast::Node & n : op.branches())
464
names.push_back(n.token());
466
return host.executeCommon(op, names);
469
InterpretState OperationParser::parseUsing(ScriptSemantics_abstract &host, const ast::Node & op)
471
if (op.branches().empty())
472
throw bormental::DrBormental("OperationParser::parseUsing",
473
inout::fmt("Incorrect operator 'using' structure"));
475
return host.executeUsing(op, op.branches().front());
478
InterpretState OperationParser::parseFiberOperations(ScriptSemantics_abstract &host, const ast::Node & op)
480
switch (ScriptOperationCode(op.operation()))
482
case ScriptOperationCode::FiberMake:
483
return host.executeFiberMake(op);
485
case ScriptOperationCode::FiberWait:
486
return host.executeFiberWait(op);
488
case ScriptOperationCode::FiberPull:
489
case ScriptOperationCode::FiberPush:
490
return host.executeFiberPushPull(op);
492
case ScriptOperationCode::FiberFlow:
493
return host.executeFiberFlow(op);
499
throw bormental::DrBormental("OperationParser::parseFiberOperations",
500
inout::fmt("Incorrect inter operation structure"));
503
InterpretState OperationParser::parseCheckState(ScriptSemantics_abstract &host, const ast::Node & op)
505
return host.executeCheckState(op);
508
InterpretState OperationParser::parseArrayPush(ScriptSemantics_abstract &host, const ast::Node & op)
510
return host.executeArrayPush(op);
513
InterpretState OperationParser::parseArrayPop(ScriptSemantics_abstract &host, const ast::Node & op)
515
return host.executeArrayPop(op);