yukigo 0.2.3 → 0.3.2

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 +105 -40
  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 +22 -14
  13. package/dist/analyzer/inspections/generic/generic.js +82 -60
  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 +13 -5
  115. package/dist/utils/helpers.js +38 -85
  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 -577
  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 +113 -169
  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 +156 -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,99 +1,236 @@
1
- import { LiteralPattern, SymbolPrimitive, Variable, VariablePattern, isPattern, NumberPrimitive, StringPrimitive, BooleanPrimitive, ListPrimitive, ListPattern, ConsExpression, ConsPattern, FunctorPattern, } from "yukigo-ast";
2
- import { instantiate } from "./LogicResolver.js";
1
+ import { isPattern, ConsPattern, } from "yukigo-ast";
2
+ import { VariableTerm, ConstantTerm, ListTerm, ConsTerm, WildcardTerm, CompoundTerm, } from "./LogicTerm.js";
3
+ import { error, raise } from "../../utils.js";
3
4
  import { InterpreterError } from "../../errors.js";
4
- export class LogicTranslator {
5
+ import { StepCommand, BindCommand, } from "../kernel/commands.js";
6
+ import { YuNumber, YuString, YuBoolean, YuNil, isLogicTerm, isRuntimeObject, } from "../../primitives/index.js";
7
+ /**
8
+ * Sync visitor to convert Patterns to LogicTerms.
9
+ */
10
+ class PatternToTermVisitor {
11
+ translator;
12
+ scope;
13
+ constructor(translator, scope) {
14
+ this.translator = translator;
15
+ this.scope = scope;
16
+ }
17
+ visitVariablePattern(node) {
18
+ const name = node.name.value;
19
+ if (this.scope) {
20
+ let term = this.scope.get(name);
21
+ if (!term) {
22
+ term = new VariableTerm(this.translator.getNextId(name), name);
23
+ this.scope.set(name, term);
24
+ }
25
+ return term;
26
+ }
27
+ return new VariableTerm(this.translator.getNextId(name), name);
28
+ }
29
+ visitLiteralPattern(node) {
30
+ const raw = node.name.value;
31
+ let wrapped;
32
+ if (typeof raw === "number")
33
+ wrapped = new YuNumber(raw);
34
+ else if (typeof raw === "string")
35
+ wrapped = new YuString(raw);
36
+ else if (typeof raw === "boolean")
37
+ wrapped = new YuBoolean(raw);
38
+ else
39
+ wrapped = YuNil.getInstance();
40
+ return new ConstantTerm(wrapped);
41
+ }
42
+ visitListPattern(node) {
43
+ return new ListTerm(node.elements.map((el) => el.accept(this)));
44
+ }
45
+ visitTuplePattern(node) {
46
+ return new ListTerm(node.elements.map((el) => el.accept(this)));
47
+ }
48
+ visitConsPattern(node) {
49
+ let curr = node;
50
+ const lefts = [];
51
+ while (curr instanceof ConsPattern) {
52
+ lefts.push(curr.left);
53
+ curr = curr.right;
54
+ }
55
+ let result = curr.accept(this);
56
+ for (let i = lefts.length - 1; i >= 0; i--) {
57
+ result = new ConsTerm(lefts[i].accept(this), result);
58
+ }
59
+ return result;
60
+ }
61
+ visitWildcardPattern(node) {
62
+ return new WildcardTerm();
63
+ }
64
+ visitFunctorPattern(node) {
65
+ return new CompoundTerm(node.identifier.value, node.args.map((a) => a.accept(this)));
66
+ }
67
+ visitConstructorPattern(node) {
68
+ return new CompoundTerm(node.identifier.value, node.args.map((a) => a.accept(this)));
69
+ }
70
+ visitAsPattern(node) {
71
+ return node.right.accept(this);
72
+ }
73
+ visitUnionPattern(node) {
74
+ throw new InterpreterError("Logic", "UnionPattern not supported in logic engine yet");
75
+ }
76
+ visitTypePattern(node) {
77
+ throw new InterpreterError("Logic", "TypePattern not supported in logic engine yet");
78
+ }
79
+ visitApplicationPattern(node) {
80
+ return new CompoundTerm(node.identifier.value, node.args.map((a) => a.accept(this)));
81
+ }
82
+ fallback(node) {
83
+ throw new InterpreterError("Logic", `Pattern ${node.constructor.name} translation not implemented`);
84
+ }
85
+ }
86
+ /**
87
+ * Kernel-based visitor to convert Expressions to LogicTerms.
88
+ */
89
+ class ExpressionToTermVisitor {
90
+ translator;
5
91
  evaluator;
6
92
  ctx;
7
- constructor(evaluator, ctx) {
93
+ scope;
94
+ constructor(translator, evaluator, ctx, scope) {
95
+ this.translator = translator;
8
96
  this.evaluator = evaluator;
9
97
  this.ctx = ctx;
98
+ this.scope = scope;
10
99
  }
11
- patternToPrimitive(pat) {
12
- if (pat instanceof LiteralPattern) {
13
- const primitive = pat.name;
14
- return primitive.value;
15
- }
16
- if (pat instanceof ListPattern) {
17
- return pat.elements.map((el) => this.patternToPrimitive(el));
100
+ visitListPrimitive(node) {
101
+ const terms = [];
102
+ const next = (index) => {
103
+ if (index >= node.value.length)
104
+ return new StepCommand(new ListTerm(terms));
105
+ return new BindCommand(this.translator.expressionToTerm(node.value[index], this.scope), (t) => {
106
+ if (!isLogicTerm(t))
107
+ return raise(error("ExpressionToTermVisitor", "expected LogicTerm in visitListPrimitive"));
108
+ terms.push(t);
109
+ return next(index + 1);
110
+ });
111
+ };
112
+ return next(0);
113
+ }
114
+ visitConsExpression(node) {
115
+ return new BindCommand(this.translator.expressionToTerm(node.head, this.scope), (head) => {
116
+ if (!isLogicTerm(head))
117
+ return raise(error("ExpressionToTermVisitor", "expected LogicTerm in visitConsExpression"));
118
+ return new BindCommand(this.translator.expressionToTerm(node.tail, this.scope), (tail) => {
119
+ if (!isLogicTerm(tail))
120
+ return raise(error("ExpressionToTermVisitor", "expected LogicTerm in visitConsExpression"));
121
+ return new StepCommand(new ConsTerm(head, tail));
122
+ });
123
+ });
124
+ }
125
+ visitVariable(node) {
126
+ const name = node.identifier.value;
127
+ if (this.ctx.isDefined(name)) {
128
+ return new BindCommand(this.evaluator.evaluate(node), (val) => {
129
+ return new StepCommand(this.translator.primitiveToTerm(val));
130
+ });
18
131
  }
19
- if (pat instanceof ConsPattern) {
20
- const head = this.patternToPrimitive(pat.left);
21
- const tail = this.patternToPrimitive(pat.right);
22
- if (Array.isArray(tail)) {
23
- return [head, ...tail];
132
+ if (this.scope) {
133
+ let term = this.scope.get(name);
134
+ if (!term) {
135
+ term = new VariableTerm(this.translator.getNextId(name), name);
136
+ this.scope.set(name, term);
24
137
  }
25
- return [head, tail];
26
- }
27
- // Return the pattern itself for non-primitive logic terms (VariablePattern, FunctorPattern, etc.)
28
- return pat;
29
- }
30
- expressionToPattern(expr, k) {
31
- if (isPattern(expr))
32
- return k(expr);
33
- if (expr instanceof ListPrimitive) {
34
- const results = [];
35
- const next = (index) => {
36
- if (index >= expr.value.length)
37
- return k(new ListPattern(results));
38
- return this.expressionToPattern(expr.value[index], (p) => {
39
- results.push(p);
40
- return () => next(index + 1);
41
- });
42
- };
43
- return next(0);
138
+ return new StepCommand(term);
44
139
  }
45
- if (expr instanceof ConsExpression) {
46
- return this.expressionToPattern(expr.head, (headPat) => {
47
- return () => this.expressionToPattern(expr.tail, (tailPat) => {
48
- return k(new ConsPattern(headPat, tailPat));
49
- });
140
+ return new StepCommand(new VariableTerm(this.translator.getNextId(name), name));
141
+ }
142
+ visitSymbolPrimitive(node) {
143
+ const name = node.value;
144
+ if (this.ctx.isDefined(name)) {
145
+ return new BindCommand(this.evaluator.evaluate(node), (val) => {
146
+ return new StepCommand(this.translator.primitiveToTerm(val));
50
147
  });
51
148
  }
52
- if (expr instanceof Variable || expr instanceof SymbolPrimitive) {
53
- const name = expr instanceof Variable ? expr.identifier.value : expr.value;
54
- if (this.ctx.isDefined(name)) {
55
- return this.evaluator.evaluate(expr, (val) => {
56
- return k(this.primitiveToPattern(val));
57
- });
149
+ const isVariable = /^[A-Z_]/.test(name);
150
+ if (!isVariable) {
151
+ return new StepCommand(new ConstantTerm(new YuString(name)));
152
+ }
153
+ if (this.scope) {
154
+ let term = this.scope.get(name);
155
+ if (!term) {
156
+ term = new VariableTerm(this.translator.getNextId(name), name);
157
+ this.scope.set(name, term);
58
158
  }
59
- return k(new VariablePattern(expr instanceof Variable ? expr.identifier : expr));
159
+ return new StepCommand(term);
60
160
  }
61
- return this.evaluator.evaluate(expr, (val) => {
62
- return k(this.primitiveToPattern(val));
63
- });
161
+ return new StepCommand(new VariableTerm(this.translator.getNextId(name), name));
64
162
  }
65
- primitiveToPattern(val) {
66
- if (isPattern(val)) {
67
- return val;
68
- }
69
- if (typeof val === "number") {
70
- return new LiteralPattern(new NumberPrimitive(val));
71
- }
72
- if (typeof val === "string") {
73
- return new LiteralPattern(new StringPrimitive(val));
163
+ fallback(node) {
164
+ if (isPattern(node)) {
165
+ return new StepCommand(this.translator.patternToTerm(node, this.scope));
74
166
  }
75
- if (typeof val === "boolean") {
76
- return new LiteralPattern(new BooleanPrimitive(val));
167
+ return new BindCommand(this.evaluator.evaluate(node), (val) => {
168
+ return new StepCommand(this.translator.primitiveToTerm(val));
169
+ });
170
+ }
171
+ }
172
+ export class LogicTranslator {
173
+ evaluator;
174
+ ctx;
175
+ constructor(evaluator, ctx) {
176
+ this.evaluator = evaluator;
177
+ this.ctx = ctx;
178
+ }
179
+ getNextId(name) {
180
+ const id = ++this.ctx.logicState.variableCounter;
181
+ this.ctx.logicState.idToName.set(id, name);
182
+ return id;
183
+ }
184
+ getName(id) {
185
+ return this.ctx.logicState.idToName.get(id);
186
+ }
187
+ /**
188
+ * Translates a Pattern (AST) into a LogicTerm (Runtime).
189
+ */
190
+ patternToTerm(pat, scope) {
191
+ const visitor = new PatternToTermVisitor(this, scope);
192
+ return pat.accept(visitor);
193
+ }
194
+ /**
195
+ * Converts a PrimitiveValue to a LogicTerm.
196
+ */
197
+ primitiveToTerm(val) {
198
+ if (val.asNumeric ||
199
+ val.asSummable instanceof YuString ||
200
+ val.asLogic ||
201
+ val instanceof YuNil) {
202
+ return new ConstantTerm(val);
77
203
  }
78
- if (Array.isArray(val)) {
79
- return new ListPattern(val.map((v) => this.primitiveToPattern(v)));
204
+ const seq = val.asSequence;
205
+ if (seq) {
206
+ return new ListTerm([...seq].map((v) => this.primitiveToTerm(v)));
80
207
  }
81
- if (val &&
82
- typeof val === "object" &&
83
- "type" in val &&
84
- val.type === "Object") {
85
- // Convert RuntimeObject to FunctorPattern for logic matching
208
+ if (isRuntimeObject(val)) {
86
209
  const args = [];
87
210
  for (const [_, fieldVal] of val.fields) {
88
- args.push(this.primitiveToPattern(fieldVal));
211
+ args.push(this.primitiveToTerm(fieldVal));
89
212
  }
90
- return new FunctorPattern(new SymbolPrimitive(val.className || val.identifier), args);
213
+ return new CompoundTerm(val.className || val.identifier, args);
91
214
  }
92
- throw new InterpreterError("primitiveToPattern", `Cannot convert value ${val} to Logic Pattern`);
215
+ if (isLogicTerm(val))
216
+ return val;
217
+ throw new InterpreterError("primitiveToTerm", `Cannot convert value ${val} to Logic Term`);
218
+ }
219
+ /**
220
+ * Evaluates an expression and returns its LogicTerm representation via the Kernel.
221
+ */
222
+ expressionToTerm(expr, scope) {
223
+ const visitor = new ExpressionToTermVisitor(this, this.evaluator, this.ctx, scope);
224
+ return expr.accept(visitor);
93
225
  }
94
- instantiateExpressionAsPattern(expr, substs, k) {
95
- return this.expressionToPattern(expr, (patternBase) => {
96
- return k(instantiate(patternBase, substs));
226
+ /**
227
+ * Instantiates an expression as a logic term, resolving logic variables.
228
+ */
229
+ instantiateExpressionAsTerm(expr, substs, scope) {
230
+ return new BindCommand(this.expressionToTerm(expr, scope), (term) => {
231
+ if (!isLogicTerm(term))
232
+ return raise(error("instantiateExpressionAsTerm", "expected LogicTerm in visitConsExpression"));
233
+ return new StepCommand(term.instantiate(substs));
97
234
  });
98
235
  }
99
236
  }
@@ -1,11 +1,13 @@
1
- import { PrimitiveValue, RuntimeFunction } from "yukigo-ast";
2
- import { Continuation, CPSThunk, Thunk } from "../../trampoline.js";
1
+ import { PrimitiveThunk } from "../../utils.js";
3
2
  import { RuntimeContext } from "../RuntimeContext.js";
3
+ import { ExecutionCommand } from "../kernel/commands.js";
4
+ import { YuValue } from "../../primitives/YuValue.js";
5
+ import { RuntimeFunction } from "../../primitives/index.js";
4
6
  export declare class FunctionRuntime {
5
7
  private context;
6
8
  constructor(context: RuntimeContext);
7
- apply(func: RuntimeFunction, args: PrimitiveValue[], k: Continuation<PrimitiveValue>): Thunk<PrimitiveValue>;
8
- applyArguments(func: RuntimeFunction, args: (PrimitiveValue | (() => PrimitiveValue))[]): CPSThunk<PrimitiveValue>;
9
+ apply(func: RuntimeFunction, args: YuValue[]): ExecutionCommand;
10
+ applyArguments(func: RuntimeFunction, args?: (YuValue | PrimitiveThunk)[]): ExecutionCommand;
9
11
  private preloadDefinitions;
10
12
  private patternsMatch;
11
13
  private evaluateSequence;
@@ -1,10 +1,11 @@
1
- import { UnguardedBody, Sequence, Return, Function, isRuntimeFunction, } from "yukigo-ast";
1
+ import { Return, Function, } from "yukigo-ast";
2
2
  import { PatternMatcher } from "../PatternMatcher.js";
3
+ import { boolean, isTrue, raise, error } from "../../utils.js";
3
4
  import { InterpreterError } from "../../errors.js";
4
5
  import { EnvBuilderVisitor } from "../EnvBuilder.js";
5
- import { valueToCPS } from "../../trampoline.js";
6
6
  import { RuntimeContext } from "../RuntimeContext.js";
7
- import { InterpreterVisitor } from "../Visitor.js";
7
+ import { StepCommand, BindCommand, FailCommand, RaiseCommand, } from "../kernel/commands.js";
8
+ import { isRuntimeFunction, YuNil, } from "../../primitives/index.js";
8
9
  class NonExhaustivePatterns extends InterpreterError {
9
10
  constructor(funcName) {
10
11
  super("PatternMatch", `Non-exhaustive patterns in '${funcName}'`);
@@ -15,90 +16,88 @@ export class FunctionRuntime {
15
16
  constructor(context) {
16
17
  this.context = context;
17
18
  }
18
- apply(func, args, k) {
19
+ apply(func, args) {
19
20
  const funcName = func.identifier;
21
+ const selfContext = this.context;
20
22
  const equations = func.equations;
21
23
  const oldEnv = this.context.env;
22
- if (this.context.config.debug)
23
- console.log(`[FunctionRuntime] Applying function: ${funcName} with args:`, args);
24
24
  const tryNextEquation = (eqIndex) => {
25
25
  if (eqIndex >= equations.length) {
26
26
  this.context.setEnv(oldEnv);
27
- throw new NonExhaustivePatterns(funcName);
27
+ return raise(new NonExhaustivePatterns(func.name));
28
28
  }
29
29
  const eq = equations[eqIndex];
30
30
  if (eq.patterns.length !== args.length)
31
- return () => tryNextEquation(eqIndex + 1);
31
+ return tryNextEquation(eqIndex + 1);
32
32
  const bindings = [];
33
- return this.patternsMatch(eq, args, bindings, (isMatch) => {
34
- if (!isMatch)
35
- return () => tryNextEquation(eqIndex + 1);
36
- if (this.context.config.debug)
37
- console.log(`[FunctionRuntime] Match successful for ${funcName} equation ${eqIndex}`);
33
+ return new BindCommand(this.patternsMatch(eq, args, bindings), (matchRes) => {
34
+ if (!isTrue(matchRes))
35
+ return tryNextEquation(eqIndex + 1);
38
36
  const localEnv = new Map(bindings);
39
37
  if (func.closure)
40
- this.context.setEnv(func.closure);
38
+ this.context.setEnv(this.context.cloneEnv(func.closure));
41
39
  this.context.pushEnv(localEnv);
42
- const wrappedK = (res) => {
40
+ const nextWithEnvRestore = (res) => {
43
41
  this.context.setEnv(oldEnv);
44
- return k(res);
42
+ return new StepCommand(res);
45
43
  };
46
- const evaluatorFactory = (ctx) => new InterpreterVisitor(ctx);
47
- const body = eq.body;
48
- // UnguardedBody
49
- if (body instanceof UnguardedBody)
50
- return this.evaluateSequence(body.sequence, this.context, evaluatorFactory, wrappedK);
51
- // GuardedBody
52
- return () => {
53
- if (Array.isArray(body) && body.length > 0) {
54
- const prototypeBody = body[0].body;
55
- if (prototypeBody instanceof Sequence)
56
- this.preloadDefinitions(prototypeBody, evaluatorFactory);
44
+ const dummyVisitor = this.context.evaluatorFactory(this.context);
45
+ const BaseVisitor = dummyVisitor.constructor;
46
+ class GuardBacktrackingVisitor extends BaseVisitor {
47
+ visitGuardedExpression(expr) {
48
+ const tryNextGuard = (guardIndex) => {
49
+ if (guardIndex >= expr.guards.length) {
50
+ selfContext.setEnv(oldEnv);
51
+ return tryNextEquation(eqIndex + 1);
52
+ }
53
+ const guard = expr.guards[guardIndex];
54
+ return new BindCommand(this.evaluate(guard.condition), (cond) => {
55
+ if (!isTrue(cond))
56
+ return tryNextGuard(guardIndex + 1);
57
+ return this.evaluate(guard.body);
58
+ });
59
+ };
60
+ return tryNextGuard(0);
57
61
  }
58
- const tryNextGuard = (guardIndex) => {
59
- if (guardIndex >= body.length) {
60
- this.context.setEnv(oldEnv);
61
- return () => tryNextEquation(eqIndex + 1);
62
+ }
63
+ const evaluatorFactory = (ctx) => new GuardBacktrackingVisitor(ctx);
64
+ return eq.body.accept({
65
+ visitUnguardedBody: (b) => {
66
+ return new BindCommand(this.evaluateSequence(b.sequence, this.context, evaluatorFactory), nextWithEnvRestore);
67
+ },
68
+ visitNativeBody: (b) => {
69
+ const currentHolder = this.context.lookup("__CONTEXT_CLASS__");
70
+ const lookupKey = `${currentHolder.identifier}.${funcName}`;
71
+ const nativeImpl = this.context.config.nativeProviders.get(lookupKey);
72
+ if (nativeImpl) {
73
+ const capturedContext = this.context.clone();
74
+ return new BindCommand(nativeImpl(this.context.lookup("self"), args, capturedContext), nextWithEnvRestore);
62
75
  }
63
- const evaluator = evaluatorFactory(this.context);
64
- const guard = body[guardIndex];
65
- return evaluator.evaluate(guard.condition, (cond) => {
66
- if (cond !== true)
67
- return () => tryNextGuard(guardIndex + 1);
68
- if (!(guard.body instanceof Sequence))
69
- return evaluator.evaluate(guard.body, wrappedK);
70
- return this.evaluateSequence(guard.body, this.context, evaluatorFactory, wrappedK);
71
- });
72
- };
73
- return tryNextGuard(0);
74
- };
76
+ const voidObj = this.context.lookup("void");
77
+ return nextWithEnvRestore(voidObj ?? YuNil.getInstance());
78
+ },
79
+ fallback: (node) => {
80
+ return new RaiseCommand(new InterpreterError("FunctionRuntime.apply", `Unexpected node: ${node.toJSON()}`));
81
+ },
82
+ });
75
83
  });
76
84
  };
77
85
  return tryNextEquation(0);
78
86
  }
79
87
  applyArguments(func, args) {
80
- if (args.length < func.arity) {
81
- return valueToCPS({
82
- ...func,
83
- pendingArgs: args,
84
- });
85
- }
86
- const argsToConsume = args.slice(0, func.arity);
87
- const remainingArgs = args.slice(func.arity);
88
+ const targetFunc = args ? func.bind(...args) : func;
89
+ const allArgs = targetFunc.pendingArgs ?? [];
90
+ if (allArgs.length < targetFunc.arity)
91
+ return new StepCommand(targetFunc);
92
+ const argsToConsume = allArgs.slice(0, targetFunc.arity);
93
+ const remainingArgs = allArgs.slice(targetFunc.arity);
88
94
  const evaluatedArgs = argsToConsume.map((arg) => typeof arg === "function" ? arg() : arg);
89
- return (cont) => () => this.apply(func, evaluatedArgs, (result) => {
90
- if (remainingArgs.length > 0) {
91
- if (isRuntimeFunction(result)) {
92
- const nextArgs = result.pendingArgs
93
- ? [...result.pendingArgs, ...remainingArgs]
94
- : remainingArgs;
95
- return this.applyArguments(result, nextArgs)(cont);
96
- }
97
- else {
98
- throw new InterpreterError("Application", `Too many arguments provided. Result was '${result}' (not a function), but had ${remainingArgs.length} args left.`);
99
- }
100
- }
101
- return cont(result);
95
+ return new BindCommand(this.apply(targetFunc, evaluatedArgs), (result) => {
96
+ if (remainingArgs.length == 0)
97
+ return new StepCommand(result);
98
+ if (!isRuntimeFunction(result))
99
+ return new FailCommand(new Error(`[Application] Too many arguments provided. Result was '${result}' (not a function), but had ${remainingArgs.length} args left.`));
100
+ return this.applyArguments(result, remainingArgs);
102
101
  });
103
102
  }
104
103
  preloadDefinitions(seq, evaluatorFactory) {
@@ -106,42 +105,41 @@ export class FunctionRuntime {
106
105
  new EnvBuilderVisitor(ctx).build(seq.statements);
107
106
  const evaluator = evaluatorFactory(ctx);
108
107
  for (const stmt of seq.statements) {
109
- if (stmt instanceof Function || stmt instanceof Return)
108
+ if (stmt.is(Function) || stmt.is(Return))
110
109
  continue;
111
- evaluator.evaluate(stmt, (val) => val);
110
+ evaluator.evaluate(stmt);
112
111
  }
113
112
  }
114
- patternsMatch(eq, args, bindings, k) {
113
+ patternsMatch(eq, args, bindings) {
115
114
  const matchNext = (index) => {
116
115
  if (index >= args.length)
117
- return k(true);
116
+ return boolean(true);
118
117
  const matcher = new PatternMatcher(args[index], bindings, this.context);
119
- return eq.patterns[index].accept(matcher)((isMatch) => {
120
- if (!isMatch)
121
- return k(false);
122
- return () => matchNext(index + 1);
118
+ return new BindCommand(eq.patterns[index].accept(matcher), (res) => {
119
+ if (!isTrue(res))
120
+ return boolean(false);
121
+ return matchNext(index + 1);
123
122
  });
124
123
  };
125
124
  return matchNext(0);
126
125
  }
127
- evaluateSequence(seq, ctx, evaluatorFactory, k) {
126
+ evaluateSequence(seq, ctx, evaluatorFactory) {
128
127
  new EnvBuilderVisitor(ctx).build(seq.statements);
129
128
  const evaluator = evaluatorFactory(ctx);
130
129
  const evaluateNext = (index, lastResult) => {
131
130
  if (index >= seq.statements.length)
132
- return k(lastResult);
131
+ return new StepCommand(lastResult);
133
132
  const stmt = seq.statements[index];
134
- if (stmt instanceof Function)
135
- return () => evaluateNext(index + 1, lastResult);
136
- if (stmt instanceof Return) {
137
- return evaluator.evaluate(stmt.body, k);
138
- }
139
- else {
140
- return evaluator.evaluate(stmt, (result) => {
141
- return () => evaluateNext(index + 1, result);
133
+ if (stmt.is(Function))
134
+ return evaluateNext(index + 1, lastResult);
135
+ if (!stmt.is(Return))
136
+ return new BindCommand(evaluator.evaluate(stmt), (result) => {
137
+ return evaluateNext(index + 1, result);
142
138
  });
143
- }
139
+ if (!stmt.body)
140
+ return raise(error("FunctionRuntime", "Return \`body\` was undefined"));
141
+ return evaluator.evaluate(stmt.body);
144
142
  };
145
- return evaluateNext(0, undefined);
143
+ return evaluateNext(0, YuNil.getInstance());
146
144
  }
147
145
  }
@@ -1,19 +1,18 @@
1
- import { PrimitiveValue, RangeExpression, ConsExpression, ListBinaryOperation } from "yukigo-ast";
2
- import { ExpressionEvaluator } from "../../utils.js";
3
- import { Continuation, Thunk } from "../../trampoline.js";
1
+ import { RangeExpression, ConsExpression } from "yukigo-ast";
4
2
  import { RuntimeContext } from "../RuntimeContext.js";
3
+ import { ExecutionCommand } from "../kernel/commands.js";
4
+ import { YuValue } from "../../primitives/YuValue.js";
5
+ import { YuSequence } from "../../primitives/capabilities.js";
6
+ import { Evaluator } from "../evaluators/BaseEvaluator.js";
5
7
  export declare class LazyRuntime {
6
8
  private context;
7
9
  constructor(context: RuntimeContext);
8
- realizeList<R = PrimitiveValue[]>(val: PrimitiveValue, k: Continuation<PrimitiveValue[], R>): Thunk<R>;
9
- evaluateRange(node: RangeExpression, evaluator: ExpressionEvaluator, k: Continuation<PrimitiveValue>): Thunk<PrimitiveValue>;
10
- evaluateCons(node: ConsExpression, evaluator: ExpressionEvaluator, k: Continuation<PrimitiveValue>): Thunk<PrimitiveValue>;
11
- evaluateConcat(left: PrimitiveValue, right: PrimitiveValue, k: Continuation<PrimitiveValue>): Thunk<PrimitiveValue>;
12
- evaluateConcatLazy(node: ListBinaryOperation, evaluator: ExpressionEvaluator, k: Continuation<PrimitiveValue>): Thunk<PrimitiveValue>;
13
- deepEqual<R = boolean>(a: PrimitiveValue, b: PrimitiveValue, k: Continuation<boolean, R>): Thunk<R>;
14
- private isPlainObject;
15
- private isCollection;
16
- private isListLike;
17
- private deepEqualCollection;
18
- private deepEqualObject;
10
+ /**
11
+ * Realizes a list or lazy list into a YuArray.
12
+ */
13
+ realizeList(val: YuValue): ExecutionCommand;
14
+ evaluateRange(node: RangeExpression, evaluator: Evaluator): ExecutionCommand;
15
+ evaluateCons(node: ConsExpression, evaluator: Evaluator): ExecutionCommand;
16
+ private arrayToLazyList;
17
+ evaluateConcat(left: YuSequence, right: YuSequence): ExecutionCommand;
19
18
  }