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
@@ -1,52 +1,50 @@
1
- import { PrimitiveValue, AST, EnvStack, ASTNode } from "yukigo-ast";
2
- import { InterpreterVisitor } from "./components/Visitor.js";
3
- import { EnvBuilderVisitor } from "./components/EnvBuilder.js";
4
- import { InterpreterError } from "./errors.js";
5
- import { createGlobalEnv } from "./utils.js";
6
- import { idContinuation, trampoline } from "./trampoline.js";
7
- import {
8
- InterpreterConfig,
9
- RuntimeContext,
10
- } from "./components/RuntimeContext.js";
11
- import { LazyRuntime } from "./components/runtimes/LazyRuntime.js";
12
- import { FunctionRuntime } from "./components/runtimes/FunctionRuntime.js";
13
- import { ObjectRuntime } from "./components/runtimes/ObjectRuntime.js";
14
-
15
- export type Bindings = [string, PrimitiveValue][];
16
-
17
- /**
18
- * The Interpreter class is responsible for evaluating the Abstract Syntax Tree (AST)
19
- * generated by the parsers.
20
- *
21
- * It manages the global execution environment and delegates the actual evaluation
22
- * of Expression nodes to a dedicated visitor.
23
- */
24
- export class Interpreter {
25
- private context: RuntimeContext;
26
-
27
- /**
28
- * @param ast The Abstract Syntax Tree (AST) of the program to be interpreted.
29
- */
30
- constructor(ast: AST, config: InterpreterConfig = {}) {
31
- this.context = new RuntimeContext(config);
32
- const builder = new EnvBuilderVisitor(this.context);
33
- builder.build(ast);
34
- }
35
-
36
- /**
37
- * Evaluates a single Expression node within the context of the global environment.
38
- *
39
- * @param expr The root Expression node to be evaluated.
40
- * @returns The resulting primitive value (number, string, boolean, etc.) after evaluation.
41
- */
42
- public evaluate(expr: ASTNode): PrimitiveValue {
43
- try {
44
- const visitor = new InterpreterVisitor(this.context);
45
- const evaluatedCPS = expr.accept(visitor);
46
- return trampoline(evaluatedCPS(idContinuation));
47
- } catch (error) {
48
- if (error instanceof InterpreterError) console.log(error.formatStack());
49
- throw error;
50
- }
51
- }
52
- }
1
+ import { AST, ASTNode } from "yukigo-ast";
2
+ import { EnvBuilderVisitor } from "./components/EnvBuilder.js";
3
+ import {
4
+ RuntimeContext,
5
+ } from "./components/RuntimeContext.js";
6
+ import { YukigoKernel } from "./components/kernel/index.js";
7
+ import { EvalCommand } from "./components/kernel/commands.js";
8
+ import { YuValue } from "./primitives/index.js";
9
+ import { InterpreterConfig } from "../utils/helpers.js";
10
+ import { InterpreterVisitor } from "./components/evaluators/index.js";
11
+ export * from "./primitives/index.js";
12
+
13
+ export type Bindings = [string, YuValue][];
14
+
15
+ /**
16
+ * The Interpreter class is responsible for evaluating the Abstract Syntax Tree (AST)
17
+ * generated by the parsers.
18
+ *
19
+ * It manages the global execution environment and delegates the actual evaluation
20
+ * of Expression nodes to a dedicated visitor.
21
+ */
22
+ export class Interpreter {
23
+ private context: RuntimeContext;
24
+
25
+ /**
26
+ * @param ast The Abstract Syntax Tree (AST) of the program to be interpreted.
27
+ */
28
+ constructor(ast: AST, config: Partial<InterpreterConfig> = {}) {
29
+ this.context = new RuntimeContext(config);
30
+ const builder = new EnvBuilderVisitor(this.context);
31
+ builder.build(ast);
32
+ }
33
+
34
+ /**
35
+ * Evaluates a single Expression node within the context of the global environment.
36
+ *
37
+ * @param expr The root Expression node to be evaluated.
38
+ * @returns The resulting primitive value (number, string, boolean, etc.) after evaluation.
39
+ */
40
+ public evaluate(expr: ASTNode): YuValue {
41
+ const visitor = new InterpreterVisitor(this.context);
42
+ const outputMode = this.context.config.outputMode;
43
+ const kernel = new YukigoKernel(visitor, outputMode);
44
+ return kernel.run(new EvalCommand(expr));
45
+ }
46
+
47
+ public getContext(): RuntimeContext {
48
+ return this.context;
49
+ }
50
+ }
@@ -0,0 +1,64 @@
1
+ import {
2
+ ExecutionCommand,
3
+ StepCommand,
4
+ } from "../components/kernel/commands.js";
5
+ import { boolean } from "../utils.js";
6
+ import {
7
+ YuNumeric,
8
+ YuSummable,
9
+ YuSequence,
10
+ YuLogic,
11
+ YuComparable,
12
+ YuStepResult,
13
+ } from "./capabilities.js";
14
+ import { YuBoolean } from "./scalars/YuBoolean.js";
15
+
16
+ /**
17
+ * Base class for all Yukigo values.
18
+ */
19
+ export abstract class YuValue {
20
+ abstract toString(seen?: Set<YuValue>): string;
21
+ abstract toJSON(keyOrSeen?: string | Set<YuValue>): unknown;
22
+
23
+ public getType(): string {
24
+ return this.constructor.name.replace("Yu", "");
25
+ }
26
+
27
+ public realize(): ExecutionCommand {
28
+ return new StepCommand(this);
29
+ }
30
+
31
+ // Capability Accessors (Delegation)
32
+ get asSummable(): YuSummable | undefined {
33
+ return undefined;
34
+ }
35
+ get asNumeric(): YuNumeric | undefined {
36
+ return undefined;
37
+ }
38
+ get asSequence(): YuSequence | undefined {
39
+ return undefined;
40
+ }
41
+ get asLogic(): YuLogic | undefined {
42
+ return undefined;
43
+ }
44
+ get asComparable(): YuComparable | undefined {
45
+ return undefined;
46
+ }
47
+ get asStepResult(): YuStepResult | undefined {
48
+ return undefined;
49
+ }
50
+
51
+ get isNil(): boolean {
52
+ return false;
53
+ }
54
+
55
+ // Comparison
56
+ public abstract equals(other: YuValue): ExecutionCommand;
57
+ public abstract compare(other: YuValue): ExecutionCommand;
58
+
59
+ public isSame(other: YuValue): ExecutionCommand {
60
+ if (this.getType() !== other.getType())
61
+ return boolean(false);
62
+ return this.equals(other);
63
+ }
64
+ }
@@ -0,0 +1,111 @@
1
+ import { ExecutionCommand } from "../components/kernel/commands.js";
2
+ import { YuValue } from "./YuValue.js";
3
+
4
+
5
+ /**
6
+ * Capability for addition and concatenation.
7
+ */
8
+ export interface Summable {
9
+ plus(other: YuValue): ExecutionCommand;
10
+ plusWithNumber(left: YuValue): ExecutionCommand;
11
+ plusWithString(left: YuValue): ExecutionCommand;
12
+ }
13
+ export type YuSummable = YuValue & Summable
14
+
15
+
16
+ /**
17
+ * Capability for numeric operations.
18
+ */
19
+ export interface Numeric extends Summable {
20
+ readonly value: number;
21
+ minus(other: YuValue): ExecutionCommand;
22
+ multiply(other: YuValue): ExecutionCommand;
23
+ divide(other: YuValue): ExecutionCommand;
24
+ modulo(other: YuValue): ExecutionCommand;
25
+ power(other: YuValue): ExecutionCommand;
26
+ min(other: YuValue): ExecutionCommand;
27
+ max(other: YuValue): ExecutionCommand;
28
+
29
+ round(): ExecutionCommand
30
+ abs(): ExecutionCommand
31
+ ceil(): ExecutionCommand
32
+ floor(): ExecutionCommand
33
+ negation(): ExecutionCommand
34
+ sqrt(): ExecutionCommand
35
+
36
+ minusWithNumber(left: YuValue): ExecutionCommand;
37
+ multiplyWithNumber(left: YuValue): ExecutionCommand;
38
+ divideWithNumber(left: YuValue): ExecutionCommand;
39
+ moduloWithNumber(left: YuValue): ExecutionCommand;
40
+ powerWithNumber(left: YuValue): ExecutionCommand;
41
+ minWithNumber(left: YuValue): ExecutionCommand;
42
+ maxWithNumber(left: YuValue): ExecutionCommand;
43
+ }
44
+
45
+ export type YuNumeric = YuValue & Numeric
46
+
47
+ /**
48
+ * Capability for sequences.
49
+ */
50
+ export interface Sequence {
51
+ step(): ExecutionCommand;
52
+ realize(): ExecutionCommand;
53
+
54
+ size(): ExecutionCommand;
55
+
56
+ concat(other: YuValue): ExecutionCommand;
57
+ concatWithArray(arr: YuValue): ExecutionCommand
58
+ concatWithString(str: YuValue): ExecutionCommand
59
+
60
+ [Symbol.iterator](): Iterator<YuValue>;
61
+ getType(): string;
62
+ toJSON(): unknown;
63
+ readonly isNil: boolean;
64
+ readonly asStepResult?: StepResult;
65
+ }
66
+
67
+ export type YuSequence = YuValue & Sequence
68
+
69
+ /**
70
+ * Capability for logical operations.
71
+ */
72
+ export interface Logic {
73
+ readonly value: boolean;
74
+ not(): ExecutionCommand;
75
+ toJSON(): unknown;
76
+ }
77
+
78
+ export type YuLogic = YuValue & Logic
79
+
80
+
81
+ /**
82
+ * Capability for comparisons.
83
+ */
84
+ export interface Comparable {
85
+ equals(other: YuValue): ExecutionCommand;
86
+ compare(other: YuValue): ExecutionCommand;
87
+
88
+ equalsWithNumber(left: YuValue): ExecutionCommand;
89
+ equalsWithBoolean(left: YuValue): ExecutionCommand;
90
+ equalsWithString(left: YuValue): ExecutionCommand;
91
+ equalsWithArray(left: YuValue): ExecutionCommand;
92
+ equalsWithNil(left: YuValue): ExecutionCommand;
93
+
94
+ compareWithNumber(left: YuValue): ExecutionCommand;
95
+ compareWithBoolean(left: YuValue): ExecutionCommand;
96
+ compareWithString(left: YuValue): ExecutionCommand;
97
+ compareWithArray(left: YuValue): ExecutionCommand;
98
+ compareWithNil(left: YuValue): ExecutionCommand;
99
+ }
100
+
101
+ export type YuComparable = YuValue & Comparable
102
+
103
+ /**
104
+ * Result of stepping a sequence.
105
+ */
106
+ export interface StepResult {
107
+ readonly head: YuValue;
108
+ readonly tail: YuSequence | null;
109
+ }
110
+
111
+ export type YuStepResult = YuValue & StepResult
@@ -0,0 +1,225 @@
1
+ import {
2
+ ExecutionCommand,
3
+ StepCommand,
4
+ BindCommand,
5
+ } from "../../components/kernel/commands.js";
6
+ import { RuntimeContext } from "../../components/RuntimeContext.js";
7
+ import { InterpreterError, NotConcatenable } from "../../errors.js";
8
+ import { boolean, error, raise } from "../../utils.js";
9
+ import {
10
+ Sequence,
11
+ StepResult,
12
+ YuSequence,
13
+ YuStepResult,
14
+ } from "../capabilities.js";
15
+ import { YuBoolean } from "../index.js";
16
+ import { YuNil } from "../scalars/YuNil.js";
17
+ import { YuArray } from "../sequences/YuArray.js";
18
+ import { YuValue } from "../YuValue.js";
19
+
20
+ /**
21
+ * Represents the result of forcing one step of a LazyList.
22
+ * If null, the list is empty.
23
+ */
24
+ export class LazyStepResult extends YuValue implements StepResult {
25
+ constructor(
26
+ public readonly head: YuValue,
27
+ public readonly tail: YuSequence | null,
28
+ ) {
29
+ super();
30
+ }
31
+
32
+ get asStepResult(): YuStepResult {
33
+ return this;
34
+ }
35
+
36
+ public equals(other: YuValue): ExecutionCommand {
37
+ return boolean(other === this);
38
+ }
39
+ public compare(other: YuValue): ExecutionCommand {
40
+ return raise(error("LazyStepResult", "Step results are not comparable"));
41
+ }
42
+ public toString(): string {
43
+ return `StepResult(${this.head}, ${this.tail})`;
44
+ }
45
+ public toJSON(): unknown {
46
+ return { head: this.head.toJSON(), tail: this.tail?.toJSON() };
47
+ }
48
+ }
49
+
50
+ /**
51
+ * A LazyList represents a potentially infinite sequence of values evaluated on demand.
52
+ */
53
+ export class LazyList extends YuValue implements Sequence {
54
+ // Use 'undefined' for un-evaluated, 'null' for empty list.
55
+ private memoized: LazyStepResult | null | undefined = undefined;
56
+
57
+ constructor(
58
+ private readonly producer: (ctx?: RuntimeContext) => ExecutionCommand,
59
+ public readonly identifier: string = "lazy",
60
+ public readonly capturedContext?: RuntimeContext,
61
+ ) {
62
+ super();
63
+ }
64
+
65
+ public equals(other: YuValue): ExecutionCommand {
66
+ return boolean(other === this);
67
+ }
68
+ public compare(other: YuValue): ExecutionCommand {
69
+ return raise(error("LazyList.compare", "LazyLists are not comparable"));
70
+ }
71
+
72
+ get asSequence(): YuSequence {
73
+ return this;
74
+ }
75
+
76
+ public *[Symbol.iterator](): Iterator<YuValue> {
77
+ throw new Error(
78
+ "Cannot synchronously iterate a LazyList. Use realize() or step().",
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Evaluates the first element of the list and returns it along with the tail.
84
+ */
85
+ public step(): ExecutionCommand {
86
+ if (this.memoized !== undefined) {
87
+ return new StepCommand(
88
+ this.memoized === null ? YuNil.getInstance() : this.memoized,
89
+ );
90
+ }
91
+
92
+ return new BindCommand(
93
+ this.producer(this.capturedContext),
94
+ (result: any) => {
95
+ if (
96
+ result === null ||
97
+ result === undefined ||
98
+ result instanceof YuNil
99
+ ) {
100
+ this.memoized = null;
101
+ } else if (result instanceof LazyStepResult) {
102
+ this.memoized = result;
103
+ } else if (result instanceof YuValue) {
104
+ this.memoized = new LazyStepResult(result, null);
105
+ } else {
106
+ // Fallback for raw JS values if any still exist
107
+ return raise(
108
+ error("LazyList.step", "LazyList producer returned non-YuValue"),
109
+ );
110
+ }
111
+ return new StepCommand(
112
+ this.memoized === null ? YuNil.getInstance() : this.memoized,
113
+ );
114
+ },
115
+ );
116
+ }
117
+
118
+ public size(): ExecutionCommand {
119
+ return raise(
120
+ error("[LazyList.size]", "Cannot calculate the length of a LazyList"),
121
+ );
122
+ }
123
+
124
+ public realize(): ExecutionCommand {
125
+ const result: YuValue[] = [];
126
+
127
+ const next = (list: Sequence): ExecutionCommand => {
128
+ return new BindCommand(list.step(), (stepRes) => {
129
+ if (stepRes instanceof YuNil)
130
+ return new StepCommand(new YuArray(result));
131
+
132
+ if (!(stepRes instanceof LazyStepResult))
133
+ return raise(
134
+ error(
135
+ "LazyList.realize",
136
+ "LazyList step did not return LazyStepResult",
137
+ ),
138
+ );
139
+
140
+ result.push(stepRes.head);
141
+ if (stepRes.tail) {
142
+ const tailSeq = stepRes.tail.asSequence;
143
+ if (tailSeq) return next(tailSeq);
144
+ }
145
+ return new StepCommand(new YuArray(result));
146
+ });
147
+ };
148
+ return next(this);
149
+ }
150
+
151
+ public concat(other: YuValue): ExecutionCommand {
152
+ const rightSeq = other.asSequence;
153
+ if (!rightSeq)
154
+ return raise(
155
+ error("LazyList.concat", "Cannot concatenate with a non-sequence"),
156
+ );
157
+ return new StepCommand(this.createLazyConcat(this, rightSeq));
158
+ }
159
+
160
+ public concatWithArray(arr: YuValue): ExecutionCommand {
161
+ const leftSeq = arr.asSequence;
162
+ if (!leftSeq) return raise(new NotConcatenable());
163
+
164
+ return new StepCommand(this.createLazyConcat(leftSeq, this));
165
+ }
166
+
167
+ public concatWithString(str: YuValue): ExecutionCommand {
168
+ const leftSeq = str.asSequence;
169
+ if (!leftSeq) return raise(new NotConcatenable());
170
+ return new StepCommand(this.createLazyConcat(leftSeq, this));
171
+ }
172
+
173
+ private createLazyConcat(left: YuSequence, right: YuSequence): LazyList {
174
+ return new LazyList(
175
+ (ctx) => {
176
+ // Step through the left sequence first
177
+ return new BindCommand(left.step(), (stepRes: YuValue) => {
178
+ // if left is exhausted, fallback immediately to stepping the right sequence
179
+ if (stepRes.isNil) return right.step();
180
+
181
+ // ensure we have a valid step result
182
+ const stepResult = stepRes.asStepResult;
183
+ if (!stepResult)
184
+ return raise(
185
+ error(
186
+ "LazyList.createLazyConcat",
187
+ "Invalid sequence step: Expected a StepResult",
188
+ ),
189
+ );
190
+
191
+ // recursively and lazily build the tail sequence
192
+ const nextTail =
193
+ stepResult.tail && !stepResult.tail.isNil
194
+ ? this.createLazyConcat(stepResult.tail, right)
195
+ : right;
196
+
197
+ return new StepCommand(new LazyStepResult(stepResult.head, nextTail));
198
+ });
199
+ },
200
+ `lazyConcat`,
201
+ this.capturedContext,
202
+ );
203
+ }
204
+
205
+ public toJSON() {
206
+ return {
207
+ identifier: this.identifier,
208
+ memoized:
209
+ this.memoized === undefined
210
+ ? "?"
211
+ : this.memoized === null
212
+ ? "[]"
213
+ : this.memoized.toJSON(),
214
+ };
215
+ }
216
+ public toString(): string {
217
+ const state =
218
+ this.memoized === undefined ? "?" : this.memoized === null ? "[]" : "...";
219
+ return `[LazyList ${this.identifier} ${state}]`;
220
+ }
221
+ }
222
+
223
+ export function isLazyList(prim: unknown): prim is LazyList {
224
+ return prim instanceof LazyList;
225
+ }
@@ -0,0 +1,133 @@
1
+ import {
2
+ ExecutionCommand,
3
+ StepCommand,
4
+ } from "../../components/kernel/commands.js";
5
+ import { boolean, error, raise } from "../../utils.js";
6
+ import { YuBoolean } from "../index.js";
7
+ import { YuValue } from "../YuValue.js";
8
+
9
+ /**
10
+ * Interface for logic terms that can be treated as runtime values.
11
+ */
12
+ export abstract class LogicTerm extends YuValue {
13
+ abstract readonly logicTermType: string;
14
+ abstract unify(other: LogicTerm, env: Substitution): ExecutionCommand;
15
+ abstract resolve(env: Substitution): LogicTerm;
16
+ abstract instantiate(env: Substitution, seen?: Set<number>): LogicTerm;
17
+ abstract toPrimitive(env: Substitution): YuValue;
18
+ abstract occurs(v: any, env: Substitution): boolean;
19
+
20
+ public equals(other: YuValue): ExecutionCommand {
21
+ return boolean(this === other);
22
+ }
23
+
24
+ public compare(other: YuValue): ExecutionCommand {
25
+ return raise(
26
+ error(
27
+ "LogicTerm.compare",
28
+ `Comparison not supported for LogicTerm: ${this.logicTermType}`,
29
+ ),
30
+ );
31
+ }
32
+ }
33
+
34
+ export function isLogicTerm(val: unknown): val is LogicTerm {
35
+ return val !== null && typeof val === "object" && "logicTermType" in val;
36
+ }
37
+
38
+ /**
39
+ * Substitution map that supports numeric IDs (internally) and string names (for results).
40
+ */
41
+ export type Substitution = Map<string | number, LogicTerm>;
42
+
43
+ export class LogicAnswer extends YuValue {
44
+ private _success: boolean;
45
+ private _solution: Substitution;
46
+ constructor(success: boolean, solution: Substitution) {
47
+ super();
48
+ this._success = success;
49
+ this._solution = solution;
50
+ }
51
+ public equals(other: YuValue): ExecutionCommand {
52
+ return boolean(other === this);
53
+ }
54
+ public compare(other: YuValue): ExecutionCommand {
55
+ return raise(error("LogicAnswer.compare", "LogicAnswer is not comparable"));
56
+ }
57
+ public isSuccessful(): boolean {
58
+ return this._success;
59
+ }
60
+ public getSolution(): Substitution {
61
+ return this._solution;
62
+ }
63
+ public get success(): boolean {
64
+ return this.isSuccessful();
65
+ }
66
+ /**
67
+ * Returns a view of the solutions containing only string-named variables (for the user).
68
+ */
69
+ public get solutions(): Substitution {
70
+ return this._solution;
71
+ }
72
+
73
+ public toJSON(): unknown {
74
+ const sol: Record<string, unknown> = {};
75
+ for (const [key, val] of this._solution) {
76
+ if (typeof key === "string") sol[key] = val.toJSON();
77
+ }
78
+ return { success: this._success, solution: sol };
79
+ }
80
+ public toString(): string {
81
+ return `Answer(${this._success})`;
82
+ }
83
+ }
84
+
85
+ export class LogicResult extends YuValue {
86
+ private answers: LogicAnswer[];
87
+ constructor(answers: LogicAnswer[]) {
88
+ super();
89
+ this.answers = answers;
90
+ }
91
+ public equals(other: YuValue): ExecutionCommand {
92
+ return boolean(other === this);
93
+ }
94
+ public compare(other: YuValue): ExecutionCommand {
95
+ return raise(error("LogicResult.compare", "LogicResult is not comparable"));
96
+ }
97
+ public get allAnswers(): LogicAnswer[] {
98
+ return this.answers;
99
+ }
100
+ public getAllSuccessful(): LogicAnswer[] {
101
+ return this.answers.filter((answer) => answer.isSuccessful());
102
+ }
103
+ public allSuccessful(): boolean {
104
+ return (
105
+ this.answers.length > 0 &&
106
+ this.answers.every((answer) => answer.isSuccessful())
107
+ );
108
+ }
109
+ public getSuccessfulSolutions(): Substitution[] {
110
+ return this.getAllSuccessful().map((ans) => ans.getSolution());
111
+ }
112
+ public get success(): boolean {
113
+ return (
114
+ this.answers.length > 0 && this.answers.every((a) => a.isSuccessful())
115
+ );
116
+ }
117
+ public get solutions(): Substitution {
118
+ const answers = this.getAllSuccessful();
119
+ if (answers.length === 0) return new Map();
120
+ return answers[0].solutions;
121
+ }
122
+
123
+ public toJSON(): unknown {
124
+ return this.answers.map((a) => a.toJSON());
125
+ }
126
+ public toString(): string {
127
+ return `LogicResult(${this.answers.length})`;
128
+ }
129
+ }
130
+
131
+ export function isLogicResult(value: YuValue): value is LogicResult {
132
+ return value instanceof LogicResult;
133
+ }