yukigo 0.2.2 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.json +3 -3
- package/CHANGELOG.md +102 -41
- package/README.md +193 -193
- package/dist/analyzer/GraphBuilder.d.ts +1 -0
- package/dist/analyzer/GraphBuilder.js +2 -1
- package/dist/analyzer/index.d.ts +0 -7
- package/dist/analyzer/index.js +3 -3
- package/dist/analyzer/inspections/functional/functional.d.ts +1 -1
- package/dist/analyzer/inspections/functional/functional.js +1 -1
- package/dist/analyzer/inspections/functional/smells.d.ts +3 -3
- package/dist/analyzer/inspections/functional/smells.js +27 -35
- package/dist/analyzer/inspections/generic/generic.d.ts +21 -14
- package/dist/analyzer/inspections/generic/generic.js +78 -59
- package/dist/analyzer/inspections/generic/smells.d.ts +2 -0
- package/dist/analyzer/inspections/generic/smells.js +55 -64
- package/dist/analyzer/inspections/imperative/imperative.d.ts +3 -3
- package/dist/analyzer/inspections/imperative/imperative.js +3 -3
- package/dist/analyzer/inspections/imperative/smells.d.ts +1 -0
- package/dist/analyzer/inspections/imperative/smells.js +8 -5
- package/dist/analyzer/inspections/logic/logic.d.ts +8 -8
- package/dist/analyzer/inspections/logic/logic.js +5 -5
- package/dist/analyzer/inspections/logic/smells.js +2 -2
- package/dist/analyzer/inspections/object/object.d.ts +5 -5
- package/dist/analyzer/inspections/object/object.js +22 -21
- package/dist/analyzer/inspections/object/smells.js +11 -23
- package/dist/analyzer/utils.d.ts +6 -2
- package/dist/analyzer/utils.js +6 -2
- package/dist/interpreter/components/EnvBuilder.d.ts +20 -1
- package/dist/interpreter/components/EnvBuilder.js +211 -66
- package/dist/interpreter/components/EqualityComparer.d.ts +15 -0
- package/dist/interpreter/components/EqualityComparer.js +69 -0
- package/dist/interpreter/components/Operations.d.ts +17 -14
- package/dist/interpreter/components/Operations.js +61 -62
- package/dist/interpreter/components/PatternMatcher.d.ts +19 -58
- package/dist/interpreter/components/PatternMatcher.js +185 -286
- package/dist/interpreter/components/RuntimeContext.d.ts +24 -15
- package/dist/interpreter/components/RuntimeContext.js +43 -4
- package/dist/interpreter/components/TestRunner.d.ts +15 -13
- package/dist/interpreter/components/TestRunner.js +86 -53
- package/dist/interpreter/components/evaluators/BaseEvaluator.d.ts +19 -0
- package/dist/interpreter/components/evaluators/BaseEvaluator.js +20 -0
- package/dist/interpreter/components/evaluators/ExpressionEvaluator.d.ts +34 -0
- package/dist/interpreter/components/evaluators/ExpressionEvaluator.js +298 -0
- package/dist/interpreter/components/evaluators/OperationEvaluator.d.ts +25 -0
- package/dist/interpreter/components/evaluators/OperationEvaluator.js +226 -0
- package/dist/interpreter/components/evaluators/PrimitiveEvaluator.d.ts +19 -0
- package/dist/interpreter/components/evaluators/PrimitiveEvaluator.js +50 -0
- package/dist/interpreter/components/evaluators/StatementEvaluator.d.ts +28 -0
- package/dist/interpreter/components/evaluators/StatementEvaluator.js +240 -0
- package/dist/interpreter/components/evaluators/TestingEvaluator.d.ts +15 -0
- package/dist/interpreter/components/evaluators/TestingEvaluator.js +14 -0
- package/dist/interpreter/components/evaluators/index.d.ts +110 -0
- package/dist/interpreter/components/evaluators/index.js +21 -0
- package/dist/interpreter/components/evaluators/utils.d.ts +7 -0
- package/dist/interpreter/components/evaluators/utils.js +50 -0
- package/dist/interpreter/components/hooks/YukigoHook.d.ts +27 -0
- package/dist/interpreter/components/hooks/YukigoHook.js +1 -0
- package/dist/interpreter/components/kernel/commands.d.ts +122 -0
- package/dist/interpreter/components/kernel/commands.js +203 -0
- package/dist/interpreter/components/kernel/index.d.ts +51 -0
- package/dist/interpreter/components/kernel/index.js +176 -0
- package/dist/interpreter/components/logic/LogicEngine.d.ts +26 -23
- package/dist/interpreter/components/logic/LogicEngine.js +234 -221
- package/dist/interpreter/components/logic/LogicResolver.d.ts +22 -51
- package/dist/interpreter/components/logic/LogicResolver.js +73 -440
- package/dist/interpreter/components/logic/LogicTerm.d.ts +104 -0
- package/dist/interpreter/components/logic/LogicTerm.js +423 -0
- package/dist/interpreter/components/logic/LogicTranslator.d.ts +25 -9
- package/dist/interpreter/components/logic/LogicTranslator.js +211 -74
- package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +6 -4
- package/dist/interpreter/components/runtimes/FunctionRuntime.js +82 -84
- package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +13 -14
- package/dist/interpreter/components/runtimes/LazyRuntime.js +112 -239
- package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +17 -14
- package/dist/interpreter/components/runtimes/ObjectRuntime.js +105 -74
- package/dist/interpreter/errors.d.ts +10 -0
- package/dist/interpreter/errors.js +17 -0
- package/dist/interpreter/index.d.ts +9 -5
- package/dist/interpreter/index.js +11 -13
- package/dist/interpreter/primitives/YuValue.d.ts +21 -0
- package/dist/interpreter/primitives/YuValue.js +40 -0
- package/dist/interpreter/primitives/capabilities.d.ts +90 -0
- package/dist/interpreter/primitives/capabilities.js +1 -0
- package/dist/interpreter/primitives/entities/LazyList.d.ts +48 -0
- package/dist/interpreter/primitives/entities/LazyList.js +164 -0
- package/dist/interpreter/primitives/entities/LogicResult.d.ts +51 -0
- package/dist/interpreter/primitives/entities/LogicResult.js +101 -0
- package/dist/interpreter/primitives/entities/RuntimeClass.d.ts +24 -0
- package/dist/interpreter/primitives/entities/RuntimeClass.js +57 -0
- package/dist/interpreter/primitives/entities/RuntimeFunction.d.ts +40 -0
- package/dist/interpreter/primitives/entities/RuntimeFunction.js +73 -0
- package/dist/interpreter/primitives/entities/RuntimeObject.d.ts +27 -0
- package/dist/interpreter/primitives/entities/RuntimeObject.js +82 -0
- package/dist/interpreter/primitives/entities/RuntimePredicate.d.ts +19 -0
- package/dist/interpreter/primitives/entities/RuntimePredicate.js +59 -0
- package/dist/interpreter/primitives/index.d.ts +14 -0
- package/dist/interpreter/primitives/index.js +14 -0
- package/dist/interpreter/primitives/scalars/YuBoolean.d.ts +24 -0
- package/dist/interpreter/primitives/scalars/YuBoolean.js +69 -0
- package/dist/interpreter/primitives/scalars/YuChar.d.ts +28 -0
- package/dist/interpreter/primitives/scalars/YuChar.js +78 -0
- package/dist/interpreter/primitives/scalars/YuNil.d.ts +25 -0
- package/dist/interpreter/primitives/scalars/YuNil.js +73 -0
- package/dist/interpreter/primitives/scalars/YuNumber.d.ts +49 -0
- package/dist/interpreter/primitives/scalars/YuNumber.js +165 -0
- package/dist/interpreter/primitives/sequences/YuArray.d.ts +33 -0
- package/dist/interpreter/primitives/sequences/YuArray.js +150 -0
- package/dist/interpreter/primitives/sequences/YuString.d.ts +40 -0
- package/dist/interpreter/primitives/sequences/YuString.js +130 -0
- package/dist/interpreter/utils.d.ts +23 -10
- package/dist/interpreter/utils.js +25 -30
- package/dist/tester/index.d.ts +3 -3
- package/dist/tester/index.js +39 -28
- package/dist/utils/helpers.d.ts +12 -5
- package/dist/utils/helpers.js +6 -79
- package/package.json +3 -16
- package/src/analyzer/GraphBuilder.ts +143 -142
- package/src/analyzer/index.ts +185 -194
- package/src/analyzer/inspections/functional/functional.ts +121 -121
- package/src/analyzer/inspections/functional/smells.ts +88 -102
- package/src/analyzer/inspections/generic/generic.ts +610 -581
- package/src/analyzer/inspections/generic/smells.ts +355 -365
- package/src/analyzer/inspections/imperative/imperative.ts +104 -101
- package/src/analyzer/inspections/imperative/smells.ts +58 -54
- package/src/analyzer/inspections/logic/logic.ts +84 -90
- package/src/analyzer/inspections/logic/smells.ts +54 -54
- package/src/analyzer/inspections/object/object.ts +295 -264
- package/src/analyzer/inspections/object/smells.ts +130 -144
- package/src/analyzer/utils.ts +115 -109
- package/src/index.ts +3 -3
- package/src/interpreter/components/EnvBuilder.ts +405 -202
- package/src/interpreter/components/EqualityComparer.ts +107 -0
- package/src/interpreter/components/Operations.ts +126 -99
- package/src/interpreter/components/PatternMatcher.ts +375 -475
- package/src/interpreter/components/RuntimeContext.ts +181 -119
- package/src/interpreter/components/TestRunner.ts +223 -151
- package/src/interpreter/components/evaluators/BaseEvaluator.ts +36 -0
- package/src/interpreter/components/evaluators/ExpressionEvaluator.ts +475 -0
- package/src/interpreter/components/evaluators/OperationEvaluator.ts +477 -0
- package/src/interpreter/components/evaluators/PrimitiveEvaluator.ts +80 -0
- package/src/interpreter/components/evaluators/StatementEvaluator.ts +372 -0
- package/src/interpreter/components/evaluators/TestingEvaluator.ts +26 -0
- package/src/interpreter/components/evaluators/index.ts +34 -0
- package/src/interpreter/components/evaluators/utils.ts +64 -0
- package/src/interpreter/components/hooks/YukigoHook.ts +45 -0
- package/src/interpreter/components/kernel/commands.ts +255 -0
- package/src/interpreter/components/kernel/index.ts +222 -0
- package/src/interpreter/components/logic/LogicEngine.ts +509 -519
- package/src/interpreter/components/logic/LogicResolver.ts +209 -858
- package/src/interpreter/components/logic/LogicTerm.ts +477 -0
- package/src/interpreter/components/logic/LogicTranslator.ts +362 -149
- package/src/interpreter/components/runtimes/FunctionRuntime.ts +249 -227
- package/src/interpreter/components/runtimes/LazyRuntime.ts +226 -334
- package/src/interpreter/components/runtimes/ObjectRuntime.ts +262 -224
- package/src/interpreter/errors.ts +68 -47
- package/src/interpreter/index.ts +50 -52
- package/src/interpreter/primitives/YuValue.ts +64 -0
- package/src/interpreter/primitives/capabilities.ts +111 -0
- package/src/interpreter/primitives/entities/LazyList.ts +225 -0
- package/src/interpreter/primitives/entities/LogicResult.ts +133 -0
- package/src/interpreter/primitives/entities/RuntimeClass.ts +70 -0
- package/src/interpreter/primitives/entities/RuntimeFunction.ts +108 -0
- package/src/interpreter/primitives/entities/RuntimeObject.ts +110 -0
- package/src/interpreter/primitives/entities/RuntimePredicate.ts +77 -0
- package/src/interpreter/primitives/index.ts +17 -0
- package/src/interpreter/primitives/scalars/YuBoolean.ts +79 -0
- package/src/interpreter/primitives/scalars/YuChar.ts +94 -0
- package/src/interpreter/primitives/scalars/YuNil.ts +84 -0
- package/src/interpreter/primitives/scalars/YuNumber.ts +187 -0
- package/src/interpreter/primitives/sequences/YuArray.ts +178 -0
- package/src/interpreter/primitives/sequences/YuString.ts +165 -0
- package/src/interpreter/utils.ts +105 -84
- package/src/tester/index.ts +157 -128
- package/src/utils/helpers.ts +81 -168
- package/tests/analyzer/functional.spec.ts +221 -207
- package/tests/analyzer/generic.spec.ts +178 -178
- package/tests/analyzer/helpers.spec.ts +83 -89
- package/tests/analyzer/logic.spec.ts +237 -237
- package/tests/analyzer/oop.spec.ts +320 -323
- package/tests/analyzer/transitive.spec.ts +166 -166
- package/tests/interpreter/EnvBuilder.spec.ts +181 -183
- package/tests/interpreter/FunctionRuntime.spec.ts +224 -223
- package/tests/interpreter/LazyRuntime.spec.ts +227 -225
- package/tests/interpreter/LogicEngine.spec.ts +371 -327
- package/tests/interpreter/LogicSubstitution.spec.ts +90 -80
- package/tests/interpreter/ObjectRuntime.spec.ts +431 -606
- package/tests/interpreter/Operations.spec.ts +312 -220
- package/tests/interpreter/PatternSystem.spec.ts +254 -213
- package/tests/interpreter/Tests.spec.ts +122 -122
- package/tests/interpreter/interpreter.spec.ts +1143 -991
- package/tests/kernel/YukigoKernel.spec.ts +112 -0
- package/tests/tester/Tester.spec.ts +188 -152
- package/tsconfig.build.json +16 -15
- package/tsconfig.json +27 -25
- package/dist/interpreter/components/Visitor.d.ts +0 -70
- package/dist/interpreter/components/Visitor.js +0 -634
- package/dist/interpreter/entities.d.ts +0 -105
- package/dist/interpreter/entities.js +0 -96
- package/dist/interpreter/trampoline.d.ts +0 -17
- package/dist/interpreter/trampoline.js +0 -38
- package/dist/src/analyzer/GraphBuilder.d.ts +0 -30
- package/dist/src/analyzer/GraphBuilder.js +0 -100
- package/dist/src/analyzer/index.d.ts +0 -59
- package/dist/src/analyzer/index.js +0 -152
- package/dist/src/analyzer/inspections/functional/functional.d.ts +0 -44
- package/dist/src/analyzer/inspections/functional/functional.js +0 -149
- package/dist/src/analyzer/inspections/functional/smells.d.ts +0 -16
- package/dist/src/analyzer/inspections/functional/smells.js +0 -98
- package/dist/src/analyzer/inspections/generic/generic.d.ts +0 -178
- package/dist/src/analyzer/inspections/generic/generic.js +0 -604
- package/dist/src/analyzer/inspections/generic/smells.d.ts +0 -61
- package/dist/src/analyzer/inspections/generic/smells.js +0 -349
- package/dist/src/analyzer/inspections/imperative/imperative.d.ts +0 -35
- package/dist/src/analyzer/inspections/imperative/imperative.js +0 -109
- package/dist/src/analyzer/inspections/imperative/smells.d.ts +0 -16
- package/dist/src/analyzer/inspections/imperative/smells.js +0 -58
- package/dist/src/analyzer/inspections/logic/logic.d.ts +0 -32
- package/dist/src/analyzer/inspections/logic/logic.js +0 -96
- package/dist/src/analyzer/inspections/logic/smells.d.ts +0 -15
- package/dist/src/analyzer/inspections/logic/smells.js +0 -60
- package/dist/src/analyzer/inspections/object/object.d.ts +0 -90
- package/dist/src/analyzer/inspections/object/object.js +0 -321
- package/dist/src/analyzer/inspections/object/smells.d.ts +0 -30
- package/dist/src/analyzer/inspections/object/smells.js +0 -135
- package/dist/src/analyzer/utils.d.ts +0 -30
- package/dist/src/analyzer/utils.js +0 -78
- package/dist/src/index.d.ts +0 -4
- package/dist/src/index.js +0 -4
- package/dist/src/interpreter/components/EnvBuilder.d.ts +0 -21
- package/dist/src/interpreter/components/EnvBuilder.js +0 -155
- package/dist/src/interpreter/components/Operations.d.ts +0 -14
- package/dist/src/interpreter/components/Operations.js +0 -84
- package/dist/src/interpreter/components/PatternMatcher.d.ts +0 -73
- package/dist/src/interpreter/components/PatternMatcher.js +0 -358
- package/dist/src/interpreter/components/RuntimeContext.d.ts +0 -35
- package/dist/src/interpreter/components/RuntimeContext.js +0 -93
- package/dist/src/interpreter/components/TestRunner.d.ts +0 -19
- package/dist/src/interpreter/components/TestRunner.js +0 -110
- package/dist/src/interpreter/components/Visitor.d.ts +0 -71
- package/dist/src/interpreter/components/Visitor.js +0 -638
- package/dist/src/interpreter/components/logic/LogicEngine.d.ts +0 -29
- package/dist/src/interpreter/components/logic/LogicEngine.js +0 -259
- package/dist/src/interpreter/components/logic/LogicResolver.d.ts +0 -53
- package/dist/src/interpreter/components/logic/LogicResolver.js +0 -484
- package/dist/src/interpreter/components/logic/LogicTranslator.d.ts +0 -14
- package/dist/src/interpreter/components/logic/LogicTranslator.js +0 -99
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.d.ts +0 -12
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.js +0 -149
- package/dist/src/interpreter/components/runtimes/LazyRuntime.d.ts +0 -19
- package/dist/src/interpreter/components/runtimes/LazyRuntime.js +0 -269
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.d.ts +0 -35
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.js +0 -126
- package/dist/src/interpreter/errors.d.ts +0 -19
- package/dist/src/interpreter/errors.js +0 -36
- package/dist/src/interpreter/index.d.ts +0 -24
- package/dist/src/interpreter/index.js +0 -41
- package/dist/src/interpreter/trampoline.d.ts +0 -17
- package/dist/src/interpreter/trampoline.js +0 -38
- package/dist/src/interpreter/utils.d.ts +0 -11
- package/dist/src/interpreter/utils.js +0 -65
- package/dist/src/tester/index.d.ts +0 -25
- package/dist/src/tester/index.js +0 -113
- package/dist/src/utils/helpers.d.ts +0 -13
- package/dist/src/utils/helpers.js +0 -52
- package/src/interpreter/components/Visitor.ts +0 -1065
- package/src/interpreter/trampoline.ts +0 -71
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { TraverseVisitor, NamedArgument, } from "yukigo-ast";
|
|
2
|
+
import { InterpreterError, UnexpectedNode } from "../errors.js";
|
|
3
|
+
import { YukigoKernel } from "./kernel/index.js";
|
|
4
|
+
import { EvalCommand } from "./kernel/commands.js";
|
|
5
|
+
import { RuntimeFunction, RuntimeClass, RuntimeObject, isRuntimePredicate, RuntimePredicate, } from "../primitives/index.js";
|
|
6
|
+
import { InterpreterVisitor } from "./evaluators/index.js";
|
|
7
|
+
class NotValidPredicate extends InterpreterError {
|
|
8
|
+
constructor(identifier) {
|
|
9
|
+
super("[EnvBuilder]", `"${identifier}" is not a predicate. Maybe there is something else defined as "${identifier}"?`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
class FunctionWithNoEquations extends InterpreterError {
|
|
13
|
+
constructor(identifier) {
|
|
14
|
+
super("[EnvBuilder]", `Function ${identifier} has no equations`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class FunctionArityMismatch extends InterpreterError {
|
|
18
|
+
constructor(identifier) {
|
|
19
|
+
super("[EnvBuilder]", `All equations of ${identifier} must have the same arity`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
5
22
|
/**
|
|
6
23
|
* Builds the initial environment by collecting all top-level function declarations.
|
|
7
24
|
* Each function captures a closure of the environment at its definition time,
|
|
@@ -9,14 +26,24 @@ import { InterpreterError } from "../errors.js";
|
|
|
9
26
|
*/
|
|
10
27
|
export class EnvBuilderVisitor extends TraverseVisitor {
|
|
11
28
|
ctx;
|
|
29
|
+
deferredInitializations = [];
|
|
12
30
|
constructor(ctx) {
|
|
13
31
|
super();
|
|
14
32
|
this.ctx = ctx;
|
|
15
33
|
}
|
|
16
34
|
build(ast) {
|
|
35
|
+
this.declareGlobalSymbols(ast);
|
|
36
|
+
this.initializeGlobalStates();
|
|
37
|
+
}
|
|
38
|
+
declareGlobalSymbols(ast) {
|
|
17
39
|
for (const node of ast)
|
|
18
40
|
node.accept(this);
|
|
19
41
|
}
|
|
42
|
+
initializeGlobalStates() {
|
|
43
|
+
for (const initialization of this.deferredInitializations) {
|
|
44
|
+
initialization.execute(this.ctx);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
20
47
|
visitSequence(node) {
|
|
21
48
|
for (const stmt of node.statements)
|
|
22
49
|
stmt.accept(this);
|
|
@@ -26,24 +53,18 @@ export class EnvBuilderVisitor extends TraverseVisitor {
|
|
|
26
53
|
if (this.ctx.config.debug)
|
|
27
54
|
console.log(`[EnvBuilder] Defining function: ${name}`);
|
|
28
55
|
if (node.equations.length === 0)
|
|
29
|
-
throw new
|
|
56
|
+
throw new FunctionWithNoEquations(name);
|
|
30
57
|
const arity = node.equations[0].patterns.length;
|
|
31
58
|
if (node.equations.some((eq) => eq.patterns.length !== arity))
|
|
32
|
-
throw new
|
|
33
|
-
let placeholder;
|
|
34
|
-
this.ctx.
|
|
59
|
+
throw new FunctionArityMismatch(name);
|
|
60
|
+
let placeholder = new RuntimeFunction(0, []);
|
|
61
|
+
this.ctx.defineGlobal(name, placeholder);
|
|
35
62
|
const equations = node.equations.map((eq) => ({
|
|
36
63
|
patterns: eq.patterns,
|
|
37
64
|
body: eq.body,
|
|
38
65
|
}));
|
|
39
|
-
const runtimeFunc =
|
|
40
|
-
|
|
41
|
-
identifier: name,
|
|
42
|
-
arity,
|
|
43
|
-
equations,
|
|
44
|
-
closure: this.ctx.env,
|
|
45
|
-
};
|
|
46
|
-
this.ctx.define(name, runtimeFunc);
|
|
66
|
+
const runtimeFunc = new RuntimeFunction(arity, equations, name, undefined, this.ctx.env);
|
|
67
|
+
this.ctx.defineGlobal(name, runtimeFunc);
|
|
47
68
|
}
|
|
48
69
|
visitClass(node) {
|
|
49
70
|
const identifier = node.identifier.value;
|
|
@@ -51,98 +72,222 @@ export class EnvBuilderVisitor extends TraverseVisitor {
|
|
|
51
72
|
console.log(`[EnvBuilder] Defining class: ${identifier}`);
|
|
52
73
|
const superclass = node.extendsSymbol?.value;
|
|
53
74
|
const mixins = node.includes.map((symbol) => symbol.value);
|
|
54
|
-
const collector = new OOPCollector();
|
|
75
|
+
const collector = new OOPCollector(this.ctx);
|
|
55
76
|
node.expression.accept(collector);
|
|
56
77
|
const fields = collector.collectedFields;
|
|
57
78
|
const methods = collector.collectedMethods;
|
|
58
|
-
const runtimeClass =
|
|
59
|
-
|
|
60
|
-
identifier,
|
|
61
|
-
fields,
|
|
62
|
-
methods,
|
|
63
|
-
superclass,
|
|
64
|
-
mixins,
|
|
65
|
-
};
|
|
66
|
-
this.ctx.define(identifier, runtimeClass);
|
|
79
|
+
const runtimeClass = new RuntimeClass(identifier, fields, methods, mixins, superclass, collector.fieldInitializers);
|
|
80
|
+
this.ctx.defineGlobal(identifier, runtimeClass);
|
|
67
81
|
}
|
|
68
82
|
visitObject(node) {
|
|
69
83
|
const identifier = node.identifier.value;
|
|
70
84
|
if (this.ctx.config.debug)
|
|
71
85
|
console.log(`[EnvBuilder] Defining object: ${identifier}`);
|
|
72
|
-
const collector = new OOPCollector();
|
|
86
|
+
const collector = new OOPCollector(this.ctx);
|
|
73
87
|
node.expression.accept(collector);
|
|
74
|
-
const fields = collector
|
|
88
|
+
const fields = this.resolveObjectFields(node, collector);
|
|
75
89
|
const methods = collector.collectedMethods;
|
|
76
|
-
const runtimeObject =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
const runtimeObject = new RuntimeObject(identifier, node.extendsSymbol?.value || "", fields, methods);
|
|
91
|
+
// Encolamos de forma declarativa la inicialización tardía delegando la tarea
|
|
92
|
+
const initializers = this.collectAllInitializers(node, collector);
|
|
93
|
+
this.deferredInitializations.push(new DeferredInitialization(runtimeObject, initializers));
|
|
94
|
+
this.ctx.defineGlobal(identifier, runtimeObject);
|
|
95
|
+
}
|
|
96
|
+
resolveObjectFields(node, collector) {
|
|
97
|
+
const fields = collector.collectedFields;
|
|
98
|
+
const extendsSymbol = node.extendsSymbol?.value;
|
|
99
|
+
if (extendsSymbol) {
|
|
100
|
+
const classDef = this.ctx.lookup(extendsSymbol);
|
|
101
|
+
if (classDef && classDef instanceof RuntimeClass) {
|
|
102
|
+
const inheritedFields = this.getClassFields(classDef);
|
|
103
|
+
for (const [k, v] of inheritedFields.entries()) {
|
|
104
|
+
if (!fields.has(k))
|
|
105
|
+
fields.set(k, v);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return fields;
|
|
110
|
+
}
|
|
111
|
+
collectAllInitializers(node, collector) {
|
|
112
|
+
const initializers = new Map();
|
|
113
|
+
const extendsSymbol = node.extendsSymbol?.value;
|
|
114
|
+
// 1. Heredados de la Clase Madre
|
|
115
|
+
if (extendsSymbol) {
|
|
116
|
+
const classDef = this.ctx.lookup(extendsSymbol);
|
|
117
|
+
if (classDef && classDef instanceof RuntimeClass) {
|
|
118
|
+
for (const [k, expr] of this.getClassInitializers(classDef).entries()) {
|
|
119
|
+
initializers.set(k, expr);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// 2. Definiciones locales del propio Objeto
|
|
124
|
+
for (const [k, expr] of collector.fieldInitializers.entries()) {
|
|
125
|
+
initializers.set(k, expr);
|
|
126
|
+
}
|
|
127
|
+
// 3. Argumentos nombrados por constructor inline
|
|
128
|
+
const extendsArgs = node.extendsArgs || [];
|
|
129
|
+
for (const arg of extendsArgs) {
|
|
130
|
+
if (arg instanceof NamedArgument ||
|
|
131
|
+
arg.constructor.name === "NamedArgument") {
|
|
132
|
+
initializers.set(arg.identifier.value, arg.expression);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return initializers;
|
|
84
136
|
}
|
|
85
137
|
visitFact(node) {
|
|
86
138
|
const identifier = node.identifier.value;
|
|
87
139
|
if (this.ctx.config.debug)
|
|
88
140
|
console.log(`[EnvBuilder] Defining fact: ${identifier}`);
|
|
89
|
-
|
|
141
|
+
if (this.ctx.isDefined(identifier)) {
|
|
90
142
|
const runtimeValue = this.ctx.lookup(identifier);
|
|
91
143
|
if (!isRuntimePredicate(runtimeValue))
|
|
92
|
-
throw new
|
|
93
|
-
runtimeValue.
|
|
144
|
+
throw new NotValidPredicate(identifier);
|
|
145
|
+
runtimeValue.addClause(node);
|
|
94
146
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
identifier,
|
|
99
|
-
equations: [node],
|
|
100
|
-
});
|
|
147
|
+
else {
|
|
148
|
+
const predicate = new RuntimePredicate(identifier, [node]);
|
|
149
|
+
this.ctx.defineGlobal(identifier, predicate);
|
|
101
150
|
}
|
|
102
151
|
}
|
|
103
152
|
visitRule(node) {
|
|
104
153
|
const identifier = node.identifier.value;
|
|
105
154
|
if (this.ctx.config.debug)
|
|
106
155
|
console.log(`[EnvBuilder] Defining rule: ${identifier}`);
|
|
107
|
-
|
|
156
|
+
if (this.ctx.isDefined(identifier)) {
|
|
108
157
|
const runtimeValue = this.ctx.lookup(identifier);
|
|
109
158
|
if (!isRuntimePredicate(runtimeValue))
|
|
110
|
-
throw new
|
|
111
|
-
runtimeValue.
|
|
159
|
+
throw new NotValidPredicate(identifier);
|
|
160
|
+
runtimeValue.addClause(node);
|
|
112
161
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
identifier,
|
|
117
|
-
equations: [node],
|
|
118
|
-
});
|
|
162
|
+
else {
|
|
163
|
+
const predicate = new RuntimePredicate(identifier, [node]);
|
|
164
|
+
this.ctx.defineGlobal(identifier, predicate);
|
|
119
165
|
}
|
|
120
166
|
}
|
|
167
|
+
getClassFields(classDef) {
|
|
168
|
+
const fields = new Map();
|
|
169
|
+
const collect = (c) => {
|
|
170
|
+
if (c.superclass) {
|
|
171
|
+
const superDef = this.ctx.lookup(c.superclass);
|
|
172
|
+
if (superDef && superDef instanceof RuntimeClass) {
|
|
173
|
+
collect(superDef);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
for (const mixin of c.mixins) {
|
|
177
|
+
const mixinDef = this.ctx.lookup(mixin);
|
|
178
|
+
if (mixinDef && mixinDef instanceof RuntimeClass) {
|
|
179
|
+
collect(mixinDef);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
for (const [k, v] of c.fields.entries()) {
|
|
183
|
+
fields.set(k, v);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
collect(classDef);
|
|
187
|
+
return fields;
|
|
188
|
+
}
|
|
189
|
+
getClassInitializers(classDef) {
|
|
190
|
+
const initializers = new Map();
|
|
191
|
+
const collect = (c) => {
|
|
192
|
+
if (c.superclass) {
|
|
193
|
+
const superDef = this.ctx.lookup(c.superclass);
|
|
194
|
+
if (superDef && superDef instanceof RuntimeClass) {
|
|
195
|
+
collect(superDef);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
for (const mixin of c.mixins) {
|
|
199
|
+
const mixinDef = this.ctx.lookup(mixin);
|
|
200
|
+
if (mixinDef && mixinDef instanceof RuntimeClass) {
|
|
201
|
+
collect(mixinDef);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const cInitializers = c.fieldInitializers;
|
|
205
|
+
if (cInitializers) {
|
|
206
|
+
for (const [k, v] of cInitializers.entries()) {
|
|
207
|
+
initializers.set(k, v);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
collect(classDef);
|
|
212
|
+
return initializers;
|
|
213
|
+
}
|
|
121
214
|
visitVariable(node) {
|
|
122
215
|
const identifier = node.identifier.value;
|
|
123
216
|
if (this.ctx.config.debug)
|
|
124
217
|
console.log(`[EnvBuilder] Defining variable: ${identifier}`);
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
this.ctx.
|
|
218
|
+
const visitor = new InterpreterVisitor(this.ctx);
|
|
219
|
+
const kernel = new YukigoKernel(visitor);
|
|
220
|
+
this.ctx.defineGlobal(identifier, kernel.run(new EvalCommand(node.expression)));
|
|
128
221
|
}
|
|
129
222
|
visit(node) {
|
|
130
223
|
return node.accept(this);
|
|
131
224
|
}
|
|
225
|
+
fallback(node) {
|
|
226
|
+
throw new UnexpectedNode(node.constructor.name, "EnvBuilderVisitor");
|
|
227
|
+
}
|
|
132
228
|
}
|
|
133
|
-
class
|
|
229
|
+
class DeferredInitialization {
|
|
230
|
+
runtimeObject;
|
|
231
|
+
initializers;
|
|
232
|
+
constructor(runtimeObject, initializers) {
|
|
233
|
+
this.runtimeObject = runtimeObject;
|
|
234
|
+
this.initializers = initializers;
|
|
235
|
+
}
|
|
236
|
+
execute(ctx) {
|
|
237
|
+
for (const [fieldName, expression] of this.initializers.entries()) {
|
|
238
|
+
this.initializeField(fieldName, expression, ctx);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
initializeField(fieldName, expr, ctx) {
|
|
242
|
+
try {
|
|
243
|
+
const rawResult = InterpreterVisitor.evaluateLiteral(expr, ctx);
|
|
244
|
+
const evaluatedValue = this.resolveExecutionValue(rawResult, ctx);
|
|
245
|
+
this.runtimeObject.setField(fieldName, evaluatedValue);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
this.logWarning(fieldName, error, ctx);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
resolveExecutionValue(rawResult, ctx) {
|
|
252
|
+
// Si el resultado requiere ejecución diferida en el Kernel de Yukigo, lo resolvemos de forma atómica
|
|
253
|
+
if (rawResult && typeof rawResult.execute === "function") {
|
|
254
|
+
const visitor = new InterpreterVisitor(ctx);
|
|
255
|
+
const uniqueKernel = new YukigoKernel(visitor, "first");
|
|
256
|
+
return uniqueKernel.run(rawResult);
|
|
257
|
+
}
|
|
258
|
+
return rawResult;
|
|
259
|
+
}
|
|
260
|
+
logWarning(fieldName, error, ctx) {
|
|
261
|
+
if (ctx.config.debug) {
|
|
262
|
+
console.log(`[EnvBuilder] [Warning Tardío] No se pudo evaluar el atributo ${fieldName} en '${this.runtimeObject.identifier}':`, error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
export class OOPCollector extends TraverseVisitor {
|
|
267
|
+
ctx;
|
|
134
268
|
collectedMethods = new Map();
|
|
135
269
|
collectedFields = new Map();
|
|
270
|
+
fieldInitializers = new Map();
|
|
271
|
+
constructor(ctx) {
|
|
272
|
+
super();
|
|
273
|
+
this.ctx = ctx;
|
|
274
|
+
}
|
|
136
275
|
visitMethod(node) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
};
|
|
143
|
-
this.collectedMethods.set(node.identifier.value, runtimeMethod);
|
|
276
|
+
const name = node.identifier.value;
|
|
277
|
+
const arity = node.equations[0].patterns.length;
|
|
278
|
+
const key = `${name}/${arity}`;
|
|
279
|
+
const runtimeMethod = new RuntimeFunction(arity, [...node.equations], name);
|
|
280
|
+
this.collectedMethods.set(key, runtimeMethod);
|
|
144
281
|
}
|
|
145
282
|
visitAttribute(node) {
|
|
146
|
-
|
|
283
|
+
const fieldName = node.identifier.value;
|
|
284
|
+
// Registramos la expresión diferida
|
|
285
|
+
this.fieldInitializers.set(fieldName, node.expression);
|
|
286
|
+
// Inicializamos transitoriamente el campo con YuNil para reservar su espacio en la firma
|
|
287
|
+
const initialPlaceholder = global.YuNil?.getInstance() || null;
|
|
288
|
+
this.collectedFields.set(fieldName, initialPlaceholder);
|
|
289
|
+
}
|
|
290
|
+
fallback(node) {
|
|
291
|
+
throw new UnexpectedNode(node.constructor.name, "OOPCollector");
|
|
147
292
|
}
|
|
148
293
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { YuValue } from "../primitives/YuValue.js";
|
|
2
|
+
import { ExecutionCommand } from "./kernel/commands.js";
|
|
3
|
+
import { RuntimeContext } from "./RuntimeContext.js";
|
|
4
|
+
/**
|
|
5
|
+
* Utility to perform deep equality checks between YuValues,
|
|
6
|
+
* including lazy sequences, using polymorphic capabilities.
|
|
7
|
+
*/
|
|
8
|
+
export declare class EqualityComparer {
|
|
9
|
+
/**
|
|
10
|
+
* Performs a deep equality check between two values.
|
|
11
|
+
* If both are sequences, they are compared element by element lazily.
|
|
12
|
+
*/
|
|
13
|
+
static compare(a: YuValue, b: YuValue, ctx?: RuntimeContext): ExecutionCommand;
|
|
14
|
+
private static compareSequences;
|
|
15
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { boolean, isTrue } from "../utils.js";
|
|
2
|
+
import { BindCommand, } from "./kernel/commands.js";
|
|
3
|
+
import { RuntimeFunction } from "../primitives/entities/RuntimeFunction.js";
|
|
4
|
+
/**
|
|
5
|
+
* Utility to perform deep equality checks between YuValues,
|
|
6
|
+
* including lazy sequences, using polymorphic capabilities.
|
|
7
|
+
*/
|
|
8
|
+
export class EqualityComparer {
|
|
9
|
+
/**
|
|
10
|
+
* Performs a deep equality check between two values.
|
|
11
|
+
* If both are sequences, they are compared element by element lazily.
|
|
12
|
+
*/
|
|
13
|
+
static compare(a, b, ctx) {
|
|
14
|
+
if (ctx &&
|
|
15
|
+
a instanceof RuntimeFunction &&
|
|
16
|
+
a.arity === 0 &&
|
|
17
|
+
(a.pendingArgs?.length ?? 0) === 0) {
|
|
18
|
+
return new BindCommand(ctx.forceValue(a), (forcedA) => this.compare(forcedA, b, ctx));
|
|
19
|
+
}
|
|
20
|
+
if (ctx &&
|
|
21
|
+
b instanceof RuntimeFunction &&
|
|
22
|
+
b.arity === 0 &&
|
|
23
|
+
(b.pendingArgs?.length ?? 0) === 0) {
|
|
24
|
+
return new BindCommand(ctx.forceValue(b), (forcedB) => this.compare(a, forcedB, ctx));
|
|
25
|
+
}
|
|
26
|
+
const seqA = a.asSequence;
|
|
27
|
+
const seqB = b.asSequence;
|
|
28
|
+
if (seqA && seqB) {
|
|
29
|
+
return this.compareSequences(seqA, seqB, ctx);
|
|
30
|
+
}
|
|
31
|
+
const compA = a.asComparable;
|
|
32
|
+
if (compA)
|
|
33
|
+
return compA.equals(b);
|
|
34
|
+
return boolean(a === b);
|
|
35
|
+
}
|
|
36
|
+
static compareSequences(sA, sB, ctx) {
|
|
37
|
+
if (!sA && !sB)
|
|
38
|
+
return boolean(true);
|
|
39
|
+
// If one is null, the other must be empty to be equal
|
|
40
|
+
if (!sA) {
|
|
41
|
+
return new BindCommand(sB.step(), (resB) => boolean(resB.isNil));
|
|
42
|
+
}
|
|
43
|
+
if (!sB) {
|
|
44
|
+
return new BindCommand(sA.step(), (resA) => boolean(resA.isNil));
|
|
45
|
+
}
|
|
46
|
+
return new BindCommand(sA.step(), (resA) => {
|
|
47
|
+
return new BindCommand(sB.step(), (resB) => {
|
|
48
|
+
// Use polymorphism (isNil) instead of instanceof YuNil
|
|
49
|
+
if (resA.isNil && resB.isNil)
|
|
50
|
+
return boolean(true);
|
|
51
|
+
if (resA.isNil || resB.isNil)
|
|
52
|
+
return boolean(false);
|
|
53
|
+
// Use polymorphism (asStepResult) instead of instanceof LazyStepResult
|
|
54
|
+
const stepResA = resA.asStepResult;
|
|
55
|
+
const stepResB = resB.asStepResult;
|
|
56
|
+
if (!stepResA || !stepResB)
|
|
57
|
+
return boolean(false);
|
|
58
|
+
// Compare heads recursively
|
|
59
|
+
return new BindCommand(this.compare(stepResA.head, stepResB.head, ctx), (headsEqual) => {
|
|
60
|
+
const areHeadsEqual = isTrue(headsEqual);
|
|
61
|
+
if (!areHeadsEqual)
|
|
62
|
+
return boolean(false);
|
|
63
|
+
// Compare tails
|
|
64
|
+
return this.compareSequences(stepResA.tail, stepResB.tail, ctx);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export type
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export declare const
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const
|
|
1
|
+
import { YuNumeric, YuComparable, YuLogic, YuSummable, YuSequence } from "../primitives/capabilities.js";
|
|
2
|
+
import { YuValue } from "../primitives/index.js";
|
|
3
|
+
import { ExecutionCommand } from "./kernel/commands.js";
|
|
4
|
+
export type UnaryOp<T extends YuValue> = (x: T) => ExecutionCommand;
|
|
5
|
+
export type BinaryOp<T1 extends YuValue, T2 = T1> = (x: T1, y: T2) => ExecutionCommand;
|
|
6
|
+
export type BinaryTable<T1 extends YuValue, T2 = T1> = Record<string, BinaryOp<T1, T2>>;
|
|
7
|
+
export type UnaryTable<T extends YuValue> = Record<string, UnaryOp<T>>;
|
|
8
|
+
export declare const ArithmeticBinaryTable: BinaryTable<YuNumeric>;
|
|
9
|
+
export declare const ComparisonOperationTable: BinaryTable<YuComparable>;
|
|
10
|
+
export declare const LogicalBinaryTable: BinaryTable<YuLogic, () => ExecutionCommand>;
|
|
11
|
+
export declare const StringOperationTable: BinaryTable<YuSummable>;
|
|
12
|
+
export declare const BitwiseBinaryTable: BinaryTable<YuNumeric>;
|
|
13
|
+
export declare const BitwiseUnaryTable: UnaryTable<YuNumeric>;
|
|
14
|
+
export declare const LogicalUnaryTable: UnaryTable<YuLogic>;
|
|
15
|
+
export declare const ListBinaryTable: BinaryTable<YuSequence>;
|
|
16
|
+
export declare const ListUnaryTable: UnaryTable<YuSequence>;
|
|
17
|
+
export declare const ArithmeticUnaryTable: UnaryTable<YuNumeric>;
|
|
@@ -1,84 +1,83 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { InterpreterError } from "../errors.js";
|
|
2
|
+
import { YuNumber, YuArray, YuString } from "../primitives/index.js";
|
|
3
|
+
import { compareResult, not, number } from "../utils.js";
|
|
4
|
+
import { RaiseCommand, StepCommand, } from "./kernel/commands.js";
|
|
2
5
|
export const ArithmeticBinaryTable = {
|
|
3
|
-
Plus: (a, b) => a
|
|
4
|
-
Minus: (a, b) => a
|
|
5
|
-
Multiply: (a, b) => a
|
|
6
|
-
Divide: (a, b) => a
|
|
7
|
-
Modulo: (a, b) => a
|
|
8
|
-
Power: (a, b) => a
|
|
9
|
-
Min: (a, b) =>
|
|
10
|
-
Max: (a, b) =>
|
|
6
|
+
Plus: (a, b) => a.plus(b),
|
|
7
|
+
Minus: (a, b) => a.minus(b),
|
|
8
|
+
Multiply: (a, b) => a.multiply(b),
|
|
9
|
+
Divide: (a, b) => a.divide(b),
|
|
10
|
+
Modulo: (a, b) => a.modulo(b),
|
|
11
|
+
Power: (a, b) => a.power(b),
|
|
12
|
+
Min: (a, b) => a.min(b),
|
|
13
|
+
Max: (a, b) => a.max(b),
|
|
11
14
|
};
|
|
12
15
|
export const ComparisonOperationTable = {
|
|
13
|
-
Equal: (a, b) => a
|
|
14
|
-
NotEqual: (a, b) => a
|
|
15
|
-
Same: (a, b) => a
|
|
16
|
-
NotSame: (a, b) => a
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
LessOrEqualThan: (a, b) => a <= b,
|
|
22
|
-
LessThan: (a, b) => a < b,
|
|
16
|
+
Equal: (a, b) => a.equals(b),
|
|
17
|
+
NotEqual: (a, b) => not(a.equals(b)),
|
|
18
|
+
Same: (a, b) => a.isSame(b),
|
|
19
|
+
NotSame: (a, b) => not(a.isSame(b)),
|
|
20
|
+
GreaterOrEqualThan: (a, b) => compareResult(a.compare(b), (res) => res >= 0),
|
|
21
|
+
GreaterThan: (a, b) => compareResult(a.compare(b), (res) => res > 0),
|
|
22
|
+
LessOrEqualThan: (a, b) => compareResult(a.compare(b), (res) => res <= 0),
|
|
23
|
+
LessThan: (a, b) => compareResult(a.compare(b), (res) => res < 0),
|
|
23
24
|
};
|
|
24
25
|
export const LogicalBinaryTable = {
|
|
25
|
-
And: (left, rightThunk) => left
|
|
26
|
-
Or: (left, rightThunk) => left
|
|
27
|
-
};
|
|
28
|
-
export const BitwiseBinaryTable = {
|
|
29
|
-
BitwiseOr: (a, b) => a | b,
|
|
30
|
-
BitwiseAnd: (a, b) => a & b,
|
|
31
|
-
BitwiseLeftShift: (a, b) => a << b,
|
|
32
|
-
BitwiseRightShift: (a, b) => a >> b,
|
|
33
|
-
BitwiseUnsignedRightShift: (a, b) => a >>> b,
|
|
34
|
-
BitwiseXor: (a, b) => a ^ b,
|
|
26
|
+
And: (left, rightThunk) => left.value ? rightThunk() : new StepCommand(left),
|
|
27
|
+
Or: (left, rightThunk) => left.value ? new StepCommand(left) : rightThunk(),
|
|
35
28
|
};
|
|
36
29
|
export const StringOperationTable = {
|
|
37
|
-
Concat: (a, b) =>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
Concat: (a, b) => a.plus(b),
|
|
31
|
+
};
|
|
32
|
+
export const BitwiseBinaryTable = {
|
|
33
|
+
BitwiseOr: (a, b) => new StepCommand(new YuNumber(a.value | b.value)),
|
|
34
|
+
BitwiseAnd: (a, b) => new StepCommand(new YuNumber(a.value & b.value)),
|
|
35
|
+
BitwiseLeftShift: (a, b) => new StepCommand(new YuNumber(a.value << b.value)),
|
|
36
|
+
BitwiseRightShift: (a, b) => new StepCommand(new YuNumber(a.value >> b.value)),
|
|
37
|
+
BitwiseUnsignedRightShift: (a, b) => new StepCommand(new YuNumber(a.value >>> b.value)),
|
|
38
|
+
BitwiseXor: (a, b) => new StepCommand(new YuNumber(a.value ^ b.value)),
|
|
44
39
|
};
|
|
45
40
|
export const BitwiseUnaryTable = {
|
|
46
|
-
BitwiseNot: (a) => ~a,
|
|
41
|
+
BitwiseNot: (a) => number(~a.value),
|
|
47
42
|
};
|
|
48
43
|
export const LogicalUnaryTable = {
|
|
49
|
-
Negation: (a) =>
|
|
44
|
+
Negation: (a) => a.not(),
|
|
50
45
|
};
|
|
51
46
|
export const ListBinaryTable = {
|
|
52
|
-
Concat: (a, b) =>
|
|
53
|
-
const res = a.concat(b);
|
|
54
|
-
if (typeof a === "string" && typeof b === "string") {
|
|
55
|
-
const hasNonString = res.some((c) => typeof c !== "string");
|
|
56
|
-
if (!hasNonString)
|
|
57
|
-
return res.join("");
|
|
58
|
-
}
|
|
59
|
-
return res;
|
|
60
|
-
},
|
|
47
|
+
Concat: (a, b) => a.concat(b),
|
|
61
48
|
};
|
|
62
49
|
export const ListUnaryTable = {
|
|
63
|
-
Size: (a) => a.
|
|
50
|
+
Size: (a) => a.size(),
|
|
64
51
|
DetectMax: (a) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
52
|
+
const items = [...a].map((i) => {
|
|
53
|
+
const n = i.toJSON();
|
|
54
|
+
return n;
|
|
55
|
+
});
|
|
56
|
+
if (items.some((n) => typeof n !== "number"))
|
|
57
|
+
return new RaiseCommand(new InterpreterError("DetectMax", "elements must be numbers")); // TODO: make it work with chars, etc.
|
|
58
|
+
return number(Math.max(...items));
|
|
68
59
|
},
|
|
69
60
|
DetectMin: (a) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
const items = [...a].map((i) => {
|
|
62
|
+
const n = i.toJSON();
|
|
63
|
+
return n;
|
|
64
|
+
});
|
|
65
|
+
if (items.some((n) => typeof n !== "number"))
|
|
66
|
+
return new RaiseCommand(new InterpreterError("DetectMin", "elements must be numbers")); // TODO: make it work with chars, etc.
|
|
67
|
+
return number(Math.min(...items));
|
|
68
|
+
},
|
|
69
|
+
Flatten: (a) => {
|
|
70
|
+
if (!(a instanceof YuArray))
|
|
71
|
+
return new RaiseCommand(new InterpreterError("[Flat operator]", "Operand must be a YuArray"));
|
|
72
|
+
return new StepCommand(a.flat());
|
|
73
73
|
},
|
|
74
|
-
Flatten: (a) => a.flat(),
|
|
75
74
|
};
|
|
76
75
|
export const ArithmeticUnaryTable = {
|
|
77
|
-
Round: (a) =>
|
|
78
|
-
Absolute: (a) =>
|
|
79
|
-
Ceil: (a) =>
|
|
80
|
-
Floor: (a) =>
|
|
81
|
-
Negation: (a) => a
|
|
82
|
-
Sqrt: (a) =>
|
|
83
|
-
ToString: (a) => String(a),
|
|
76
|
+
Round: (a) => a.round(),
|
|
77
|
+
Absolute: (a) => a.abs(),
|
|
78
|
+
Ceil: (a) => a.ceil(),
|
|
79
|
+
Floor: (a) => a.floor(),
|
|
80
|
+
Negation: (a) => a.negation(),
|
|
81
|
+
Sqrt: (a) => a.sqrt(),
|
|
82
|
+
ToString: (a) => new StepCommand(new YuString(String(a.toJSON()))),
|
|
84
83
|
};
|