|
|
@@ -9,11 +9,10 @@ module.exports = class Generator {
|
|
|
this.triggers = parsed.triggers;
|
|
|
}
|
|
|
|
|
|
- //TODO: try to tweak for Tail Recursion Optimization (we can use Babel to fix it up for browsers)
|
|
|
- *generate(obj, scope=1, n=0, i=0) {
|
|
|
+ *generate(obj, scope=1, pre=[], gen=0, idx=0) {
|
|
|
let min = obj.scope && typeof obj.scope.min === "number" ? obj.scope.min : 1;
|
|
|
let max = obj.scope && typeof obj.scope.max === "number" ? obj.scope.max : scope;
|
|
|
- //console.log(`t=${obj.type} id=${obj.id || `...${obj.body.length}`} n=${n} i=${i} s=${scope} min=${min} max=${max}`);
|
|
|
+ //console.log(`t=${obj.type} id=${obj.id || `...${obj.body.length}`} gen=${gen} idx=${idx} s=${scope} min=${min} max=${max}`);
|
|
|
|
|
|
let id = null;
|
|
|
switch (obj.type) {
|
|
|
@@ -29,32 +28,29 @@ module.exports = class Generator {
|
|
|
/* falls through */
|
|
|
case "System": // or Behavior
|
|
|
if (!obj.body) throw new Error(`Unexpected empty ${obj.type}`);
|
|
|
- id = `${obj.id}_${n + 1}of${max}`;
|
|
|
+ id = `${obj.id}_${gen + 1}of${max}`;
|
|
|
/* falls through */
|
|
|
case "Sequence":
|
|
|
case "Group":
|
|
|
case "Alternation":
|
|
|
- let outs = [];
|
|
|
- if (i === 0) {
|
|
|
+ let outs = [...pre];
|
|
|
+ if (idx === 0) {
|
|
|
+ if (gen === 0 && min === 0) yield outs; // if first item in first generation and optional output empty case
|
|
|
if (id !== null) outs.push(id); // add to trace unless structural only (e.g., sequences)
|
|
|
- if (n === 0 && min === 0) yield []; // if first item in first generation and optional output empty case
|
|
|
}
|
|
|
- if (i < obj.body.length) {
|
|
|
+ if (idx < obj.body.length) {
|
|
|
if (obj.type !== "Alternation") {
|
|
|
- for (let evts of this.generate(obj.body[i], scope, 0, 0)) {
|
|
|
- for (let nextEvts of this.generate(obj, scope, n, i + 1)) {
|
|
|
- yield outs.concat(evts, nextEvts);
|
|
|
- }
|
|
|
+ for (let evts of this.generate(obj.body[idx], scope, outs, 0, 0)) {
|
|
|
+ yield* this.generate(obj, scope, evts, gen, idx + 1);
|
|
|
}
|
|
|
} else { // Alternation
|
|
|
- yield* this.generate(obj.body[i], scope, 0, 0);
|
|
|
- yield* this.generate(obj, scope, n, i + 1);
|
|
|
+ yield* this.generate(obj.body[idx], scope, outs, 0, 0);
|
|
|
+ yield* this.generate(obj, scope, outs, gen, idx + 1);
|
|
|
}
|
|
|
} else {
|
|
|
- if (n >= min - 1 && obj.type !== "Alternation") yield outs;
|
|
|
- if (n < max - 1) {
|
|
|
- for (let nextEvts of this.generate(obj, scope, n + 1, 0))
|
|
|
- yield outs.concat(nextEvts);
|
|
|
+ if (gen >= min - 1 && obj.type !== "Alternation") yield outs;
|
|
|
+ if (gen < max - 1) {
|
|
|
+ yield* this.generate(obj, scope, outs, gen + 1, 0);
|
|
|
}
|
|
|
}
|
|
|
break;
|