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,991 +1,1143 @@
1
- import {
2
- Application,
3
- ArithmeticBinaryOperation,
4
- ArithmeticUnaryOperation,
5
- Assignment,
6
- AssignOperation,
7
- BitwiseBinaryOperation,
8
- BitwiseUnaryOperation,
9
- BooleanPrimitive,
10
- ComparisonOperation,
11
- CompositionExpression,
12
- Equation,
13
- Function,
14
- isLazyList,
15
- Lambda,
16
- ListPrimitive,
17
- ListUnaryOperation,
18
- LiteralPattern,
19
- LogicalBinaryOperation,
20
- LogicalUnaryOperation,
21
- NumberPrimitive,
22
- RangeExpression,
23
- Return,
24
- Sequence,
25
- SimpleType,
26
- StringOperation,
27
- StringPrimitive,
28
- SymbolPrimitive,
29
- TypeCast,
30
- UnguardedBody,
31
- Variable,
32
- VariablePattern,
33
- } from "yukigo-ast";
34
- import { Interpreter } from "../../src/interpreter/index.js";
35
- import { assert } from "chai";
36
-
37
- describe("Interpreter Spec", () => {
38
- let interpreter: Interpreter;
39
- beforeEach(() => {
40
- interpreter = new Interpreter([], { debug: true });
41
- });
42
- it("Evaluates ArithmeticBinaryOperation", () => {
43
- assert.equal(
44
- interpreter.evaluate(
45
- new ArithmeticBinaryOperation(
46
- "Plus",
47
- new NumberPrimitive(3),
48
- new NumberPrimitive(4)
49
- )
50
- ),
51
- 7
52
- );
53
- assert.equal(
54
- interpreter.evaluate(
55
- new ArithmeticBinaryOperation(
56
- "Minus",
57
- new NumberPrimitive(3),
58
- new NumberPrimitive(4)
59
- )
60
- ),
61
- -1
62
- );
63
- assert.equal(
64
- interpreter.evaluate(
65
- new ArithmeticBinaryOperation(
66
- "Multiply",
67
- new NumberPrimitive(3),
68
- new NumberPrimitive(4)
69
- )
70
- ),
71
- 12
72
- );
73
- assert.equal(
74
- interpreter.evaluate(
75
- new ArithmeticBinaryOperation(
76
- "Divide",
77
- new NumberPrimitive(3),
78
- new NumberPrimitive(4)
79
- )
80
- ),
81
- 0.75
82
- );
83
- assert.equal(
84
- interpreter.evaluate(
85
- new ArithmeticBinaryOperation(
86
- "Modulo",
87
- new NumberPrimitive(3),
88
- new NumberPrimitive(4)
89
- )
90
- ),
91
- 3
92
- );
93
- assert.equal(
94
- interpreter.evaluate(
95
- new ArithmeticBinaryOperation(
96
- "Power",
97
- new NumberPrimitive(3),
98
- new NumberPrimitive(4)
99
- )
100
- ),
101
- 81
102
- );
103
- assert.equal(
104
- interpreter.evaluate(
105
- new ArithmeticBinaryOperation(
106
- "Min",
107
- new NumberPrimitive(3),
108
- new NumberPrimitive(4)
109
- )
110
- ),
111
- 3
112
- );
113
- assert.equal(
114
- interpreter.evaluate(
115
- new ArithmeticBinaryOperation(
116
- "Max",
117
- new NumberPrimitive(3),
118
- new NumberPrimitive(4)
119
- )
120
- ),
121
- 4
122
- );
123
- });
124
-
125
- it("Evaluates ArithmeticUnaryOperation", () => {
126
- assert.equal(
127
- interpreter.evaluate(
128
- new ArithmeticUnaryOperation("Round", new NumberPrimitive(3.4))
129
- ),
130
- 3
131
- );
132
- assert.equal(
133
- interpreter.evaluate(
134
- new ArithmeticUnaryOperation("Round", new NumberPrimitive(3.5))
135
- ),
136
- 4
137
- );
138
- assert.equal(
139
- interpreter.evaluate(
140
- new ArithmeticUnaryOperation("Absolute", new NumberPrimitive(-3))
141
- ),
142
- 3
143
- );
144
- assert.equal(
145
- interpreter.evaluate(
146
- new ArithmeticUnaryOperation("Absolute", new NumberPrimitive(3))
147
- ),
148
- 3
149
- );
150
- assert.equal(
151
- interpreter.evaluate(
152
- new ArithmeticUnaryOperation("Ceil", new NumberPrimitive(3.3))
153
- ),
154
- 4
155
- );
156
- assert.equal(
157
- interpreter.evaluate(
158
- new ArithmeticUnaryOperation("Floor", new NumberPrimitive(3.3))
159
- ),
160
- 3
161
- );
162
- assert.equal(
163
- interpreter.evaluate(
164
- new ArithmeticUnaryOperation("Negation", new NumberPrimitive(3.3))
165
- ),
166
- -3.3
167
- );
168
- assert.equal(
169
- interpreter.evaluate(
170
- new ArithmeticUnaryOperation("Sqrt", new NumberPrimitive(25))
171
- ),
172
- 5
173
- );
174
- });
175
- describe("Evaluates ComparisonOperation", () => {
176
- it("Equal Operator", () => {
177
- assert.equal(
178
- interpreter.evaluate(
179
- new ComparisonOperation(
180
- "Equal",
181
- new NumberPrimitive(3.4),
182
- new NumberPrimitive(3.4)
183
- )
184
- ),
185
- true
186
- );
187
- assert.equal(
188
- interpreter.evaluate(
189
- new ComparisonOperation(
190
- "Equal",
191
- new NumberPrimitive(3.4),
192
- new NumberPrimitive(4)
193
- )
194
- ),
195
- false
196
- );
197
- assert.equal(
198
- interpreter.evaluate(
199
- new ComparisonOperation(
200
- "Equal",
201
- new NumberPrimitive(3),
202
- new StringPrimitive("3")
203
- )
204
- ),
205
- true
206
- );
207
- assert.equal(
208
- interpreter.evaluate(
209
- new ComparisonOperation(
210
- "Equal",
211
- new NumberPrimitive(3),
212
- new StringPrimitive("4")
213
- )
214
- ),
215
- false
216
- );
217
- });
218
- it("NotEqual Operator", () => {
219
- assert.equal(
220
- interpreter.evaluate(
221
- new ComparisonOperation(
222
- "NotEqual",
223
- new NumberPrimitive(3.4),
224
- new NumberPrimitive(3.4)
225
- )
226
- ),
227
- false
228
- );
229
- assert.equal(
230
- interpreter.evaluate(
231
- new ComparisonOperation(
232
- "NotEqual",
233
- new NumberPrimitive(3.4),
234
- new NumberPrimitive(4)
235
- )
236
- ),
237
- true
238
- );
239
- assert.equal(
240
- interpreter.evaluate(
241
- new ComparisonOperation(
242
- "NotEqual",
243
- new NumberPrimitive(3),
244
- new StringPrimitive("3")
245
- )
246
- ),
247
- false
248
- );
249
- assert.equal(
250
- interpreter.evaluate(
251
- new ComparisonOperation(
252
- "NotEqual",
253
- new NumberPrimitive(3),
254
- new StringPrimitive("4")
255
- )
256
- ),
257
- true
258
- );
259
- });
260
- it("Same Operator", () => {
261
- assert.equal(
262
- interpreter.evaluate(
263
- new ComparisonOperation(
264
- "Same",
265
- new NumberPrimitive(3.4),
266
- new NumberPrimitive(3.4)
267
- )
268
- ),
269
- true
270
- );
271
- assert.equal(
272
- interpreter.evaluate(
273
- new ComparisonOperation(
274
- "Same",
275
- new NumberPrimitive(3.4),
276
- new NumberPrimitive(4)
277
- )
278
- ),
279
- false
280
- );
281
- assert.equal(
282
- interpreter.evaluate(
283
- new ComparisonOperation(
284
- "Same",
285
- new NumberPrimitive(3),
286
- new StringPrimitive("3")
287
- )
288
- ),
289
- false
290
- );
291
- assert.equal(
292
- interpreter.evaluate(
293
- new ComparisonOperation(
294
- "Same",
295
- new NumberPrimitive(3),
296
- new StringPrimitive("4")
297
- )
298
- ),
299
- false
300
- );
301
- });
302
- it("NotSame Operator", () => {
303
- assert.equal(
304
- interpreter.evaluate(
305
- new ComparisonOperation(
306
- "NotSame",
307
- new NumberPrimitive(3.4),
308
- new NumberPrimitive(3.4)
309
- )
310
- ),
311
- false
312
- );
313
- assert.equal(
314
- interpreter.evaluate(
315
- new ComparisonOperation(
316
- "NotSame",
317
- new NumberPrimitive(3.4),
318
- new NumberPrimitive(4)
319
- )
320
- ),
321
- true
322
- );
323
- assert.equal(
324
- interpreter.evaluate(
325
- new ComparisonOperation(
326
- "NotSame",
327
- new NumberPrimitive(3),
328
- new StringPrimitive("3")
329
- )
330
- ),
331
- true
332
- );
333
- assert.equal(
334
- interpreter.evaluate(
335
- new ComparisonOperation(
336
- "NotSame",
337
- new NumberPrimitive(3),
338
- new StringPrimitive("4")
339
- )
340
- ),
341
- true
342
- );
343
- });
344
- it("GreaterOrEqualThan Operator", () => {
345
- assert.equal(
346
- interpreter.evaluate(
347
- new ComparisonOperation(
348
- "GreaterOrEqualThan",
349
- new NumberPrimitive(3.4),
350
- new NumberPrimitive(3.4)
351
- )
352
- ),
353
- true
354
- );
355
- assert.equal(
356
- interpreter.evaluate(
357
- new ComparisonOperation(
358
- "GreaterOrEqualThan",
359
- new NumberPrimitive(3.4),
360
- new NumberPrimitive(4)
361
- )
362
- ),
363
- false
364
- );
365
- assert.equal(
366
- interpreter.evaluate(
367
- new ComparisonOperation(
368
- "GreaterOrEqualThan",
369
- new NumberPrimitive(3),
370
- new StringPrimitive("3")
371
- )
372
- ),
373
- true
374
- );
375
- assert.equal(
376
- interpreter.evaluate(
377
- new ComparisonOperation(
378
- "GreaterOrEqualThan",
379
- new NumberPrimitive(3),
380
- new StringPrimitive("4")
381
- )
382
- ),
383
- false
384
- );
385
- });
386
- it("GreaterThan Operator", () => {
387
- assert.equal(
388
- interpreter.evaluate(
389
- new ComparisonOperation(
390
- "GreaterThan",
391
- new NumberPrimitive(3.4),
392
- new NumberPrimitive(3.4)
393
- )
394
- ),
395
- false
396
- );
397
- assert.equal(
398
- interpreter.evaluate(
399
- new ComparisonOperation(
400
- "GreaterThan",
401
- new NumberPrimitive(3.4),
402
- new NumberPrimitive(4)
403
- )
404
- ),
405
- false
406
- );
407
- assert.equal(
408
- interpreter.evaluate(
409
- new ComparisonOperation(
410
- "GreaterThan",
411
- new NumberPrimitive(3),
412
- new StringPrimitive("3")
413
- )
414
- ),
415
- false
416
- );
417
- assert.equal(
418
- interpreter.evaluate(
419
- new ComparisonOperation(
420
- "GreaterThan",
421
- new NumberPrimitive(3),
422
- new StringPrimitive("4")
423
- )
424
- ),
425
- false
426
- );
427
- });
428
- it("LessOrEqualThan Operator", () => {
429
- assert.equal(
430
- interpreter.evaluate(
431
- new ComparisonOperation(
432
- "LessOrEqualThan",
433
- new NumberPrimitive(3.4),
434
- new NumberPrimitive(3.4)
435
- )
436
- ),
437
- true
438
- );
439
- assert.equal(
440
- interpreter.evaluate(
441
- new ComparisonOperation(
442
- "LessOrEqualThan",
443
- new NumberPrimitive(3.4),
444
- new NumberPrimitive(4)
445
- )
446
- ),
447
- true
448
- );
449
- assert.equal(
450
- interpreter.evaluate(
451
- new ComparisonOperation(
452
- "LessOrEqualThan",
453
- new NumberPrimitive(3),
454
- new StringPrimitive("3")
455
- )
456
- ),
457
- true
458
- );
459
- assert.equal(
460
- interpreter.evaluate(
461
- new ComparisonOperation(
462
- "LessOrEqualThan",
463
- new NumberPrimitive(3),
464
- new StringPrimitive("4")
465
- )
466
- ),
467
- true
468
- );
469
- });
470
- it("LessThan Operator", () => {
471
- assert.equal(
472
- interpreter.evaluate(
473
- new ComparisonOperation(
474
- "LessThan",
475
- new NumberPrimitive(3.4),
476
- new NumberPrimitive(3.4)
477
- )
478
- ),
479
- false
480
- );
481
- assert.equal(
482
- interpreter.evaluate(
483
- new ComparisonOperation(
484
- "LessThan",
485
- new NumberPrimitive(3.4),
486
- new NumberPrimitive(4)
487
- )
488
- ),
489
- true
490
- );
491
- assert.equal(
492
- interpreter.evaluate(
493
- new ComparisonOperation(
494
- "LessThan",
495
- new NumberPrimitive(3),
496
- new StringPrimitive("3")
497
- )
498
- ),
499
- false
500
- );
501
- assert.equal(
502
- interpreter.evaluate(
503
- new ComparisonOperation(
504
- "LessThan",
505
- new NumberPrimitive(3),
506
- new StringPrimitive("4")
507
- )
508
- ),
509
- true
510
- );
511
- });
512
- });
513
- describe("Evaluates LogicalBinaryOperation", () => {
514
- it("And Operator", () => {
515
- assert.equal(
516
- interpreter.evaluate(
517
- new LogicalBinaryOperation(
518
- "And",
519
- new BooleanPrimitive(true),
520
- new BooleanPrimitive(true)
521
- )
522
- ),
523
- true
524
- );
525
- assert.equal(
526
- interpreter.evaluate(
527
- new LogicalBinaryOperation(
528
- "And",
529
- new BooleanPrimitive(true),
530
- new BooleanPrimitive(false)
531
- )
532
- ),
533
- false
534
- );
535
- assert.equal(
536
- interpreter.evaluate(
537
- new LogicalBinaryOperation(
538
- "And",
539
- new BooleanPrimitive(false),
540
- new BooleanPrimitive(true)
541
- )
542
- ),
543
- false
544
- );
545
- assert.equal(
546
- interpreter.evaluate(
547
- new LogicalBinaryOperation(
548
- "And",
549
- new BooleanPrimitive(false),
550
- new BooleanPrimitive(false)
551
- )
552
- ),
553
- false
554
- );
555
- });
556
- it("Or Operator", () => {
557
- assert.equal(
558
- interpreter.evaluate(
559
- new LogicalBinaryOperation(
560
- "Or",
561
- new BooleanPrimitive(true),
562
- new BooleanPrimitive(true)
563
- )
564
- ),
565
- true
566
- );
567
- assert.equal(
568
- interpreter.evaluate(
569
- new LogicalBinaryOperation(
570
- "Or",
571
- new BooleanPrimitive(true),
572
- new BooleanPrimitive(false)
573
- )
574
- ),
575
- true
576
- );
577
- assert.equal(
578
- interpreter.evaluate(
579
- new LogicalBinaryOperation(
580
- "Or",
581
- new BooleanPrimitive(false),
582
- new BooleanPrimitive(true)
583
- )
584
- ),
585
- true
586
- );
587
- assert.equal(
588
- interpreter.evaluate(
589
- new LogicalBinaryOperation(
590
- "Or",
591
- new BooleanPrimitive(false),
592
- new BooleanPrimitive(false)
593
- )
594
- ),
595
- false
596
- );
597
- });
598
- });
599
- describe("Evaluates LogicalUnaryOperation", () => {
600
- it("Negation Operator", () => {
601
- assert.equal(
602
- interpreter.evaluate(
603
- new LogicalUnaryOperation("Negation", new BooleanPrimitive(true))
604
- ),
605
- false
606
- );
607
- assert.equal(
608
- interpreter.evaluate(
609
- new LogicalUnaryOperation("Negation", new BooleanPrimitive(false))
610
- ),
611
- true
612
- );
613
- });
614
- });
615
- describe("Evaluates StringOperation", () => {
616
- it("Concat Operator", () => {
617
- assert.equal(
618
- interpreter.evaluate(
619
- new StringOperation(
620
- "Concat",
621
- new StringPrimitive("Hello"),
622
- new StringPrimitive(" world!")
623
- )
624
- ),
625
- "Hello world!"
626
- );
627
- });
628
- });
629
- describe("Evaluates ListUnaryOperation", () => {
630
- it("Size Operator", () => {
631
- assert.equal(
632
- interpreter.evaluate(
633
- new ListUnaryOperation(
634
- "Size",
635
- new ListPrimitive([
636
- new StringPrimitive("Hello"),
637
- new StringPrimitive("world!"),
638
- ])
639
- )
640
- ),
641
- 2
642
- );
643
- });
644
- it("DetectMax Operator", () => {
645
- assert.equal(
646
- interpreter.evaluate(
647
- new ListUnaryOperation(
648
- "DetectMax",
649
- new ListPrimitive([new NumberPrimitive(2), new NumberPrimitive(4)])
650
- )
651
- ),
652
- 4
653
- );
654
- });
655
- it("DetectMin Operator", () => {
656
- assert.equal(
657
- interpreter.evaluate(
658
- new ListUnaryOperation(
659
- "DetectMin",
660
- new ListPrimitive([new NumberPrimitive(2), new NumberPrimitive(4)])
661
- )
662
- ),
663
- 2
664
- );
665
- });
666
- it("Flatten Operator", () => {
667
- assert.deepEqual(
668
- interpreter.evaluate(
669
- new ListUnaryOperation(
670
- "Flatten",
671
- new ListPrimitive([
672
- new ListPrimitive([new NumberPrimitive(2)]),
673
- new ListPrimitive([
674
- new NumberPrimitive(3),
675
- new NumberPrimitive(8),
676
- ]),
677
- ])
678
- )
679
- ),
680
- [2, 3, 8]
681
- );
682
- });
683
- });
684
- describe("Evaluates BitwiseBinaryOperation", () => {
685
- it("BitwiseOr Operator", () => {
686
- assert.equal(
687
- interpreter.evaluate(
688
- new BitwiseBinaryOperation(
689
- "BitwiseOr",
690
- new NumberPrimitive(5),
691
- new NumberPrimitive(1)
692
- )
693
- ),
694
- 5
695
- );
696
- });
697
- it("BitwiseAnd Operator", () => {
698
- assert.equal(
699
- interpreter.evaluate(
700
- new BitwiseBinaryOperation(
701
- "BitwiseAnd",
702
- new NumberPrimitive(5),
703
- new NumberPrimitive(1)
704
- )
705
- ),
706
- 1
707
- );
708
- });
709
- it("BitwiseLeftShift Operator", () => {
710
- assert.equal(
711
- interpreter.evaluate(
712
- new BitwiseBinaryOperation(
713
- "BitwiseLeftShift",
714
- new NumberPrimitive(5),
715
- new NumberPrimitive(1)
716
- )
717
- ),
718
- 10
719
- );
720
- });
721
- it("BitwiseRightShift Operator", () => {
722
- assert.equal(
723
- interpreter.evaluate(
724
- new BitwiseBinaryOperation(
725
- "BitwiseRightShift",
726
- new NumberPrimitive(5),
727
- new NumberPrimitive(1)
728
- )
729
- ),
730
- 2
731
- );
732
- });
733
- it("BitwiseUnsignedRightShift Operator", () => {
734
- assert.equal(
735
- interpreter.evaluate(
736
- new BitwiseBinaryOperation(
737
- "BitwiseUnsignedRightShift",
738
- new NumberPrimitive(5),
739
- new NumberPrimitive(1)
740
- )
741
- ),
742
- 2
743
- );
744
- });
745
- it("BitwiseXor Operator", () => {
746
- assert.equal(
747
- interpreter.evaluate(
748
- new BitwiseBinaryOperation(
749
- "BitwiseXor",
750
- new NumberPrimitive(5),
751
- new NumberPrimitive(1)
752
- )
753
- ),
754
- 4
755
- );
756
- });
757
- });
758
- describe("Evaluates BitwiseUnaryOperator", () => {
759
- it("BitwiseNot Operator", () => {
760
- assert.equal(
761
- interpreter.evaluate(
762
- new BitwiseUnaryOperation("BitwiseNot", new NumberPrimitive(5))
763
- ),
764
- -6
765
- );
766
- });
767
- });
768
- describe("Evaluates Application", () => {
769
- beforeEach(() => {
770
- interpreter = new Interpreter([
771
- new Function(new SymbolPrimitive("f"), [
772
- new Equation(
773
- [new LiteralPattern(new NumberPrimitive(3))],
774
- new UnguardedBody(
775
- new Sequence([new Return(new NumberPrimitive(6))])
776
- ),
777
- new Return(new NumberPrimitive(6))
778
- ),
779
- new Equation(
780
- [new VariablePattern(new SymbolPrimitive("y"))],
781
- new UnguardedBody(
782
- new Sequence([
783
- new Return(
784
- new ArithmeticBinaryOperation(
785
- "Plus",
786
- new SymbolPrimitive("y"),
787
- new NumberPrimitive(3)
788
- )
789
- ),
790
- ])
791
- ),
792
- new Return(
793
- new ArithmeticBinaryOperation(
794
- "Plus",
795
- new SymbolPrimitive("y"),
796
- new NumberPrimitive(3)
797
- )
798
- )
799
- ),
800
- ]),
801
- ]);
802
- });
803
- it("Lambda + currified Application", () => {
804
- const lambda = new Lambda(
805
- [
806
- new VariablePattern(new SymbolPrimitive("x")),
807
- new VariablePattern(new SymbolPrimitive("y")),
808
- new VariablePattern(new SymbolPrimitive("z")),
809
- ],
810
- new ArithmeticBinaryOperation(
811
- "Plus",
812
- new ArithmeticBinaryOperation(
813
- "Plus",
814
- new SymbolPrimitive("x"),
815
- new SymbolPrimitive("y")
816
- ),
817
- new SymbolPrimitive("z")
818
- )
819
- );
820
- const app1 = new Application(lambda, new NumberPrimitive(1));
821
- const app2 = new Application(app1, new NumberPrimitive(2));
822
- const app3 = new Application(app2, new NumberPrimitive(3));
823
- assert.equal(interpreter.evaluate(app3), 6);
824
- });
825
- it("Application of Function", () => {
826
- const app1 = new Application(
827
- new SymbolPrimitive("f"),
828
- new NumberPrimitive(3)
829
- );
830
- assert.equal(interpreter.evaluate(app1), 6);
831
- });
832
- });
833
- describe("Evaluates Composition", () => {
834
- beforeEach(() => {
835
- interpreter = new Interpreter(
836
- [
837
- new Function(new SymbolPrimitive("doble"), [
838
- new Equation(
839
- [new VariablePattern(new SymbolPrimitive("x"))],
840
- new UnguardedBody(
841
- new Sequence([
842
- new Return(
843
- new ArithmeticBinaryOperation(
844
- "Multiply",
845
- new SymbolPrimitive("x"),
846
- new NumberPrimitive(2)
847
- )
848
- ),
849
- ])
850
- ),
851
- new Return(
852
- new ArithmeticBinaryOperation(
853
- "Multiply",
854
- new SymbolPrimitive("x"),
855
- new NumberPrimitive(2)
856
- )
857
- )
858
- ),
859
- ]),
860
- new Function(new SymbolPrimitive("cuadrado"), [
861
- new Equation(
862
- [new VariablePattern(new SymbolPrimitive("x"))],
863
- new UnguardedBody(
864
- new Sequence([
865
- new Return(
866
- new ArithmeticBinaryOperation(
867
- "Power",
868
- new SymbolPrimitive("x"),
869
- new NumberPrimitive(2)
870
- )
871
- ),
872
- ])
873
- ),
874
- new Return(
875
- new ArithmeticBinaryOperation(
876
- "Power",
877
- new SymbolPrimitive("x"),
878
- new NumberPrimitive(2)
879
- )
880
- )
881
- ),
882
- ]),
883
- ],
884
- { debug: true }
885
- );
886
- });
887
- it("Composition (cuadrado . doble) 2 should be 16", () => {
888
- const fog = new CompositionExpression(
889
- new SymbolPrimitive("cuadrado"),
890
- new SymbolPrimitive("doble")
891
- );
892
- const app = new Application(fog, new NumberPrimitive(2));
893
- const res = interpreter.evaluate(app)
894
- assert.equal(res, 16);
895
- });
896
- });
897
- describe("Evaluates TypeCast", () => {
898
- it("Type casting of number 2 to string should be '2'", () => {
899
- const res = interpreter.evaluate(
900
- new TypeCast(new NumberPrimitive(2), new SimpleType("String", [])),
901
- );
902
- assert.equal(res, "2");
903
- });
904
- });
905
- describe("Evaluates Range Expression", () => {
906
- it("Evaluates [1..5] to full range", () => {
907
- const range = new RangeExpression(
908
- new NumberPrimitive(1),
909
- new NumberPrimitive(5)
910
- );
911
- assert.deepEqual(interpreter.evaluate(range), [1, 2, 3, 4, 5]);
912
- });
913
- it("Evaluates [0,0.5..2] to full range", () => {
914
- const range = new RangeExpression(
915
- new NumberPrimitive(0),
916
- new NumberPrimitive(2),
917
- new NumberPrimitive(0.5)
918
- );
919
- assert.deepEqual(interpreter.evaluate(range), [0, 0.5, 1, 1.5, 2]);
920
- });
921
- it("Evaluates [1..] lazily", () => {
922
- interpreter = new Interpreter([], { lazyLoading: true });
923
- const range = new RangeExpression(new NumberPrimitive(1));
924
- const evaluatedList = interpreter.evaluate(range);
925
- if (!isLazyList(evaluatedList))
926
- assert.fail("Evaluated list should be LazyList");
927
- const iter = evaluatedList.generator();
928
- assert.equal(iter.next().value, 1);
929
- assert.equal(iter.next().value, 2);
930
- });
931
- });
932
-
933
- describe("Immutability Configuration", () => {
934
- it("Should allow variable reassignment when mutability is enabled (default)", () => {
935
- const ast = [
936
- new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
937
- new Assignment(new SymbolPrimitive("x"), new NumberPrimitive(10)),
938
- ];
939
- interpreter = new Interpreter(ast, { mutability: true });
940
-
941
- // Should not throw
942
- assert.doesNotThrow(() => {
943
- interpreter.evaluate(new SymbolPrimitive("x"));
944
- });
945
- });
946
-
947
- it("Should throw when attempting variable reassignment with mutability disabled", () => {
948
- const ast = [
949
- new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
950
- ];
951
- interpreter = new Interpreter(ast, { mutability: false });
952
-
953
- // Attempting reassignment should throw
954
- assert.throws(
955
- () => {
956
- interpreter.evaluate(
957
- new Assignment(
958
- new SymbolPrimitive("x"),
959
- new NumberPrimitive(10)
960
- )
961
- );
962
- },
963
- /Cannot reassign variable 'x': mutability is disabled/
964
- );
965
- });
966
-
967
- it("Should throw when attempting assignment operation with mutability disabled", () => {
968
- const ast = [
969
- new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
970
- ];
971
- interpreter = new Interpreter(ast, { mutability: false });
972
-
973
- // Attempting assignment operation should throw
974
- assert.throws(
975
- () => {
976
- interpreter.evaluate(
977
- new AssignOperation(
978
- "Assign",
979
- new Variable(
980
- new SymbolPrimitive("x"),
981
- new NumberPrimitive(5)
982
- ),
983
- new NumberPrimitive(3)
984
- )
985
- );
986
- },
987
- /Cannot perform assignment operation: mutability is disabled/
988
- );
989
- });
990
- });
991
- });
1
+ import {
2
+ Application,
3
+ ArithmeticBinaryOperation,
4
+ ArithmeticUnaryOperation,
5
+ Assignment,
6
+ AssignOperation,
7
+ BitwiseBinaryOperation,
8
+ BitwiseUnaryOperation,
9
+ BooleanPrimitive,
10
+ ComparisonOperation,
11
+ CompositionExpression,
12
+ Equation,
13
+ Function,
14
+ Lambda,
15
+ ListPrimitive,
16
+ ListUnaryOperation,
17
+ LiteralPattern,
18
+ LogicalBinaryOperation,
19
+ LogicalUnaryOperation,
20
+ NumberPrimitive,
21
+ RangeExpression,
22
+ Return,
23
+ Sequence,
24
+ SimpleType,
25
+ StringOperation,
26
+ StringPrimitive,
27
+ SymbolPrimitive,
28
+ TypeCast,
29
+ UnguardedBody,
30
+ Variable,
31
+ VariablePattern,
32
+ } from "yukigo-ast";
33
+ import { Interpreter } from "../../src/interpreter/index.js";
34
+ import { assert } from "chai";
35
+ import { YukigoKernel } from "../../src/interpreter/components/kernel/index.js";
36
+ import { RuntimeContext } from "../../src/interpreter/components/RuntimeContext.js";
37
+ import {
38
+ YuValue,
39
+ isLazyList,
40
+ LazyStepResult,
41
+ } from "../../src/interpreter/primitives/index.js";
42
+ import { InterpreterVisitor } from "../../src/interpreter/components/evaluators/index.js";
43
+
44
+ describe("Interpreter Spec", () => {
45
+ let interpreter: Interpreter;
46
+ beforeEach(() => {
47
+ interpreter = new Interpreter([]);
48
+ });
49
+ it("Evaluates ArithmeticBinaryOperation", () => {
50
+ assert.equal(
51
+ (
52
+ interpreter.evaluate(
53
+ new ArithmeticBinaryOperation(
54
+ "Plus",
55
+ new NumberPrimitive(3),
56
+ new NumberPrimitive(4),
57
+ ),
58
+ ) as YuValue
59
+ ).toJSON(),
60
+ 7,
61
+ );
62
+ assert.equal(
63
+ (
64
+ interpreter.evaluate(
65
+ new ArithmeticBinaryOperation(
66
+ "Minus",
67
+ new NumberPrimitive(3),
68
+ new NumberPrimitive(4),
69
+ ),
70
+ ) as YuValue
71
+ ).toJSON(),
72
+ -1,
73
+ );
74
+ assert.equal(
75
+ (
76
+ interpreter.evaluate(
77
+ new ArithmeticBinaryOperation(
78
+ "Multiply",
79
+ new NumberPrimitive(3),
80
+ new NumberPrimitive(4),
81
+ ),
82
+ ) as YuValue
83
+ ).toJSON(),
84
+ 12,
85
+ );
86
+ assert.equal(
87
+ (
88
+ interpreter.evaluate(
89
+ new ArithmeticBinaryOperation(
90
+ "Divide",
91
+ new NumberPrimitive(3),
92
+ new NumberPrimitive(4),
93
+ ),
94
+ ) as YuValue
95
+ ).toJSON(),
96
+ 0.75,
97
+ );
98
+ assert.equal(
99
+ (
100
+ interpreter.evaluate(
101
+ new ArithmeticBinaryOperation(
102
+ "Modulo",
103
+ new NumberPrimitive(3),
104
+ new NumberPrimitive(4),
105
+ ),
106
+ ) as YuValue
107
+ ).toJSON(),
108
+ 3,
109
+ );
110
+ assert.equal(
111
+ (
112
+ interpreter.evaluate(
113
+ new ArithmeticBinaryOperation(
114
+ "Power",
115
+ new NumberPrimitive(3),
116
+ new NumberPrimitive(4),
117
+ ),
118
+ ) as YuValue
119
+ ).toJSON(),
120
+ 81,
121
+ );
122
+ assert.equal(
123
+ (
124
+ interpreter.evaluate(
125
+ new ArithmeticBinaryOperation(
126
+ "Min",
127
+ new NumberPrimitive(3),
128
+ new NumberPrimitive(4),
129
+ ),
130
+ ) as YuValue
131
+ ).toJSON(),
132
+ 3,
133
+ );
134
+ assert.equal(
135
+ (
136
+ interpreter.evaluate(
137
+ new ArithmeticBinaryOperation(
138
+ "Max",
139
+ new NumberPrimitive(3),
140
+ new NumberPrimitive(4),
141
+ ),
142
+ ) as YuValue
143
+ ).toJSON(),
144
+ 4,
145
+ );
146
+ });
147
+
148
+ it("Evaluates ArithmeticUnaryOperation", () => {
149
+ assert.equal(
150
+ (
151
+ interpreter.evaluate(
152
+ new ArithmeticUnaryOperation("Round", new NumberPrimitive(3.4)),
153
+ ) as YuValue
154
+ ).toJSON(),
155
+ 3,
156
+ );
157
+ assert.equal(
158
+ (
159
+ interpreter.evaluate(
160
+ new ArithmeticUnaryOperation("Round", new NumberPrimitive(3.5)),
161
+ ) as YuValue
162
+ ).toJSON(),
163
+ 4,
164
+ );
165
+ assert.equal(
166
+ (
167
+ interpreter.evaluate(
168
+ new ArithmeticUnaryOperation("Absolute", new NumberPrimitive(-3)),
169
+ ) as YuValue
170
+ ).toJSON(),
171
+ 3,
172
+ );
173
+ assert.equal(
174
+ (
175
+ interpreter.evaluate(
176
+ new ArithmeticUnaryOperation("Absolute", new NumberPrimitive(3)),
177
+ ) as YuValue
178
+ ).toJSON(),
179
+ 3,
180
+ );
181
+ assert.equal(
182
+ (
183
+ interpreter.evaluate(
184
+ new ArithmeticUnaryOperation("Ceil", new NumberPrimitive(3.3)),
185
+ ) as YuValue
186
+ ).toJSON(),
187
+ 4,
188
+ );
189
+ assert.equal(
190
+ (
191
+ interpreter.evaluate(
192
+ new ArithmeticUnaryOperation("Floor", new NumberPrimitive(3.3)),
193
+ ) as YuValue
194
+ ).toJSON(),
195
+ 3,
196
+ );
197
+ assert.equal(
198
+ (
199
+ interpreter.evaluate(
200
+ new ArithmeticUnaryOperation("Negation", new NumberPrimitive(3.3)),
201
+ ) as YuValue
202
+ ).toJSON(),
203
+ -3.3,
204
+ );
205
+ assert.equal(
206
+ (
207
+ interpreter.evaluate(
208
+ new ArithmeticUnaryOperation("Sqrt", new NumberPrimitive(25)),
209
+ ) as YuValue
210
+ ).toJSON(),
211
+ 5,
212
+ );
213
+ });
214
+ describe("Evaluates ComparisonOperation", () => {
215
+ it("Equal Operator", () => {
216
+ assert.equal(
217
+ (
218
+ interpreter.evaluate(
219
+ new ComparisonOperation(
220
+ "Equal",
221
+ new NumberPrimitive(3.4),
222
+ new NumberPrimitive(3.4),
223
+ ),
224
+ ) as YuValue
225
+ ).toJSON(),
226
+ true,
227
+ );
228
+ assert.equal(
229
+ (
230
+ interpreter.evaluate(
231
+ new ComparisonOperation(
232
+ "Equal",
233
+ new NumberPrimitive(3.4),
234
+ new NumberPrimitive(4),
235
+ ),
236
+ ) as YuValue
237
+ ).toJSON(),
238
+ false,
239
+ );
240
+ assert.equal(
241
+ (
242
+ interpreter.evaluate(
243
+ new ComparisonOperation(
244
+ "Equal",
245
+ new NumberPrimitive(3),
246
+ new StringPrimitive("3"),
247
+ ),
248
+ ) as YuValue
249
+ ).toJSON(),
250
+ true,
251
+ );
252
+ assert.equal(
253
+ (
254
+ interpreter.evaluate(
255
+ new ComparisonOperation(
256
+ "Equal",
257
+ new NumberPrimitive(3),
258
+ new StringPrimitive("4"),
259
+ ),
260
+ ) as YuValue
261
+ ).toJSON(),
262
+ false,
263
+ );
264
+ });
265
+ it("NotEqual Operator", () => {
266
+ assert.equal(
267
+ (
268
+ interpreter.evaluate(
269
+ new ComparisonOperation(
270
+ "NotEqual",
271
+ new NumberPrimitive(3.4),
272
+ new NumberPrimitive(3.4),
273
+ ),
274
+ ) as YuValue
275
+ ).toJSON(),
276
+ false,
277
+ );
278
+ assert.equal(
279
+ (
280
+ interpreter.evaluate(
281
+ new ComparisonOperation(
282
+ "NotEqual",
283
+ new NumberPrimitive(3.4),
284
+ new NumberPrimitive(4),
285
+ ),
286
+ ) as YuValue
287
+ ).toJSON(),
288
+ true,
289
+ );
290
+ assert.equal(
291
+ (
292
+ interpreter.evaluate(
293
+ new ComparisonOperation(
294
+ "NotEqual",
295
+ new NumberPrimitive(3),
296
+ new StringPrimitive("3"),
297
+ ),
298
+ ) as YuValue
299
+ ).toJSON(),
300
+ false,
301
+ );
302
+ assert.equal(
303
+ (
304
+ interpreter.evaluate(
305
+ new ComparisonOperation(
306
+ "NotEqual",
307
+ new NumberPrimitive(3),
308
+ new StringPrimitive("4"),
309
+ ),
310
+ ) as YuValue
311
+ ).toJSON(),
312
+ true,
313
+ );
314
+ });
315
+ it("Same Operator", () => {
316
+ assert.equal(
317
+ (
318
+ interpreter.evaluate(
319
+ new ComparisonOperation(
320
+ "Same",
321
+ new NumberPrimitive(3.4),
322
+ new NumberPrimitive(3.4),
323
+ ),
324
+ ) as YuValue
325
+ ).toJSON(),
326
+ true,
327
+ );
328
+ assert.equal(
329
+ (
330
+ interpreter.evaluate(
331
+ new ComparisonOperation(
332
+ "Same",
333
+ new NumberPrimitive(3.4),
334
+ new NumberPrimitive(4),
335
+ ),
336
+ ) as YuValue
337
+ ).toJSON(),
338
+ false,
339
+ );
340
+ assert.equal(
341
+ (
342
+ interpreter.evaluate(
343
+ new ComparisonOperation(
344
+ "Same",
345
+ new NumberPrimitive(3),
346
+ new StringPrimitive("3"),
347
+ ),
348
+ ) as YuValue
349
+ ).toJSON(),
350
+ false,
351
+ );
352
+ assert.equal(
353
+ (
354
+ interpreter.evaluate(
355
+ new ComparisonOperation(
356
+ "Same",
357
+ new NumberPrimitive(3),
358
+ new StringPrimitive("4"),
359
+ ),
360
+ ) as YuValue
361
+ ).toJSON(),
362
+ false,
363
+ );
364
+ });
365
+ it("NotSame Operator", () => {
366
+ assert.equal(
367
+ (
368
+ interpreter.evaluate(
369
+ new ComparisonOperation(
370
+ "NotSame",
371
+ new NumberPrimitive(3.4),
372
+ new NumberPrimitive(3.4),
373
+ ),
374
+ ) as YuValue
375
+ ).toJSON(),
376
+ false,
377
+ );
378
+ assert.equal(
379
+ (
380
+ interpreter.evaluate(
381
+ new ComparisonOperation(
382
+ "NotSame",
383
+ new NumberPrimitive(3.4),
384
+ new NumberPrimitive(4),
385
+ ),
386
+ ) as YuValue
387
+ ).toJSON(),
388
+ true,
389
+ );
390
+ assert.equal(
391
+ (
392
+ interpreter.evaluate(
393
+ new ComparisonOperation(
394
+ "NotSame",
395
+ new NumberPrimitive(3),
396
+ new StringPrimitive("3"),
397
+ ),
398
+ ) as YuValue
399
+ ).toJSON(),
400
+ true,
401
+ );
402
+ assert.equal(
403
+ (
404
+ interpreter.evaluate(
405
+ new ComparisonOperation(
406
+ "NotSame",
407
+ new NumberPrimitive(3),
408
+ new StringPrimitive("4"),
409
+ ),
410
+ ) as YuValue
411
+ ).toJSON(),
412
+ true,
413
+ );
414
+ });
415
+ it("GreaterOrEqualThan Operator", () => {
416
+ assert.equal(
417
+ (
418
+ interpreter.evaluate(
419
+ new ComparisonOperation(
420
+ "GreaterOrEqualThan",
421
+ new NumberPrimitive(3.4),
422
+ new NumberPrimitive(3.4),
423
+ ),
424
+ ) as YuValue
425
+ ).toJSON(),
426
+ true,
427
+ );
428
+ assert.equal(
429
+ (
430
+ interpreter.evaluate(
431
+ new ComparisonOperation(
432
+ "GreaterOrEqualThan",
433
+ new NumberPrimitive(3.4),
434
+ new NumberPrimitive(4),
435
+ ),
436
+ ) as YuValue
437
+ ).toJSON(),
438
+ false,
439
+ );
440
+ assert.equal(
441
+ (
442
+ interpreter.evaluate(
443
+ new ComparisonOperation(
444
+ "GreaterOrEqualThan",
445
+ new NumberPrimitive(3),
446
+ new StringPrimitive("3"),
447
+ ),
448
+ ) as YuValue
449
+ ).toJSON(),
450
+ true,
451
+ );
452
+ assert.equal(
453
+ (
454
+ interpreter.evaluate(
455
+ new ComparisonOperation(
456
+ "GreaterOrEqualThan",
457
+ new NumberPrimitive(3),
458
+ new StringPrimitive("4"),
459
+ ),
460
+ ) as YuValue
461
+ ).toJSON(),
462
+ false,
463
+ );
464
+ });
465
+ it("GreaterThan Operator", () => {
466
+ assert.equal(
467
+ (
468
+ interpreter.evaluate(
469
+ new ComparisonOperation(
470
+ "GreaterThan",
471
+ new NumberPrimitive(3.4),
472
+ new NumberPrimitive(3.4),
473
+ ),
474
+ ) as YuValue
475
+ ).toJSON(),
476
+ false,
477
+ );
478
+ assert.equal(
479
+ (
480
+ interpreter.evaluate(
481
+ new ComparisonOperation(
482
+ "GreaterThan",
483
+ new NumberPrimitive(3.4),
484
+ new NumberPrimitive(4),
485
+ ),
486
+ ) as YuValue
487
+ ).toJSON(),
488
+ false,
489
+ );
490
+ assert.equal(
491
+ (
492
+ interpreter.evaluate(
493
+ new ComparisonOperation(
494
+ "GreaterThan",
495
+ new NumberPrimitive(3),
496
+ new StringPrimitive("3"),
497
+ ),
498
+ ) as YuValue
499
+ ).toJSON(),
500
+ false,
501
+ );
502
+ assert.equal(
503
+ (
504
+ interpreter.evaluate(
505
+ new ComparisonOperation(
506
+ "GreaterThan",
507
+ new NumberPrimitive(3),
508
+ new StringPrimitive("4"),
509
+ ),
510
+ ) as YuValue
511
+ ).toJSON(),
512
+ false,
513
+ );
514
+ });
515
+ it("LessOrEqualThan Operator", () => {
516
+ assert.equal(
517
+ (
518
+ interpreter.evaluate(
519
+ new ComparisonOperation(
520
+ "LessOrEqualThan",
521
+ new NumberPrimitive(3.4),
522
+ new NumberPrimitive(3.4),
523
+ ),
524
+ ) as YuValue
525
+ ).toJSON(),
526
+ true,
527
+ );
528
+ assert.equal(
529
+ (
530
+ interpreter.evaluate(
531
+ new ComparisonOperation(
532
+ "LessOrEqualThan",
533
+ new NumberPrimitive(3.4),
534
+ new NumberPrimitive(4),
535
+ ),
536
+ ) as YuValue
537
+ ).toJSON(),
538
+ true,
539
+ );
540
+ assert.equal(
541
+ (
542
+ interpreter.evaluate(
543
+ new ComparisonOperation(
544
+ "LessOrEqualThan",
545
+ new NumberPrimitive(3),
546
+ new StringPrimitive("3"),
547
+ ),
548
+ ) as YuValue
549
+ ).toJSON(),
550
+ true,
551
+ );
552
+ assert.equal(
553
+ (
554
+ interpreter.evaluate(
555
+ new ComparisonOperation(
556
+ "LessOrEqualThan",
557
+ new NumberPrimitive(3),
558
+ new StringPrimitive("4"),
559
+ ),
560
+ ) as YuValue
561
+ ).toJSON(),
562
+ true,
563
+ );
564
+ });
565
+ it("LessThan Operator", () => {
566
+ assert.equal(
567
+ (
568
+ interpreter.evaluate(
569
+ new ComparisonOperation(
570
+ "LessThan",
571
+ new NumberPrimitive(3.4),
572
+ new NumberPrimitive(3.4),
573
+ ),
574
+ ) as YuValue
575
+ ).toJSON(),
576
+ false,
577
+ );
578
+ assert.equal(
579
+ (
580
+ interpreter.evaluate(
581
+ new ComparisonOperation(
582
+ "LessThan",
583
+ new NumberPrimitive(3.4),
584
+ new NumberPrimitive(4),
585
+ ),
586
+ ) as YuValue
587
+ ).toJSON(),
588
+ true,
589
+ );
590
+ assert.equal(
591
+ (
592
+ interpreter.evaluate(
593
+ new ComparisonOperation(
594
+ "LessThan",
595
+ new NumberPrimitive(3),
596
+ new StringPrimitive("3"),
597
+ ),
598
+ ) as YuValue
599
+ ).toJSON(),
600
+ false,
601
+ );
602
+ assert.equal(
603
+ (
604
+ interpreter.evaluate(
605
+ new ComparisonOperation(
606
+ "LessThan",
607
+ new NumberPrimitive(3),
608
+ new StringPrimitive("4"),
609
+ ),
610
+ ) as YuValue
611
+ ).toJSON(),
612
+ true,
613
+ );
614
+ });
615
+ });
616
+ describe("Evaluates LogicalBinaryOperation", () => {
617
+ it("And Operator", () => {
618
+ assert.equal(
619
+ (
620
+ interpreter.evaluate(
621
+ new LogicalBinaryOperation(
622
+ "And",
623
+ new BooleanPrimitive(true),
624
+ new BooleanPrimitive(true),
625
+ ),
626
+ ) as YuValue
627
+ ).toJSON(),
628
+ true,
629
+ );
630
+ assert.equal(
631
+ (
632
+ interpreter.evaluate(
633
+ new LogicalBinaryOperation(
634
+ "And",
635
+ new BooleanPrimitive(true),
636
+ new BooleanPrimitive(false),
637
+ ),
638
+ ) as YuValue
639
+ ).toJSON(),
640
+ false,
641
+ );
642
+ assert.equal(
643
+ (
644
+ interpreter.evaluate(
645
+ new LogicalBinaryOperation(
646
+ "And",
647
+ new BooleanPrimitive(false),
648
+ new BooleanPrimitive(true),
649
+ ),
650
+ ) as YuValue
651
+ ).toJSON(),
652
+ false,
653
+ );
654
+ assert.equal(
655
+ (
656
+ interpreter.evaluate(
657
+ new LogicalBinaryOperation(
658
+ "And",
659
+ new BooleanPrimitive(false),
660
+ new BooleanPrimitive(false),
661
+ ),
662
+ ) as YuValue
663
+ ).toJSON(),
664
+ false,
665
+ );
666
+ });
667
+ it("Or Operator", () => {
668
+ assert.equal(
669
+ (
670
+ interpreter.evaluate(
671
+ new LogicalBinaryOperation(
672
+ "Or",
673
+ new BooleanPrimitive(true),
674
+ new BooleanPrimitive(true),
675
+ ),
676
+ ) as YuValue
677
+ ).toJSON(),
678
+ true,
679
+ );
680
+ assert.equal(
681
+ (
682
+ interpreter.evaluate(
683
+ new LogicalBinaryOperation(
684
+ "Or",
685
+ new BooleanPrimitive(true),
686
+ new BooleanPrimitive(false),
687
+ ),
688
+ ) as YuValue
689
+ ).toJSON(),
690
+ true,
691
+ );
692
+ assert.equal(
693
+ (
694
+ interpreter.evaluate(
695
+ new LogicalBinaryOperation(
696
+ "Or",
697
+ new BooleanPrimitive(false),
698
+ new BooleanPrimitive(true),
699
+ ),
700
+ ) as YuValue
701
+ ).toJSON(),
702
+ true,
703
+ );
704
+ assert.equal(
705
+ (
706
+ interpreter.evaluate(
707
+ new LogicalBinaryOperation(
708
+ "Or",
709
+ new BooleanPrimitive(false),
710
+ new BooleanPrimitive(false),
711
+ ),
712
+ ) as YuValue
713
+ ).toJSON(),
714
+ false,
715
+ );
716
+ });
717
+ });
718
+ describe("Evaluates LogicalUnaryOperation", () => {
719
+ it("Negation Operator", () => {
720
+ assert.equal(
721
+ (
722
+ interpreter.evaluate(
723
+ new LogicalUnaryOperation("Negation", new BooleanPrimitive(true)),
724
+ ) as YuValue
725
+ ).toJSON(),
726
+ false,
727
+ );
728
+ assert.equal(
729
+ (
730
+ interpreter.evaluate(
731
+ new LogicalUnaryOperation("Negation", new BooleanPrimitive(false)),
732
+ ) as YuValue
733
+ ).toJSON(),
734
+ true,
735
+ );
736
+ });
737
+ });
738
+ describe("Evaluates StringOperation", () => {
739
+ it("Concat Operator", () => {
740
+ assert.equal(
741
+ (
742
+ interpreter.evaluate(
743
+ new StringOperation(
744
+ "Concat",
745
+ new StringPrimitive("Hello"),
746
+ new StringPrimitive(" world!"),
747
+ ),
748
+ ) as YuValue
749
+ ).toJSON(),
750
+ "Hello world!",
751
+ );
752
+ });
753
+ });
754
+ describe("Evaluates ListUnaryOperation", () => {
755
+ it("Size Operator", () => {
756
+ assert.equal(
757
+ (
758
+ interpreter.evaluate(
759
+ new ListUnaryOperation(
760
+ "Size",
761
+ new ListPrimitive([
762
+ new StringPrimitive("Hello"),
763
+ new StringPrimitive("world!"),
764
+ ]),
765
+ ),
766
+ ) as YuValue
767
+ ).toJSON(),
768
+ 2,
769
+ );
770
+ });
771
+ it("DetectMax Operator", () => {
772
+ assert.equal(
773
+ (
774
+ interpreter.evaluate(
775
+ new ListUnaryOperation(
776
+ "DetectMax",
777
+ new ListPrimitive([
778
+ new NumberPrimitive(2),
779
+ new NumberPrimitive(4),
780
+ ]),
781
+ ),
782
+ ) as YuValue
783
+ ).toJSON(),
784
+ 4,
785
+ );
786
+ });
787
+ it("DetectMin Operator", () => {
788
+ assert.equal(
789
+ (
790
+ interpreter.evaluate(
791
+ new ListUnaryOperation(
792
+ "DetectMin",
793
+ new ListPrimitive([
794
+ new NumberPrimitive(2),
795
+ new NumberPrimitive(4),
796
+ ]),
797
+ ),
798
+ ) as YuValue
799
+ ).toJSON(),
800
+ 2,
801
+ );
802
+ });
803
+ it("Flatten Operator", () => {
804
+ assert.deepEqual(
805
+ (
806
+ interpreter.evaluate(
807
+ new ListUnaryOperation(
808
+ "Flatten",
809
+ new ListPrimitive([
810
+ new ListPrimitive([new NumberPrimitive(2)]),
811
+ new ListPrimitive([
812
+ new NumberPrimitive(3),
813
+ new NumberPrimitive(8),
814
+ ]),
815
+ ]),
816
+ ),
817
+ ) as YuValue
818
+ ).toJSON(),
819
+ [2, 3, 8],
820
+ );
821
+ });
822
+ });
823
+ describe("Evaluates BitwiseBinaryOperation", () => {
824
+ it("BitwiseOr Operator", () => {
825
+ assert.equal(
826
+ (
827
+ interpreter.evaluate(
828
+ new BitwiseBinaryOperation(
829
+ "BitwiseOr",
830
+ new NumberPrimitive(5),
831
+ new NumberPrimitive(1),
832
+ ),
833
+ ) as YuValue
834
+ ).toJSON(),
835
+ 5,
836
+ );
837
+ });
838
+ it("BitwiseAnd Operator", () => {
839
+ assert.equal(
840
+ (
841
+ interpreter.evaluate(
842
+ new BitwiseBinaryOperation(
843
+ "BitwiseAnd",
844
+ new NumberPrimitive(5),
845
+ new NumberPrimitive(1),
846
+ ),
847
+ ) as YuValue
848
+ ).toJSON(),
849
+ 1,
850
+ );
851
+ });
852
+ it("BitwiseLeftShift Operator", () => {
853
+ assert.equal(
854
+ (
855
+ interpreter.evaluate(
856
+ new BitwiseBinaryOperation(
857
+ "BitwiseLeftShift",
858
+ new NumberPrimitive(5),
859
+ new NumberPrimitive(1),
860
+ ),
861
+ ) as YuValue
862
+ ).toJSON(),
863
+ 10,
864
+ );
865
+ });
866
+ it("BitwiseRightShift Operator", () => {
867
+ assert.equal(
868
+ (
869
+ interpreter.evaluate(
870
+ new BitwiseBinaryOperation(
871
+ "BitwiseRightShift",
872
+ new NumberPrimitive(5),
873
+ new NumberPrimitive(1),
874
+ ),
875
+ ) as YuValue
876
+ ).toJSON(),
877
+ 2,
878
+ );
879
+ });
880
+ it("BitwiseUnsignedRightShift Operator", () => {
881
+ assert.equal(
882
+ (
883
+ interpreter.evaluate(
884
+ new BitwiseBinaryOperation(
885
+ "BitwiseUnsignedRightShift",
886
+ new NumberPrimitive(5),
887
+ new NumberPrimitive(1),
888
+ ),
889
+ ) as YuValue
890
+ ).toJSON(),
891
+ 2,
892
+ );
893
+ });
894
+ it("BitwiseXor Operator", () => {
895
+ assert.equal(
896
+ (
897
+ interpreter.evaluate(
898
+ new BitwiseBinaryOperation(
899
+ "BitwiseXor",
900
+ new NumberPrimitive(5),
901
+ new NumberPrimitive(1),
902
+ ),
903
+ ) as YuValue
904
+ ).toJSON(),
905
+ 4,
906
+ );
907
+ });
908
+ });
909
+ describe("Evaluates BitwiseUnaryOperator", () => {
910
+ it("BitwiseNot Operator", () => {
911
+ assert.equal(
912
+ (
913
+ interpreter.evaluate(
914
+ new BitwiseUnaryOperation("BitwiseNot", new NumberPrimitive(5)),
915
+ ) as YuValue
916
+ ).toJSON(),
917
+ -6,
918
+ );
919
+ });
920
+ });
921
+ describe("Evaluates Application", () => {
922
+ beforeEach(() => {
923
+ interpreter = new Interpreter([
924
+ new Function(new SymbolPrimitive("f"), [
925
+ new Equation(
926
+ [new LiteralPattern(new NumberPrimitive(3))],
927
+ new UnguardedBody(
928
+ new Sequence([new Return(new NumberPrimitive(6))]),
929
+ ),
930
+ new Return(new NumberPrimitive(6)),
931
+ ),
932
+ new Equation(
933
+ [new VariablePattern(new SymbolPrimitive("y"))],
934
+ new UnguardedBody(
935
+ new Sequence([
936
+ new Return(
937
+ new ArithmeticBinaryOperation(
938
+ "Plus",
939
+ new SymbolPrimitive("y"),
940
+ new NumberPrimitive(3),
941
+ ),
942
+ ),
943
+ ]),
944
+ ),
945
+ new Return(
946
+ new ArithmeticBinaryOperation(
947
+ "Plus",
948
+ new SymbolPrimitive("y"),
949
+ new NumberPrimitive(3),
950
+ ),
951
+ ),
952
+ ),
953
+ ]),
954
+ ]);
955
+ });
956
+ it("Lambda + currified Application", () => {
957
+ const lambda = new Lambda(
958
+ [
959
+ new VariablePattern(new SymbolPrimitive("x")),
960
+ new VariablePattern(new SymbolPrimitive("y")),
961
+ new VariablePattern(new SymbolPrimitive("z")),
962
+ ],
963
+ new ArithmeticBinaryOperation(
964
+ "Plus",
965
+ new ArithmeticBinaryOperation(
966
+ "Plus",
967
+ new SymbolPrimitive("x"),
968
+ new SymbolPrimitive("y"),
969
+ ),
970
+ new SymbolPrimitive("z"),
971
+ ),
972
+ );
973
+ const app1 = new Application(lambda, new NumberPrimitive(1));
974
+ const app2 = new Application(app1, new NumberPrimitive(2));
975
+ const app3 = new Application(app2, new NumberPrimitive(3));
976
+ assert.equal((interpreter.evaluate(app3) as YuValue).toJSON(), 6);
977
+ });
978
+ it("Application of Function", () => {
979
+ const app1 = new Application(
980
+ new SymbolPrimitive("f"),
981
+ new NumberPrimitive(3),
982
+ );
983
+ assert.equal((interpreter.evaluate(app1) as YuValue).toJSON(), 6);
984
+ });
985
+ });
986
+ describe("Evaluates Composition", () => {
987
+ beforeEach(() => {
988
+ interpreter = new Interpreter(
989
+ [
990
+ new Function(new SymbolPrimitive("doble"), [
991
+ new Equation(
992
+ [new VariablePattern(new SymbolPrimitive("x"))],
993
+ new UnguardedBody(
994
+ new Sequence([
995
+ new Return(
996
+ new ArithmeticBinaryOperation(
997
+ "Multiply",
998
+ new SymbolPrimitive("x"),
999
+ new NumberPrimitive(2),
1000
+ ),
1001
+ ),
1002
+ ]),
1003
+ ),
1004
+ new Return(
1005
+ new ArithmeticBinaryOperation(
1006
+ "Multiply",
1007
+ new SymbolPrimitive("x"),
1008
+ new NumberPrimitive(2),
1009
+ ),
1010
+ ),
1011
+ ),
1012
+ ]),
1013
+ new Function(new SymbolPrimitive("cuadrado"), [
1014
+ new Equation(
1015
+ [new VariablePattern(new SymbolPrimitive("x"))],
1016
+ new UnguardedBody(
1017
+ new Sequence([
1018
+ new Return(
1019
+ new ArithmeticBinaryOperation(
1020
+ "Power",
1021
+ new SymbolPrimitive("x"),
1022
+ new NumberPrimitive(2),
1023
+ ),
1024
+ ),
1025
+ ]),
1026
+ ),
1027
+ new Return(
1028
+ new ArithmeticBinaryOperation(
1029
+ "Power",
1030
+ new SymbolPrimitive("x"),
1031
+ new NumberPrimitive(2),
1032
+ ),
1033
+ ),
1034
+ ),
1035
+ ]),
1036
+ ],
1037
+ { debug: true },
1038
+ );
1039
+ });
1040
+ it("Composition (cuadrado . doble) 2 should be 16", () => {
1041
+ const fog = new CompositionExpression(
1042
+ new SymbolPrimitive("cuadrado"),
1043
+ new SymbolPrimitive("doble"),
1044
+ );
1045
+ const app = new Application(fog, new NumberPrimitive(2));
1046
+ const res = interpreter.evaluate(app);
1047
+ assert.equal((res as YuValue).toJSON(), 16);
1048
+ });
1049
+ });
1050
+ describe("Evaluates TypeCast", () => {
1051
+ it("Type casting of number 2 to string should be '2'", () => {
1052
+ const res = interpreter.evaluate(
1053
+ new TypeCast(new NumberPrimitive(2), new SimpleType("String", [])),
1054
+ );
1055
+ assert.equal((res as YuValue).toJSON(), "2");
1056
+ });
1057
+ });
1058
+ describe("Evaluates Range Expression", () => {
1059
+ it("Evaluates [1..5] to full range", () => {
1060
+ const range = new RangeExpression(
1061
+ new NumberPrimitive(1),
1062
+ new NumberPrimitive(5),
1063
+ );
1064
+ assert.deepEqual(
1065
+ (interpreter.evaluate(range) as YuValue).toJSON(),
1066
+ [1, 2, 3, 4, 5],
1067
+ );
1068
+ });
1069
+ it("Evaluates [0,0.5..2] to full range", () => {
1070
+ const range = new RangeExpression(
1071
+ new NumberPrimitive(0),
1072
+ new NumberPrimitive(2),
1073
+ new NumberPrimitive(0.5),
1074
+ );
1075
+ assert.deepEqual(
1076
+ (interpreter.evaluate(range) as YuValue).toJSON(),
1077
+ [0, 0.5, 1, 1.5, 2],
1078
+ );
1079
+ });
1080
+ it("Evaluates [1..] lazily", () => {
1081
+ interpreter = new Interpreter([], { lazyLoading: true });
1082
+ const range = new RangeExpression(new NumberPrimitive(1));
1083
+ const evaluatedList = interpreter.evaluate(range);
1084
+ if (!isLazyList(evaluatedList))
1085
+ assert.fail("Evaluated list should be LazyList");
1086
+
1087
+ const kernel = new YukigoKernel(
1088
+ new InterpreterVisitor(new RuntimeContext({ lazyLoading: true })),
1089
+ );
1090
+ const step1 = kernel.run(evaluatedList.step()) as LazyStepResult;
1091
+ assert.equal((step1.head as YuValue).toJSON(), 1);
1092
+ const step2 = kernel.run(step1.tail!.step()) as LazyStepResult;
1093
+ assert.equal((step2.head as YuValue).toJSON(), 2);
1094
+ });
1095
+ });
1096
+
1097
+ describe("Immutability Configuration", () => {
1098
+ it("Should allow variable reassignment when mutability is enabled (default)", () => {
1099
+ const ast = [
1100
+ new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
1101
+ new Assignment(new SymbolPrimitive("x"), new NumberPrimitive(10)),
1102
+ ];
1103
+ interpreter = new Interpreter(ast, { mutability: true });
1104
+
1105
+ // Should not throw
1106
+ assert.doesNotThrow(() => {
1107
+ interpreter.evaluate(new SymbolPrimitive("x"));
1108
+ });
1109
+ });
1110
+
1111
+ it("Should throw when attempting variable reassignment with mutability disabled", () => {
1112
+ const ast = [
1113
+ new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
1114
+ ];
1115
+ interpreter = new Interpreter(ast, { mutability: false });
1116
+
1117
+ // Attempting reassignment should throw
1118
+ assert.throws(() => {
1119
+ interpreter.evaluate(
1120
+ new Assignment(new SymbolPrimitive("x"), new NumberPrimitive(10)),
1121
+ );
1122
+ }, /Cannot reassign variable 'x': mutability is disabled/);
1123
+ });
1124
+
1125
+ it("Should throw when attempting assignment operation with mutability disabled", () => {
1126
+ const ast = [
1127
+ new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
1128
+ ];
1129
+ interpreter = new Interpreter(ast, { mutability: false });
1130
+
1131
+ // Attempting assignment operation should throw
1132
+ assert.throws(() => {
1133
+ interpreter.evaluate(
1134
+ new AssignOperation(
1135
+ "Assign",
1136
+ new Variable(new SymbolPrimitive("x"), new NumberPrimitive(5)),
1137
+ new NumberPrimitive(3),
1138
+ ),
1139
+ );
1140
+ }, /Cannot perform assignment operation: mutability is disabled/);
1141
+ });
1142
+ });
1143
+ });