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.
- package/.mocharc.json +3 -3
- package/CHANGELOG.md +105 -40
- 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 +22 -14
- package/dist/analyzer/inspections/generic/generic.js +82 -60
- 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 +13 -5
- package/dist/utils/helpers.js +38 -85
- 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 -577
- 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 +113 -169
- 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 +156 -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
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Application,
|
|
3
|
+
Call,
|
|
4
|
+
CompositionExpression,
|
|
5
|
+
ConsExpression,
|
|
6
|
+
DataExpression,
|
|
7
|
+
Exist,
|
|
8
|
+
ExpressionVisitor,
|
|
9
|
+
FieldExpression,
|
|
10
|
+
Findall,
|
|
11
|
+
Forall,
|
|
12
|
+
Goal,
|
|
13
|
+
GuardedExpression,
|
|
14
|
+
Lambda,
|
|
15
|
+
LetInExpression,
|
|
16
|
+
ListComprehension,
|
|
17
|
+
NamedArgument,
|
|
18
|
+
New,
|
|
19
|
+
Not,
|
|
20
|
+
Generator as YuGenerator,
|
|
21
|
+
Otherwise,
|
|
22
|
+
RangeExpression,
|
|
23
|
+
Send,
|
|
24
|
+
SymbolPrimitive,
|
|
25
|
+
TupleExpression,
|
|
26
|
+
Expression,
|
|
27
|
+
Return,
|
|
28
|
+
Sequence,
|
|
29
|
+
Super,
|
|
30
|
+
UnguardedBody,
|
|
31
|
+
VariablePattern,
|
|
32
|
+
TypeCast,
|
|
33
|
+
} from "yukigo-ast";
|
|
34
|
+
import {
|
|
35
|
+
BindCommand,
|
|
36
|
+
ExecutionCommand,
|
|
37
|
+
FailCommand,
|
|
38
|
+
RaiseCommand,
|
|
39
|
+
StepCommand,
|
|
40
|
+
} from "../kernel/commands.js";
|
|
41
|
+
import { Constructor, EvaluatorBase } from "./BaseEvaluator.js";
|
|
42
|
+
import { InterpreterError } from "../../errors.js";
|
|
43
|
+
import {
|
|
44
|
+
YuArray,
|
|
45
|
+
YuValue,
|
|
46
|
+
EquationRuntime,
|
|
47
|
+
RuntimeClass,
|
|
48
|
+
RuntimeFunction,
|
|
49
|
+
} from "../../primitives/index.js";
|
|
50
|
+
import { boolean, EnvStack, error, isTrue, raise } from "../../utils.js";
|
|
51
|
+
import { EnvBuilderVisitor } from "../EnvBuilder.js";
|
|
52
|
+
import {
|
|
53
|
+
getClassFields,
|
|
54
|
+
getClassInitializers,
|
|
55
|
+
getLogicEngine,
|
|
56
|
+
} from "./utils.js";
|
|
57
|
+
|
|
58
|
+
export function ExpressionEvaluator<TBase extends Constructor<EvaluatorBase>>(
|
|
59
|
+
Base: TBase,
|
|
60
|
+
) {
|
|
61
|
+
return class
|
|
62
|
+
extends Base
|
|
63
|
+
implements Partial<ExpressionVisitor<ExecutionCommand>>
|
|
64
|
+
{
|
|
65
|
+
visitTupleExpr(node: TupleExpression): ExecutionCommand {
|
|
66
|
+
const results: YuValue[] = [];
|
|
67
|
+
const evaluateNext = (index: number): ExecutionCommand => {
|
|
68
|
+
if (index >= node.elements.length)
|
|
69
|
+
return new StepCommand(new YuArray(results));
|
|
70
|
+
return new BindCommand(this.evaluate(node.elements[index]), (val) => {
|
|
71
|
+
results.push(val);
|
|
72
|
+
return evaluateNext(index + 1);
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
return evaluateNext(0);
|
|
76
|
+
}
|
|
77
|
+
visitFieldExpression(node: FieldExpression): ExecutionCommand {
|
|
78
|
+
return new BindCommand(this.evaluate(node.name), (obj) => {
|
|
79
|
+
return new StepCommand(
|
|
80
|
+
this.context.objRuntime.getField(obj, node.name.value),
|
|
81
|
+
);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
visitDataExpr(node: DataExpression): ExecutionCommand {
|
|
85
|
+
const fieldValues = new Map<string, YuValue>();
|
|
86
|
+
|
|
87
|
+
const evaluateFields = (index: number): ExecutionCommand => {
|
|
88
|
+
if (index >= node.contents.length) {
|
|
89
|
+
const identifier = node.name.value;
|
|
90
|
+
const classDef = new RuntimeClass(
|
|
91
|
+
identifier,
|
|
92
|
+
fieldValues,
|
|
93
|
+
new Map(),
|
|
94
|
+
[],
|
|
95
|
+
);
|
|
96
|
+
return new StepCommand(classDef.instantiate(identifier));
|
|
97
|
+
}
|
|
98
|
+
const field = node.contents[index];
|
|
99
|
+
return new BindCommand(this.evaluate(field.expression), (value) => {
|
|
100
|
+
fieldValues.set(field.name.value, value);
|
|
101
|
+
return evaluateFields(index + 1);
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return evaluateFields(0);
|
|
106
|
+
}
|
|
107
|
+
visitConsExpr(node: ConsExpression): ExecutionCommand {
|
|
108
|
+
return this.context.lazyRuntime.evaluateCons(node, this);
|
|
109
|
+
}
|
|
110
|
+
visitLetInExpr(node: LetInExpression): ExecutionCommand {
|
|
111
|
+
const oldEnv = this.context.env;
|
|
112
|
+
this.context.pushEnv();
|
|
113
|
+
const envBuilder = new EnvBuilderVisitor(this.context);
|
|
114
|
+
node.declarations.accept(envBuilder);
|
|
115
|
+
return new BindCommand(this.evaluate(node.expression), (result) => {
|
|
116
|
+
this.context.env = oldEnv;
|
|
117
|
+
return new StepCommand(result);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
visitCall(node: Call): ExecutionCommand {
|
|
121
|
+
return new BindCommand(this.evaluate(node.callee), (callee) => {
|
|
122
|
+
const args: YuValue[] = [];
|
|
123
|
+
const evaluateArgs = (index: number): ExecutionCommand => {
|
|
124
|
+
if (index < node.args.length)
|
|
125
|
+
return new BindCommand(this.evaluate(node.args[index]), (val) => {
|
|
126
|
+
args.push(val);
|
|
127
|
+
return evaluateArgs(index + 1);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
if (!(callee instanceof RuntimeFunction))
|
|
131
|
+
return new FailCommand(
|
|
132
|
+
new InterpreterError("Call", "Target is not a function"),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
return this.context.funcRuntime.apply(callee, args);
|
|
136
|
+
};
|
|
137
|
+
return evaluateArgs(0);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
visitOtherwise(node: Otherwise): ExecutionCommand {
|
|
141
|
+
return boolean(true);
|
|
142
|
+
}
|
|
143
|
+
visitCompositionExpression(node: CompositionExpression): ExecutionCommand {
|
|
144
|
+
return new BindCommand(this.evaluate(node.left), (f) => {
|
|
145
|
+
return new BindCommand(this.evaluate(node.right), (g) => {
|
|
146
|
+
if (
|
|
147
|
+
!(f instanceof RuntimeFunction) ||
|
|
148
|
+
!(g instanceof RuntimeFunction)
|
|
149
|
+
) {
|
|
150
|
+
return new FailCommand(
|
|
151
|
+
new InterpreterError(
|
|
152
|
+
"Composition",
|
|
153
|
+
"Both operands of (.) must be functions",
|
|
154
|
+
),
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const F_REF = "__internal_f";
|
|
159
|
+
const G_REF = "__internal_g";
|
|
160
|
+
const PARAM_NAME = "__x";
|
|
161
|
+
|
|
162
|
+
const compositionBody = new Application(
|
|
163
|
+
new SymbolPrimitive(F_REF),
|
|
164
|
+
new Application(
|
|
165
|
+
new SymbolPrimitive(G_REF),
|
|
166
|
+
new SymbolPrimitive(PARAM_NAME),
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const patterns = [
|
|
171
|
+
new VariablePattern(new SymbolPrimitive(PARAM_NAME)),
|
|
172
|
+
];
|
|
173
|
+
const equation: EquationRuntime = {
|
|
174
|
+
patterns,
|
|
175
|
+
body: new UnguardedBody(
|
|
176
|
+
new Sequence([new Return(compositionBody)]),
|
|
177
|
+
),
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const privateScope = new Map<string, YuValue>();
|
|
181
|
+
privateScope.set(F_REF, f);
|
|
182
|
+
privateScope.set(G_REF, g);
|
|
183
|
+
|
|
184
|
+
const capturedEnv: EnvStack = {
|
|
185
|
+
head: privateScope,
|
|
186
|
+
tail: this.context.env,
|
|
187
|
+
};
|
|
188
|
+
const func = new RuntimeFunction(
|
|
189
|
+
1,
|
|
190
|
+
[equation],
|
|
191
|
+
`<(${f.identifier} . ${g.identifier})>`,
|
|
192
|
+
[],
|
|
193
|
+
capturedEnv,
|
|
194
|
+
);
|
|
195
|
+
return new StepCommand(func);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
visitLambda(node: Lambda): ExecutionCommand {
|
|
201
|
+
const patterns = node.parameters;
|
|
202
|
+
const equation: EquationRuntime = {
|
|
203
|
+
patterns,
|
|
204
|
+
body: new UnguardedBody(new Sequence([new Return(node.body)])),
|
|
205
|
+
};
|
|
206
|
+
const func = new RuntimeFunction(
|
|
207
|
+
patterns.length,
|
|
208
|
+
[equation],
|
|
209
|
+
"<lambda>",
|
|
210
|
+
[],
|
|
211
|
+
this.context.env,
|
|
212
|
+
);
|
|
213
|
+
return new StepCommand(func);
|
|
214
|
+
}
|
|
215
|
+
public visitGuardedExpression(expr: GuardedExpression): ExecutionCommand {
|
|
216
|
+
const tryNextGuard = (guardIndex: number): ExecutionCommand => {
|
|
217
|
+
if (guardIndex >= expr.guards.length) {
|
|
218
|
+
return new RaiseCommand(
|
|
219
|
+
new InterpreterError(
|
|
220
|
+
"PatternMatch",
|
|
221
|
+
"Non-exhaustive guards in equation: the pattern matched but no guard succeeded.",
|
|
222
|
+
),
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const guard = expr.guards[guardIndex];
|
|
227
|
+
return new BindCommand(this.evaluate(guard.condition), (cond) => {
|
|
228
|
+
if (!isTrue(cond)) return tryNextGuard(guardIndex + 1);
|
|
229
|
+
return this.evaluate(guard.body);
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
return tryNextGuard(0);
|
|
234
|
+
}
|
|
235
|
+
visitApplication(node: Application): ExecutionCommand {
|
|
236
|
+
const { funcRuntime } = this.context;
|
|
237
|
+
return new BindCommand(this.evaluate(node.functionExpr), (func) => {
|
|
238
|
+
if (!(func instanceof RuntimeFunction)) {
|
|
239
|
+
return new FailCommand(
|
|
240
|
+
new InterpreterError("Application", "Cannot apply non-function"),
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const applyFuncToNode = (func: RuntimeFunction): ExecutionCommand =>
|
|
245
|
+
new BindCommand(this.evaluate(node.parameter), (arg) => {
|
|
246
|
+
return funcRuntime.applyArguments(func, [() => arg]);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
if (func.arity === 0) {
|
|
250
|
+
return new BindCommand(
|
|
251
|
+
funcRuntime.applyArguments(func),
|
|
252
|
+
(resultOfFunc) => {
|
|
253
|
+
if (!(resultOfFunc instanceof RuntimeFunction))
|
|
254
|
+
return new FailCommand(
|
|
255
|
+
new InterpreterError(
|
|
256
|
+
"Application",
|
|
257
|
+
"Cannot apply non-function result of arity-0 function",
|
|
258
|
+
),
|
|
259
|
+
);
|
|
260
|
+
return applyFuncToNode(resultOfFunc);
|
|
261
|
+
},
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return applyFuncToNode(func);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
visitExist(node: Exist): ExecutionCommand {
|
|
269
|
+
return getLogicEngine(this, this.context).solveGoalLike(node);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
visitNot(node: Not): ExecutionCommand {
|
|
273
|
+
return getLogicEngine(this, this.context).solveNot(node);
|
|
274
|
+
}
|
|
275
|
+
visitFindall(node: Findall): ExecutionCommand {
|
|
276
|
+
return getLogicEngine(this, this.context).solveFindall(node);
|
|
277
|
+
}
|
|
278
|
+
visitForall(node: Forall): ExecutionCommand {
|
|
279
|
+
return getLogicEngine(this, this.context).solveForall(node);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
visitGoal(node: Goal): ExecutionCommand {
|
|
283
|
+
return getLogicEngine(this, this.context).solveGoalLike(node);
|
|
284
|
+
}
|
|
285
|
+
visitSend(node: Send): ExecutionCommand {
|
|
286
|
+
if (node.receiver instanceof Super) {
|
|
287
|
+
const methodName = node.selector.value;
|
|
288
|
+
const args: YuValue[] = [];
|
|
289
|
+
const evaluateNextArg = (index: number): ExecutionCommand => {
|
|
290
|
+
if (index >= node.args.length) {
|
|
291
|
+
try {
|
|
292
|
+
return this.context.objRuntime.dispatchSuper(methodName, args);
|
|
293
|
+
} catch (error: any) {
|
|
294
|
+
if (error instanceof InterpreterError) {
|
|
295
|
+
const mappedErrors = this.context.dispatchHook(
|
|
296
|
+
"onInterpreterError",
|
|
297
|
+
error,
|
|
298
|
+
this.context,
|
|
299
|
+
);
|
|
300
|
+
const userException = mappedErrors.find(
|
|
301
|
+
(res: any) => res !== undefined && res !== null,
|
|
302
|
+
);
|
|
303
|
+
return new RaiseCommand((userException as any) || error);
|
|
304
|
+
}
|
|
305
|
+
return new RaiseCommand(
|
|
306
|
+
new InterpreterError("RuntimeError", String(error)),
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return new BindCommand(this.evaluate(node.args[index]), (val) => {
|
|
311
|
+
args.push(val);
|
|
312
|
+
return evaluateNextArg(index + 1);
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
return evaluateNextArg(0);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return new BindCommand(this.evaluate(node.receiver), (receiver) => {
|
|
319
|
+
const methodName = node.selector.value;
|
|
320
|
+
const args: YuValue[] = [];
|
|
321
|
+
const evaluateNextArg = (index: number): ExecutionCommand => {
|
|
322
|
+
if (index >= node.args.length) {
|
|
323
|
+
try {
|
|
324
|
+
return this.context.objRuntime.dispatch(
|
|
325
|
+
receiver,
|
|
326
|
+
methodName,
|
|
327
|
+
args,
|
|
328
|
+
);
|
|
329
|
+
} catch (error: any) {
|
|
330
|
+
if (error instanceof InterpreterError) {
|
|
331
|
+
const mappedErrors = this.context.dispatchHook(
|
|
332
|
+
"onInterpreterError",
|
|
333
|
+
error,
|
|
334
|
+
this.context,
|
|
335
|
+
);
|
|
336
|
+
const userException = mappedErrors.find(
|
|
337
|
+
(res) => res !== undefined && res !== null,
|
|
338
|
+
);
|
|
339
|
+
return new RaiseCommand((userException as any) || error);
|
|
340
|
+
}
|
|
341
|
+
return new RaiseCommand(
|
|
342
|
+
new InterpreterError("RuntimeError", String(error)),
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return new BindCommand(this.evaluate(node.args[index]), (val) => {
|
|
347
|
+
args.push(val);
|
|
348
|
+
return evaluateNextArg(index + 1);
|
|
349
|
+
});
|
|
350
|
+
};
|
|
351
|
+
return evaluateNextArg(0);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
visitNew(node: New): ExecutionCommand {
|
|
356
|
+
const className = node.identifier.value;
|
|
357
|
+
const classDef = this.context.lookup(className);
|
|
358
|
+
if (!(classDef instanceof RuntimeClass))
|
|
359
|
+
return new FailCommand(
|
|
360
|
+
new InterpreterError("New", `${className} is not a class.`),
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
const instance = classDef.instantiate(node.identifier.value);
|
|
364
|
+
instance.fields = getClassFields(classDef, this.context);
|
|
365
|
+
|
|
366
|
+
const evaluateArgs = (index: number): ExecutionCommand => {
|
|
367
|
+
if (index >= node.args.length) {
|
|
368
|
+
return new StepCommand(instance);
|
|
369
|
+
}
|
|
370
|
+
const arg = node.args[index];
|
|
371
|
+
if (
|
|
372
|
+
arg instanceof NamedArgument ||
|
|
373
|
+
arg.constructor.name === "NamedArgument"
|
|
374
|
+
) {
|
|
375
|
+
const fieldName = (arg as any).identifier.value;
|
|
376
|
+
return new BindCommand(
|
|
377
|
+
this.evaluate((arg as any).expression),
|
|
378
|
+
(val) => {
|
|
379
|
+
instance.setField(fieldName, val);
|
|
380
|
+
return evaluateArgs(index + 1);
|
|
381
|
+
},
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
return evaluateArgs(index + 1);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const initializers = getClassInitializers(classDef, this.context);
|
|
388
|
+
const initializerKeys = Array.from(initializers.keys());
|
|
389
|
+
|
|
390
|
+
const evaluateInitializers = (keyIndex: number): ExecutionCommand => {
|
|
391
|
+
if (keyIndex >= initializerKeys.length) {
|
|
392
|
+
return evaluateArgs(0);
|
|
393
|
+
}
|
|
394
|
+
const key = initializerKeys[keyIndex];
|
|
395
|
+
const expr = initializers.get(key);
|
|
396
|
+
return new BindCommand(this.evaluate(expr), (val) => {
|
|
397
|
+
instance.setField(key, val);
|
|
398
|
+
return evaluateInitializers(keyIndex + 1);
|
|
399
|
+
});
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
return evaluateInitializers(0);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
visitListComprehension(node: ListComprehension): ExecutionCommand {
|
|
406
|
+
const results: YuValue[] = [];
|
|
407
|
+
|
|
408
|
+
const process = (index: number): ExecutionCommand => {
|
|
409
|
+
if (index >= node.generators.length) {
|
|
410
|
+
return new BindCommand(this.evaluate(node.projection), (proj) => {
|
|
411
|
+
results.push(proj);
|
|
412
|
+
return new StepCommand(new YuArray(results));
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
const current = node.generators[index];
|
|
417
|
+
|
|
418
|
+
if (current instanceof YuGenerator) {
|
|
419
|
+
return new BindCommand(
|
|
420
|
+
this.evaluate(current.expression),
|
|
421
|
+
(exprResult) => {
|
|
422
|
+
return new BindCommand(
|
|
423
|
+
this.context.lazyRuntime.realizeList(exprResult),
|
|
424
|
+
(sourceListVal) => {
|
|
425
|
+
const sourceList = sourceListVal.asSequence;
|
|
426
|
+
if (!(sourceList instanceof YuArray))
|
|
427
|
+
return raise(
|
|
428
|
+
error(
|
|
429
|
+
"visitListComprehension",
|
|
430
|
+
`Error expected YuArray and got ${sourceListVal.getType()}`,
|
|
431
|
+
),
|
|
432
|
+
);
|
|
433
|
+
const iterateSource = (
|
|
434
|
+
sourceIndex: number,
|
|
435
|
+
): ExecutionCommand => {
|
|
436
|
+
if (sourceIndex >= sourceList.items.length)
|
|
437
|
+
return new StepCommand(new YuArray(results));
|
|
438
|
+
|
|
439
|
+
const item = sourceList.at(sourceIndex);
|
|
440
|
+
const varName = current.variable.value;
|
|
441
|
+
this.context.define(varName, item);
|
|
442
|
+
|
|
443
|
+
return process(index + 1);
|
|
444
|
+
};
|
|
445
|
+
return iterateSource(0);
|
|
446
|
+
},
|
|
447
|
+
);
|
|
448
|
+
},
|
|
449
|
+
);
|
|
450
|
+
} else {
|
|
451
|
+
return new BindCommand(
|
|
452
|
+
this.evaluate(current as Expression),
|
|
453
|
+
(condition) => {
|
|
454
|
+
return isTrue(condition)
|
|
455
|
+
? process(index + 1)
|
|
456
|
+
: new StepCommand(new YuArray(results));
|
|
457
|
+
},
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
this.context.pushEnv();
|
|
463
|
+
return process(0);
|
|
464
|
+
}
|
|
465
|
+
visitGenerator(node: YuGenerator): ExecutionCommand {
|
|
466
|
+
return this.evaluate(node.expression);
|
|
467
|
+
}
|
|
468
|
+
visitRangeExpression(node: RangeExpression): ExecutionCommand {
|
|
469
|
+
return this.context.lazyRuntime.evaluateRange(node, this);
|
|
470
|
+
}
|
|
471
|
+
visitTypeCast(node: TypeCast): ExecutionCommand {
|
|
472
|
+
return node.expression.accept(this);
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
}
|