PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/node_modules/montage/node_modules/frb/compile-assigner.js

https://github.com/huan-nba/Test
JavaScript | 199 lines | 179 code | 20 blank | 0 comment | 53 complexity | 316570fa1aad4ed260c4cf7705233c98 MD5 | raw file
Possible License(s): BSD-3-Clause, CC-BY-SA-4.0, 0BSD
  1. var compileEvaluator = require("./compile-evaluator");
  2. var solve = require("./algebra");
  3. var Scope = require("./scope");
  4. var valueSyntax = {type: "value"};
  5. var trueScope = {type: "literal", value: true};
  6. var falseScope = {type: "literal", value: false};
  7. module.exports = compile;
  8. function compile(syntax) {
  9. return compile.semantics.compile(syntax);
  10. }
  11. compile.semantics = {
  12. compile: function (syntax) {
  13. var compilers = this.compilers;
  14. if (syntax.type === "equals") {
  15. var assignLeft = this.compile(syntax.args[0]);
  16. var evaluateRight = this.compileEvaluator(syntax.args[1]);
  17. return compilers.equals(assignLeft, evaluateRight);
  18. } else if (syntax.type === "if") {
  19. var evaluateCondition = this.compileEvaluator(syntax.args[0]);
  20. var assignConsequent = this.compile(syntax.args[1]);
  21. var assignAlternate = this.compile(syntax.args[2]);
  22. return compilers["if"](evaluateCondition, assignConsequent, assignAlternate);
  23. } else if (syntax.type === "and" || syntax.type === "or") {
  24. var leftArgs = solve(syntax.args[0], valueSyntax);
  25. var rightArgs = solve(syntax.args[1], valueSyntax);
  26. var evaluateLeft = this.compileEvaluator(syntax.args[0]);
  27. var evaluateRight = this.compileEvaluator(syntax.args[1]);
  28. var evaluateLeftAssign = this.compileEvaluator(leftArgs[1]);
  29. var evaluateRightAssign = this.compileEvaluator(rightArgs[1]);
  30. var assignLeft = this.compile(leftArgs[0]);
  31. var assignRight = this.compile(rightArgs[0]);
  32. return compilers[syntax.type](
  33. assignLeft,
  34. assignRight,
  35. evaluateLeft,
  36. evaluateRight,
  37. evaluateLeftAssign,
  38. evaluateRightAssign
  39. );
  40. } else if (syntax.type === "everyBlock") {
  41. var evaluateCollection = this.compileEvaluator(syntax.args[0]);
  42. var args = solve(syntax.args[1], {type: "literal", value: true});
  43. var assignCondition = this.compile(args[0]);
  44. var evaluateValue = this.compileEvaluator(args[1]);
  45. return compilers["everyBlock"](evaluateCollection, assignCondition, evaluateValue);
  46. } else if (syntax.type === "parent") {
  47. var assignParent = this.compile(syntax.args[0]);
  48. return function (value, scope) {
  49. return assignParent(value, scope.parent);
  50. };
  51. } else if (compilers.hasOwnProperty(syntax.type)) {
  52. var argEvaluators = syntax.args.map(this.compileEvaluator, this.compileEvaluator.semantics);
  53. return compilers[syntax.type].apply(null, argEvaluators);
  54. } else {
  55. throw new Error("Can't compile assigner for " + JSON.stringify(syntax.type));
  56. }
  57. },
  58. compileEvaluator: compileEvaluator,
  59. compilers: {
  60. property: function (evaluateObject, evaluateKey) {
  61. return function (value, scope) {
  62. var object = evaluateObject(scope);
  63. if (!object) return;
  64. var key = evaluateKey(scope);
  65. if (key == null) return;
  66. if (Array.isArray(object)) {
  67. object.set(key, value);
  68. } else {
  69. object[key] = value;
  70. }
  71. };
  72. },
  73. get: function (evaluateCollection, evaluateKey) {
  74. return function (value, scope) {
  75. var collection = evaluateCollection(scope);
  76. if (!collection) return;
  77. var key = evaluateKey(scope);
  78. if (key == null) return;
  79. collection.set(key, value);
  80. };
  81. },
  82. has: function (evaluateCollection, evaluateValue) {
  83. return function (has, scope) {
  84. var collection = evaluateCollection(scope);
  85. if (!collection) return;
  86. var value = evaluateValue(scope);
  87. if (has == null) return;
  88. if (has) {
  89. if (!(collection.has || collection.contains).call(collection, value)) {
  90. collection.add(value);
  91. }
  92. } else {
  93. if ((collection.has || collection.contains).call(collection, value)) {
  94. (collection.remove || collection["delete"]).call(collection, value);
  95. }
  96. }
  97. };
  98. },
  99. equals: function (assignLeft, evaluateRight) {
  100. return function (value, scope) {
  101. if (value) {
  102. return assignLeft(evaluateRight(scope), scope);
  103. }
  104. };
  105. },
  106. "if": function (evaluateCondition, assignConsequent, assignAlternate) {
  107. return function (value, scope) {
  108. var condition = evaluateCondition(scope);
  109. if (condition == null) return;
  110. if (condition) {
  111. return assignConsequent(value, scope);
  112. } else {
  113. return assignAlternate(value, scope);
  114. }
  115. };
  116. },
  117. and: function (assignLeft, assignRight, evaluateLeft, evaluateRight, evaluateLeftAssign, evaluateRightAssign) {
  118. return function (value, scope) {
  119. if (value == null) return;
  120. if (value) {
  121. assignLeft(evaluateLeftAssign(trueScope), scope);
  122. assignRight(evaluateRightAssign(trueScope), scope);
  123. } else {
  124. assignLeft(evaluateLeft(scope) && !evaluateRight(scope), scope);
  125. }
  126. }
  127. },
  128. or: function (assignLeft, assignRight, evaluateLeft, evaluateRight, evaluateLeftAssign, evaluateRightAssign) {
  129. return function (value, scope) {
  130. if (value == null) return;
  131. if (!value) {
  132. assignLeft(evaluateLeftAssign(falseScope), scope);
  133. assignRight(evaluateRightAssign(falseScope), scope);
  134. } else {
  135. assignLeft(evaluateLeft(scope) || !evaluateRight(scope), scope);
  136. }
  137. }
  138. },
  139. rangeContent: function (evaluateTarget) {
  140. return function (value, scope) {
  141. var target = evaluateTarget(scope);
  142. if (!target) return;
  143. if (!value) {
  144. target.clear();
  145. } else {
  146. target.swap(0, target.length, value);
  147. }
  148. };
  149. },
  150. mapContent: function (evaluateTarget) {
  151. return function (value, scope) {
  152. var target = evaluateTarget(scope);
  153. if (!target) return;
  154. target.clear();
  155. if (scope.value) {
  156. target.addEach(value);
  157. }
  158. };
  159. },
  160. reversed: function (evaluateTarget) {
  161. return function (value, scope) {
  162. var target = evaluateTarget(scope);
  163. if (!target) return;
  164. target.swap(0, target.length, value.reversed());
  165. };
  166. },
  167. everyBlock: function (evaluateCollection, assignCondition, evaluateEffect) {
  168. return function (value, scope) {
  169. if (value) {
  170. var collection = evaluateCollection(scope);
  171. var effect = evaluateEffect(scope);
  172. collection.forEach(function (content) {
  173. assignCondition(effect, scope.nest(content));
  174. });
  175. }
  176. };
  177. }
  178. }
  179. }