yukigo 0.1.0 → 0.2.0
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 +26 -0
- package/README.md +193 -199
- package/dist/analyzer/GraphBuilder.d.ts +29 -0
- package/dist/analyzer/GraphBuilder.js +99 -0
- package/dist/analyzer/index.d.ts +11 -23
- package/dist/analyzer/index.js +100 -58
- package/dist/analyzer/inspections/functional/functional.d.ts +44 -0
- package/dist/analyzer/inspections/functional/functional.js +149 -0
- package/dist/analyzer/inspections/functional/smells.d.ts +16 -0
- package/dist/analyzer/inspections/functional/smells.js +98 -0
- package/dist/analyzer/inspections/{generic.d.ts → generic/generic.d.ts} +70 -43
- package/dist/analyzer/inspections/generic/generic.js +604 -0
- package/dist/analyzer/inspections/generic/smells.d.ts +61 -0
- package/dist/analyzer/inspections/generic/smells.js +349 -0
- package/dist/analyzer/inspections/imperative/imperative.d.ts +35 -0
- package/dist/analyzer/inspections/imperative/imperative.js +109 -0
- package/dist/analyzer/inspections/imperative/smells.d.ts +16 -0
- package/dist/analyzer/inspections/imperative/smells.js +58 -0
- package/dist/analyzer/inspections/logic/logic.d.ts +32 -0
- package/dist/analyzer/inspections/logic/logic.js +96 -0
- package/dist/analyzer/inspections/logic/smells.d.ts +15 -0
- package/dist/analyzer/inspections/logic/smells.js +60 -0
- package/dist/analyzer/inspections/object/object.d.ts +88 -0
- package/dist/analyzer/inspections/object/object.js +319 -0
- package/dist/analyzer/inspections/object/smells.d.ts +30 -0
- package/dist/analyzer/inspections/object/smells.js +135 -0
- package/dist/analyzer/utils.d.ts +26 -4
- package/dist/analyzer/utils.js +71 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/components/EnvBuilder.d.ts +9 -5
- package/dist/interpreter/components/EnvBuilder.js +100 -30
- package/dist/interpreter/components/Operations.d.ts +4 -4
- package/dist/interpreter/components/Operations.js +17 -2
- package/dist/interpreter/components/PatternMatcher.d.ts +47 -17
- package/dist/interpreter/components/PatternMatcher.js +264 -119
- package/dist/interpreter/components/RuntimeContext.d.ts +35 -0
- package/dist/interpreter/components/RuntimeContext.js +93 -0
- package/dist/interpreter/components/TestRunner.d.ts +18 -0
- package/dist/interpreter/components/TestRunner.js +103 -0
- package/dist/interpreter/components/Visitor.d.ts +63 -57
- package/dist/interpreter/components/Visitor.js +508 -173
- package/dist/interpreter/components/logic/LogicEngine.d.ts +29 -0
- package/dist/interpreter/components/logic/LogicEngine.js +259 -0
- package/dist/interpreter/components/logic/LogicResolver.d.ts +53 -0
- package/dist/interpreter/components/logic/LogicResolver.js +471 -0
- package/dist/interpreter/components/logic/LogicTranslator.d.ts +14 -0
- package/dist/interpreter/components/logic/LogicTranslator.js +99 -0
- package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +12 -0
- package/dist/interpreter/components/runtimes/FunctionRuntime.js +147 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +19 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.js +269 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.js +126 -0
- package/dist/interpreter/entities.d.ts +105 -0
- package/dist/interpreter/entities.js +96 -0
- package/dist/interpreter/errors.d.ts +1 -1
- package/dist/interpreter/index.d.ts +4 -12
- package/dist/interpreter/index.js +10 -13
- package/dist/interpreter/trampoline.d.ts +17 -0
- package/dist/interpreter/trampoline.js +38 -0
- package/dist/interpreter/utils.d.ts +4 -7
- package/dist/interpreter/utils.js +25 -17
- package/dist/tester/index.d.ts +25 -0
- package/dist/tester/index.js +108 -0
- package/dist/utils/helpers.d.ts +0 -4
- package/dist/utils/helpers.js +20 -24
- package/package.json +2 -2
- package/src/analyzer/GraphBuilder.ts +142 -0
- package/src/analyzer/index.ts +185 -132
- package/src/analyzer/inspections/functional/functional.ts +121 -0
- package/src/analyzer/inspections/functional/smells.ts +102 -0
- package/src/analyzer/inspections/{generic.ts → generic/generic.ts} +581 -499
- package/src/analyzer/inspections/generic/smells.ts +365 -0
- package/src/analyzer/inspections/imperative/imperative.ts +101 -0
- package/src/analyzer/inspections/imperative/smells.ts +54 -0
- package/src/analyzer/inspections/logic/logic.ts +90 -0
- package/src/analyzer/inspections/logic/smells.ts +54 -0
- package/src/analyzer/inspections/{object.ts → object/object.ts} +264 -282
- package/src/analyzer/inspections/object/smells.ts +144 -0
- package/src/analyzer/utils.ts +109 -26
- package/src/index.ts +3 -2
- package/src/interpreter/components/EnvBuilder.ts +202 -97
- package/src/interpreter/components/Operations.ts +99 -81
- package/src/interpreter/components/PatternMatcher.ts +475 -254
- package/src/interpreter/components/RuntimeContext.ts +119 -0
- package/src/interpreter/components/TestRunner.ts +151 -0
- package/src/interpreter/components/Visitor.ts +1065 -493
- package/src/interpreter/components/logic/LogicEngine.ts +519 -0
- package/src/interpreter/components/logic/LogicResolver.ts +858 -0
- package/src/interpreter/components/logic/LogicTranslator.ts +149 -0
- package/src/interpreter/components/runtimes/FunctionRuntime.ts +227 -0
- package/src/interpreter/components/runtimes/LazyRuntime.ts +334 -0
- package/src/interpreter/components/runtimes/ObjectRuntime.ts +224 -0
- package/src/interpreter/errors.ts +47 -47
- package/src/interpreter/index.ts +52 -59
- package/src/interpreter/trampoline.ts +71 -0
- package/src/interpreter/utils.ts +84 -79
- package/src/tester/index.ts +128 -0
- package/src/utils/helpers.ts +67 -73
- package/tests/analyzer/functional.spec.ts +207 -221
- package/tests/analyzer/generic.spec.ts +178 -100
- package/tests/analyzer/helpers.spec.ts +83 -83
- package/tests/analyzer/logic.spec.ts +237 -292
- package/tests/analyzer/oop.spec.ts +323 -338
- package/tests/analyzer/transitive.spec.ts +166 -0
- package/tests/interpreter/EnvBuilder.spec.ts +183 -178
- package/tests/interpreter/FunctionRuntime.spec.ts +223 -234
- package/tests/interpreter/LazyRuntime.spec.ts +225 -190
- package/tests/interpreter/LogicEngine.spec.ts +327 -194
- package/tests/interpreter/LogicSubstitution.spec.ts +80 -0
- package/tests/interpreter/ObjectRuntime.spec.ts +606 -0
- package/tests/interpreter/Operations.spec.ts +220 -220
- package/tests/interpreter/PatternSystem.spec.ts +213 -189
- package/tests/interpreter/Tests.spec.ts +122 -0
- package/tests/interpreter/interpreter.spec.ts +991 -937
- package/tests/tester/Tester.spec.ts +153 -0
- package/tsconfig.build.json +15 -7
- package/tsconfig.json +25 -17
- package/dist/analyzer/inspections/functional.d.ts +0 -46
- package/dist/analyzer/inspections/functional.js +0 -123
- package/dist/analyzer/inspections/generic.js +0 -427
- package/dist/analyzer/inspections/imperative.d.ts +0 -37
- package/dist/analyzer/inspections/imperative.js +0 -105
- package/dist/analyzer/inspections/logic.d.ts +0 -49
- package/dist/analyzer/inspections/logic.js +0 -140
- package/dist/analyzer/inspections/object.d.ts +0 -83
- package/dist/analyzer/inspections/object.js +0 -235
- package/dist/interpreter/components/FunctionRuntime.d.ts +0 -8
- package/dist/interpreter/components/FunctionRuntime.js +0 -52
- package/dist/interpreter/components/LazyRuntime.d.ts +0 -7
- package/dist/interpreter/components/LazyRuntime.js +0 -75
- package/dist/interpreter/components/LogicEngine.d.ts +0 -21
- package/dist/interpreter/components/LogicEngine.js +0 -152
- package/dist/interpreter/components/LogicResolver.d.ts +0 -11
- package/dist/interpreter/components/LogicResolver.js +0 -87
- package/src/analyzer/inspections/functional.ts +0 -159
- package/src/analyzer/inspections/imperative.ts +0 -129
- package/src/analyzer/inspections/logic.ts +0 -166
- package/src/interpreter/components/FunctionRuntime.ts +0 -79
- package/src/interpreter/components/LazyRuntime.ts +0 -97
- package/src/interpreter/components/LogicEngine.ts +0 -227
- package/src/interpreter/components/LogicResolver.ts +0 -130
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { AssignOperation, Exist, StopTraversalException, SymbolPrimitive, TraverseVisitor, } from "@yukigo/ast";
|
|
2
|
-
import { executeVisitor } from "../utils.js";
|
|
3
|
-
import { isYukigoPrimitive } from "@yukigo/ast";
|
|
4
|
-
export class DeclaresBinding extends TraverseVisitor {
|
|
5
|
-
targetBinding;
|
|
6
|
-
constructor(binding) {
|
|
7
|
-
super();
|
|
8
|
-
this.targetBinding = binding;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export class DeclaresFact extends DeclaresBinding {
|
|
12
|
-
visitFact(node) {
|
|
13
|
-
const bindingName = node.identifier.value;
|
|
14
|
-
if (!this.targetBinding || bindingName === this.targetBinding)
|
|
15
|
-
throw new StopTraversalException();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export class DeclaresRule extends DeclaresBinding {
|
|
19
|
-
visitRule(node) {
|
|
20
|
-
const bindingName = node.identifier.value;
|
|
21
|
-
if (!this.targetBinding || bindingName === this.targetBinding)
|
|
22
|
-
throw new StopTraversalException();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
export class DeclaresPredicate extends DeclaresBinding {
|
|
26
|
-
visitFact(node) {
|
|
27
|
-
new DeclaresFact(this.targetBinding).visitFact(node);
|
|
28
|
-
}
|
|
29
|
-
visitRule(node) {
|
|
30
|
-
new DeclaresRule(this.targetBinding).visitRule(node);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export class PredicateVisitor extends TraverseVisitor {
|
|
34
|
-
targetBinding;
|
|
35
|
-
isInsideTargetScope = false; // this flag helps to check nested functions inside the targetBinding scope
|
|
36
|
-
constructor(binding) {
|
|
37
|
-
super();
|
|
38
|
-
this.targetBinding = binding;
|
|
39
|
-
}
|
|
40
|
-
visitFact(node) {
|
|
41
|
-
const nodeName = node.identifier.value;
|
|
42
|
-
if (!this.isInsideTargetScope) {
|
|
43
|
-
if (nodeName === this.targetBinding) {
|
|
44
|
-
this.isInsideTargetScope = true;
|
|
45
|
-
this.traverseCollection(node.patterns);
|
|
46
|
-
this.isInsideTargetScope = false;
|
|
47
|
-
}
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.traverseCollection(node.patterns);
|
|
51
|
-
}
|
|
52
|
-
visitRule(node) {
|
|
53
|
-
const nodeName = node.identifier.value;
|
|
54
|
-
if (!this.isInsideTargetScope) {
|
|
55
|
-
if (nodeName === this.targetBinding) {
|
|
56
|
-
this.isInsideTargetScope = true;
|
|
57
|
-
this.traverseCollection(node.expressions);
|
|
58
|
-
this.isInsideTargetScope = false;
|
|
59
|
-
}
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
this.traverseCollection(node.expressions);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
export class UsesFindall extends TraverseVisitor {
|
|
66
|
-
visitFindall(node) {
|
|
67
|
-
throw new StopTraversalException();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
export class UsesForall extends TraverseVisitor {
|
|
71
|
-
visitForall(node) {
|
|
72
|
-
throw new StopTraversalException();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
export class UsesNot extends TraverseVisitor {
|
|
76
|
-
visitNot(node) {
|
|
77
|
-
throw new StopTraversalException();
|
|
78
|
-
}
|
|
79
|
-
visitExist(node) {
|
|
80
|
-
if (node.identifier.value === "not")
|
|
81
|
-
throw new StopTraversalException();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
export class UsesUnificationOperator extends PredicateVisitor {
|
|
85
|
-
visitUnifyOperation(node) {
|
|
86
|
-
throw new StopTraversalException();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
export class UsesCut extends PredicateVisitor {
|
|
90
|
-
visitExist(node) {
|
|
91
|
-
if (node.identifier.value === "!")
|
|
92
|
-
throw new StopTraversalException();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
export class UsesFail extends PredicateVisitor {
|
|
96
|
-
visitExist(node) {
|
|
97
|
-
if (node.identifier.value === "fail")
|
|
98
|
-
throw new StopTraversalException();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
export class HasRedundantReduction extends TraverseVisitor {
|
|
102
|
-
targetBinding;
|
|
103
|
-
isInsideTargetScope = false;
|
|
104
|
-
constructor(binding) {
|
|
105
|
-
super();
|
|
106
|
-
this.targetBinding = binding;
|
|
107
|
-
}
|
|
108
|
-
visitRule(node) {
|
|
109
|
-
// Only inspect the specified rule if a binding is provided
|
|
110
|
-
if (this.targetBinding && node.identifier.value !== this.targetBinding)
|
|
111
|
-
return;
|
|
112
|
-
// Check each unification in the rule's body
|
|
113
|
-
for (const bodyElement of node.expressions) {
|
|
114
|
-
if (bodyElement instanceof AssignOperation) {
|
|
115
|
-
const left = bodyElement.left;
|
|
116
|
-
const right = bodyElement.right;
|
|
117
|
-
if (!(left instanceof SymbolPrimitive))
|
|
118
|
-
continue;
|
|
119
|
-
const redundantReductionParameters = isYukigoPrimitive(right);
|
|
120
|
-
const redundantReductionFunctors = right instanceof Exist;
|
|
121
|
-
// Check if reduction is redundant
|
|
122
|
-
const isRedundant = redundantReductionParameters || redundantReductionFunctors;
|
|
123
|
-
if (isRedundant)
|
|
124
|
-
throw new StopTraversalException();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
export const logicInspections = {
|
|
130
|
-
DeclaresFact: (node, args, binding) => executeVisitor(node, new DeclaresFact(binding)),
|
|
131
|
-
DeclaresRule: (node, args, binding) => executeVisitor(node, new DeclaresRule(binding)),
|
|
132
|
-
DeclaresPredicate: (node, args, binding) => executeVisitor(node, new DeclaresPredicate(binding)),
|
|
133
|
-
UsesFindall: (node, args, binding) => executeVisitor(node, new UsesFindall()),
|
|
134
|
-
UsesForall: (node, args, binding) => executeVisitor(node, new UsesForall()),
|
|
135
|
-
UsesNot: (node, args, binding) => executeVisitor(node, new UsesNot()),
|
|
136
|
-
UsesUnificationOperator: (node, args, binding) => executeVisitor(node, new UsesUnificationOperator(binding)),
|
|
137
|
-
UsesCut: (node, args, binding) => executeVisitor(node, new UsesCut(binding)),
|
|
138
|
-
UsesFail: (node, args, binding) => executeVisitor(node, new UsesFail(binding)),
|
|
139
|
-
HasRedundantReduction: (node, args, binding) => executeVisitor(node, new HasRedundantReduction(binding)),
|
|
140
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Attribute, Class, Include, Interface, Method, New, Object, PrimitiveMethod, Send, TraverseVisitor } from "@yukigo/ast";
|
|
2
|
-
import { InspectionMap } from "../utils.js";
|
|
3
|
-
export declare class DeclaresAttribute extends TraverseVisitor {
|
|
4
|
-
private attributeName;
|
|
5
|
-
constructor(attributeName: string);
|
|
6
|
-
visitAttribute(node: Attribute): void;
|
|
7
|
-
}
|
|
8
|
-
export declare class DeclaresClass extends TraverseVisitor {
|
|
9
|
-
private className;
|
|
10
|
-
constructor(className: string);
|
|
11
|
-
visitClass(node: Class): void;
|
|
12
|
-
}
|
|
13
|
-
export declare class DeclaresInterface extends TraverseVisitor {
|
|
14
|
-
private interfaceName;
|
|
15
|
-
constructor(interfaceName: string);
|
|
16
|
-
visitInterface(node: Interface): void;
|
|
17
|
-
}
|
|
18
|
-
export declare class DeclaresMethod extends TraverseVisitor {
|
|
19
|
-
private methodName;
|
|
20
|
-
constructor(methodName: string);
|
|
21
|
-
visitMethod(node: Method): void;
|
|
22
|
-
}
|
|
23
|
-
export declare class DeclaresObject extends TraverseVisitor {
|
|
24
|
-
private objectName;
|
|
25
|
-
constructor(objectName: string);
|
|
26
|
-
visitObject(node: Object): void;
|
|
27
|
-
}
|
|
28
|
-
export declare class DeclaresPrimitive extends TraverseVisitor {
|
|
29
|
-
private operatorName;
|
|
30
|
-
constructor(operatorName: string);
|
|
31
|
-
visitPrimitiveMethod(node: PrimitiveMethod): void;
|
|
32
|
-
}
|
|
33
|
-
export declare class DeclaresSuperclass extends TraverseVisitor {
|
|
34
|
-
private superclassName;
|
|
35
|
-
constructor(superclassName: string);
|
|
36
|
-
visitClass(node: Class): void;
|
|
37
|
-
}
|
|
38
|
-
export declare class Implements extends TraverseVisitor {
|
|
39
|
-
private interfaceName;
|
|
40
|
-
constructor(interfaceName: string);
|
|
41
|
-
visitClass(node: Class): void;
|
|
42
|
-
}
|
|
43
|
-
export declare class IncludeMixin extends TraverseVisitor {
|
|
44
|
-
private mixinsName;
|
|
45
|
-
constructor(mixinsName: string);
|
|
46
|
-
visitInclude(node: Include): void;
|
|
47
|
-
}
|
|
48
|
-
export declare class Instantiates extends TraverseVisitor {
|
|
49
|
-
private className;
|
|
50
|
-
constructor(className: string);
|
|
51
|
-
visitNew(node: New): void;
|
|
52
|
-
}
|
|
53
|
-
export declare class UsesDynamicPolymorphism extends TraverseVisitor {
|
|
54
|
-
private selectorName;
|
|
55
|
-
private count;
|
|
56
|
-
constructor(selectorName: string);
|
|
57
|
-
visitMethod(node: Method): void;
|
|
58
|
-
}
|
|
59
|
-
export declare class UsesInheritance extends TraverseVisitor {
|
|
60
|
-
visitClass(node: Class): void;
|
|
61
|
-
visitInterface(node: Interface): void;
|
|
62
|
-
}
|
|
63
|
-
export declare class UsesMixins extends TraverseVisitor {
|
|
64
|
-
visitInclude(node: Include): void;
|
|
65
|
-
}
|
|
66
|
-
export declare class UsesObjectComposition extends TraverseVisitor {
|
|
67
|
-
visitAttribute(node: Attribute): void;
|
|
68
|
-
}
|
|
69
|
-
export declare class UsesStaticMethodOverload extends TraverseVisitor {
|
|
70
|
-
private scopes;
|
|
71
|
-
visitClass(node: Class): void;
|
|
72
|
-
visitObject(node: Object): void;
|
|
73
|
-
visitMethod(node: Method): void;
|
|
74
|
-
}
|
|
75
|
-
export declare class UsesDynamicMethodOverload extends TraverseVisitor {
|
|
76
|
-
visitMethod(node: Method): void;
|
|
77
|
-
}
|
|
78
|
-
export declare class UsesTemplateMethod extends TraverseVisitor {
|
|
79
|
-
private abstractMethodsStack;
|
|
80
|
-
visitClass(node: Class): void;
|
|
81
|
-
visitSend(node: Send): void;
|
|
82
|
-
}
|
|
83
|
-
export declare const objectInspections: InspectionMap;
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { New, Self, StopTraversalException, SymbolPrimitive, TraverseVisitor, } from "@yukigo/ast";
|
|
2
|
-
import { executeVisitor } from "../utils.js";
|
|
3
|
-
export class DeclaresAttribute extends TraverseVisitor {
|
|
4
|
-
attributeName;
|
|
5
|
-
constructor(attributeName) {
|
|
6
|
-
super();
|
|
7
|
-
this.attributeName = attributeName;
|
|
8
|
-
}
|
|
9
|
-
visitAttribute(node) {
|
|
10
|
-
if (node.identifier.value === this.attributeName)
|
|
11
|
-
throw new StopTraversalException();
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export class DeclaresClass extends TraverseVisitor {
|
|
15
|
-
className;
|
|
16
|
-
constructor(className) {
|
|
17
|
-
super();
|
|
18
|
-
this.className = className;
|
|
19
|
-
}
|
|
20
|
-
visitClass(node) {
|
|
21
|
-
if (node.identifier.value === this.className)
|
|
22
|
-
throw new StopTraversalException();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
export class DeclaresInterface extends TraverseVisitor {
|
|
26
|
-
interfaceName;
|
|
27
|
-
constructor(interfaceName) {
|
|
28
|
-
super();
|
|
29
|
-
this.interfaceName = interfaceName;
|
|
30
|
-
}
|
|
31
|
-
visitInterface(node) {
|
|
32
|
-
if (node.identifier.value === this.interfaceName)
|
|
33
|
-
throw new StopTraversalException();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export class DeclaresMethod extends TraverseVisitor {
|
|
37
|
-
methodName;
|
|
38
|
-
constructor(methodName) {
|
|
39
|
-
super();
|
|
40
|
-
this.methodName = methodName;
|
|
41
|
-
}
|
|
42
|
-
visitMethod(node) {
|
|
43
|
-
if (node.identifier.value === this.methodName)
|
|
44
|
-
throw new StopTraversalException();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export class DeclaresObject extends TraverseVisitor {
|
|
48
|
-
objectName;
|
|
49
|
-
constructor(objectName) {
|
|
50
|
-
super();
|
|
51
|
-
this.objectName = objectName;
|
|
52
|
-
}
|
|
53
|
-
visitObject(node) {
|
|
54
|
-
if (node.identifier.value === this.objectName)
|
|
55
|
-
throw new StopTraversalException();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
export class DeclaresPrimitive extends TraverseVisitor {
|
|
59
|
-
operatorName;
|
|
60
|
-
constructor(operatorName) {
|
|
61
|
-
super();
|
|
62
|
-
this.operatorName = operatorName;
|
|
63
|
-
}
|
|
64
|
-
visitPrimitiveMethod(node) {
|
|
65
|
-
if (node.operator === this.operatorName)
|
|
66
|
-
throw new StopTraversalException();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export class DeclaresSuperclass extends TraverseVisitor {
|
|
70
|
-
superclassName;
|
|
71
|
-
constructor(superclassName) {
|
|
72
|
-
super();
|
|
73
|
-
this.superclassName = superclassName;
|
|
74
|
-
}
|
|
75
|
-
visitClass(node) {
|
|
76
|
-
if (node.extendsSymbol && node.extendsSymbol.value === this.superclassName)
|
|
77
|
-
throw new StopTraversalException();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
export class Implements extends TraverseVisitor {
|
|
81
|
-
interfaceName;
|
|
82
|
-
constructor(interfaceName) {
|
|
83
|
-
super();
|
|
84
|
-
this.interfaceName = interfaceName;
|
|
85
|
-
}
|
|
86
|
-
visitClass(node) {
|
|
87
|
-
if (node.implementsNode &&
|
|
88
|
-
node.implementsNode.identifier.value === this.interfaceName)
|
|
89
|
-
throw new StopTraversalException();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
export class IncludeMixin extends TraverseVisitor {
|
|
93
|
-
mixinsName;
|
|
94
|
-
constructor(mixinsName) {
|
|
95
|
-
super();
|
|
96
|
-
this.mixinsName = mixinsName;
|
|
97
|
-
}
|
|
98
|
-
visitInclude(node) {
|
|
99
|
-
if (node.identifier.value === this.mixinsName)
|
|
100
|
-
throw new StopTraversalException();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
export class Instantiates extends TraverseVisitor {
|
|
104
|
-
className;
|
|
105
|
-
constructor(className) {
|
|
106
|
-
super();
|
|
107
|
-
this.className = className;
|
|
108
|
-
}
|
|
109
|
-
visitNew(node) {
|
|
110
|
-
if (node.identifier.value === this.className)
|
|
111
|
-
throw new StopTraversalException();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
export class UsesDynamicPolymorphism extends TraverseVisitor {
|
|
115
|
-
selectorName;
|
|
116
|
-
count = 0;
|
|
117
|
-
constructor(selectorName) {
|
|
118
|
-
super();
|
|
119
|
-
this.selectorName = selectorName;
|
|
120
|
-
}
|
|
121
|
-
visitMethod(node) {
|
|
122
|
-
if (node.identifier.value === this.selectorName) {
|
|
123
|
-
this.count++;
|
|
124
|
-
if (this.count >= 2)
|
|
125
|
-
throw new StopTraversalException();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
export class UsesInheritance extends TraverseVisitor {
|
|
130
|
-
visitClass(node) {
|
|
131
|
-
if (node.extendsSymbol)
|
|
132
|
-
throw new StopTraversalException();
|
|
133
|
-
}
|
|
134
|
-
visitInterface(node) {
|
|
135
|
-
if (node.extendsSymbol && node.extendsSymbol.length > 0)
|
|
136
|
-
throw new StopTraversalException();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
export class UsesMixins extends TraverseVisitor {
|
|
140
|
-
visitInclude(node) {
|
|
141
|
-
throw new StopTraversalException();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
export class UsesObjectComposition extends TraverseVisitor {
|
|
145
|
-
visitAttribute(node) {
|
|
146
|
-
if (node.expression instanceof New)
|
|
147
|
-
throw new StopTraversalException();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
export class UsesStaticMethodOverload extends TraverseVisitor {
|
|
151
|
-
scopes = [];
|
|
152
|
-
visitClass(node) {
|
|
153
|
-
this.scopes.push(new Set());
|
|
154
|
-
node.expression.accept(this);
|
|
155
|
-
this.scopes.pop();
|
|
156
|
-
}
|
|
157
|
-
visitObject(node) {
|
|
158
|
-
this.scopes.push(new Set());
|
|
159
|
-
node.expression.accept(this);
|
|
160
|
-
this.scopes.pop();
|
|
161
|
-
}
|
|
162
|
-
visitMethod(node) {
|
|
163
|
-
const currentScope = this.scopes[0];
|
|
164
|
-
const methodName = node.identifier.value;
|
|
165
|
-
if (currentScope.has(methodName))
|
|
166
|
-
throw new StopTraversalException();
|
|
167
|
-
currentScope.add(methodName);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
export class UsesDynamicMethodOverload extends TraverseVisitor {
|
|
171
|
-
visitMethod(node) {
|
|
172
|
-
if (node.equations.length > 1)
|
|
173
|
-
throw new StopTraversalException();
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
class AbstractMethodCollector extends TraverseVisitor {
|
|
177
|
-
abstractMethods = new Set();
|
|
178
|
-
visitMethod(node) {
|
|
179
|
-
if (node.getMetadata("isAbstract") === true)
|
|
180
|
-
this.abstractMethods.add(node.identifier.value);
|
|
181
|
-
}
|
|
182
|
-
// stop propagation to not mix scopes
|
|
183
|
-
visitClass(node) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
visitObject(node) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
export class UsesTemplateMethod extends TraverseVisitor {
|
|
191
|
-
abstractMethodsStack = [];
|
|
192
|
-
visitClass(node) {
|
|
193
|
-
const collector = new AbstractMethodCollector();
|
|
194
|
-
if (node.expression)
|
|
195
|
-
executeVisitor(node.expression, collector);
|
|
196
|
-
this.abstractMethodsStack.push(collector.abstractMethods);
|
|
197
|
-
node.expression.accept(this);
|
|
198
|
-
this.abstractMethodsStack.pop();
|
|
199
|
-
}
|
|
200
|
-
visitSend(node) {
|
|
201
|
-
if (node.receiver instanceof Self) {
|
|
202
|
-
if (this.abstractMethodsStack.length === 0)
|
|
203
|
-
return;
|
|
204
|
-
const currentAbstractMethods = this.abstractMethodsStack[0];
|
|
205
|
-
// This doesnt match if message is complex expression
|
|
206
|
-
if (!(node.selector instanceof SymbolPrimitive))
|
|
207
|
-
return;
|
|
208
|
-
const selectorName = node.selector.value;
|
|
209
|
-
const isMessageAbstract = currentAbstractMethods.has(selectorName);
|
|
210
|
-
if (isMessageAbstract)
|
|
211
|
-
throw new StopTraversalException();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
export const objectInspections = {
|
|
216
|
-
DeclaresAttribute: (node, args) => executeVisitor(node, new DeclaresAttribute(args[0])),
|
|
217
|
-
DeclaresClass: (node, args) => executeVisitor(node, new DeclaresClass(args[0])),
|
|
218
|
-
DeclaresInterface: (node, args) => executeVisitor(node, new DeclaresInterface(args[0])),
|
|
219
|
-
DeclaresMethod: (node, args) => executeVisitor(node, new DeclaresMethod(args[0])),
|
|
220
|
-
DeclaresObject: (node, args) => executeVisitor(node, new DeclaresObject(args[0])),
|
|
221
|
-
DeclaresPrimitive: (node, args) => executeVisitor(node, new DeclaresPrimitive(args[0])),
|
|
222
|
-
DeclaresSuperclass: (node, args) => executeVisitor(node, new DeclaresSuperclass(args[0])),
|
|
223
|
-
Implements: (node, args) => executeVisitor(node, new Implements(args[0])),
|
|
224
|
-
Include: (node, args) => executeVisitor(node, new IncludeMixin(args[0])),
|
|
225
|
-
Inherits: (node, args) => executeVisitor(node, new DeclaresSuperclass(args[0])),
|
|
226
|
-
Instantiates: (node, args) => executeVisitor(node, new Instantiates(args[0])),
|
|
227
|
-
UsesDynamicPolymorphism: (node, args) => executeVisitor(node, new UsesDynamicPolymorphism(args[0])),
|
|
228
|
-
UsesInheritance: (node, args) => executeVisitor(node, new UsesInheritance()),
|
|
229
|
-
UsesMixins: (node, args) => executeVisitor(node, new UsesMixins()),
|
|
230
|
-
UsesObjectComposition: (node, args) => executeVisitor(node, new UsesObjectComposition()),
|
|
231
|
-
UsesStaticMethodOverload: (node, args) => executeVisitor(node, new UsesStaticMethodOverload()),
|
|
232
|
-
UsesDynamicMethodOverload: (node, args) => executeVisitor(node, new UsesDynamicMethodOverload()),
|
|
233
|
-
UsesTemplateMethod: (node, args) => executeVisitor(node, new UsesTemplateMethod()),
|
|
234
|
-
UsesStaticPolymorphism: (node, args) => executeVisitor(node, new UsesStaticMethodOverload()),
|
|
235
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { EquationRuntime, PrimitiveValue } from "@yukigo/ast";
|
|
2
|
-
import { EnvStack } from "../index.js";
|
|
3
|
-
import { ExpressionEvaluator } from "../utils.js";
|
|
4
|
-
export declare class FunctionRuntime {
|
|
5
|
-
static apply(funcName: string, equations: EquationRuntime[], args: PrimitiveValue[], currentEnv: EnvStack, evaluatorFactory: (env: EnvStack) => ExpressionEvaluator): PrimitiveValue;
|
|
6
|
-
private static patternsMatch;
|
|
7
|
-
private static evaluateSequence;
|
|
8
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { UnguardedBody, Return, } from "@yukigo/ast";
|
|
2
|
-
import { PatternMatcher } from "./PatternMatcher.js";
|
|
3
|
-
import { InterpreterError } from "../errors.js";
|
|
4
|
-
class NonExhaustivePatterns extends InterpreterError {
|
|
5
|
-
constructor(funcName) {
|
|
6
|
-
super("PatternMatch", `Non-exhaustive patterns in '${funcName}'`);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
export class FunctionRuntime {
|
|
10
|
-
static apply(funcName, equations, args, currentEnv, evaluatorFactory) {
|
|
11
|
-
for (const eq of equations) {
|
|
12
|
-
if (eq.patterns.length !== args.length)
|
|
13
|
-
continue;
|
|
14
|
-
const bindings = [];
|
|
15
|
-
if (!FunctionRuntime.patternsMatch(eq, args, bindings))
|
|
16
|
-
continue;
|
|
17
|
-
const localEnv = new Map(bindings);
|
|
18
|
-
const newStack = [localEnv, ...currentEnv];
|
|
19
|
-
const scopeEvaluator = evaluatorFactory(newStack);
|
|
20
|
-
// UnguardedBody
|
|
21
|
-
if (eq.body instanceof UnguardedBody)
|
|
22
|
-
return this.evaluateSequence(eq.body.sequence, scopeEvaluator);
|
|
23
|
-
// GuardedBody
|
|
24
|
-
for (const guard of eq.body) {
|
|
25
|
-
const cond = scopeEvaluator.evaluate(guard.condition);
|
|
26
|
-
if (cond === true)
|
|
27
|
-
return scopeEvaluator.evaluate(guard.body);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
throw new NonExhaustivePatterns(funcName);
|
|
31
|
-
}
|
|
32
|
-
static patternsMatch(eq, args, bindings) {
|
|
33
|
-
for (let i = 0; i < args.length; i++) {
|
|
34
|
-
const matcher = new PatternMatcher(args[i], bindings);
|
|
35
|
-
if (!eq.patterns[i].accept(matcher))
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
static evaluateSequence(seq, evaluator) {
|
|
41
|
-
let result = undefined;
|
|
42
|
-
for (const stmt of seq.statements) {
|
|
43
|
-
if (stmt instanceof Return) {
|
|
44
|
-
return evaluator.evaluate(stmt.body);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
result = evaluator.evaluate(stmt);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { PrimitiveValue, RangeExpression, ConsExpression } from "@yukigo/ast";
|
|
2
|
-
import { ExpressionEvaluator } from "../utils.js";
|
|
3
|
-
export declare class LazyRuntime {
|
|
4
|
-
static realizeList(val: PrimitiveValue): PrimitiveValue[];
|
|
5
|
-
static evaluateRange(node: RangeExpression, evaluator: ExpressionEvaluator, config: any): PrimitiveValue;
|
|
6
|
-
static evaluateCons(node: ConsExpression, evaluator: ExpressionEvaluator, lazy: boolean): PrimitiveValue;
|
|
7
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { isLazyList, } from "@yukigo/ast";
|
|
2
|
-
import { createStream } from "../utils.js";
|
|
3
|
-
export class LazyRuntime {
|
|
4
|
-
static realizeList(val) {
|
|
5
|
-
if (Array.isArray(val))
|
|
6
|
-
return val;
|
|
7
|
-
if (isLazyList(val)) {
|
|
8
|
-
const result = [];
|
|
9
|
-
const iter = val.generator();
|
|
10
|
-
let next = iter.next();
|
|
11
|
-
while (!next.done) {
|
|
12
|
-
if (next.value === undefined)
|
|
13
|
-
throw new Error("LazyList yielded undefined");
|
|
14
|
-
result.push(next.value);
|
|
15
|
-
next = iter.next();
|
|
16
|
-
}
|
|
17
|
-
return result;
|
|
18
|
-
}
|
|
19
|
-
throw new Error(`Expected List or LazyList, got ${typeof val}`);
|
|
20
|
-
}
|
|
21
|
-
static evaluateRange(node, evaluator, config) {
|
|
22
|
-
const startVal = evaluator.evaluate(node.start);
|
|
23
|
-
if (typeof startVal !== "number")
|
|
24
|
-
throw new Error("Range start must be a number");
|
|
25
|
-
const hasEnd = node.end != null;
|
|
26
|
-
let step = 1;
|
|
27
|
-
if (node.step) {
|
|
28
|
-
const secondVal = evaluator.evaluate(node.step);
|
|
29
|
-
if (typeof secondVal !== "number")
|
|
30
|
-
throw new Error("Range step must be a number");
|
|
31
|
-
step = secondVal - startVal;
|
|
32
|
-
if (step === 0)
|
|
33
|
-
throw new Error("Range step cannot be zero");
|
|
34
|
-
}
|
|
35
|
-
if (!hasEnd) {
|
|
36
|
-
return createStream(function* () {
|
|
37
|
-
let current = startVal;
|
|
38
|
-
while (true) {
|
|
39
|
-
yield current;
|
|
40
|
-
current += step;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
const endVal = evaluator.evaluate(node.end);
|
|
45
|
-
if (typeof endVal !== "number")
|
|
46
|
-
throw new Error("Range end must be a number");
|
|
47
|
-
const result = [];
|
|
48
|
-
let current = startVal;
|
|
49
|
-
const cond = step > 0 ? () => current <= endVal : () => current >= endVal;
|
|
50
|
-
while (cond()) {
|
|
51
|
-
result.push(current);
|
|
52
|
-
current += step;
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
static evaluateCons(node, evaluator, lazy) {
|
|
57
|
-
const head = evaluator.evaluate(node.head);
|
|
58
|
-
if (lazy) {
|
|
59
|
-
const tail = evaluator.evaluate(node.tail);
|
|
60
|
-
if (Array.isArray(tail))
|
|
61
|
-
return [head, ...tail];
|
|
62
|
-
if (isLazyList(tail))
|
|
63
|
-
return createStream(function* () {
|
|
64
|
-
yield head;
|
|
65
|
-
yield* tail.generator();
|
|
66
|
-
});
|
|
67
|
-
throw new Error(`Invalid tail type for Cons: ${typeof tail}`);
|
|
68
|
-
}
|
|
69
|
-
// Eager behavior
|
|
70
|
-
const tail = evaluator.evaluate(node.tail);
|
|
71
|
-
if (isLazyList(tail) || !Array.isArray(tail))
|
|
72
|
-
throw new Error("Expected Array in eager Cons");
|
|
73
|
-
return [head, ...tail];
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Exist, Findall, Goal, PrimitiveValue, Query } from "@yukigo/ast";
|
|
2
|
-
import { EnvStack, InterpreterConfig } from "../index.js";
|
|
3
|
-
import { ExpressionEvaluator } from "../utils.js";
|
|
4
|
-
export declare class LogicEngine {
|
|
5
|
-
private env;
|
|
6
|
-
private config;
|
|
7
|
-
private evaluator;
|
|
8
|
-
constructor(env: EnvStack, config: InterpreterConfig, evaluator: ExpressionEvaluator);
|
|
9
|
-
solveQuery(node: Query): PrimitiveValue;
|
|
10
|
-
solveGoal(node: Goal): PrimitiveValue;
|
|
11
|
-
solveFindall(node: Findall): PrimitiveValue;
|
|
12
|
-
solveExist(node: Exist): PrimitiveValue;
|
|
13
|
-
private solveConjunction;
|
|
14
|
-
private expressionToPattern;
|
|
15
|
-
private primitiveToPattern;
|
|
16
|
-
private instantiateExpressionAsPattern;
|
|
17
|
-
private substitutePattern;
|
|
18
|
-
private instantiateTemplate;
|
|
19
|
-
private handleOutputMode;
|
|
20
|
-
private formatLogicResult;
|
|
21
|
-
}
|