25
25
namespace Langulus ::Flow
26
26
{
27
27
28
- // / Nested AND/OR scope execution (discarding outputs)
29
- // / TODO optimize for unneeded outputs
30
- // / @param flow - the flow to execute
31
- // / @param context - the environment in which flow will be executed
32
- // / @param silent - whether or not to silence logging, in case we're
33
- // / executing at compile-time, for example
34
- // / @return true of no errors occured
35
- /* bool Execute(const Many& flow, Many& context, const bool silent) {
36
- Many output;
37
- bool skipVerbs = false;
38
- return Execute(flow, context, output, skipVerbs, silent);
39
- }*/
40
-
41
28
// / Nested AND/OR scope execution with output
42
29
// / @param flow - the flow to execute
43
30
// / @param context - the environment in which scope will be executed
44
31
// / @param output - [out] verb result will be pushed here
32
+ // / @param integrate - execution happens in two styles:
33
+ // / 1. integration - everything not executed will still be pushed to
34
+ // / output, preserving the hierarchy. useful when integrating verbs
35
+ // / 2. not integration - only unexecuted verbs will push to output,
36
+ // / useful for collecting side-effects when updating
45
37
// / @param silent - whether or not to silence logging, in case we're
46
38
// / executing at compile-time, for example
47
39
// / @return true of no errors occured
48
- bool Execute (const Many& flow, Many& context, Many& output, const bool silent) {
40
+ bool Execute (
41
+ const Many& flow, Many& context, Many& output,
42
+ const bool integrate, const bool silent
43
+ ) {
49
44
bool skipVerbs = false ;
50
- return Execute (flow, context, output, skipVerbs, silent);
45
+ return Execute (flow, context, output, integrate, skipVerbs, silent);
51
46
}
52
47
53
48
// / Nested AND/OR scope execution with output
54
49
// / @param flow - the flow to execute
55
50
// / @param context - the environment in which scope will be executed
56
51
// / @param output - [out] verb result will be pushed here
52
+ // / @param integrate - execution happens in two styles:
53
+ // / 1. integration - everything not executed will still be pushed to
54
+ // / output, preserving the hierarchy. useful when integrating verbs
55
+ // / 2. not integration - only unexecuted verbs will push to output,
56
+ // / useful for collecting side-effects when updating
57
57
// / @param skipVerbs - [in/out] whether to skip verbs after OR success
58
58
// / @param silent - whether or not to silence logging, in case we're
59
59
// / executing at compile-time, for example
60
60
// / @return true of no errors occured
61
- bool Execute (const Many& flow, Many& context, Many& output, bool & skipVerbs, const bool silent) {
61
+ bool Execute (
62
+ const Many& flow, Many& context, Many& output,
63
+ const bool integrate, bool & skipVerbs, const bool silent
64
+ ) {
62
65
auto results = Many::FromState (flow);
63
66
if (flow) {
64
- VERBOSE_TAB (" Executing scope: [" , flow, ' ]' );
67
+ if (integrate)
68
+ VERBOSE_TAB (" Executing scope (integrating): [" , flow, ' ]' );
69
+ else
70
+ VERBOSE_TAB (" Executing scope: [" , flow, ' ]' );
65
71
66
72
try {
67
73
if (flow.IsOr ())
68
- ExecuteOR (flow, context, results, skipVerbs, silent);
74
+ ExecuteOR (flow, context, results, integrate, skipVerbs, silent);
69
75
else
70
- ExecuteAND (flow, context, results, skipVerbs, silent);
76
+ ExecuteAND (flow, context, results, integrate, skipVerbs, silent);
71
77
}
72
78
catch (const Except::Flow&) {
73
79
// Execution failed
@@ -83,17 +89,25 @@ namespace Langulus::Flow
83
89
// / @param flow - the flow to execute
84
90
// / @param context - the environment in which scope will be executed
85
91
// / @param output - [out] verb result will be pushed here
92
+ // / @param integrate - execution happens in two styles:
93
+ // / 1. integration - everything not executed will still be pushed to
94
+ // / output, preserving the hierarchy. useful when integrating verbs
95
+ // / 2. not integration - only unexecuted verbs will push to output,
96
+ // / useful for collecting side-effects when updating
86
97
// / @param skipVerbs - [in/out] whether to skip verbs after OR success
87
98
// / @param silent - whether or not to silence logging, in case we're
88
99
// / executing at compile-time, for example
89
100
// / @return true of no errors occured
90
- bool ExecuteAND (const Many& flow, Many& context, Many& output, bool & skipVerbs, const bool silent) {
101
+ bool ExecuteAND (
102
+ const Many& flow, Many& context, Many& output,
103
+ const bool integrate, bool & skipVerbs, const bool silent
104
+ ) {
91
105
Count executed = 0 ;
92
106
if (flow.IsDeep () and flow.IsDense ()) {
93
107
executed = flow.ForEach ([&](const Many& block) {
94
108
// Nest if deep
95
109
Many local;
96
- if (not Execute (block, context, local, skipVerbs, silent)) {
110
+ if (not Execute (block, context, local, integrate, skipVerbs, silent)) {
97
111
if (silent)
98
112
LANGULUS_THROW (Flow, " Deep AND failure" );
99
113
else
@@ -108,7 +122,7 @@ namespace Langulus::Flow
108
122
[&](const Inner::Missing& missing) {
109
123
// Nest if missing points
110
124
Many local;
111
- if (not Execute (missing.mContent , context, local, skipVerbs, silent)) {
125
+ if (not Execute (missing.mContent , context, local, integrate, skipVerbs, silent)) {
112
126
if (silent)
113
127
LANGULUS_THROW (Flow, " Missing point failure" );
114
128
else
@@ -126,7 +140,7 @@ namespace Langulus::Flow
126
140
}
127
141
128
142
Many local;
129
- if (not Execute (trait, context, local, skipVerbs, silent)) {
143
+ if (not Execute (trait, context, local, integrate, skipVerbs, silent)) {
130
144
if (silent)
131
145
LANGULUS_THROW (Flow, " Trait AND failure" );
132
146
else
@@ -178,24 +192,26 @@ namespace Langulus::Flow
178
192
);
179
193
180
194
VERBOSE (" Executing construct (verbs executed): " , local);
181
- // if (constructIsMissing) {
182
- // Just propagate, if missing
195
+ if (constructIsMissing
196
+ or construct.GetType ()->mProducerRetriever
197
+ or not construct.GetType ()->mDescriptorConstructor ) {
198
+ // Just propagate if missing or not instantiatable at
199
+ // compile-time
183
200
output.SmartPush (IndexBack, Abandon (local));
184
- // return;
185
- // }
201
+ return ;
202
+ }
186
203
187
- // A construct always means an implicit Verbs::Create
188
- // Try creating it in the current environment, it should
189
- // produce everything possible, including stateless ones
190
- /* Verbs::Create creator {&local};
204
+ // We can attempt an implicit Verbs::Create to make
205
+ // the data at compile-time
206
+ Verbs::Create creator {&local};
191
207
if (DispatchDeep<true , true , false >(context, creator))
192
208
output.SmartPush (IndexBack, Abandon (creator.GetOutput ()));
193
209
else {
194
210
if (silent)
195
211
LANGULUS_THROW (Flow, " Construct creation failure" );
196
212
else
197
213
LANGULUS_OOPS (Flow, " Construct creation failure: " , flow);
198
- }*/
214
+ }
199
215
},
200
216
[&](const A::Verb& constVerb) {
201
217
// Execute verbs
@@ -235,7 +251,7 @@ namespace Langulus::Flow
235
251
);
236
252
}
237
253
238
- if (not executed) {
254
+ if (not executed and integrate ) {
239
255
// If this is reached, then we had non-verb content
240
256
// Just propagate its contents
241
257
output.SmartPush (IndexBack, flow);
@@ -249,19 +265,27 @@ namespace Langulus::Flow
249
265
// / @param flow - the flow to execute
250
266
// / @param context - the context in which scope will be executed
251
267
// / @param output - [out] verb result will be pushed here
268
+ // / @param integrate - execution happens in two styles:
269
+ // / 1. integration - everything not executed will still be pushed to
270
+ // / output, preserving the hierarchy. useful when integrating verbs
271
+ // / 2. not integration - only unexecuted verbs will push to output,
272
+ // / useful for collecting side-effects when updating
252
273
// / @param skipVerbs - [out] whether to skip verbs after OR success
253
274
// / @param silent - whether or not to silence logging, in case we're
254
275
// / executing at compile-time, for example
255
276
// / @return true of no errors occured
256
- bool ExecuteOR (const Many& flow, Many& context, Many& output, bool & skipVerbs, const bool silent) {
277
+ bool ExecuteOR (
278
+ const Many& flow, Many& context, Many& output,
279
+ const bool integrate, bool & skipVerbs, const bool silent
280
+ ) {
257
281
Count executed = 0 ;
258
282
bool localSkipVerbs = false ;
259
283
260
284
if (flow.IsDeep () and flow.IsDense ()) {
261
285
executed = flow.ForEach ([&](const Many& block) {
262
286
// Nest if deep
263
287
Many local;
264
- if (Execute (block, context, local, localSkipVerbs, silent)) {
288
+ if (Execute (block, context, local, integrate, localSkipVerbs, silent)) {
265
289
executed = true ;
266
290
output.SmartPush (IndexBack, Abandon (local));
267
291
}
@@ -278,7 +302,7 @@ namespace Langulus::Flow
278
302
}
279
303
280
304
Many local;
281
- if (Execute (trait, context, local, silent)) {
305
+ if (Execute (trait, context, local, integrate, silent)) {
282
306
executed = true ;
283
307
output.SmartPush (IndexBack, Trait::From (trait.GetTrait (), Abandon (local)));
284
308
}
@@ -317,24 +341,26 @@ namespace Langulus::Flow
317
341
}
318
342
);
319
343
320
- // if (constructIsMissing) {
321
- // Just propagate, if missing
344
+ if (constructIsMissing
345
+ or construct.GetType ()->mProducerRetriever
346
+ or not construct.GetType ()->mDescriptorConstructor ) {
347
+ // Just propagate if missing or not instantiatable at
348
+ // compile-time
322
349
output.SmartPush (IndexBack, Abandon (local));
323
- // return;
324
- // }
350
+ return ;
351
+ }
325
352
326
- // A construct always means an implicit Verbs::Create
327
- // Try creating it in the current environment, it should
328
- // produce everything possible, including stateless ones
329
- /* Verbs::Create creator {&local};
353
+ // We can attempt an implicit Verbs::Create to make
354
+ // the data at compile-time
355
+ Verbs::Create creator {&local};
330
356
if (DispatchDeep<true , true , false >(context, creator))
331
357
output.SmartPush (IndexBack, Abandon (creator.GetOutput ()));
332
358
else {
333
359
if (silent)
334
360
LANGULUS_THROW (Flow, " Construct creation failure" );
335
361
else
336
362
LANGULUS_OOPS (Flow, " Construct creation failure: " , flow);
337
- }*/
363
+ }
338
364
},
339
365
[&](const Verb& constVerb) {
340
366
// Execute verbs
@@ -362,7 +388,7 @@ namespace Langulus::Flow
362
388
363
389
skipVerbs |= localSkipVerbs;
364
390
365
- if (not executed) {
391
+ if (not executed and integrate ) {
366
392
// If this is reached, then we have non-verb flat content
367
393
// Just propagate it
368
394
output.SmartPush (IndexBack, flow);
@@ -390,7 +416,7 @@ namespace Langulus::Flow
390
416
391
417
// Integrate the verb source to environment
392
418
Many localSource;
393
- if (not Execute (verb.GetSource (), context, localSource, silent)) {
419
+ if (not Execute (verb.GetSource (), context, localSource, true , silent)) {
394
420
// It's considered error only if verb is not monocast
395
421
if (not silent)
396
422
FLOW_ERRORS (" Error at source of: " , verb);
@@ -402,7 +428,7 @@ namespace Langulus::Flow
402
428
403
429
// Integrate the verb argument to the source
404
430
Many localArgument;
405
- if (not Execute (verb.GetArgument (), localSource, localArgument, silent)) {
431
+ if (not Execute (verb.GetArgument (), localSource, localArgument, true , silent)) {
406
432
// It's considered error only if verb is not monocast
407
433
if (not silent)
408
434
FLOW_ERRORS (" Error at argument of: " , verb);
0 commit comments