modellang.es6 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. "use strict";
  2. module.exports = class Generator {
  3. constructor(parsed) {
  4. this.systems = parsed.systems;
  5. this.behaviors = parsed.behaviors;
  6. this.interactions = parsed.interactions;
  7. this.triggers = parsed.triggers;
  8. }
  9. *generate(obj, scope=1, n=0, i=0) {
  10. let min = obj.scope && typeof obj.scope.min === "number" ? obj.scope.min : 1;
  11. let max = obj.scope && typeof obj.scope.max === "number" ? obj.scope.max : scope;
  12. console.log(`t=${obj.type} id=${obj.id || `...${obj.body.length}`} n=${n} i=${i} s=${scope} min=${min} max=${max}`);
  13. let id = null;
  14. switch (obj.type) {
  15. case "Behavior":
  16. if (!obj.body) { // Behavior reference
  17. let realObj = this.behaviors[obj.id];
  18. if (!realObj || !realObj.body) throw new Error(`Unable to find referenced behavior: ${obj.id}`);
  19. Object.defineProperty(obj, "body", { // use real body but keep it hidden (for debugging the AST mainly)
  20. value: realObj.body,
  21. });
  22. }
  23. /* falls through */
  24. case "System": // or Behavior
  25. if (!obj.body) throw new Error(`Unexpected empty ${obj.type}`);
  26. id = `${obj.id}_${n + 1}of${max}`;
  27. /* falls through */
  28. case "Sequence": // or System or Behavior
  29. let outs = [];
  30. if (i === 0 && id !== null) outs.push(id);
  31. if (i < obj.body.length) {
  32. for (let evts of this.generate(obj.body[i], scope)) {
  33. for (let nextEvts of this.generate(obj, scope, n, i + 1)) {
  34. yield outs.concat(evts, nextEvts);
  35. }
  36. }
  37. } else {
  38. if (n >= min - 1) yield outs;
  39. if (n < max - 1) {
  40. for (let nextEvts of this.generate(obj, scope, n + 1, 0))
  41. yield outs.concat(nextEvts);
  42. }
  43. }
  44. break;
  45. default:
  46. throw new Error(`UNIMPLEMENTED TYPE: ${obj.type}`);
  47. }
  48. }
  49. };