yukigo 0.2.2 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/.mocharc.json +3 -3
  2. package/CHANGELOG.md +102 -41
  3. package/README.md +193 -193
  4. package/dist/analyzer/GraphBuilder.d.ts +1 -0
  5. package/dist/analyzer/GraphBuilder.js +2 -1
  6. package/dist/analyzer/index.d.ts +0 -7
  7. package/dist/analyzer/index.js +3 -3
  8. package/dist/analyzer/inspections/functional/functional.d.ts +1 -1
  9. package/dist/analyzer/inspections/functional/functional.js +1 -1
  10. package/dist/analyzer/inspections/functional/smells.d.ts +3 -3
  11. package/dist/analyzer/inspections/functional/smells.js +27 -35
  12. package/dist/analyzer/inspections/generic/generic.d.ts +21 -14
  13. package/dist/analyzer/inspections/generic/generic.js +78 -59
  14. package/dist/analyzer/inspections/generic/smells.d.ts +2 -0
  15. package/dist/analyzer/inspections/generic/smells.js +55 -64
  16. package/dist/analyzer/inspections/imperative/imperative.d.ts +3 -3
  17. package/dist/analyzer/inspections/imperative/imperative.js +3 -3
  18. package/dist/analyzer/inspections/imperative/smells.d.ts +1 -0
  19. package/dist/analyzer/inspections/imperative/smells.js +8 -5
  20. package/dist/analyzer/inspections/logic/logic.d.ts +8 -8
  21. package/dist/analyzer/inspections/logic/logic.js +5 -5
  22. package/dist/analyzer/inspections/logic/smells.js +2 -2
  23. package/dist/analyzer/inspections/object/object.d.ts +5 -5
  24. package/dist/analyzer/inspections/object/object.js +22 -21
  25. package/dist/analyzer/inspections/object/smells.js +11 -23
  26. package/dist/analyzer/utils.d.ts +6 -2
  27. package/dist/analyzer/utils.js +6 -2
  28. package/dist/interpreter/components/EnvBuilder.d.ts +20 -1
  29. package/dist/interpreter/components/EnvBuilder.js +211 -66
  30. package/dist/interpreter/components/EqualityComparer.d.ts +15 -0
  31. package/dist/interpreter/components/EqualityComparer.js +69 -0
  32. package/dist/interpreter/components/Operations.d.ts +17 -14
  33. package/dist/interpreter/components/Operations.js +61 -62
  34. package/dist/interpreter/components/PatternMatcher.d.ts +19 -58
  35. package/dist/interpreter/components/PatternMatcher.js +185 -286
  36. package/dist/interpreter/components/RuntimeContext.d.ts +24 -15
  37. package/dist/interpreter/components/RuntimeContext.js +43 -4
  38. package/dist/interpreter/components/TestRunner.d.ts +15 -13
  39. package/dist/interpreter/components/TestRunner.js +86 -53
  40. package/dist/interpreter/components/evaluators/BaseEvaluator.d.ts +19 -0
  41. package/dist/interpreter/components/evaluators/BaseEvaluator.js +20 -0
  42. package/dist/interpreter/components/evaluators/ExpressionEvaluator.d.ts +34 -0
  43. package/dist/interpreter/components/evaluators/ExpressionEvaluator.js +298 -0
  44. package/dist/interpreter/components/evaluators/OperationEvaluator.d.ts +25 -0
  45. package/dist/interpreter/components/evaluators/OperationEvaluator.js +226 -0
  46. package/dist/interpreter/components/evaluators/PrimitiveEvaluator.d.ts +19 -0
  47. package/dist/interpreter/components/evaluators/PrimitiveEvaluator.js +50 -0
  48. package/dist/interpreter/components/evaluators/StatementEvaluator.d.ts +28 -0
  49. package/dist/interpreter/components/evaluators/StatementEvaluator.js +240 -0
  50. package/dist/interpreter/components/evaluators/TestingEvaluator.d.ts +15 -0
  51. package/dist/interpreter/components/evaluators/TestingEvaluator.js +14 -0
  52. package/dist/interpreter/components/evaluators/index.d.ts +110 -0
  53. package/dist/interpreter/components/evaluators/index.js +21 -0
  54. package/dist/interpreter/components/evaluators/utils.d.ts +7 -0
  55. package/dist/interpreter/components/evaluators/utils.js +50 -0
  56. package/dist/interpreter/components/hooks/YukigoHook.d.ts +27 -0
  57. package/dist/interpreter/components/hooks/YukigoHook.js +1 -0
  58. package/dist/interpreter/components/kernel/commands.d.ts +122 -0
  59. package/dist/interpreter/components/kernel/commands.js +203 -0
  60. package/dist/interpreter/components/kernel/index.d.ts +51 -0
  61. package/dist/interpreter/components/kernel/index.js +176 -0
  62. package/dist/interpreter/components/logic/LogicEngine.d.ts +26 -23
  63. package/dist/interpreter/components/logic/LogicEngine.js +234 -221
  64. package/dist/interpreter/components/logic/LogicResolver.d.ts +22 -51
  65. package/dist/interpreter/components/logic/LogicResolver.js +73 -440
  66. package/dist/interpreter/components/logic/LogicTerm.d.ts +104 -0
  67. package/dist/interpreter/components/logic/LogicTerm.js +423 -0
  68. package/dist/interpreter/components/logic/LogicTranslator.d.ts +25 -9
  69. package/dist/interpreter/components/logic/LogicTranslator.js +211 -74
  70. package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +6 -4
  71. package/dist/interpreter/components/runtimes/FunctionRuntime.js +82 -84
  72. package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +13 -14
  73. package/dist/interpreter/components/runtimes/LazyRuntime.js +112 -239
  74. package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +17 -14
  75. package/dist/interpreter/components/runtimes/ObjectRuntime.js +105 -74
  76. package/dist/interpreter/errors.d.ts +10 -0
  77. package/dist/interpreter/errors.js +17 -0
  78. package/dist/interpreter/index.d.ts +9 -5
  79. package/dist/interpreter/index.js +11 -13
  80. package/dist/interpreter/primitives/YuValue.d.ts +21 -0
  81. package/dist/interpreter/primitives/YuValue.js +40 -0
  82. package/dist/interpreter/primitives/capabilities.d.ts +90 -0
  83. package/dist/interpreter/primitives/capabilities.js +1 -0
  84. package/dist/interpreter/primitives/entities/LazyList.d.ts +48 -0
  85. package/dist/interpreter/primitives/entities/LazyList.js +164 -0
  86. package/dist/interpreter/primitives/entities/LogicResult.d.ts +51 -0
  87. package/dist/interpreter/primitives/entities/LogicResult.js +101 -0
  88. package/dist/interpreter/primitives/entities/RuntimeClass.d.ts +24 -0
  89. package/dist/interpreter/primitives/entities/RuntimeClass.js +57 -0
  90. package/dist/interpreter/primitives/entities/RuntimeFunction.d.ts +40 -0
  91. package/dist/interpreter/primitives/entities/RuntimeFunction.js +73 -0
  92. package/dist/interpreter/primitives/entities/RuntimeObject.d.ts +27 -0
  93. package/dist/interpreter/primitives/entities/RuntimeObject.js +82 -0
  94. package/dist/interpreter/primitives/entities/RuntimePredicate.d.ts +19 -0
  95. package/dist/interpreter/primitives/entities/RuntimePredicate.js +59 -0
  96. package/dist/interpreter/primitives/index.d.ts +14 -0
  97. package/dist/interpreter/primitives/index.js +14 -0
  98. package/dist/interpreter/primitives/scalars/YuBoolean.d.ts +24 -0
  99. package/dist/interpreter/primitives/scalars/YuBoolean.js +69 -0
  100. package/dist/interpreter/primitives/scalars/YuChar.d.ts +28 -0
  101. package/dist/interpreter/primitives/scalars/YuChar.js +78 -0
  102. package/dist/interpreter/primitives/scalars/YuNil.d.ts +25 -0
  103. package/dist/interpreter/primitives/scalars/YuNil.js +73 -0
  104. package/dist/interpreter/primitives/scalars/YuNumber.d.ts +49 -0
  105. package/dist/interpreter/primitives/scalars/YuNumber.js +165 -0
  106. package/dist/interpreter/primitives/sequences/YuArray.d.ts +33 -0
  107. package/dist/interpreter/primitives/sequences/YuArray.js +150 -0
  108. package/dist/interpreter/primitives/sequences/YuString.d.ts +40 -0
  109. package/dist/interpreter/primitives/sequences/YuString.js +130 -0
  110. package/dist/interpreter/utils.d.ts +23 -10
  111. package/dist/interpreter/utils.js +25 -30
  112. package/dist/tester/index.d.ts +3 -3
  113. package/dist/tester/index.js +39 -28
  114. package/dist/utils/helpers.d.ts +12 -5
  115. package/dist/utils/helpers.js +6 -79
  116. package/package.json +3 -16
  117. package/src/analyzer/GraphBuilder.ts +143 -142
  118. package/src/analyzer/index.ts +185 -194
  119. package/src/analyzer/inspections/functional/functional.ts +121 -121
  120. package/src/analyzer/inspections/functional/smells.ts +88 -102
  121. package/src/analyzer/inspections/generic/generic.ts +610 -581
  122. package/src/analyzer/inspections/generic/smells.ts +355 -365
  123. package/src/analyzer/inspections/imperative/imperative.ts +104 -101
  124. package/src/analyzer/inspections/imperative/smells.ts +58 -54
  125. package/src/analyzer/inspections/logic/logic.ts +84 -90
  126. package/src/analyzer/inspections/logic/smells.ts +54 -54
  127. package/src/analyzer/inspections/object/object.ts +295 -264
  128. package/src/analyzer/inspections/object/smells.ts +130 -144
  129. package/src/analyzer/utils.ts +115 -109
  130. package/src/index.ts +3 -3
  131. package/src/interpreter/components/EnvBuilder.ts +405 -202
  132. package/src/interpreter/components/EqualityComparer.ts +107 -0
  133. package/src/interpreter/components/Operations.ts +126 -99
  134. package/src/interpreter/components/PatternMatcher.ts +375 -475
  135. package/src/interpreter/components/RuntimeContext.ts +181 -119
  136. package/src/interpreter/components/TestRunner.ts +223 -151
  137. package/src/interpreter/components/evaluators/BaseEvaluator.ts +36 -0
  138. package/src/interpreter/components/evaluators/ExpressionEvaluator.ts +475 -0
  139. package/src/interpreter/components/evaluators/OperationEvaluator.ts +477 -0
  140. package/src/interpreter/components/evaluators/PrimitiveEvaluator.ts +80 -0
  141. package/src/interpreter/components/evaluators/StatementEvaluator.ts +372 -0
  142. package/src/interpreter/components/evaluators/TestingEvaluator.ts +26 -0
  143. package/src/interpreter/components/evaluators/index.ts +34 -0
  144. package/src/interpreter/components/evaluators/utils.ts +64 -0
  145. package/src/interpreter/components/hooks/YukigoHook.ts +45 -0
  146. package/src/interpreter/components/kernel/commands.ts +255 -0
  147. package/src/interpreter/components/kernel/index.ts +222 -0
  148. package/src/interpreter/components/logic/LogicEngine.ts +509 -519
  149. package/src/interpreter/components/logic/LogicResolver.ts +209 -858
  150. package/src/interpreter/components/logic/LogicTerm.ts +477 -0
  151. package/src/interpreter/components/logic/LogicTranslator.ts +362 -149
  152. package/src/interpreter/components/runtimes/FunctionRuntime.ts +249 -227
  153. package/src/interpreter/components/runtimes/LazyRuntime.ts +226 -334
  154. package/src/interpreter/components/runtimes/ObjectRuntime.ts +262 -224
  155. package/src/interpreter/errors.ts +68 -47
  156. package/src/interpreter/index.ts +50 -52
  157. package/src/interpreter/primitives/YuValue.ts +64 -0
  158. package/src/interpreter/primitives/capabilities.ts +111 -0
  159. package/src/interpreter/primitives/entities/LazyList.ts +225 -0
  160. package/src/interpreter/primitives/entities/LogicResult.ts +133 -0
  161. package/src/interpreter/primitives/entities/RuntimeClass.ts +70 -0
  162. package/src/interpreter/primitives/entities/RuntimeFunction.ts +108 -0
  163. package/src/interpreter/primitives/entities/RuntimeObject.ts +110 -0
  164. package/src/interpreter/primitives/entities/RuntimePredicate.ts +77 -0
  165. package/src/interpreter/primitives/index.ts +17 -0
  166. package/src/interpreter/primitives/scalars/YuBoolean.ts +79 -0
  167. package/src/interpreter/primitives/scalars/YuChar.ts +94 -0
  168. package/src/interpreter/primitives/scalars/YuNil.ts +84 -0
  169. package/src/interpreter/primitives/scalars/YuNumber.ts +187 -0
  170. package/src/interpreter/primitives/sequences/YuArray.ts +178 -0
  171. package/src/interpreter/primitives/sequences/YuString.ts +165 -0
  172. package/src/interpreter/utils.ts +105 -84
  173. package/src/tester/index.ts +157 -128
  174. package/src/utils/helpers.ts +81 -168
  175. package/tests/analyzer/functional.spec.ts +221 -207
  176. package/tests/analyzer/generic.spec.ts +178 -178
  177. package/tests/analyzer/helpers.spec.ts +83 -89
  178. package/tests/analyzer/logic.spec.ts +237 -237
  179. package/tests/analyzer/oop.spec.ts +320 -323
  180. package/tests/analyzer/transitive.spec.ts +166 -166
  181. package/tests/interpreter/EnvBuilder.spec.ts +181 -183
  182. package/tests/interpreter/FunctionRuntime.spec.ts +224 -223
  183. package/tests/interpreter/LazyRuntime.spec.ts +227 -225
  184. package/tests/interpreter/LogicEngine.spec.ts +371 -327
  185. package/tests/interpreter/LogicSubstitution.spec.ts +90 -80
  186. package/tests/interpreter/ObjectRuntime.spec.ts +431 -606
  187. package/tests/interpreter/Operations.spec.ts +312 -220
  188. package/tests/interpreter/PatternSystem.spec.ts +254 -213
  189. package/tests/interpreter/Tests.spec.ts +122 -122
  190. package/tests/interpreter/interpreter.spec.ts +1143 -991
  191. package/tests/kernel/YukigoKernel.spec.ts +112 -0
  192. package/tests/tester/Tester.spec.ts +188 -152
  193. package/tsconfig.build.json +16 -15
  194. package/tsconfig.json +27 -25
  195. package/dist/interpreter/components/Visitor.d.ts +0 -70
  196. package/dist/interpreter/components/Visitor.js +0 -634
  197. package/dist/interpreter/entities.d.ts +0 -105
  198. package/dist/interpreter/entities.js +0 -96
  199. package/dist/interpreter/trampoline.d.ts +0 -17
  200. package/dist/interpreter/trampoline.js +0 -38
  201. package/dist/src/analyzer/GraphBuilder.d.ts +0 -30
  202. package/dist/src/analyzer/GraphBuilder.js +0 -100
  203. package/dist/src/analyzer/index.d.ts +0 -59
  204. package/dist/src/analyzer/index.js +0 -152
  205. package/dist/src/analyzer/inspections/functional/functional.d.ts +0 -44
  206. package/dist/src/analyzer/inspections/functional/functional.js +0 -149
  207. package/dist/src/analyzer/inspections/functional/smells.d.ts +0 -16
  208. package/dist/src/analyzer/inspections/functional/smells.js +0 -98
  209. package/dist/src/analyzer/inspections/generic/generic.d.ts +0 -178
  210. package/dist/src/analyzer/inspections/generic/generic.js +0 -604
  211. package/dist/src/analyzer/inspections/generic/smells.d.ts +0 -61
  212. package/dist/src/analyzer/inspections/generic/smells.js +0 -349
  213. package/dist/src/analyzer/inspections/imperative/imperative.d.ts +0 -35
  214. package/dist/src/analyzer/inspections/imperative/imperative.js +0 -109
  215. package/dist/src/analyzer/inspections/imperative/smells.d.ts +0 -16
  216. package/dist/src/analyzer/inspections/imperative/smells.js +0 -58
  217. package/dist/src/analyzer/inspections/logic/logic.d.ts +0 -32
  218. package/dist/src/analyzer/inspections/logic/logic.js +0 -96
  219. package/dist/src/analyzer/inspections/logic/smells.d.ts +0 -15
  220. package/dist/src/analyzer/inspections/logic/smells.js +0 -60
  221. package/dist/src/analyzer/inspections/object/object.d.ts +0 -90
  222. package/dist/src/analyzer/inspections/object/object.js +0 -321
  223. package/dist/src/analyzer/inspections/object/smells.d.ts +0 -30
  224. package/dist/src/analyzer/inspections/object/smells.js +0 -135
  225. package/dist/src/analyzer/utils.d.ts +0 -30
  226. package/dist/src/analyzer/utils.js +0 -78
  227. package/dist/src/index.d.ts +0 -4
  228. package/dist/src/index.js +0 -4
  229. package/dist/src/interpreter/components/EnvBuilder.d.ts +0 -21
  230. package/dist/src/interpreter/components/EnvBuilder.js +0 -155
  231. package/dist/src/interpreter/components/Operations.d.ts +0 -14
  232. package/dist/src/interpreter/components/Operations.js +0 -84
  233. package/dist/src/interpreter/components/PatternMatcher.d.ts +0 -73
  234. package/dist/src/interpreter/components/PatternMatcher.js +0 -358
  235. package/dist/src/interpreter/components/RuntimeContext.d.ts +0 -35
  236. package/dist/src/interpreter/components/RuntimeContext.js +0 -93
  237. package/dist/src/interpreter/components/TestRunner.d.ts +0 -19
  238. package/dist/src/interpreter/components/TestRunner.js +0 -110
  239. package/dist/src/interpreter/components/Visitor.d.ts +0 -71
  240. package/dist/src/interpreter/components/Visitor.js +0 -638
  241. package/dist/src/interpreter/components/logic/LogicEngine.d.ts +0 -29
  242. package/dist/src/interpreter/components/logic/LogicEngine.js +0 -259
  243. package/dist/src/interpreter/components/logic/LogicResolver.d.ts +0 -53
  244. package/dist/src/interpreter/components/logic/LogicResolver.js +0 -484
  245. package/dist/src/interpreter/components/logic/LogicTranslator.d.ts +0 -14
  246. package/dist/src/interpreter/components/logic/LogicTranslator.js +0 -99
  247. package/dist/src/interpreter/components/runtimes/FunctionRuntime.d.ts +0 -12
  248. package/dist/src/interpreter/components/runtimes/FunctionRuntime.js +0 -149
  249. package/dist/src/interpreter/components/runtimes/LazyRuntime.d.ts +0 -19
  250. package/dist/src/interpreter/components/runtimes/LazyRuntime.js +0 -269
  251. package/dist/src/interpreter/components/runtimes/ObjectRuntime.d.ts +0 -35
  252. package/dist/src/interpreter/components/runtimes/ObjectRuntime.js +0 -126
  253. package/dist/src/interpreter/errors.d.ts +0 -19
  254. package/dist/src/interpreter/errors.js +0 -36
  255. package/dist/src/interpreter/index.d.ts +0 -24
  256. package/dist/src/interpreter/index.js +0 -41
  257. package/dist/src/interpreter/trampoline.d.ts +0 -17
  258. package/dist/src/interpreter/trampoline.js +0 -38
  259. package/dist/src/interpreter/utils.d.ts +0 -11
  260. package/dist/src/interpreter/utils.js +0 -65
  261. package/dist/src/tester/index.d.ts +0 -25
  262. package/dist/src/tester/index.js +0 -113
  263. package/dist/src/utils/helpers.d.ts +0 -13
  264. package/dist/src/utils/helpers.js +0 -52
  265. package/src/interpreter/components/Visitor.ts +0 -1065
  266. package/src/interpreter/trampoline.ts +0 -71
