@bikky/replication 1.0.2 → 1.0.4
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/.idea/Replication.iml +12 -0
- package/.idea/compiler.xml +6 -0
- package/.idea/encodings.xml +4 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/Constants/Errors.js +1 -0
- package/Constants/Errors.js.map +1 -0
- package/Constants/Logging.d.ts +1 -0
- package/Constants/Logging.js +2 -2
- package/Constants/Logging.js.map +1 -0
- package/Constants/ReplicableRegistry.d.ts +4 -3
- package/Constants/ReplicableRegistry.js +7 -8
- package/Constants/ReplicableRegistry.js.map +1 -0
- package/Constants/SerialisationTypes.js +4 -4
- package/Constants/SerialisationTypes.js.map +1 -0
- package/Constants/SourceMaps.js +1 -0
- package/Constants/SourceMaps.js.map +1 -0
- package/Constants/TraversalStep.js +1 -0
- package/Constants/TraversalStep.js.map +1 -0
- package/Constants/Versions.d.ts +2 -1
- package/Constants/Versions.js +1 -0
- package/Constants/Versions.js.map +1 -0
- package/Expressions/Compiler/BuiltinGrammar.js +1 -0
- package/Expressions/Compiler/BuiltinGrammar.js.map +1 -0
- package/Expressions/Compiler/ExpressionGrammar.js +1 -0
- package/Expressions/Compiler/ExpressionGrammar.js.map +1 -0
- package/Expressions/Compiler/Grammar/Accessors.d.ts +32 -0
- package/Expressions/Compiler/Grammar/Accessors.js +227 -0
- package/Expressions/Compiler/Grammar/Accessors.js.map +1 -0
- package/Expressions/Compiler/Grammar/ControlFlow.d.ts +38 -0
- package/Expressions/Compiler/Grammar/ControlFlow.js +178 -0
- package/Expressions/Compiler/Grammar/ControlFlow.js.map +1 -0
- package/Expressions/Compiler/Grammar/Declarations.d.ts +22 -0
- package/Expressions/Compiler/Grammar/Declarations.js +84 -0
- package/Expressions/Compiler/Grammar/Declarations.js.map +1 -0
- package/Expressions/Compiler/Grammar/Function.d.ts +30 -0
- package/Expressions/Compiler/Grammar/Function.js +292 -0
- package/Expressions/Compiler/Grammar/Function.js.map +1 -0
- package/Expressions/Compiler/Grammar/General.d.ts +55 -0
- package/Expressions/Compiler/Grammar/General.js +248 -0
- package/Expressions/Compiler/Grammar/General.js.map +1 -0
- package/Expressions/Compiler/Grammar/Maths.d.ts +26 -0
- package/Expressions/Compiler/Grammar/Maths.js +164 -0
- package/Expressions/Compiler/Grammar/Maths.js.map +1 -0
- package/Expressions/Compiler/Grammar/Misc.d.ts +20 -0
- package/Expressions/Compiler/Grammar/Misc.js +50 -0
- package/Expressions/Compiler/Grammar/Misc.js.map +1 -0
- package/Expressions/Compiler/Grammar/Preprocessors.d.ts +18 -0
- package/Expressions/Compiler/Grammar/Preprocessors.js +43 -0
- package/Expressions/Compiler/Grammar/Preprocessors.js.map +1 -0
- package/Expressions/Compiler/Grammar/Struct.d.ts +21 -0
- package/Expressions/Compiler/Grammar/Struct.js +42 -0
- package/Expressions/Compiler/Grammar/Struct.js.map +1 -0
- package/Expressions/Compiler/Grammar/Tokens.d.ts +7 -0
- package/Expressions/Compiler/Grammar/Tokens.js +270 -0
- package/Expressions/Compiler/Grammar/Tokens.js.map +1 -0
- package/Expressions/Compiler/Grammar/Types.d.ts +35 -0
- package/Expressions/Compiler/Grammar/Types.js +230 -0
- package/Expressions/Compiler/Grammar/Types.js.map +1 -0
- package/Expressions/Compiler/GrammarRegistry.d.ts +20 -0
- package/Expressions/Compiler/GrammarRegistry.js +51 -0
- package/Expressions/Compiler/GrammarRegistry.js.map +1 -0
- package/Expressions/Compiler/Parser/Checks.d.ts +8 -0
- package/Expressions/Compiler/Parser/Checks.js +40 -0
- package/Expressions/Compiler/Parser/Checks.js.map +1 -0
- package/Expressions/Compiler/Parser/Enums.d.ts +73 -0
- package/Expressions/Compiler/Parser/Enums.js +77 -0
- package/Expressions/Compiler/Parser/Enums.js.map +1 -0
- package/Expressions/Compiler/Parser/Interfaces.d.ts +118 -0
- package/Expressions/Compiler/Parser/Interfaces.js +112 -0
- package/Expressions/Compiler/Parser/Interfaces.js.map +1 -0
- package/Expressions/Compiler/Parser/MatchGrammar.d.ts +15 -0
- package/Expressions/Compiler/Parser/MatchGrammar.js +128 -0
- package/Expressions/Compiler/Parser/MatchGrammar.js.map +1 -0
- package/Expressions/Compiler/Parser/MatchRepeatingRule.d.ts +4 -0
- package/Expressions/Compiler/Parser/MatchRepeatingRule.js +51 -0
- package/Expressions/Compiler/Parser/MatchRepeatingRule.js.map +1 -0
- package/Expressions/Compiler/Parser/MatchRule.d.ts +4 -0
- package/Expressions/Compiler/Parser/MatchRule.js +57 -0
- package/Expressions/Compiler/Parser/MatchRule.js.map +1 -0
- package/Expressions/Compiler/Parser/Parser.d.ts +26 -0
- package/Expressions/Compiler/Parser/Parser.js +67 -0
- package/Expressions/Compiler/Parser/Parser.js.map +1 -0
- package/Expressions/Compiler/Parser/Tokenizer.d.ts +12 -0
- package/Expressions/Compiler/Parser/Tokenizer.js +138 -0
- package/Expressions/Compiler/Parser/Tokenizer.js.map +1 -0
- package/Expressions/Compiler/Parser/TypesAndPrint.d.ts +29 -0
- package/Expressions/Compiler/Parser/TypesAndPrint.js +15 -0
- package/Expressions/Compiler/Parser/TypesAndPrint.js.map +1 -0
- package/Expressions/Compiler/Parser/Updates.d.ts +10 -0
- package/Expressions/Compiler/Parser/Updates.js +79 -0
- package/Expressions/Compiler/Parser/Updates.js.map +1 -0
- package/Expressions/Compiler/Parser.js +27 -18
- package/Expressions/Compiler/Parser.js.map +1 -0
- package/Expressions/Compiler/Tokenizer.js +1 -0
- package/Expressions/Compiler/Tokenizer.js.map +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.js +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.js.map +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.js +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.js.map +1 -0
- package/Expressions/CreateEvaluator.js +1 -0
- package/Expressions/CreateEvaluator.js.map +1 -0
- package/Expressions/EvaluatorChain.js +6 -1
- package/Expressions/EvaluatorChain.js.map +1 -0
- package/Expressions/EvaluatorSteps.js +1 -0
- package/Expressions/EvaluatorSteps.js.map +1 -0
- package/Expressions/EvaluatorString.js +1 -0
- package/Expressions/EvaluatorString.js.map +1 -0
- package/Expressions/Expression.js +10 -3
- package/Expressions/Expression.js.map +1 -0
- package/Expressions/Traverser.js +2 -2
- package/Expressions/Traverser.js.map +1 -0
- package/Expressions/TypeRegistry/Accessors.js +1 -0
- package/Expressions/TypeRegistry/Accessors.js.map +1 -0
- package/Expressions/TypeRegistry/ChainCollections.js +1 -0
- package/Expressions/TypeRegistry/ChainCollections.js.map +1 -0
- package/Expressions/TypeRegistry/ChainTypes.js +1 -0
- package/Expressions/TypeRegistry/ChainTypes.js.map +1 -0
- package/Expressions/TypeRegistry/CustomAPI.d.ts +6 -4
- package/Expressions/TypeRegistry/CustomAPI.js +16 -34
- package/Expressions/TypeRegistry/CustomAPI.js.map +1 -0
- package/Expressions/TypeRegistry/Primitive.js +1 -0
- package/Expressions/TypeRegistry/Primitive.js.map +1 -0
- package/Expressions/TypeRegistry/Registry.js +6 -6
- package/Expressions/TypeRegistry/Registry.js.map +1 -0
- package/Expressions/TypeRegistry/ReplAPI.d.ts +7 -5
- package/Expressions/TypeRegistry/ReplAPI.js +9 -22
- package/Expressions/TypeRegistry/ReplAPI.js.map +1 -0
- package/Expressions/TypeRegistry/Scope.js +1 -0
- package/Expressions/TypeRegistry/Scope.js.map +1 -0
- package/Expressions/TypeRegistry/Types.js +1 -0
- package/Expressions/TypeRegistry/Types.js.map +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.js +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.js.map +1 -0
- package/Expressions/__tests__/ExpressionExamples.js +1 -0
- package/Expressions/__tests__/ExpressionExamples.js.map +1 -0
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.js +4 -3
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.js.map +1 -0
- package/IDPool.data.d.ts +2 -0
- package/IDPool.js +1 -0
- package/IDPool.js.map +1 -0
- package/Main.js +1 -0
- package/Main.js.map +1 -0
- package/Networking.d.ts +3 -0
- package/Networking.js +22 -9
- package/Networking.js.map +1 -0
- package/Replicatable.js +5 -6
- package/Replicatable.js.map +1 -0
- package/Tracking/Buffable.d.ts +3 -2
- package/Tracking/Buffable.js +1 -0
- package/Tracking/Buffable.js.map +1 -0
- package/Tracking/Class.d.ts +6 -4
- package/Tracking/Class.js +37 -19
- package/Tracking/Class.js.map +1 -0
- package/Tracking/Functions.js +3 -2
- package/Tracking/Functions.js.map +1 -0
- package/Tracking/GlobalGroup.js +2 -2
- package/Tracking/GlobalGroup.js.map +1 -0
- package/Tracking/Property.d.ts +3 -2
- package/Tracking/Property.js +9 -5
- package/Tracking/Property.js.map +1 -0
- package/Tracking/Types.js +1 -0
- package/Tracking/Types.js.map +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.js.map +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.js.map +1 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.js.map +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.js.map +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.js.map +1 -0
- package/Transformers/Configurer.d.ts +15 -1
- package/Transformers/Configurer.js +130 -21
- package/Transformers/Configurer.js.map +1 -0
- package/Transformers/Constructor.js +1 -0
- package/Transformers/Constructor.js.map +1 -0
- package/Transformers/Definitions.d.ts +3 -3
- package/Transformers/Definitions.js +41 -21
- package/Transformers/Definitions.js.map +1 -0
- package/Transformers/Loader.js +21 -11
- package/Transformers/Loader.js.map +1 -0
- package/Transformers/Progress.js +19 -13
- package/Transformers/Progress.js.map +1 -0
- package/Transformers/Reference.js +3 -2
- package/Transformers/Reference.js.map +1 -0
- package/Transformers/SchemaGenerator.d.ts +2 -2
- package/Transformers/SchemaGenerator.js +89 -7
- package/Transformers/SchemaGenerator.js.map +1 -0
- package/Transformers/Serialiser.js +1 -0
- package/Transformers/Serialiser.js.map +1 -0
- package/Transformers/Utils.d.ts +1 -1
- package/Transformers/Utils.js +43 -26
- package/Transformers/Utils.js.map +1 -0
- package/Transformers/__tests__/Examples.d.ts +36 -0
- package/Transformers/__tests__/Examples.js +40 -0
- package/Transformers/__tests__/Examples.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.js +18 -16
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.js +2 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.js +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.js +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.js +14 -2
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.js +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.js +11 -2
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.js.map +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.js +95 -82
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.js.map +1 -0
- package/__tests__/Configuration/Mocks.d.ts +2 -0
- package/__tests__/Configuration/Mocks.js +98 -0
- package/__tests__/Configuration/Mocks.js.map +1 -0
- package/__tests__/Configuration/Setup.d.ts +1 -0
- package/__tests__/Configuration/Setup.js +14 -0
- package/__tests__/Configuration/Setup.js.map +1 -0
- package/__tests__/Configuration/TestTypes.d.ts +33 -0
- package/__tests__/Replicable.Expressions.test.js +1 -0
- package/__tests__/Replicable.Expressions.test.js.map +1 -0
- package/__tests__/Replicable.IDPool.test.js +1 -0
- package/__tests__/Replicable.IDPool.test.js.map +1 -0
- package/__tests__/Replicable.ReplicableRegistry.test.js +23 -13
- package/__tests__/Replicable.ReplicableRegistry.test.js.map +1 -0
- package/__tests__/Replicable.Serialisation.test.js +1 -0
- package/__tests__/Replicable.Serialisation.test.js.map +1 -0
- package/package.json +28 -18
- package/tsconfig.json +7 -4
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.d.ts +2 -0
- package/vitest.config.js +32 -0
- package/vitest.config.js.map +1 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NodeType } from "../Parser/Enums.js";
|
|
2
|
+
import { GrammarInterfaces } from "../Parser/Interfaces.js";
|
|
3
|
+
import { BlockNode, ExpressionNode, StatementNode } from "./General.js";
|
|
4
|
+
import EAST_Complex_Node = GrammarInterfaces.EAST_Complex_Node;
|
|
5
|
+
import Node = GrammarInterfaces.Node;
|
|
6
|
+
export declare const CONTROL_FLOW_STATEMENTS: NodeType[];
|
|
7
|
+
type ControlFlowLoopNodes = BreakNode | ContinueNode;
|
|
8
|
+
export declare function IsLoopNode(node: Node): node is ForNode | WhileNode;
|
|
9
|
+
export declare function IsControlFlowNode(node: Node): node is ContinueNode | BreakNode;
|
|
10
|
+
export interface ContinueNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
11
|
+
type: NodeType.CONTINUE;
|
|
12
|
+
values: undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function IsContinueNode(node: Node): node is ContinueNode;
|
|
15
|
+
export interface BreakNode extends EAST_Complex_Node {
|
|
16
|
+
type: NodeType.BREAK;
|
|
17
|
+
values: undefined;
|
|
18
|
+
}
|
|
19
|
+
export declare function IsBreakNode(node: Node): node is BreakNode;
|
|
20
|
+
export interface WhileNode extends EAST_Complex_Node {
|
|
21
|
+
type: NodeType.WHILE_LOOP;
|
|
22
|
+
values: {
|
|
23
|
+
test: ExpressionNode;
|
|
24
|
+
body: BlockNode<ControlFlowLoopNodes> | StatementNode;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare function IsWhileNode(node: Node): node is WhileNode;
|
|
28
|
+
export interface ForNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
29
|
+
type: NodeType.FOR_LOOP;
|
|
30
|
+
values: {
|
|
31
|
+
initialiser: ExpressionNode;
|
|
32
|
+
test: ExpressionNode;
|
|
33
|
+
incrementer: ExpressionNode;
|
|
34
|
+
body: BlockNode<ControlFlowLoopNodes> | StatementNode;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export declare function IsForNode(node: Node): node is ForNode;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { NodeType, TokenType } from "../Parser/Enums.js";
|
|
2
|
+
import { GrammarInterfaces } from "../Parser/Interfaces.js";
|
|
3
|
+
import { GrammarRegistry } from "../GrammarRegistry.js";
|
|
4
|
+
import { Versions } from "../../../Constants/Versions.js";
|
|
5
|
+
var SpecialType = GrammarInterfaces.SpecialType;
|
|
6
|
+
var ExpressionSyntaxError = GrammarRegistry.ExpressionSyntaxError;
|
|
7
|
+
import { ChainBoolean } from "../../TypeRegistry/Primitive.js";
|
|
8
|
+
import { CreateChildScope } from "../../TypeRegistry/Types.js";
|
|
9
|
+
export const CONTROL_FLOW_STATEMENTS = [NodeType.FOR_LOOP, NodeType.WHILE_LOOP, NodeType.DOWHILE_LOOP, NodeType.IF];
|
|
10
|
+
const CONTROL_FLOW_LOOP = [NodeType.BREAK, NodeType.CONTINUE];
|
|
11
|
+
//-------------------------------------------------LOOPS-----------------------------------------------
|
|
12
|
+
export function IsLoopNode(node) {
|
|
13
|
+
return node.type === NodeType.FOR_LOOP || node.type === NodeType.WHILE_LOOP || node.type === NodeType.DOWHILE_LOOP;
|
|
14
|
+
}
|
|
15
|
+
export function IsControlFlowNode(node) {
|
|
16
|
+
return node.type === NodeType.CONTINUE || node.type === NodeType.BREAK || node.type === NodeType.RETURN;
|
|
17
|
+
}
|
|
18
|
+
export function IsContinueNode(node) {
|
|
19
|
+
return node.type === NodeType.CONTINUE;
|
|
20
|
+
}
|
|
21
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.CONTINUE, [[
|
|
22
|
+
{ type: TokenType.KEYWORD, value: "continue" },
|
|
23
|
+
{ type: TokenType.OPERATOR, value: ";" }
|
|
24
|
+
]], {
|
|
25
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
26
|
+
return {
|
|
27
|
+
interrupt: "continue",
|
|
28
|
+
type: null,
|
|
29
|
+
value: null
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
33
|
+
if (outputType !== null) {
|
|
34
|
+
throw new ExpressionSyntaxError("Continue statements cannot return values", currentNode);
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
export function IsBreakNode(node) {
|
|
40
|
+
return node.type === NodeType.BREAK;
|
|
41
|
+
}
|
|
42
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.BREAK, [[
|
|
43
|
+
{ type: TokenType.KEYWORD, value: "break" },
|
|
44
|
+
{ type: TokenType.OPERATOR, value: ";" }
|
|
45
|
+
]], {
|
|
46
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
47
|
+
return {
|
|
48
|
+
interrupt: "break",
|
|
49
|
+
type: null,
|
|
50
|
+
value: null
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
54
|
+
if (outputType !== null) {
|
|
55
|
+
throw new ExpressionSyntaxError("Break statements cannot return values", currentNode);
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
export function IsWhileNode(node) {
|
|
61
|
+
return node.type === NodeType.WHILE_LOOP;
|
|
62
|
+
}
|
|
63
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.WHILE_LOOP, [[
|
|
64
|
+
{ type: TokenType.KEYWORD, value: "while" },
|
|
65
|
+
{ type: TokenType.OPERATOR, value: "(" },
|
|
66
|
+
{ type: NodeType.EXPRESSION, name: "test" },
|
|
67
|
+
{ type: TokenType.OPERATOR, value: ")" },
|
|
68
|
+
{
|
|
69
|
+
type: [NodeType.BLOCK, NodeType.STATEMENT],
|
|
70
|
+
input: [...CONTROL_FLOW_LOOP, GrammarInterfaces.SpecialType.INPUT_TYPES],
|
|
71
|
+
name: "body"
|
|
72
|
+
}
|
|
73
|
+
]], {
|
|
74
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
75
|
+
if (outputType !== null) {
|
|
76
|
+
throw new ExpressionSyntaxError("Loops cannot return values", currentNode);
|
|
77
|
+
}
|
|
78
|
+
// Create a new scope for the loop
|
|
79
|
+
let loopScope = CreateChildScope(scope);
|
|
80
|
+
while (true) {
|
|
81
|
+
// Evaluate the test condition
|
|
82
|
+
let testResult = currentNode.values.test.execute.runtimeExecute(loopScope, currentNode.values.test, [ChainBoolean]);
|
|
83
|
+
if (!testResult.value) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
// Execute the body
|
|
87
|
+
let bodyResult = currentNode.values.body.execute.runtimeExecute(loopScope, currentNode.values.body, null);
|
|
88
|
+
// Handle control flow statements
|
|
89
|
+
if (bodyResult.interrupt === "break") {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
if (bodyResult.interrupt === "return") {
|
|
93
|
+
return bodyResult;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
type: null,
|
|
98
|
+
value: null
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
102
|
+
if (outputType !== null) {
|
|
103
|
+
throw new ExpressionSyntaxError("Loops cannot return values", currentNode);
|
|
104
|
+
}
|
|
105
|
+
// Create a new scope for the loop body
|
|
106
|
+
let bodyScope = CreateChildScope(scope);
|
|
107
|
+
// Ensure the test condition is a boolean
|
|
108
|
+
currentNode.values.test.execute.compileTimeTraversal(bodyScope, currentNode.values.test, [ChainBoolean]);
|
|
109
|
+
// Traverse the body
|
|
110
|
+
currentNode.values.body.execute.compileTimeTraversal(bodyScope, currentNode.values.body, null);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
export function IsForNode(node) {
|
|
115
|
+
return node.type === NodeType.FOR_LOOP;
|
|
116
|
+
}
|
|
117
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.FOR_LOOP, [[
|
|
118
|
+
{ type: TokenType.KEYWORD, value: "for" },
|
|
119
|
+
{ type: TokenType.OPERATOR, value: "(" },
|
|
120
|
+
{ type: NodeType.EXPRESSION, name: "initialiser" },
|
|
121
|
+
{ type: TokenType.OPERATOR, value: ";" },
|
|
122
|
+
{ type: NodeType.EXPRESSION, name: "test" },
|
|
123
|
+
{ type: TokenType.OPERATOR, value: ";" },
|
|
124
|
+
{ type: NodeType.EXPRESSION, name: "incrementer" },
|
|
125
|
+
{ type: TokenType.OPERATOR, value: ")" },
|
|
126
|
+
{
|
|
127
|
+
type: [NodeType.BLOCK, NodeType.STATEMENT],
|
|
128
|
+
input: [...CONTROL_FLOW_LOOP, SpecialType.INPUT_TYPES],
|
|
129
|
+
name: "body"
|
|
130
|
+
}
|
|
131
|
+
]], {
|
|
132
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
133
|
+
if (outputType !== null) {
|
|
134
|
+
throw new ExpressionSyntaxError("Loops cannot return values", currentNode);
|
|
135
|
+
}
|
|
136
|
+
// Create a new scope for the loop
|
|
137
|
+
let loopScope = CreateChildScope(scope);
|
|
138
|
+
currentNode.values.initialiser.execute.runtimeExecute(loopScope, currentNode.values.initialiser, null);
|
|
139
|
+
while (true) {
|
|
140
|
+
// Evaluate the test condition
|
|
141
|
+
let testResult = currentNode.values.test.execute.runtimeExecute(loopScope, currentNode.values.test, [ChainBoolean]);
|
|
142
|
+
if (!testResult.value) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
// Execute the body
|
|
146
|
+
let bodyResult = currentNode.values.body.execute.runtimeExecute(loopScope, currentNode.values.body, null);
|
|
147
|
+
// Handle control flow statements
|
|
148
|
+
if (bodyResult.interrupt === "break") {
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
if (bodyResult.interrupt === "return") {
|
|
152
|
+
return bodyResult;
|
|
153
|
+
}
|
|
154
|
+
currentNode.values.incrementer.execute.runtimeExecute(loopScope, currentNode.values.incrementer, null);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
type: null,
|
|
158
|
+
value: null
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
162
|
+
if (outputType !== null) {
|
|
163
|
+
throw new ExpressionSyntaxError("Loops cannot return values", currentNode);
|
|
164
|
+
}
|
|
165
|
+
// Create a new scope for the loop body
|
|
166
|
+
let bodyScope = CreateChildScope(scope);
|
|
167
|
+
// Traverse the initialiser
|
|
168
|
+
currentNode.values.initialiser.execute.compileTimeTraversal(bodyScope, currentNode.values.initialiser, null);
|
|
169
|
+
// Traverse the incrementer
|
|
170
|
+
currentNode.values.incrementer.execute.compileTimeTraversal(bodyScope, currentNode.values.incrementer, null);
|
|
171
|
+
// Ensure the test condition is a boolean
|
|
172
|
+
currentNode.values.test.execute.compileTimeTraversal(bodyScope, currentNode.values.test, [ChainBoolean]);
|
|
173
|
+
// Traverse the body
|
|
174
|
+
currentNode.values.body.execute.compileTimeTraversal(bodyScope, currentNode.values.body, null);
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
//# sourceMappingURL=ControlFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ControlFlow.js","sourceRoot":"","sources":["ControlFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NodeType } from "../Parser/Enums.js";
|
|
2
|
+
import { GrammarInterfaces } from "../Parser/Interfaces.js";
|
|
3
|
+
import { ExpressionNode } from "./General.js";
|
|
4
|
+
import Node = GrammarInterfaces.Node;
|
|
5
|
+
import EAST_Token = GrammarInterfaces.EAST_Token;
|
|
6
|
+
import { TypeDefinitionNode, TypeUnionNode } from "./Types.js";
|
|
7
|
+
export interface DeclarationEntryNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
8
|
+
type: NodeType.DECLARATION_ENTRY;
|
|
9
|
+
values: {
|
|
10
|
+
name: EAST_Token;
|
|
11
|
+
type: TypeDefinitionNode | TypeUnionNode;
|
|
12
|
+
initialiser?: ExpressionNode;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare function IsDeclarationEntryNode(node: Node): node is DeclarationEntryNode;
|
|
16
|
+
export interface DeclarationNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
17
|
+
type: NodeType.DECLARATION;
|
|
18
|
+
values: {
|
|
19
|
+
declarations: DeclarationEntryNode[];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export declare function IsDeclarationNode(node: Node): node is DeclarationNode;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { NodeType, TokenType } from "../Parser/Enums.js";
|
|
2
|
+
import { GrammarRegistry } from "../GrammarRegistry.js";
|
|
3
|
+
import { Versions } from "../../../Constants/Versions.js";
|
|
4
|
+
var ExpressionSyntaxError = GrammarRegistry.ExpressionSyntaxError;
|
|
5
|
+
export function IsDeclarationEntryNode(node) {
|
|
6
|
+
return node.type === NodeType.DECLARATION_ENTRY;
|
|
7
|
+
}
|
|
8
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.DECLARATION_ENTRY, [[
|
|
9
|
+
{ type: TokenType.IDENTIFIER, name: "name" },
|
|
10
|
+
{ type: TokenType.OPERATOR, value: ":" },
|
|
11
|
+
{ type: [NodeType.TYPE_UNION, NodeType.TYPE_DEFINITION], name: "type" }, //TODO: Make this optional - only if type can be inferred from initialiser?
|
|
12
|
+
{ type: TokenType.OPERATOR, value: "=", optional: true },
|
|
13
|
+
{ type: NodeType.EXPRESSION, name: "initialiser", optional: "previous" }
|
|
14
|
+
]], {
|
|
15
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
16
|
+
if (outputType !== null) {
|
|
17
|
+
throw new ExpressionSyntaxError("Declarations do not return values", currentNode);
|
|
18
|
+
}
|
|
19
|
+
const type = currentNode.values.type.execute.runtimeExecute(scope, currentNode.values.type, outputType);
|
|
20
|
+
if (!type?.type) {
|
|
21
|
+
throw new ExpressionSyntaxError("Declaration type must not be never", currentNode);
|
|
22
|
+
}
|
|
23
|
+
if (currentNode.values.initialiser) {
|
|
24
|
+
const result = currentNode.values.initialiser.execute.runtimeExecute(scope, currentNode.values.initialiser, [type.type]);
|
|
25
|
+
return {
|
|
26
|
+
type: type.type,
|
|
27
|
+
value: result.value
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
type: type.type,
|
|
32
|
+
value: undefined
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
36
|
+
if (outputType !== null) {
|
|
37
|
+
throw new ExpressionSyntaxError("Declarations do not return values", currentNode);
|
|
38
|
+
}
|
|
39
|
+
const type = currentNode.values.type.execute.compileTimeTraversal(scope, currentNode.values.type, outputType);
|
|
40
|
+
if (!type?.type) {
|
|
41
|
+
throw new ExpressionSyntaxError("Declaration type must not be never", currentNode);
|
|
42
|
+
}
|
|
43
|
+
if (currentNode.values.initialiser) {
|
|
44
|
+
currentNode.values.initialiser.execute.compileTimeTraversal(scope, currentNode.values.initialiser, type.type);
|
|
45
|
+
}
|
|
46
|
+
return type;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
export function IsDeclarationNode(node) {
|
|
50
|
+
return node.type === NodeType.DECLARATION;
|
|
51
|
+
}
|
|
52
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.DECLARATION, [[
|
|
53
|
+
{ type: TokenType.KEYWORD, values: ["const", "var"], name: "qualifiers", repeat: [1, Number.POSITIVE_INFINITY] },
|
|
54
|
+
{
|
|
55
|
+
type: NodeType.DECLARATION_ENTRY,
|
|
56
|
+
name: "declarations",
|
|
57
|
+
repeat: [1, Number.POSITIVE_INFINITY],
|
|
58
|
+
repeatSeparator: { type: TokenType.OPERATOR, value: "," }
|
|
59
|
+
},
|
|
60
|
+
{ type: TokenType.OPERATOR, value: ";" }
|
|
61
|
+
]], {
|
|
62
|
+
runtimeExecute(scope, currentNode, outputType) {
|
|
63
|
+
if (outputType !== null) {
|
|
64
|
+
throw new ExpressionSyntaxError("Declarations do not return values", currentNode);
|
|
65
|
+
}
|
|
66
|
+
for (const decl of currentNode.values.declarations) {
|
|
67
|
+
decl.execute.runtimeExecute(scope, decl, null);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: null,
|
|
71
|
+
value: null
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
compileTimeTraversal(scope, currentNode, outputType) {
|
|
75
|
+
if (outputType !== null) {
|
|
76
|
+
throw new ExpressionSyntaxError("Declarations do not return values", currentNode);
|
|
77
|
+
}
|
|
78
|
+
for (const decl of currentNode.values.declarations) {
|
|
79
|
+
decl.execute.compileTimeTraversal(scope, decl, null);
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=Declarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Declarations.js","sourceRoot":"","sources":["Declarations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GrammarInterfaces } from "../Parser/Interfaces.js";
|
|
2
|
+
import { NodeType } from "../Parser/Enums.js";
|
|
3
|
+
import EAST_Token = GrammarInterfaces.EAST_Token;
|
|
4
|
+
import Node = GrammarInterfaces.Node;
|
|
5
|
+
import { BlockNode, ExpressionNode, ParenthetisedExpressionNode } from "./General.js";
|
|
6
|
+
import { DeclarationEntryNode } from "./Declarations.js";
|
|
7
|
+
import { TypeDefinitionNode } from "./Types.js";
|
|
8
|
+
export interface FunctionDeclarationNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
9
|
+
type: NodeType.FUNCTION_DECLARATION;
|
|
10
|
+
values: {
|
|
11
|
+
name: EAST_Token;
|
|
12
|
+
parameters: DeclarationEntryNode[];
|
|
13
|
+
returnType?: TypeDefinitionNode;
|
|
14
|
+
body: BlockNode<ReturnNode>;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function IsFunctionDeclarationNode(node: Node): node is FunctionDeclarationNode;
|
|
18
|
+
export interface FunctionCallNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
19
|
+
type: NodeType.FUNCTION_CALL;
|
|
20
|
+
values: {
|
|
21
|
+
name: EAST_Token | ParenthetisedExpressionNode;
|
|
22
|
+
arguments: ExpressionNode[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare function IsFunctionCallNode(node: Node): node is FunctionCallNode;
|
|
26
|
+
export interface ReturnNode extends GrammarInterfaces.EAST_Complex_Node {
|
|
27
|
+
type: NodeType.RETURN;
|
|
28
|
+
values: ExpressionNode["values"];
|
|
29
|
+
}
|
|
30
|
+
export declare function IsReturnNode(node: Node): node is ReturnNode;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { GrammarInterfaces } from "../Parser/Interfaces.js";
|
|
2
|
+
import { CollectionType, NodeType, TokenType } from "../Parser/Enums.js";
|
|
3
|
+
import { GrammarRegistry } from "../GrammarRegistry.js";
|
|
4
|
+
import { Versions } from "../../../Constants/Versions.js";
|
|
5
|
+
import { CreateChildScope } from "../../TypeRegistry/Types.js";
|
|
6
|
+
var ExpressionSyntaxError = GrammarRegistry.ExpressionSyntaxError;
|
|
7
|
+
import { describeObject } from "../../../Constants/SerialisationTypes.js";
|
|
8
|
+
var isAssignableCompile = GrammarInterfaces.isAssignableCompile;
|
|
9
|
+
import { ErrorStack } from "../../../Constants/Errors.js";
|
|
10
|
+
import { isToken } from "./Tokens.js";
|
|
11
|
+
export function IsFunctionDeclarationNode(node) {
|
|
12
|
+
return node.type === NodeType.FUNCTION_DECLARATION;
|
|
13
|
+
}
|
|
14
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.FUNCTION_DECLARATION, [[
|
|
15
|
+
{ type: TokenType.IDENTIFIER, value: "function" },
|
|
16
|
+
{ type: TokenType.IDENTIFIER, name: "name" },
|
|
17
|
+
{ type: TokenType.OPERATOR, value: "(" },
|
|
18
|
+
{
|
|
19
|
+
type: NodeType.DECLARATION_ENTRY,
|
|
20
|
+
name: "parameters",
|
|
21
|
+
repeat: [0, Number.POSITIVE_INFINITY],
|
|
22
|
+
repeatSeparator: { type: TokenType.OPERATOR, value: "," }
|
|
23
|
+
},
|
|
24
|
+
{ type: TokenType.OPERATOR, value: ")" },
|
|
25
|
+
{ type: [NodeType.TYPE_UNION, NodeType.TYPE_DEFINITION], name: "returnType", optional: true },
|
|
26
|
+
{ type: NodeType.BLOCK, input: [NodeType.RETURN], name: "body" }
|
|
27
|
+
]], {
|
|
28
|
+
runtimeExecute(scope, node, outputType) {
|
|
29
|
+
if (Array.isArray(outputType)) {
|
|
30
|
+
throw new ExpressionSyntaxError(`A function cannot be assigned this variable`, node);
|
|
31
|
+
}
|
|
32
|
+
let type = (node.execute.compileTimeTraversal(scope, node, outputType)?.type)[0];
|
|
33
|
+
let foo = (callingNode, ...args) => {
|
|
34
|
+
let contentScope = CreateChildScope(scope);
|
|
35
|
+
for (let i = 0; i < node.values.parameters.length; i++) {
|
|
36
|
+
let param = node.values.parameters[i];
|
|
37
|
+
let paramValue = args[i].value ?? param.execute.runtimeExecute(contentScope, param, type.parameters[i].type).value;
|
|
38
|
+
let paramType = type.parameters[i].type.find((e) => e.kind == "value" && e.isAssignableLive(scope.version, paramValue));
|
|
39
|
+
if (!paramType) {
|
|
40
|
+
throw new ExpressionSyntaxError(`Invalid parameter type for function.`
|
|
41
|
+
+ ` ${describeObject(param)} is not assignable to `
|
|
42
|
+
+ `${type.parameters[i].type.map((e) => describeObject(e)).join(" | ")}`, callingNode);
|
|
43
|
+
}
|
|
44
|
+
contentScope.local[type.parameters[i].assignmentName] = {
|
|
45
|
+
value: paramValue,
|
|
46
|
+
type: [paramType]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
let returnType = node.values.body.execute.runtimeExecute(contentScope, node.values.body, outputType);
|
|
50
|
+
if (!Array.isArray(returnType.type) && returnType.type) {
|
|
51
|
+
throw new ExpressionSyntaxError(`Cannot yet return functions from functions`, node);
|
|
52
|
+
}
|
|
53
|
+
let result = node.values.body.execute.runtimeExecute(contentScope, node.values.body, returnType.type);
|
|
54
|
+
return {
|
|
55
|
+
type: returnType.type,
|
|
56
|
+
value: result.value
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
foo.type = type;
|
|
60
|
+
scope.local[node.values.name.data] = {
|
|
61
|
+
value: foo,
|
|
62
|
+
type: [type],
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
value: foo,
|
|
66
|
+
type: null
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
compileTimeTraversal(scope, node, expectedTypes) {
|
|
70
|
+
let contentScope = CreateChildScope(scope);
|
|
71
|
+
// Validate parameters
|
|
72
|
+
let finalParamTypes = [];
|
|
73
|
+
for (let i = 0; i < node.values.parameters.length; i++) {
|
|
74
|
+
let param = node.values.parameters[i];
|
|
75
|
+
let paramType = param.execute.compileTimeTraversal(contentScope, param, null);
|
|
76
|
+
if (!paramType || !paramType.type) {
|
|
77
|
+
throw new ExpressionSyntaxError(`Function parameters failed to resolve.`, node);
|
|
78
|
+
}
|
|
79
|
+
if (!paramType.assignmentName) {
|
|
80
|
+
throw new ExpressionSyntaxError(`Function parameter's name must be defined.`, node);
|
|
81
|
+
}
|
|
82
|
+
finalParamTypes.push({
|
|
83
|
+
outputType: paramType.type,
|
|
84
|
+
assignmentName: paramType.assignmentName,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// Validate return type
|
|
88
|
+
let returnTypes = node.values.returnType?.execute?.compileTimeTraversal(scope, node.values.returnType, null);
|
|
89
|
+
// Add the function to the scope
|
|
90
|
+
let functionType = {
|
|
91
|
+
kind: "function",
|
|
92
|
+
parameters: finalParamTypes.map((param) => ({
|
|
93
|
+
type: param.outputType,
|
|
94
|
+
assignmentName: param.assignmentName,
|
|
95
|
+
})),
|
|
96
|
+
returnType: returnTypes?.type ?? null,
|
|
97
|
+
};
|
|
98
|
+
if (expectedTypes) {
|
|
99
|
+
let stack = new ErrorStack({ Version: scope.version, SourceFile: node.file.sourceLocation });
|
|
100
|
+
if (!isAssignableCompile(scope.version, expectedTypes, [functionType], node, stack)) {
|
|
101
|
+
throw new ExpressionSyntaxError(`Function return type does not match the expected type.` + stack.toString(`EXP_GF_FOO_01`), node);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
scope.local[node.values.name.data] = {
|
|
105
|
+
type: [functionType],
|
|
106
|
+
};
|
|
107
|
+
// Traverse the function body
|
|
108
|
+
node.values.body.execute.compileTimeTraversal(contentScope, node.values.body, returnTypes?.type ?? null);
|
|
109
|
+
return {
|
|
110
|
+
type: [functionType],
|
|
111
|
+
assignmentName: node.values.name.data
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
export function IsFunctionCallNode(node) {
|
|
116
|
+
return node.type === NodeType.FUNCTION_CALL;
|
|
117
|
+
}
|
|
118
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.FUNCTION_CALL, [[
|
|
119
|
+
{
|
|
120
|
+
// Function name - Builtin, identifier
|
|
121
|
+
// or a parenthetised expression that returns a function as a value.
|
|
122
|
+
type: [TokenType.BUILTIN, NodeType.PARENTHETISED_EXPRESSION, TokenType.IDENTIFIER],
|
|
123
|
+
name: "name"
|
|
124
|
+
},
|
|
125
|
+
{ type: TokenType.OPERATOR, value: "(" },
|
|
126
|
+
{
|
|
127
|
+
type: NodeType.EXPRESSION,
|
|
128
|
+
name: "arguments",
|
|
129
|
+
repeat: [0, Number.POSITIVE_INFINITY],
|
|
130
|
+
repeatSeparator: { type: TokenType.OPERATOR, value: "," }
|
|
131
|
+
},
|
|
132
|
+
{ type: TokenType.OPERATOR, value: ")" }
|
|
133
|
+
]], {
|
|
134
|
+
runtimeExecute(scope, node, outputType) {
|
|
135
|
+
const funcName = isToken(node.values.name) ? node.values.name.data
|
|
136
|
+
: node.values.name.execute.runtimeExecute(scope, node.values.name, null).value;
|
|
137
|
+
const funcValue = scope.local[funcName] ?? scope.global[funcName];
|
|
138
|
+
if (!funcValue.type) {
|
|
139
|
+
throw new Error(`Function does not have typing information set`);
|
|
140
|
+
}
|
|
141
|
+
//Use first matching type.
|
|
142
|
+
let funcType = undefined;
|
|
143
|
+
for (let type of funcValue.type) {
|
|
144
|
+
if (type.kind === "function" && funcValue.value.type == type) {
|
|
145
|
+
funcType = type;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!funcType) {
|
|
150
|
+
throw new ExpressionSyntaxError(`Function's value does not match expected function's type.`, node);
|
|
151
|
+
}
|
|
152
|
+
const inputArgNodes = node.values.arguments;
|
|
153
|
+
// Check parameter count
|
|
154
|
+
if (funcType.parameters.length !== inputArgNodes.length) {
|
|
155
|
+
throw new ExpressionSyntaxError(`Function expected ${funcType.parameters.length} argument(s), but got ${inputArgNodes.length}`, node);
|
|
156
|
+
}
|
|
157
|
+
let inputArgValues = [];
|
|
158
|
+
for (let i = 0; i < inputArgNodes.length; i++) {
|
|
159
|
+
const arg = inputArgNodes[i];
|
|
160
|
+
let argResult = arg.execute.runtimeExecute(scope, arg, null);
|
|
161
|
+
let argResultType = argResult.castType ?? (argResult.type ? [argResult.type] : null);
|
|
162
|
+
let stack = new ErrorStack({ Version: scope.version, SourceFile: node.file.sourceLocation });
|
|
163
|
+
if (!isAssignableCompile(scope.version, funcType.parameters[i].type, argResultType, arg, stack)) {
|
|
164
|
+
throw new ExpressionSyntaxError(`Argument ${i + 1} type mismatch: ${describeObject(argResult.value)} is not assignable to any of [${funcType.parameters[i].type.map(e => e.kind == "function" ? "function" : e.debugName).join(", ")}]` + stack.toString(`EXP_GF_FC_02`), node);
|
|
165
|
+
}
|
|
166
|
+
inputArgValues.push(argResult.value);
|
|
167
|
+
}
|
|
168
|
+
// Call the function
|
|
169
|
+
const result = funcValue.value(node, ...inputArgValues);
|
|
170
|
+
let stack = new ErrorStack({ Version: scope.version, SourceFile: node.file.sourceLocation });
|
|
171
|
+
if (!isAssignableCompile(scope.version, outputType, result, node, stack)) {
|
|
172
|
+
throw new ExpressionSyntaxError(`Function return type mismatch: ${describeObject(result.value)} is not assignable to any of [${outputType?.map(e => e.kind == "function" ? "function" : e.debugName).join(", ")}]` + stack.toString(`EXP_GF_FC_03`), node);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
value: result.value,
|
|
176
|
+
type: result.type
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
compileTimeTraversal(scope, node, expectedType) {
|
|
180
|
+
const nameVal = node.values.name;
|
|
181
|
+
const argNodes = node.values.arguments;
|
|
182
|
+
let possibleFuncTypes = [];
|
|
183
|
+
if (isToken(nameVal)) {
|
|
184
|
+
// (1) It's a function name token
|
|
185
|
+
const funcName = nameVal.data;
|
|
186
|
+
const funcEntry = scope.local[funcName] ?? scope.global[funcName];
|
|
187
|
+
if (!funcEntry) {
|
|
188
|
+
throw new ExpressionSyntaxError(`Function '${funcName}' not found in scope`, node);
|
|
189
|
+
}
|
|
190
|
+
if (!funcEntry.type) {
|
|
191
|
+
throw new ExpressionSyntaxError(`Function '${funcName}' has no type info`, node);
|
|
192
|
+
}
|
|
193
|
+
// We gather only the function types; if we find a non-function, we throw an error
|
|
194
|
+
funcEntry.type.forEach(t => {
|
|
195
|
+
if (t.kind === "function") {
|
|
196
|
+
possibleFuncTypes.push(t);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
throw new ExpressionSyntaxError(`Type mismatch: '${funcName}' is not a function type`, node);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
if (possibleFuncTypes.length === 0) {
|
|
203
|
+
throw new ExpressionSyntaxError(`'${funcName}' is not a valid function`, node);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
// (2) It's an expression => interpret as an inline function declaration
|
|
208
|
+
const funcTypeInfo = nameVal.execute.compileTimeTraversal(scope, nameVal, null);
|
|
209
|
+
const inlineTypes = funcTypeInfo?.type ?? [];
|
|
210
|
+
if (inlineTypes.length === 0) {
|
|
211
|
+
throw new ExpressionSyntaxError(`Inline function expression has no type`, node);
|
|
212
|
+
}
|
|
213
|
+
// If we find any type that is not a function, we throw
|
|
214
|
+
inlineTypes.forEach(t => {
|
|
215
|
+
if (t.kind !== "function") {
|
|
216
|
+
throw new ExpressionSyntaxError(`Inline expression is not a function`, node);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
possibleFuncTypes.push(t);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (possibleFuncTypes.length === 0) {
|
|
223
|
+
throw new ExpressionSyntaxError(`Inline function expression is invalid`, node);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Next, we match arguments to a candidate function signature
|
|
227
|
+
const argCount = argNodes.length;
|
|
228
|
+
let matchedType = null;
|
|
229
|
+
let errorStack = new ErrorStack({ Version: scope.version, SourceFile: node.file.sourceLocation });
|
|
230
|
+
//Candidate loop
|
|
231
|
+
for (const candidate of possibleFuncTypes) {
|
|
232
|
+
// Check param count
|
|
233
|
+
if (candidate.parameters.length !== argCount) {
|
|
234
|
+
continue; // not a match
|
|
235
|
+
}
|
|
236
|
+
// Verify each argument
|
|
237
|
+
let success = true;
|
|
238
|
+
for (let i = 0; i < argCount; i++) {
|
|
239
|
+
const argOutput = argNodes[i].execute.compileTimeTraversal(scope, argNodes[i], null);
|
|
240
|
+
// This function checks if any of argOutput.type is assignable to candidate.parameters[i].type
|
|
241
|
+
const argAssignable = isAssignableCompile(scope.version, candidate.parameters[i].type, argOutput?.type ?? null, node, errorStack);
|
|
242
|
+
if (!argAssignable) {
|
|
243
|
+
success = false;
|
|
244
|
+
break; // argument mismatch => candidate fails
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (!success) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
// If arguments matched, check return type vs expected
|
|
251
|
+
if (expectedType && !isAssignableCompile(scope.version, expectedType, candidate.returnType, node, errorStack)) {
|
|
252
|
+
continue; // This candidate doesn't match the expected return type
|
|
253
|
+
}
|
|
254
|
+
// We have a match
|
|
255
|
+
matchedType = candidate;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
if (!matchedType) {
|
|
259
|
+
throw new ExpressionSyntaxError(`No matching function signature found for call (${argCount} args)\n` + errorStack.toString("EXP_GF_FC_05"), node);
|
|
260
|
+
}
|
|
261
|
+
// Return the matched function's return type
|
|
262
|
+
return {
|
|
263
|
+
type: matchedType.returnType,
|
|
264
|
+
style: CollectionType.Single
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
export function IsReturnNode(node) {
|
|
269
|
+
return node.type === NodeType.RETURN;
|
|
270
|
+
}
|
|
271
|
+
GrammarRegistry.AddRule(Versions.v1_0_0, NodeType.RETURN, [[
|
|
272
|
+
{ type: TokenType.KEYWORD, value: "return" },
|
|
273
|
+
{ type: NodeType.EXPRESSION, unroll: true },
|
|
274
|
+
{ type: TokenType.OPERATOR, value: ";" }
|
|
275
|
+
]], {
|
|
276
|
+
runtimeExecute(scope, node, outputType) {
|
|
277
|
+
let result = node.values.expression.execute.runtimeExecute(scope, node.values.expression, null);
|
|
278
|
+
return {
|
|
279
|
+
type: result.type,
|
|
280
|
+
value: result.value,
|
|
281
|
+
interrupt: "return"
|
|
282
|
+
};
|
|
283
|
+
},
|
|
284
|
+
compileTimeTraversal(scope, node, expectedTypes) {
|
|
285
|
+
let result = node.values.expression.execute.compileTimeTraversal(scope, node.values.expression, expectedTypes);
|
|
286
|
+
return {
|
|
287
|
+
interrupt: "return",
|
|
288
|
+
type: result?.type ?? null,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
//# sourceMappingURL=Function.js.map
|