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