@@ -0,0 +1,164 @@
1
+ import { StepCommand, BindCommand, } from "../../components/kernel/commands.js";
2
+ import { NotConcatenable } from "../../errors.js";
3
+ import { boolean, error, raise } from "../../utils.js";
4
+ import { YuNil } from "../scalars/YuNil.js";
5
+ import { YuArray } from "../sequences/YuArray.js";
6
+ import { YuValue } from "../YuValue.js";
7
+ /**
8
+ * Represents the result of forcing one step of a LazyList.
9
+ * If null, the list is empty.
10
+ */
11
+ export class LazyStepResult extends YuValue {
12
+ head;
13
+ tail;
14
+ constructor(head, tail) {
15
+ super();
16
+ this.head = head;
17
+ this.tail = tail;
18
+ }
19
+ get asStepResult() {
20
+ return this;
21
+ }
22
+ equals(other) {
23
+ return boolean(other === this);
24
+ }
25
+ compare(other) {
26
+ return raise(error("LazyStepResult", "Step results are not comparable"));
27
+ }
28
+ toString() {
29
+ return `StepResult(${this.head}, ${this.tail})`;
30
+ }
31
+ toJSON() {
32
+ return { head: this.head.toJSON(), tail: this.tail?.toJSON() };
33
+ }
34
+ }
35
+ /**
36
+ * A LazyList represents a potentially infinite sequence of values evaluated on demand.
37
+ */
38
+ export class LazyList extends YuValue {
39
+ producer;
40
+ identifier;
41
+ capturedContext;
42
+ // Use 'undefined' for un-evaluated, 'null' for empty list.
43
+ memoized = undefined;
44
+ constructor(producer, identifier = "lazy", capturedContext) {
45
+ super();
46
+ this.producer = producer;
47
+ this.identifier = identifier;
48
+ this.capturedContext = capturedContext;
49
+ }
50
+ equals(other) {
51
+ return boolean(other === this);
52
+ }
53
+ compare(other) {
54
+ return raise(error("LazyList.compare", "LazyLists are not comparable"));
55
+ }
56
+ get asSequence() {
57
+ return this;
58
+ }
59
+ *[Symbol.iterator]() {
60
+ throw new Error("Cannot synchronously iterate a LazyList. Use realize() or step().");
61
+ }
62
+ /**
63
+ * Evaluates the first element of the list and returns it along with the tail.
64
+ */
65
+ step() {
66
+ if (this.memoized !== undefined) {
67
+ return new StepCommand(this.memoized === null ? YuNil.getInstance() : this.memoized);
68
+ }
69
+ return new BindCommand(this.producer(this.capturedContext), (result) => {
70
+ if (result === null ||
71
+ result === undefined ||
72
+ result instanceof YuNil) {
73
+ this.memoized = null;
74
+ }
75
+ else if (result instanceof LazyStepResult) {
76
+ this.memoized = result;
77
+ }
78
+ else if (result instanceof YuValue) {
79
+ this.memoized = new LazyStepResult(result, null);
80
+ }
81
+ else {
82
+ // Fallback for raw JS values if any still exist
83
+ return raise(error("LazyList.step", "LazyList producer returned non-YuValue"));
84
+ }
85
+ return new StepCommand(this.memoized === null ? YuNil.getInstance() : this.memoized);
86
+ });
87
+ }
88
+ size() {
89
+ return raise(error("[LazyList.size]", "Cannot calculate the length of a LazyList"));
90
+ }
91
+ realize() {
92
+ const result = [];
93
+ const next = (list) => {
94
+ return new BindCommand(list.step(), (stepRes) => {
95
+ if (stepRes instanceof YuNil)
96
+ return new StepCommand(new YuArray(result));
97
+ if (!(stepRes instanceof LazyStepResult))
98
+ return raise(error("LazyList.realize", "LazyList step did not return LazyStepResult"));
99
+ result.push(stepRes.head);
100
+ if (stepRes.tail) {
101
+ const tailSeq = stepRes.tail.asSequence;
102
+ if (tailSeq)
103
+ return next(tailSeq);
104
+ }
105
+ return new StepCommand(new YuArray(result));
106
+ });
107
+ };
108
+ return next(this);
109
+ }
110
+ concat(other) {
111
+ const rightSeq = other.asSequence;
112
+ if (!rightSeq)
113
+ return raise(error("LazyList.concat", "Cannot concatenate with a non-sequence"));
114
+ return new StepCommand(this.createLazyConcat(this, rightSeq));
115
+ }
116
+ concatWithArray(arr) {
117
+ const leftSeq = arr.asSequence;
118
+ if (!leftSeq)
119
+ return raise(new NotConcatenable());
120
+ return new StepCommand(this.createLazyConcat(leftSeq, this));
121
+ }
122
+ concatWithString(str) {
123
+ const leftSeq = str.asSequence;
124
+ if (!leftSeq)
125
+ return raise(new NotConcatenable());
126
+ return new StepCommand(this.createLazyConcat(leftSeq, this));
127
+ }
128
+ createLazyConcat(left, right) {
129
+ return new LazyList((ctx) => {
130
+ // Step through the left sequence first
131
+ return new BindCommand(left.step(), (stepRes) => {
132
+ // if left is exhausted, fallback immediately to stepping the right sequence
133
+ if (stepRes.isNil)
134
+ return right.step();
135
+ // ensure we have a valid step result
136
+ const stepResult = stepRes.asStepResult;
137
+ if (!stepResult)
138
+ return raise(error("LazyList.createLazyConcat", "Invalid sequence step: Expected a StepResult"));
139
+ // recursively and lazily build the tail sequence
140
+ const nextTail = stepResult.tail && !stepResult.tail.isNil
141
+ ? this.createLazyConcat(stepResult.tail, right)
142
+ : right;
143
+ return new StepCommand(new LazyStepResult(stepResult.head, nextTail));
144
+ });
145
+ }, `lazyConcat`, this.capturedContext);
146
+ }
147
+ toJSON() {
148
+ return {
149
+ identifier: this.identifier,
150
+ memoized: this.memoized === undefined
151
+ ? "?"
152
+ : this.memoized === null
153
+ ? "[]"
154
+ : this.memoized.toJSON(),
155
+ };
156
+ }
157
+ toString() {
158
+ const state = this.memoized === undefined ? "?" : this.memoized === null ? "[]" : "...";
159
+ return `[LazyList ${this.identifier} ${state}]`;
160
+ }
161
+ }
162
+ export function isLazyList(prim) {
163
+ return prim instanceof LazyList;
164
+ }
@@ -0,0 +1,51 @@
1
+ import { ExecutionCommand } from "../../components/kernel/commands.js";
2
+ import { YuValue } from "../YuValue.js";
3
+ /**
4
+ * Interface for logic terms that can be treated as runtime values.
5
+ */
6
+ export declare abstract class LogicTerm extends YuValue {
7
+ abstract readonly logicTermType: string;
8
+ abstract unify(other: LogicTerm, env: Substitution): ExecutionCommand;
9
+ abstract resolve(env: Substitution): LogicTerm;
10
+ abstract instantiate(env: Substitution, seen?: Set<number>): LogicTerm;
11
+ abstract toPrimitive(env: Substitution): YuValue;
12
+ abstract occurs(v: any, env: Substitution): boolean;
13
+ equals(other: YuValue): ExecutionCommand;
14
+ compare(other: YuValue): ExecutionCommand;
15
+ }
16
+ export declare function isLogicTerm(val: unknown): val is LogicTerm;
17
+ /**
18
+ * Substitution map that supports numeric IDs (internally) and string names (for results).
19
+ */
20
+ export type Substitution = Map<string | number, LogicTerm>;
21
+ export declare class LogicAnswer extends YuValue {
22
+ private _success;
23
+ private _solution;
24
+ constructor(success: boolean, solution: Substitution);
25
+ equals(other: YuValue): ExecutionCommand;
26
+ compare(other: YuValue): ExecutionCommand;
27
+ isSuccessful(): boolean;
28
+ getSolution(): Substitution;
29
+ get success(): boolean;
30
+ /**
31
+ * Returns a view of the solutions containing only string-named variables (for the user).
32
+ */
33
+ get solutions(): Substitution;
34
+ toJSON(): unknown;
35
+ toString(): string;
36
+ }
37
+ export declare class LogicResult extends YuValue {
38
+ private answers;
39
+ constructor(answers: LogicAnswer[]);
40
+ equals(other: YuValue): ExecutionCommand;
41
+ compare(other: YuValue): ExecutionCommand;
42
+ get allAnswers(): LogicAnswer[];
43
+ getAllSuccessful(): LogicAnswer[];
44
+ allSuccessful(): boolean;
45
+ getSuccessfulSolutions(): Substitution[];
46
+ get success(): boolean;
47
+ get solutions(): Substitution;
48
+ toJSON(): unknown;
49
+ toString(): string;
50
+ }
51
+ export declare function isLogicResult(value: YuValue): value is LogicResult;
@@ -0,0 +1,101 @@
1
+ import { boolean, error, raise } from "../../utils.js";
2
+ import { YuValue } from "../YuValue.js";
3
+ /**
4
+ * Interface for logic terms that can be treated as runtime values.
5
+ */
6
+ export class LogicTerm extends YuValue {
7
+ equals(other) {
8
+ return boolean(this === other);
9
+ }
10
+ compare(other) {
11
+ return raise(error("LogicTerm.compare", `Comparison not supported for LogicTerm: ${this.logicTermType}`));
12
+ }
13
+ }
14
+ export function isLogicTerm(val) {
15
+ return val !== null && typeof val === "object" && "logicTermType" in val;
16
+ }
17
+ export class LogicAnswer extends YuValue {
18
+ _success;
19
+ _solution;
20
+ constructor(success, solution) {
21
+ super();
22
+ this._success = success;
23
+ this._solution = solution;
24
+ }
25
+ equals(other) {
26
+ return boolean(other === this);
27
+ }
28
+ compare(other) {
29
+ return raise(error("LogicAnswer.compare", "LogicAnswer is not comparable"));
30
+ }
31
+ isSuccessful() {
32
+ return this._success;
33
+ }
34
+ getSolution() {
35
+ return this._solution;
36
+ }
37
+ get success() {
38
+ return this.isSuccessful();
39
+ }
40
+ /**
41
+ * Returns a view of the solutions containing only string-named variables (for the user).
42
+ */
43
+ get solutions() {
44
+ return this._solution;
45
+ }
46
+ toJSON() {
47
+ const sol = {};
48
+ for (const [key, val] of this._solution) {
49
+ if (typeof key === "string")
50
+ sol[key] = val.toJSON();
51
+ }
52
+ return { success: this._success, solution: sol };
53
+ }
54
+ toString() {
55
+ return `Answer(${this._success})`;
56
+ }
57
+ }
58
+ export class LogicResult extends YuValue {
59
+ answers;
60
+ constructor(answers) {
61
+ super();
62
+ this.answers = answers;
63
+ }
64
+ equals(other) {
65
+ return boolean(other === this);
66
+ }
67
+ compare(other) {
68
+ return raise(error("LogicResult.compare", "LogicResult is not comparable"));
69
+ }
70
+ get allAnswers() {
71
+ return this.answers;
72
+ }
73
+ getAllSuccessful() {
74
+ return this.answers.filter((answer) => answer.isSuccessful());
75
+ }
76
+ allSuccessful() {
77
+ return (this.answers.length > 0 &&
78
+ this.answers.every((answer) => answer.isSuccessful()));
79
+ }
80
+ getSuccessfulSolutions() {
81
+ return this.getAllSuccessful().map((ans) => ans.getSolution());
82
+ }
83
+ get success() {
84
+ return (this.answers.length > 0 && this.answers.every((a) => a.isSuccessful()));
85
+ }
86
+ get solutions() {
87
+ const answers = this.getAllSuccessful();
88
+ if (answers.length === 0)
89
+ return new Map();
90
+ return answers[0].solutions;
91
+ }
92
+ toJSON() {
93
+ return this.answers.map((a) => a.toJSON());
94
+ }
95
+ toString() {
96
+ return `LogicResult(${this.answers.length})`;
97
+ }
98
+ }
99
+ export function isLogicResult(value) {
100
+ return value instanceof LogicResult;
101
+ }
@@ -0,0 +1,24 @@
1
+ import { ExecutionCommand } from "../../components/kernel/commands.js";
2
+ import { YuValue } from "../YuValue.js";
3
+ import { RuntimeFunction } from "./RuntimeFunction.js";
4
+ import { RuntimeObject } from "./RuntimeObject.js";
5
+ export declare class RuntimeClass extends YuValue {
6
+ identifier: string;
7
+ fields: Map<string, YuValue>;
8
+ methods: Map<string, RuntimeFunction>;
9
+ mixins: string[];
10
+ superclass?: string | undefined;
11
+ fieldInitializers?: Map<string, any> | undefined;
12
+ private isAbstract;
13
+ constructor(identifier: string, fields: Map<string, YuValue>, methods: Map<string, RuntimeFunction>, mixins: string[], superclass?: string | undefined, fieldInitializers?: Map<string, any> | undefined, isAbstract?: boolean);
14
+ equals(other: YuValue): ExecutionCommand;
15
+ compare(other: YuValue): ExecutionCommand;
16
+ getHierarchy(): string[];
17
+ /**
18
+ * Creates a new instance of an Object.
19
+ */
20
+ instantiate(identifier: string): RuntimeObject;
21
+ toJSON(): unknown;
22
+ toString(): string;
23
+ }
24
+ export declare function isRuntimeClass(val: YuValue): val is RuntimeClass;
@@ -0,0 +1,57 @@
1
+ import { InterpreterError } from "../../errors.js";
2
+ import { boolean, error, raise } from "../../utils.js";
3
+ import { YuValue } from "../YuValue.js";
4
+ import { RuntimeObject } from "./RuntimeObject.js";
5
+ export class RuntimeClass extends YuValue {
6
+ identifier;
7
+ fields;
8
+ methods;
9
+ mixins;
10
+ superclass;
11
+ fieldInitializers;
12
+ isAbstract;
13
+ constructor(identifier, fields, methods, mixins, superclass, fieldInitializers, isAbstract = false) {
14
+ super();
15
+ this.identifier = identifier;
16
+ this.fields = fields;
17
+ this.methods = methods;
18
+ this.mixins = mixins;
19
+ this.superclass = superclass;
20
+ this.fieldInitializers = fieldInitializers;
21
+ this.isAbstract = isAbstract;
22
+ }
23
+ equals(other) {
24
+ return boolean(other === this);
25
+ }
26
+ compare(other) {
27
+ return raise(error("RuntimeClass.compare", "Classes are not comparable"));
28
+ }
29
+ getHierarchy() {
30
+ const hierarchy = [...this.mixins.reverse()];
31
+ if (this.superclass)
32
+ hierarchy.push(this.superclass);
33
+ return hierarchy;
34
+ }
35
+ /**
36
+ * Creates a new instance of an Object.
37
+ */
38
+ instantiate(identifier) {
39
+ if (this.isAbstract)
40
+ throw new InterpreterError("[ObjectRuntime]", `Cannot instantiate abstract class ${this.identifier}`);
41
+ return new RuntimeObject(identifier, this.identifier, new Map(this.fields), new Map());
42
+ }
43
+ toJSON() {
44
+ return {
45
+ identifier: this.identifier,
46
+ superclass: this.superclass,
47
+ mixins: this.mixins,
48
+ isAbstract: this.isAbstract,
49
+ };
50
+ }
51
+ toString() {
52
+ return `[Class: ${this.identifier}]`;
53
+ }
54
+ }
55
+ export function isRuntimeClass(val) {
56
+ return val instanceof RuntimeClass;
57
+ }
@@ -0,0 +1,40 @@
1
+ import { Body, Pattern } from "yukigo-ast";
2
+ import { YuValue } from "../YuValue.js";
3
+ import { EnvStack, PrimitiveThunk } from "../../utils.js";
4
+ import { ExecutionCommand } from "../../components/kernel/commands.js";
5
+ export interface EquationRuntime {
6
+ patterns: Pattern[];
7
+ body: Body;
8
+ }
9
+ /**
10
+ * Runtime Function used in the Interpreter
11
+ */
12
+ export declare class RuntimeFunction extends YuValue {
13
+ arity: number;
14
+ equations: EquationRuntime[];
15
+ identifier?: string | undefined;
16
+ pendingArgs?: (YuValue | PrimitiveThunk)[] | undefined;
17
+ closure?: EnvStack | undefined;
18
+ constructor(arity: number, equations: EquationRuntime[], identifier?: string | undefined, pendingArgs?: (YuValue | PrimitiveThunk)[] | undefined, closure?: EnvStack | undefined);
19
+ equals(other: YuValue): ExecutionCommand;
20
+ compare(other: YuValue): ExecutionCommand;
21
+ get name(): string;
22
+ get remainingArity(): number;
23
+ get isFullyApplied(): boolean;
24
+ get hasPendingArgs(): boolean;
25
+ /**
26
+ * Partially applies the function with new arguments.
27
+ */
28
+ bind(...args: (YuValue | PrimitiveThunk)[]): RuntimeFunction;
29
+ /**
30
+ * Returns a new RuntimeFunction with the given closure.
31
+ */
32
+ withClosure(closure: EnvStack): RuntimeFunction;
33
+ /**
34
+ * Evaluates all pending arguments (resolving thunks).
35
+ */
36
+ getEvaluatedArgs(): YuValue[];
37
+ toJSON(): unknown;
38
+ toString(): string;
39
+ }
40
+ export declare function isRuntimeFunction(val: YuValue): val is RuntimeFunction;
@@ -0,0 +1,73 @@
1
+ import { YuValue } from "../YuValue.js";
2
+ import { boolean, error, raise, } from "../../utils.js";
3
+ /**
4
+ * Runtime Function used in the Interpreter
5
+ */
6
+ export class RuntimeFunction extends YuValue {
7
+ arity;
8
+ equations;
9
+ identifier;
10
+ pendingArgs;
11
+ closure;
12
+ constructor(arity, equations, identifier, pendingArgs, closure) {
13
+ super();
14
+ this.arity = arity;
15
+ this.equations = equations;
16
+ this.identifier = identifier;
17
+ this.pendingArgs = pendingArgs;
18
+ this.closure = closure;
19
+ }
20
+ equals(other) {
21
+ return boolean(other === this);
22
+ }
23
+ compare(other) {
24
+ return raise(error("RuntimeFunction.compare", "Functions are not comparable"));
25
+ }
26
+ get name() {
27
+ return this.identifier ?? "<anonymous>";
28
+ }
29
+ get remainingArity() {
30
+ return this.arity - (this.pendingArgs?.length ?? 0);
31
+ }
32
+ get isFullyApplied() {
33
+ return this.remainingArity <= 0;
34
+ }
35
+ get hasPendingArgs() {
36
+ return (this.pendingArgs?.length ?? 0) > 0;
37
+ }
38
+ /**
39
+ * Partially applies the function with new arguments.
40
+ */
41
+ bind(...args) {
42
+ return new RuntimeFunction(this.arity, this.equations, this.identifier, [...(this.pendingArgs ?? []), ...args], this.closure);
43
+ }
44
+ /**
45
+ * Returns a new RuntimeFunction with the given closure.
46
+ */
47
+ withClosure(closure) {
48
+ return new RuntimeFunction(this.arity, this.equations, this.identifier, this.pendingArgs, closure);
49
+ }
50
+ /**
51
+ * Evaluates all pending arguments (resolving thunks).
52
+ */
53
+ getEvaluatedArgs() {
54
+ return (this.pendingArgs ?? []).map((arg) => typeof arg === "function" ? arg() : arg);
55
+ }
56
+ toJSON() {
57
+ return {
58
+ name: this.name,
59
+ arity: this.arity,
60
+ remainingArity: this.remainingArity,
61
+ };
62
+ }
63
+ toString() {
64
+ const arityInfo = this.arity > 0 ? `/${this.arity}` : "";
65
+ const pendingInfo = this.hasPendingArgs
66
+ ? ` (applied ${this.pendingArgs.length})`
67
+ : "";
68
+ return `[Function: ${this.name}${arityInfo}${pendingInfo}]`;
69
+ }
70
+ }
71
+ export function isRuntimeFunction(val) {
72
+ return val instanceof RuntimeFunction;
73
+ }
@@ -0,0 +1,27 @@
1
+ import { ExecutionCommand } from "../../components/kernel/commands.js";
2
+ import { YuValue } from "../YuValue.js";
3
+ import { RuntimeClass } from "./RuntimeClass.js";
4
+ import { RuntimeFunction } from "./RuntimeFunction.js";
5
+ type OOPMatch = {
6
+ method: RuntimeFunction;
7
+ holder: RuntimeObject | RuntimeClass;
8
+ };
9
+ export declare class RuntimeObject extends YuValue {
10
+ identifier: string;
11
+ className: string;
12
+ fields: Map<string, YuValue>;
13
+ methods: Map<string, RuntimeFunction>;
14
+ constructor(identifier: string, className: string, fields: Map<string, YuValue>, methods: Map<string, RuntimeFunction>);
15
+ equals(other: YuValue): ExecutionCommand;
16
+ compare(other: YuValue): ExecutionCommand;
17
+ hasField(name: string): boolean;
18
+ getField(name: string): YuValue;
19
+ setField(name: string, value: YuValue): void;
20
+ getMethod(name: string): RuntimeFunction;
21
+ hasMethod(name: string): boolean;
22
+ createDispatchScope(match: OOPMatch, targetName: YuValue): Map<string, YuValue>;
23
+ toJSON(keyOrSeen?: string | Set<YuValue>): unknown;
24
+ toString(seen?: Set<YuValue>): string;
25
+ }
26
+ export declare function isRuntimeObject(val: YuValue): val is RuntimeObject;
27
+ export {};
@@ -0,0 +1,82 @@
1
+ import { InterpreterError } from "../../errors.js";
2
+ import { boolean, error, raise } from "../../utils.js";
3
+ import { YuValue } from "../YuValue.js";
4
+ export class RuntimeObject extends YuValue {
5
+ identifier;
6
+ className;
7
+ fields;
8
+ methods;
9
+ constructor(identifier, className, fields, methods) {
10
+ super();
11
+ this.identifier = identifier;
12
+ this.className = className;
13
+ this.fields = fields;
14
+ this.methods = methods;
15
+ }
16
+ equals(other) {
17
+ return boolean(other === this);
18
+ }
19
+ compare(other) {
20
+ return raise(error("RuntimeClass.compare", "Objects are not comparable"));
21
+ }
22
+ hasField(name) {
23
+ return this.fields.has(name);
24
+ }
25
+ getField(name) {
26
+ if (!this.hasField(name))
27
+ throw new InterpreterError("[ObjectRuntime]", `Field '${name}' not found in ${this.className}`);
28
+ return this.fields.get(name);
29
+ }
30
+ setField(name, value) {
31
+ if (!this.hasField(name))
32
+ throw new InterpreterError("[ObjectRuntime]", `Cannot set unknown field '${name}'`);
33
+ this.fields.set(name, value);
34
+ }
35
+ getMethod(name) {
36
+ if (!this.hasMethod(name))
37
+ throw new InterpreterError("[ObjectRuntime]", `${this.className} does not understand '${name}`);
38
+ return this.methods.get(name);
39
+ }
40
+ hasMethod(name) {
41
+ return this.methods.has(name);
42
+ }
43
+ createDispatchScope(match, targetName) {
44
+ const objectScope = new Map();
45
+ objectScope.set("self", this);
46
+ objectScope.set("__CONTEXT_CLASS__", match.holder);
47
+ objectScope.set("__METHOD_NAME__", targetName);
48
+ for (const [key, val] of this.fields)
49
+ objectScope.set(key, val);
50
+ return objectScope;
51
+ }
52
+ toJSON(keyOrSeen) {
53
+ const seen = keyOrSeen instanceof Set ? keyOrSeen : new Set();
54
+ if (seen.has(this))
55
+ return { identifier: this.identifier, circular: true };
56
+ seen.add(this);
57
+ const fieldsJSON = {};
58
+ for (const [key, val] of this.fields)
59
+ fieldsJSON[key] = val.toJSON(seen);
60
+ seen.delete(this);
61
+ return {
62
+ identifier: this.identifier,
63
+ className: this.className,
64
+ fields: fieldsJSON,
65
+ };
66
+ }
67
+ toString(seen = new Set()) {
68
+ if (seen.has(this))
69
+ return this.identifier || this.className || "object (circular)";
70
+ seen.add(this);
71
+ const fieldsArray = [];
72
+ for (const [k, v] of this.fields.entries()) {
73
+ fieldsArray.push(`${k}=${v ? v.toString(seen) : "nil"}`);
74
+ }
75
+ const name = this.identifier || this.className || "object";
76
+ seen.delete(this);
77
+ return `${name}[${fieldsArray.join(", ")}]`;
78
+ }
79
+ }
80
+ export function isRuntimeObject(val) {
81
+ return val instanceof RuntimeObject;
82
+ }
@@ -0,0 +1,19 @@
1
+ import { Fact, Rule, Visitor } from "yukigo-ast";
2
+ import { YuValue } from "../YuValue.js";
3
+ import { ExecutionCommand } from "../../components/kernel/commands.js";
4
+ export declare class RuntimePredicate extends YuValue {
5
+ identifier: string;
6
+ equations: (Fact | Rule)[];
7
+ readonly arity: number;
8
+ constructor(identifier: string, equations: (Fact | Rule)[]);
9
+ equals(other: YuValue): ExecutionCommand;
10
+ compare(other: YuValue): ExecutionCommand;
11
+ apply<T>(visitor: Visitor<T>): T[];
12
+ addClause(clause: Fact | Rule): void;
13
+ private validateClause;
14
+ validateArity(args: number): boolean;
15
+ private getArityFromClause;
16
+ toJSON(): unknown;
17
+ toString(): string;
18
+ }
19
+ export declare const isRuntimePredicate: (prim: unknown) => prim is RuntimePredicate;