@elaraai/east 0.0.1-beta.3 → 0.0.1-beta.31
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/LICENSE.md +15 -666
- package/README.md +30 -8
- package/dist/src/analyze.d.ts +3 -0
- package/dist/src/analyze.d.ts.map +1 -1
- package/dist/src/analyze.js +76 -15
- package/dist/src/analyze.js.map +1 -1
- package/dist/src/ast.d.ts +37 -33
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast_to_ir.d.ts +6 -0
- package/dist/src/ast_to_ir.d.ts.map +1 -1
- package/dist/src/ast_to_ir.js +135 -101
- package/dist/src/ast_to_ir.js.map +1 -1
- package/dist/src/builtins.d.ts +1 -1
- package/dist/src/builtins.d.ts.map +1 -1
- package/dist/src/builtins.js +32 -0
- package/dist/src/builtins.js.map +1 -1
- package/dist/src/comparison.d.ts.map +1 -1
- package/dist/src/comparison.js +12 -4
- package/dist/src/comparison.js.map +1 -1
- package/dist/src/compile.d.ts +26 -1
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +388 -257
- package/dist/src/compile.js.map +1 -1
- package/dist/src/datetime_format/types.d.ts +23 -23
- package/dist/src/eastir.d.ts +4 -0
- package/dist/src/eastir.d.ts.map +1 -1
- package/dist/src/eastir.js +27 -7
- package/dist/src/eastir.js.map +1 -1
- package/dist/src/error.d.ts +12 -1
- package/dist/src/error.d.ts.map +1 -1
- package/dist/src/error.js +31 -1
- package/dist/src/error.js.map +1 -1
- package/dist/src/expr/array.d.ts +109 -1
- package/dist/src/expr/array.d.ts.map +1 -1
- package/dist/src/expr/array.js +204 -44
- package/dist/src/expr/array.js.map +1 -1
- package/dist/src/expr/ast.d.ts +1 -1
- package/dist/src/expr/ast.d.ts.map +1 -1
- package/dist/src/expr/ast.js +16 -28
- package/dist/src/expr/ast.js.map +1 -1
- package/dist/src/expr/asyncfunction.js +1 -1
- package/dist/src/expr/asyncfunction.js.map +1 -1
- package/dist/src/expr/blob.d.ts +73 -1
- package/dist/src/expr/blob.d.ts.map +1 -1
- package/dist/src/expr/blob.js +97 -7
- package/dist/src/expr/blob.js.map +1 -1
- package/dist/src/expr/block.d.ts +232 -12
- package/dist/src/expr/block.d.ts.map +1 -1
- package/dist/src/expr/block.js +646 -140
- package/dist/src/expr/block.js.map +1 -1
- package/dist/src/expr/boolean.d.ts +44 -0
- package/dist/src/expr/boolean.d.ts.map +1 -1
- package/dist/src/expr/boolean.js +57 -5
- package/dist/src/expr/boolean.js.map +1 -1
- package/dist/src/expr/datetime.d.ts +135 -0
- package/dist/src/expr/datetime.d.ts.map +1 -1
- package/dist/src/expr/datetime.js +183 -33
- package/dist/src/expr/datetime.js.map +1 -1
- package/dist/src/expr/dict.d.ts +42 -0
- package/dist/src/expr/dict.d.ts.map +1 -1
- package/dist/src/expr/dict.js +105 -55
- package/dist/src/expr/dict.js.map +1 -1
- package/dist/src/expr/expr.d.ts +1 -1
- package/dist/src/expr/expr.d.ts.map +1 -1
- package/dist/src/expr/expr.js.map +1 -1
- package/dist/src/expr/float.d.ts +153 -0
- package/dist/src/expr/float.d.ts.map +1 -1
- package/dist/src/expr/float.js +190 -16
- package/dist/src/expr/float.js.map +1 -1
- package/dist/src/expr/function.d.ts +7 -2
- package/dist/src/expr/function.d.ts.map +1 -1
- package/dist/src/expr/function.js +1 -1
- package/dist/src/expr/function.js.map +1 -1
- package/dist/src/expr/index.d.ts +202 -2
- package/dist/src/expr/index.d.ts.map +1 -1
- package/dist/src/expr/index.js +207 -2
- package/dist/src/expr/index.js.map +1 -1
- package/dist/src/expr/integer.d.ts +180 -0
- package/dist/src/expr/integer.d.ts.map +1 -1
- package/dist/src/expr/integer.js +188 -17
- package/dist/src/expr/integer.js.map +1 -1
- package/dist/src/expr/libs/blob.js +2 -2
- package/dist/src/expr/libs/blob.js.map +1 -1
- package/dist/src/expr/libs/integer.d.ts +19 -0
- package/dist/src/expr/libs/integer.d.ts.map +1 -1
- package/dist/src/expr/libs/integer.js +47 -0
- package/dist/src/expr/libs/integer.js.map +1 -1
- package/dist/src/expr/libs/string.js +1 -1
- package/dist/src/expr/libs/string.js.map +1 -1
- package/dist/src/expr/recursive.d.ts +83 -0
- package/dist/src/expr/recursive.d.ts.map +1 -0
- package/dist/src/expr/recursive.js +99 -0
- package/dist/src/expr/recursive.js.map +1 -0
- package/dist/src/expr/ref.js +3 -3
- package/dist/src/expr/ref.js.map +1 -1
- package/dist/src/expr/set.d.ts +44 -2
- package/dist/src/expr/set.d.ts.map +1 -1
- package/dist/src/expr/set.js +97 -47
- package/dist/src/expr/set.js.map +1 -1
- package/dist/src/expr/string.d.ts +134 -0
- package/dist/src/expr/string.d.ts.map +1 -1
- package/dist/src/expr/string.js +172 -22
- package/dist/src/expr/string.js.map +1 -1
- package/dist/src/expr/struct.d.ts +1 -1
- package/dist/src/expr/struct.d.ts.map +1 -1
- package/dist/src/expr/struct.js +1 -1
- package/dist/src/expr/struct.js.map +1 -1
- package/dist/src/expr/types.d.ts +7 -6
- package/dist/src/expr/types.d.ts.map +1 -1
- package/dist/src/expr/variant.d.ts +123 -1
- package/dist/src/expr/variant.d.ts.map +1 -1
- package/dist/src/expr/variant.js +66 -2
- package/dist/src/expr/variant.js.map +1 -1
- package/dist/src/fuzz.d.ts +36 -2
- package/dist/src/fuzz.d.ts.map +1 -1
- package/dist/src/fuzz.js +344 -77
- package/dist/src/fuzz.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/internal.d.ts +12 -0
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +13 -0
- package/dist/src/internal.js.map +1 -1
- package/dist/src/ir.d.ts +1551 -1505
- package/dist/src/ir.d.ts.map +1 -1
- package/dist/src/ir.js +49 -34
- package/dist/src/ir.js.map +1 -1
- package/dist/src/location.d.ts +30 -10
- package/dist/src/location.d.ts.map +1 -1
- package/dist/src/location.js +70 -28
- package/dist/src/location.js.map +1 -1
- package/dist/src/patch/apply.d.ts +15 -0
- package/dist/src/patch/apply.d.ts.map +1 -0
- package/dist/src/patch/apply.js +380 -0
- package/dist/src/patch/apply.js.map +1 -0
- package/dist/src/patch/compose.d.ts +15 -0
- package/dist/src/patch/compose.d.ts.map +1 -0
- package/dist/src/patch/compose.js +480 -0
- package/dist/src/patch/compose.js.map +1 -0
- package/dist/src/patch/diff.d.ts +15 -0
- package/dist/src/patch/diff.d.ts.map +1 -0
- package/dist/src/patch/diff.js +328 -0
- package/dist/src/patch/diff.js.map +1 -0
- package/dist/src/patch/fuzz.d.ts +73 -0
- package/dist/src/patch/fuzz.d.ts.map +1 -0
- package/dist/src/patch/fuzz.js +159 -0
- package/dist/src/patch/fuzz.js.map +1 -0
- package/dist/src/patch/index.d.ts +18 -0
- package/dist/src/patch/index.d.ts.map +1 -0
- package/dist/src/patch/index.js +20 -0
- package/dist/src/patch/index.js.map +1 -0
- package/dist/src/patch/invert.d.ts +15 -0
- package/dist/src/patch/invert.d.ts.map +1 -0
- package/dist/src/patch/invert.js +302 -0
- package/dist/src/patch/invert.js.map +1 -0
- package/dist/src/patch/type_of_patch.d.ts +17 -0
- package/dist/src/patch/type_of_patch.d.ts.map +1 -0
- package/dist/src/patch/type_of_patch.js +143 -0
- package/dist/src/patch/type_of_patch.js.map +1 -0
- package/dist/src/patch/types.d.ts +166 -0
- package/dist/src/patch/types.d.ts.map +1 -0
- package/dist/src/patch/types.js +69 -0
- package/dist/src/patch/types.js.map +1 -0
- package/dist/src/platform.d.ts +6 -0
- package/dist/src/platform.d.ts.map +1 -1
- package/dist/src/serialization/beast.d.ts.map +1 -1
- package/dist/src/serialization/beast.js +53 -18
- package/dist/src/serialization/beast.js.map +1 -1
- package/dist/src/serialization/beast2.d.ts +39 -3
- package/dist/src/serialization/beast2.d.ts.map +1 -1
- package/dist/src/serialization/beast2.js +241 -18
- package/dist/src/serialization/beast2.js.map +1 -1
- package/dist/src/serialization/csv.d.ts +139 -0
- package/dist/src/serialization/csv.d.ts.map +1 -0
- package/dist/src/serialization/csv.js +615 -0
- package/dist/src/serialization/csv.js.map +1 -0
- package/dist/src/serialization/index.d.ts +2 -1
- package/dist/src/serialization/index.d.ts.map +1 -1
- package/dist/src/serialization/index.js +2 -1
- package/dist/src/serialization/index.js.map +1 -1
- package/dist/src/type_of_type.d.ts +45 -34
- package/dist/src/type_of_type.d.ts.map +1 -1
- package/dist/src/type_of_type.js +62 -1
- package/dist/src/type_of_type.js.map +1 -1
- package/dist/src/types.d.ts +8 -8
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +4 -4
- package/dist/src/types.js.map +1 -1
- package/package.json +4 -5
package/dist/src/ast_to_ir.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import { printLocationValue } from "./ir.js";
|
|
2
|
-
import {
|
|
2
|
+
import { printLocations } from "./location.js";
|
|
3
3
|
import { toEastTypeValue } from "./type_of_type.js";
|
|
4
4
|
import { ArrayType, DictType, FunctionType, isSubtype, isTypeEqual, NeverType, NullType, printType, RefType, SetType, StructType, VariantType } from "./types.js";
|
|
5
5
|
import { variant } from "./containers/variant.js";
|
|
6
6
|
import { applyTypeParameters, Builtins } from "./builtins.js";
|
|
7
|
+
/** @internal An exception throw for the purpose of early loop continue */
|
|
8
|
+
export class OutOfScopeException extends Error {
|
|
9
|
+
definedLocation;
|
|
10
|
+
constructor(definedLocation) {
|
|
11
|
+
super(`Variable defined at ${printLocations(definedLocation)} is out of scope here`);
|
|
12
|
+
this.definedLocation = definedLocation;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
7
15
|
// TODO we should probably redo type checking exhaustively here?
|
|
8
|
-
function
|
|
9
|
-
return {
|
|
10
|
-
filename:
|
|
11
|
-
line: BigInt(
|
|
12
|
-
column: BigInt(
|
|
13
|
-
};
|
|
16
|
+
function toLocationValues(locations) {
|
|
17
|
+
return locations.map(loc => ({
|
|
18
|
+
filename: loc.filename,
|
|
19
|
+
line: BigInt(loc.line),
|
|
20
|
+
column: BigInt(loc.column),
|
|
21
|
+
}));
|
|
14
22
|
}
|
|
15
23
|
/** Perform scope resolution and type checking on `AST`, produce `IR` ready for serialization, compilation or evaluation.
|
|
16
24
|
*
|
|
@@ -29,7 +37,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
29
37
|
return ir;
|
|
30
38
|
}
|
|
31
39
|
else {
|
|
32
|
-
throw new
|
|
40
|
+
throw new OutOfScopeException(ast.location);
|
|
33
41
|
}
|
|
34
42
|
}
|
|
35
43
|
}
|
|
@@ -39,7 +47,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
39
47
|
const variable = variant("Variable", {
|
|
40
48
|
type: toEastTypeValue(ast.variable.type),
|
|
41
49
|
name: `_${ctx.n_vars}`,
|
|
42
|
-
location:
|
|
50
|
+
location: toLocationValues(ast.variable.location),
|
|
43
51
|
mutable: ast.variable.mutable,
|
|
44
52
|
captured: false,
|
|
45
53
|
});
|
|
@@ -50,19 +58,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
50
58
|
// This catches type errors early at AST level
|
|
51
59
|
if (!isSubtype(ast.value.type, ast.variable.type)) {
|
|
52
60
|
throw new Error(`Cannot initialize variable of type ${printType(ast.variable.type)} ` +
|
|
53
|
-
`with value of type ${printType(ast.value.type)} at ${
|
|
61
|
+
`with value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}`);
|
|
54
62
|
}
|
|
55
63
|
value = variant("As", {
|
|
56
64
|
type: toEastTypeValue(ast.variable.type),
|
|
57
65
|
value,
|
|
58
|
-
location:
|
|
66
|
+
location: toLocationValues(ast.location),
|
|
59
67
|
});
|
|
60
68
|
}
|
|
61
69
|
ctx.n_vars += 1;
|
|
62
70
|
ctx.local_ctx.set(ast.variable, variable);
|
|
63
71
|
return variant("Let", {
|
|
64
72
|
type: toEastTypeValue(ast.type),
|
|
65
|
-
location:
|
|
73
|
+
location: toLocationValues(ast.location),
|
|
66
74
|
variable,
|
|
67
75
|
value,
|
|
68
76
|
});
|
|
@@ -71,7 +79,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
71
79
|
// Fetch the variable from context
|
|
72
80
|
const variable = ast_to_ir(ast.variable, ctx);
|
|
73
81
|
if (!variable.value.mutable) {
|
|
74
|
-
throw new Error(`Variable defined const at ${printLocationValue(variable.value.location)} is being reassigned at ${
|
|
82
|
+
throw new Error(`Variable defined const at ${printLocationValue(variable.value.location)} is being reassigned at ${printLocations(ast.location)}`);
|
|
75
83
|
}
|
|
76
84
|
let value = ast_to_ir(ast.value, ctx);
|
|
77
85
|
// Get the variable's type from the IR node
|
|
@@ -82,17 +90,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
82
90
|
// Validate subtype relationship before inserting As node
|
|
83
91
|
if (!isSubtype(ast.value.type, ast.variable.type)) {
|
|
84
92
|
throw new Error(`Cannot assign value of type ${printType(ast.value.type)} ` +
|
|
85
|
-
`to variable of type ${printType(ast.variable.type)} at ${
|
|
93
|
+
`to variable of type ${printType(ast.variable.type)} at ${printLocations(ast.location)}`);
|
|
86
94
|
}
|
|
87
95
|
value = variant("As", {
|
|
88
96
|
type: variableType,
|
|
89
97
|
value,
|
|
90
|
-
location:
|
|
98
|
+
location: toLocationValues(ast.location),
|
|
91
99
|
});
|
|
92
100
|
}
|
|
93
101
|
return variant("Assign", {
|
|
94
102
|
type: toEastTypeValue(ast.type),
|
|
95
|
-
location:
|
|
103
|
+
location: toLocationValues(ast.location),
|
|
96
104
|
variable,
|
|
97
105
|
value,
|
|
98
106
|
});
|
|
@@ -105,7 +113,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
105
113
|
ctx.n_loops = ctx2.n_loops;
|
|
106
114
|
return variant("Block", {
|
|
107
115
|
type: toEastTypeValue(ast.type),
|
|
108
|
-
location:
|
|
116
|
+
location: toLocationValues(ast.location),
|
|
109
117
|
statements,
|
|
110
118
|
});
|
|
111
119
|
}
|
|
@@ -114,18 +122,18 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
114
122
|
const builtin_name = ast.builtin;
|
|
115
123
|
const builtin_def = Builtins[builtin_name];
|
|
116
124
|
if (!builtin_def) {
|
|
117
|
-
throw new Error(`Unknown builtin function '${builtin_name}' at ${
|
|
125
|
+
throw new Error(`Unknown builtin function '${builtin_name}' at ${printLocations(ast.location)}`);
|
|
118
126
|
}
|
|
119
127
|
if (builtin_def.type_parameters.length !== ast.type_parameters.length) {
|
|
120
|
-
throw new Error(`Builtin function '${builtin_name}' expected ${builtin_def.type_parameters.length} type parameters, got ${ast.type_parameters.length} at ${
|
|
128
|
+
throw new Error(`Builtin function '${builtin_name}' expected ${builtin_def.type_parameters.length} type parameters, got ${ast.type_parameters.length} at ${printLocations(ast.location)}`);
|
|
121
129
|
}
|
|
122
130
|
const type_map = new Map(builtin_def.type_parameters.map((name, i) => [name, ast.type_parameters[i]]));
|
|
123
131
|
if (ast.arguments.length !== builtin_def.inputs.length) {
|
|
124
|
-
throw new Error(`Builtin function '${builtin_name}' expected ${builtin_def.inputs.length} arguments, got ${ast.arguments.length} at ${
|
|
132
|
+
throw new Error(`Builtin function '${builtin_name}' expected ${builtin_def.inputs.length} arguments, got ${ast.arguments.length} at ${printLocations(ast.location)}`);
|
|
125
133
|
}
|
|
126
134
|
return variant("Builtin", {
|
|
127
135
|
type: toEastTypeValue(ast.type),
|
|
128
|
-
location:
|
|
136
|
+
location: toLocationValues(ast.location),
|
|
129
137
|
builtin: ast.builtin,
|
|
130
138
|
type_parameters: ast.type_parameters.map(tp => toEastTypeValue(tp)),
|
|
131
139
|
arguments: ast.arguments.map((arg, i) => {
|
|
@@ -134,12 +142,12 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
134
142
|
// Now check type compatibility
|
|
135
143
|
if (arg.type.type !== "Never" && !isTypeEqual(arg.type, expectedType)) {
|
|
136
144
|
if (!isSubtype(arg.type, expectedType)) {
|
|
137
|
-
throw new Error(`Builtin ${builtin_name} with type parameters [${ast.type_parameters.map(tp => printType(tp)).join(", ")}] argument ${i} of type ${printType(arg.type)} is not compatible with expected type ${printType(expectedType)} at ${
|
|
145
|
+
throw new Error(`Builtin ${builtin_name} with type parameters [${ast.type_parameters.map(tp => printType(tp)).join(", ")}] argument ${i} of type ${printType(arg.type)} is not compatible with expected type ${printType(expectedType)} at ${printLocations(ast.location)}`);
|
|
138
146
|
}
|
|
139
147
|
arg_ir = variant("As", {
|
|
140
|
-
type: toEastTypeValue(
|
|
148
|
+
type: toEastTypeValue(expectedType),
|
|
141
149
|
value: arg_ir,
|
|
142
|
-
location:
|
|
150
|
+
location: toLocationValues(ast.location),
|
|
143
151
|
});
|
|
144
152
|
}
|
|
145
153
|
return arg_ir;
|
|
@@ -148,37 +156,39 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
148
156
|
}
|
|
149
157
|
else if (ast.ast_type === "Platform") {
|
|
150
158
|
if (ctx.async === false && ast.async === true) {
|
|
151
|
-
throw new Error(`Async platform call not allowed outside async function at ${
|
|
159
|
+
throw new Error(`Async platform call not allowed outside async function at ${printLocations(ast.location)}`);
|
|
152
160
|
}
|
|
153
161
|
return variant("Platform", {
|
|
154
162
|
type: toEastTypeValue(ast.type),
|
|
155
|
-
location:
|
|
163
|
+
location: toLocationValues(ast.location),
|
|
156
164
|
name: ast.name,
|
|
165
|
+
type_parameters: ast.type_parameters.map(tp => toEastTypeValue(tp)),
|
|
157
166
|
arguments: ast.arguments.map(ast => ast_to_ir(ast, ctx)), // type equality handled at Expr/AST level
|
|
158
167
|
async: ast.async,
|
|
168
|
+
optional: ast.optional,
|
|
159
169
|
});
|
|
160
170
|
}
|
|
161
171
|
else if (ast.ast_type === "Struct") {
|
|
162
172
|
return variant("Struct", {
|
|
163
173
|
type: toEastTypeValue(ast.type),
|
|
164
|
-
location:
|
|
174
|
+
location: toLocationValues(ast.location),
|
|
165
175
|
fields: Object.entries(ast.fields).map(([name, fieldAst]) => {
|
|
166
176
|
let value = ast_to_ir(fieldAst, ctx);
|
|
167
177
|
const expectedType = ast.type.fields[name];
|
|
168
178
|
if (!expectedType) {
|
|
169
|
-
throw new Error(`Struct type does not have field '${name}' at ${
|
|
179
|
+
throw new Error(`Struct type does not have field '${name}' at ${printLocations(ast.location)}`);
|
|
170
180
|
}
|
|
171
181
|
if (!isTypeEqual(fieldAst.type, expectedType)) {
|
|
172
182
|
if (isSubtype(fieldAst.type, expectedType)) {
|
|
173
183
|
value = variant("As", {
|
|
174
184
|
type: toEastTypeValue(expectedType),
|
|
175
185
|
value,
|
|
176
|
-
location:
|
|
186
|
+
location: toLocationValues(ast.location),
|
|
177
187
|
});
|
|
178
188
|
}
|
|
179
189
|
else {
|
|
180
190
|
throw new Error(`Cannot assign field '${name}' of type ${printType(ast.type.fields[name])} ` +
|
|
181
|
-
`with value of type ${printType(fieldAst.type)} at ${
|
|
191
|
+
`with value of type ${printType(fieldAst.type)} at ${printLocations(ast.location)}`);
|
|
182
192
|
}
|
|
183
193
|
}
|
|
184
194
|
return { name, value };
|
|
@@ -188,7 +198,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
188
198
|
else if (ast.ast_type === "GetField") {
|
|
189
199
|
return variant("GetField", {
|
|
190
200
|
type: toEastTypeValue(ast.type),
|
|
191
|
-
location:
|
|
201
|
+
location: toLocationValues(ast.location),
|
|
192
202
|
struct: ast_to_ir(ast.struct, ctx),
|
|
193
203
|
field: ast.field,
|
|
194
204
|
});
|
|
@@ -201,17 +211,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
201
211
|
value = variant("As", {
|
|
202
212
|
type: toEastTypeValue(expectedType),
|
|
203
213
|
value,
|
|
204
|
-
location:
|
|
214
|
+
location: toLocationValues(ast.location),
|
|
205
215
|
});
|
|
206
216
|
}
|
|
207
217
|
else {
|
|
208
218
|
throw new Error(`Cannot assign case '${ast.case}' of type ${printType(expectedType)} ` +
|
|
209
|
-
`with value of type ${printType(ast.value.type)} at ${
|
|
219
|
+
`with value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}`);
|
|
210
220
|
}
|
|
211
221
|
}
|
|
212
222
|
return variant("Variant", {
|
|
213
223
|
type: toEastTypeValue(ast.type),
|
|
214
|
-
location:
|
|
224
|
+
location: toLocationValues(ast.location),
|
|
215
225
|
case: ast.case,
|
|
216
226
|
value,
|
|
217
227
|
});
|
|
@@ -221,7 +231,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
221
231
|
const param = variant("Variable", {
|
|
222
232
|
type: toEastTypeValue(parameter.type),
|
|
223
233
|
name: `_${ctx.n_vars}`,
|
|
224
|
-
location:
|
|
234
|
+
location: toLocationValues(parameter.location),
|
|
225
235
|
mutable: parameter.mutable, // false...
|
|
226
236
|
captured: false,
|
|
227
237
|
});
|
|
@@ -235,9 +245,21 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
235
245
|
const body = ast_to_ir(ast.body, ctx2);
|
|
236
246
|
ctx.n_vars = ctx2.n_vars;
|
|
237
247
|
ctx.n_loops = ctx2.n_loops;
|
|
248
|
+
// Propagate captures: if this function captured something from ctx.parent_ctx,
|
|
249
|
+
// then the enclosing function also needs to capture it
|
|
250
|
+
for (const capturedVar of captures) {
|
|
251
|
+
// Check if this variable came from our parent context (not defined locally in enclosing function)
|
|
252
|
+
for (const [_astVar, ir] of ctx.parent_ctx) {
|
|
253
|
+
if (ir === capturedVar) {
|
|
254
|
+
// This capture came from an outer scope, so enclosing function must also capture it
|
|
255
|
+
ctx.captures.add(capturedVar);
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
238
260
|
return variant("Function", {
|
|
239
261
|
type: toEastTypeValue(ast.type),
|
|
240
|
-
location:
|
|
262
|
+
location: toLocationValues(ast.location),
|
|
241
263
|
parameters,
|
|
242
264
|
captures: [...captures],
|
|
243
265
|
body,
|
|
@@ -248,7 +270,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
248
270
|
const param = variant("Variable", {
|
|
249
271
|
type: toEastTypeValue(parameter.type),
|
|
250
272
|
name: `_${ctx.n_vars}`,
|
|
251
|
-
location:
|
|
273
|
+
location: toLocationValues(parameter.location),
|
|
252
274
|
mutable: parameter.mutable, // false...
|
|
253
275
|
captured: false,
|
|
254
276
|
});
|
|
@@ -262,9 +284,21 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
262
284
|
const body = ast_to_ir(ast.body, ctx2);
|
|
263
285
|
ctx.n_vars = ctx2.n_vars;
|
|
264
286
|
ctx.n_loops = ctx2.n_loops;
|
|
287
|
+
// Propagate captures: if this function captured something from ctx.parent_ctx,
|
|
288
|
+
// then the enclosing function also needs to capture it
|
|
289
|
+
for (const capturedVar of captures) {
|
|
290
|
+
// Check if this variable came from our parent context (not defined locally in enclosing function)
|
|
291
|
+
for (const [_astVar, ir] of ctx.parent_ctx) {
|
|
292
|
+
if (ir === capturedVar) {
|
|
293
|
+
// This capture came from an outer scope, so enclosing function must also capture it
|
|
294
|
+
ctx.captures.add(capturedVar);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
265
299
|
return variant("AsyncFunction", {
|
|
266
300
|
type: toEastTypeValue(ast.type),
|
|
267
|
-
location:
|
|
301
|
+
location: toLocationValues(ast.location),
|
|
268
302
|
parameters,
|
|
269
303
|
captures: [...captures],
|
|
270
304
|
body,
|
|
@@ -275,19 +309,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
275
309
|
// TODO - what about widening the result with As?
|
|
276
310
|
return variant("Call", {
|
|
277
311
|
type: toEastTypeValue(ast.type),
|
|
278
|
-
location:
|
|
312
|
+
location: toLocationValues(ast.location),
|
|
279
313
|
function: ast_to_ir(ast.function, ctx),
|
|
280
314
|
arguments: ast.arguments.map((argument, i) => {
|
|
281
315
|
let arg = ast_to_ir(argument, ctx);
|
|
282
316
|
const expectedType = ast.function.type.inputs[i];
|
|
283
317
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
284
318
|
if (!isSubtype(argument.type, expectedType)) {
|
|
285
|
-
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${
|
|
319
|
+
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${printLocations(ast.location)}`);
|
|
286
320
|
}
|
|
287
321
|
arg = variant("As", {
|
|
288
322
|
type: toEastTypeValue(expectedType),
|
|
289
323
|
value: arg,
|
|
290
|
-
location:
|
|
324
|
+
location: toLocationValues(ast.location),
|
|
291
325
|
});
|
|
292
326
|
}
|
|
293
327
|
return arg;
|
|
@@ -296,25 +330,25 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
296
330
|
}
|
|
297
331
|
else if (ast.ast_type === "CallAsync") {
|
|
298
332
|
if (ctx.async === false) {
|
|
299
|
-
throw new Error(`Async function call not allowed outside async function at ${
|
|
333
|
+
throw new Error(`Async function call not allowed outside async function at ${printLocations(ast.location)}`);
|
|
300
334
|
}
|
|
301
335
|
// TODO - type equality could have been handled at Expr/AST level instead
|
|
302
336
|
// TODO - what about widening the result with As?
|
|
303
337
|
return variant("CallAsync", {
|
|
304
338
|
type: toEastTypeValue(ast.type),
|
|
305
|
-
location:
|
|
339
|
+
location: toLocationValues(ast.location),
|
|
306
340
|
function: ast_to_ir(ast.function, ctx),
|
|
307
341
|
arguments: ast.arguments.map((argument, i) => {
|
|
308
342
|
let arg = ast_to_ir(argument, ctx);
|
|
309
343
|
const expectedType = ast.function.type.inputs[i];
|
|
310
344
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
311
345
|
if (!isSubtype(argument.type, expectedType)) {
|
|
312
|
-
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${
|
|
346
|
+
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${printLocations(ast.location)}`);
|
|
313
347
|
}
|
|
314
348
|
arg = variant("As", {
|
|
315
349
|
type: toEastTypeValue(expectedType),
|
|
316
350
|
value: arg,
|
|
317
|
-
location:
|
|
351
|
+
location: toLocationValues(ast.location),
|
|
318
352
|
});
|
|
319
353
|
}
|
|
320
354
|
return arg;
|
|
@@ -326,17 +360,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
326
360
|
let value = ast_to_ir(ast.value, ctx);
|
|
327
361
|
if (!isTypeEqual(ast.value.type, valueType)) {
|
|
328
362
|
if (!isSubtype(ast.value.type, valueType)) {
|
|
329
|
-
throw new Error(`Ref value of type ${printType(ast.value.type)} is not compatible with expected type ${printType(valueType)} at ${
|
|
363
|
+
throw new Error(`Ref value of type ${printType(ast.value.type)} is not compatible with expected type ${printType(valueType)} at ${printLocations(ast.location)}`);
|
|
330
364
|
}
|
|
331
365
|
value = variant("As", {
|
|
332
366
|
type: toEastTypeValue(valueType),
|
|
333
367
|
value,
|
|
334
|
-
location:
|
|
368
|
+
location: toLocationValues(ast.location),
|
|
335
369
|
});
|
|
336
370
|
}
|
|
337
371
|
return variant("NewRef", {
|
|
338
372
|
type: toEastTypeValue(ast.type),
|
|
339
|
-
location:
|
|
373
|
+
location: toLocationValues(ast.location),
|
|
340
374
|
value,
|
|
341
375
|
});
|
|
342
376
|
}
|
|
@@ -344,17 +378,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
344
378
|
const valueType = ast.type.value;
|
|
345
379
|
return variant("NewArray", {
|
|
346
380
|
type: toEastTypeValue(ast.type),
|
|
347
|
-
location:
|
|
381
|
+
location: toLocationValues(ast.location),
|
|
348
382
|
values: ast.values.map((v, i) => {
|
|
349
383
|
let value = ast_to_ir(v, ctx);
|
|
350
384
|
if (!isTypeEqual(v.type, valueType)) {
|
|
351
385
|
if (!isSubtype(v.type, valueType)) {
|
|
352
|
-
throw new Error(`Array value at entry ${i} of type ${printType(v.type)} is not compatible with expected type ${printType(valueType)} at ${
|
|
386
|
+
throw new Error(`Array value at entry ${i} of type ${printType(v.type)} is not compatible with expected type ${printType(valueType)} at ${printLocations(ast.location)}`);
|
|
353
387
|
}
|
|
354
388
|
value = variant("As", {
|
|
355
389
|
type: toEastTypeValue(valueType),
|
|
356
390
|
value,
|
|
357
|
-
location:
|
|
391
|
+
location: toLocationValues(ast.location),
|
|
358
392
|
});
|
|
359
393
|
}
|
|
360
394
|
return value;
|
|
@@ -365,17 +399,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
365
399
|
const keyType = ast.type.key;
|
|
366
400
|
return variant("NewSet", {
|
|
367
401
|
type: toEastTypeValue(ast.type),
|
|
368
|
-
location:
|
|
402
|
+
location: toLocationValues(ast.location),
|
|
369
403
|
values: ast.values.map((k, i) => {
|
|
370
404
|
let key = ast_to_ir(k, ctx);
|
|
371
405
|
if (!isTypeEqual(k.type, keyType)) {
|
|
372
406
|
if (!isSubtype(k.type, keyType)) {
|
|
373
|
-
throw new Error(`Set key at entry ${i} of type ${printType(k.type)} is not compatible with expected type ${printType(keyType)} at ${
|
|
407
|
+
throw new Error(`Set key at entry ${i} of type ${printType(k.type)} is not compatible with expected type ${printType(keyType)} at ${printLocations(ast.location)}`);
|
|
374
408
|
}
|
|
375
409
|
key = variant("As", {
|
|
376
410
|
type: toEastTypeValue(keyType),
|
|
377
411
|
value: key,
|
|
378
|
-
location:
|
|
412
|
+
location: toLocationValues(ast.location),
|
|
379
413
|
});
|
|
380
414
|
}
|
|
381
415
|
return key;
|
|
@@ -387,28 +421,28 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
387
421
|
const valueType = ast.type.value;
|
|
388
422
|
return variant("NewDict", {
|
|
389
423
|
type: toEastTypeValue(ast.type),
|
|
390
|
-
location:
|
|
424
|
+
location: toLocationValues(ast.location),
|
|
391
425
|
values: ast.values.map(([k, v], i) => {
|
|
392
426
|
let key = ast_to_ir(k, ctx);
|
|
393
427
|
if (!isTypeEqual(k.type, keyType)) {
|
|
394
428
|
if (!isSubtype(k.type, keyType)) {
|
|
395
|
-
throw new Error(`Dict key at entry ${i} of type ${printType(k.type)} is not compatible with expected type ${printType(keyType)} at ${
|
|
429
|
+
throw new Error(`Dict key at entry ${i} of type ${printType(k.type)} is not compatible with expected type ${printType(keyType)} at ${printLocations(ast.location)}`);
|
|
396
430
|
}
|
|
397
431
|
key = variant("As", {
|
|
398
432
|
type: toEastTypeValue(keyType),
|
|
399
433
|
value: key,
|
|
400
|
-
location:
|
|
434
|
+
location: toLocationValues(ast.location),
|
|
401
435
|
});
|
|
402
436
|
}
|
|
403
437
|
let value = ast_to_ir(v, ctx);
|
|
404
438
|
if (!isTypeEqual(v.type, valueType)) {
|
|
405
439
|
if (!isSubtype(v.type, valueType)) {
|
|
406
|
-
throw new Error(`Dict value at entry ${i} of type ${printType(v.type)} is not compatible with expected type ${printType(valueType)} at ${
|
|
440
|
+
throw new Error(`Dict value at entry ${i} of type ${printType(v.type)} is not compatible with expected type ${printType(valueType)} at ${printLocations(ast.location)}`);
|
|
407
441
|
}
|
|
408
442
|
value = variant("As", {
|
|
409
443
|
type: toEastTypeValue(valueType),
|
|
410
444
|
value,
|
|
411
|
-
location:
|
|
445
|
+
location: toLocationValues(ast.location),
|
|
412
446
|
});
|
|
413
447
|
}
|
|
414
448
|
;
|
|
@@ -435,12 +469,12 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
435
469
|
ctx.n_loops = ctx_branch.n_loops;
|
|
436
470
|
if (branch.body.type.type !== "Never" && !isTypeEqual(branch.body.type, ast.type)) {
|
|
437
471
|
if (!isSubtype(branch.body.type, ast.type)) {
|
|
438
|
-
throw new Error(`If branch body of type ${printType(branch.body.type)} is not compatible with expected type ${printType(ast.type)} at ${
|
|
472
|
+
throw new Error(`If branch body of type ${printType(branch.body.type)} is not compatible with expected type ${printType(ast.type)} at ${printLocations(ast.location)}`);
|
|
439
473
|
}
|
|
440
474
|
branch_body = variant("As", {
|
|
441
475
|
type: toEastTypeValue(ast.type),
|
|
442
476
|
value: branch_body,
|
|
443
|
-
location:
|
|
477
|
+
location: toLocationValues(ast.location),
|
|
444
478
|
});
|
|
445
479
|
}
|
|
446
480
|
return { predicate, body: branch_body };
|
|
@@ -461,17 +495,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
461
495
|
ctx.n_loops = ctx_else.n_loops;
|
|
462
496
|
if (ast.else_body.type.type !== "Never" && !isTypeEqual(ast.else_body.type, ast.type)) {
|
|
463
497
|
if (!isSubtype(ast.else_body.type, ast.type)) {
|
|
464
|
-
throw new Error(`Else branch body of type ${printType(ast.else_body.type)} is not compatible with expected type ${printType(ast.type)} at ${
|
|
498
|
+
throw new Error(`Else branch body of type ${printType(ast.else_body.type)} is not compatible with expected type ${printType(ast.type)} at ${printLocations(ast.location)}`);
|
|
465
499
|
}
|
|
466
500
|
else_body = variant("As", {
|
|
467
501
|
type: toEastTypeValue(ast.type),
|
|
468
502
|
value: else_body,
|
|
469
|
-
location:
|
|
503
|
+
location: toLocationValues(ast.location),
|
|
470
504
|
});
|
|
471
505
|
}
|
|
472
506
|
return variant("IfElse", {
|
|
473
507
|
type: toEastTypeValue(ast.type),
|
|
474
|
-
location:
|
|
508
|
+
location: toLocationValues(ast.location),
|
|
475
509
|
ifs,
|
|
476
510
|
else_body,
|
|
477
511
|
});
|
|
@@ -479,7 +513,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
479
513
|
else if (ast.ast_type === "Error") {
|
|
480
514
|
return variant("Error", {
|
|
481
515
|
type: variant("Never", null),
|
|
482
|
-
location:
|
|
516
|
+
location: toLocationValues(ast.location),
|
|
483
517
|
message: ast_to_ir(ast.message, ctx),
|
|
484
518
|
});
|
|
485
519
|
}
|
|
@@ -502,7 +536,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
502
536
|
const message = variant("Variable", {
|
|
503
537
|
type: toEastTypeValue(ast.message.type),
|
|
504
538
|
name: `_${ctx.n_vars}`,
|
|
505
|
-
location:
|
|
539
|
+
location: toLocationValues(ast.message.location),
|
|
506
540
|
mutable: ast.message.mutable, // false...
|
|
507
541
|
captured: false,
|
|
508
542
|
});
|
|
@@ -510,7 +544,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
510
544
|
const stack = variant("Variable", {
|
|
511
545
|
type: toEastTypeValue(ast.stack.type),
|
|
512
546
|
name: `_${ctx.n_vars}`,
|
|
513
|
-
location:
|
|
547
|
+
location: toLocationValues(ast.stack.location),
|
|
514
548
|
mutable: ast.stack.mutable, // false...
|
|
515
549
|
captured: false,
|
|
516
550
|
});
|
|
@@ -550,13 +584,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
550
584
|
else {
|
|
551
585
|
finally_body = variant("Value", {
|
|
552
586
|
type: toEastTypeValue(NullType),
|
|
553
|
-
location:
|
|
587
|
+
location: toLocationValues(ast.location),
|
|
554
588
|
value: variant("Null", null),
|
|
555
589
|
});
|
|
556
590
|
}
|
|
557
591
|
return variant("TryCatch", {
|
|
558
592
|
type: toEastTypeValue(ast.type),
|
|
559
|
-
location:
|
|
593
|
+
location: toLocationValues(ast.location),
|
|
560
594
|
try_body,
|
|
561
595
|
catch_body,
|
|
562
596
|
message,
|
|
@@ -592,18 +626,18 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
592
626
|
throw new Error(`Unsupported literal value type: ${typeof ast.value} (expected ${printType(ast.type)})`);
|
|
593
627
|
}
|
|
594
628
|
if (type.type !== value.type) {
|
|
595
|
-
throw new Error(`Literal value type mismatch at ${
|
|
629
|
+
throw new Error(`Literal value type mismatch at ${printLocations(ast.location)}: expected .${type.type} but got .${value.type}`);
|
|
596
630
|
}
|
|
597
631
|
return variant("Value", {
|
|
598
632
|
type,
|
|
599
|
-
location:
|
|
633
|
+
location: toLocationValues(ast.location),
|
|
600
634
|
value,
|
|
601
635
|
});
|
|
602
636
|
}
|
|
603
637
|
else if (ast.ast_type === "As") {
|
|
604
638
|
return variant("As", {
|
|
605
639
|
type: toEastTypeValue(ast.type),
|
|
606
|
-
location:
|
|
640
|
+
location: toLocationValues(ast.location),
|
|
607
641
|
value: ast_to_ir(ast.value, ctx),
|
|
608
642
|
});
|
|
609
643
|
}
|
|
@@ -611,7 +645,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
611
645
|
const predicate = ast_to_ir(ast.predicate, ctx);
|
|
612
646
|
const label = {
|
|
613
647
|
name: `_${ctx.n_loops}`,
|
|
614
|
-
location:
|
|
648
|
+
location: toLocationValues(ast.label.location),
|
|
615
649
|
};
|
|
616
650
|
ctx.n_loops += 1;
|
|
617
651
|
const ctx2 = {
|
|
@@ -630,7 +664,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
630
664
|
ctx.n_loops = ctx2.n_loops;
|
|
631
665
|
return variant("While", {
|
|
632
666
|
type: variant("Null", null),
|
|
633
|
-
location:
|
|
667
|
+
location: toLocationValues(ast.location),
|
|
634
668
|
label,
|
|
635
669
|
predicate,
|
|
636
670
|
body,
|
|
@@ -640,13 +674,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
640
674
|
const array = ast_to_ir(ast.array, ctx);
|
|
641
675
|
const label = {
|
|
642
676
|
name: `_${ctx.n_loops}`,
|
|
643
|
-
location:
|
|
677
|
+
location: toLocationValues(ast.label.location),
|
|
644
678
|
};
|
|
645
679
|
ctx.n_loops += 1;
|
|
646
680
|
const value = variant("Variable", {
|
|
647
681
|
type: toEastTypeValue(ast.value.type),
|
|
648
682
|
name: `_${ctx.n_vars}`,
|
|
649
|
-
location:
|
|
683
|
+
location: toLocationValues(ast.value.location),
|
|
650
684
|
mutable: ast.value.mutable, // false...
|
|
651
685
|
captured: false,
|
|
652
686
|
});
|
|
@@ -654,7 +688,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
654
688
|
const key = variant("Variable", {
|
|
655
689
|
type: toEastTypeValue(ast.key.type),
|
|
656
690
|
name: `_${ctx.n_vars}`,
|
|
657
|
-
location:
|
|
691
|
+
location: toLocationValues(ast.key.location),
|
|
658
692
|
mutable: ast.key.mutable, // false...
|
|
659
693
|
captured: false,
|
|
660
694
|
});
|
|
@@ -675,7 +709,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
675
709
|
ctx.n_loops = ctx2.n_loops;
|
|
676
710
|
return variant("ForArray", {
|
|
677
711
|
type: variant("Null", null),
|
|
678
|
-
location:
|
|
712
|
+
location: toLocationValues(ast.location),
|
|
679
713
|
label,
|
|
680
714
|
key,
|
|
681
715
|
value,
|
|
@@ -687,13 +721,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
687
721
|
const set = ast_to_ir(ast.set, ctx);
|
|
688
722
|
const label = {
|
|
689
723
|
name: `_${ctx.n_loops}`,
|
|
690
|
-
location:
|
|
724
|
+
location: toLocationValues(ast.label.location),
|
|
691
725
|
};
|
|
692
726
|
ctx.n_loops += 1;
|
|
693
727
|
const key = variant("Variable", {
|
|
694
728
|
type: toEastTypeValue(ast.key.type),
|
|
695
729
|
name: `_${ctx.n_vars}`,
|
|
696
|
-
location:
|
|
730
|
+
location: toLocationValues(ast.key.location),
|
|
697
731
|
mutable: ast.key.mutable, // false...
|
|
698
732
|
captured: false,
|
|
699
733
|
});
|
|
@@ -714,7 +748,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
714
748
|
ctx.n_loops = ctx2.n_loops;
|
|
715
749
|
return variant("ForSet", {
|
|
716
750
|
type: variant("Null", null),
|
|
717
|
-
location:
|
|
751
|
+
location: toLocationValues(ast.location),
|
|
718
752
|
label,
|
|
719
753
|
key,
|
|
720
754
|
set,
|
|
@@ -725,13 +759,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
725
759
|
const dict = ast_to_ir(ast.dict, ctx);
|
|
726
760
|
const label = {
|
|
727
761
|
name: `_${ctx.n_loops}`,
|
|
728
|
-
location:
|
|
762
|
+
location: toLocationValues(ast.label.location),
|
|
729
763
|
};
|
|
730
764
|
ctx.n_loops += 1;
|
|
731
765
|
const value = variant("Variable", {
|
|
732
766
|
type: toEastTypeValue(ast.value.type),
|
|
733
767
|
name: `_${ctx.n_vars}`,
|
|
734
|
-
location:
|
|
768
|
+
location: toLocationValues(ast.value.location),
|
|
735
769
|
mutable: ast.value.mutable, // false...
|
|
736
770
|
captured: false,
|
|
737
771
|
});
|
|
@@ -739,7 +773,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
739
773
|
const key = variant("Variable", {
|
|
740
774
|
type: toEastTypeValue(ast.key.type),
|
|
741
775
|
name: `_${ctx.n_vars}`,
|
|
742
|
-
location:
|
|
776
|
+
location: toLocationValues(ast.key.location),
|
|
743
777
|
mutable: ast.key.mutable, // false...
|
|
744
778
|
captured: false,
|
|
745
779
|
});
|
|
@@ -760,7 +794,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
760
794
|
ctx.n_loops = ctx2.n_loops;
|
|
761
795
|
return variant("ForDict", {
|
|
762
796
|
type: variant("Null", null),
|
|
763
|
-
location:
|
|
797
|
+
location: toLocationValues(ast.location),
|
|
764
798
|
label,
|
|
765
799
|
key,
|
|
766
800
|
value,
|
|
@@ -775,7 +809,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
775
809
|
const variable = variant("Variable", {
|
|
776
810
|
type: toEastTypeValue(v.variable.type),
|
|
777
811
|
name: `_${ctx.n_vars}`,
|
|
778
|
-
location:
|
|
812
|
+
location: toLocationValues(v.variable.location),
|
|
779
813
|
mutable: v.variable.mutable, // false...
|
|
780
814
|
captured: false,
|
|
781
815
|
});
|
|
@@ -796,19 +830,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
796
830
|
ctx.n_loops = ctx2.n_loops;
|
|
797
831
|
if (v.body.type.type !== "Never" && !isTypeEqual(v.body.type, ast.type)) {
|
|
798
832
|
if (!isSubtype(v.body.type, ast.type)) {
|
|
799
|
-
throw new Error(`Match case '${k}' body of type ${printType(v.body.type)} is not compatible with expected type ${printType(ast.type)} at ${
|
|
833
|
+
throw new Error(`Match case '${k}' body of type ${printType(v.body.type)} is not compatible with expected type ${printType(ast.type)} at ${printLocations(ast.location)}`);
|
|
800
834
|
}
|
|
801
835
|
body = variant("As", {
|
|
802
836
|
type: toEastTypeValue(ast.type),
|
|
803
837
|
value: body,
|
|
804
|
-
location:
|
|
838
|
+
location: toLocationValues(ast.location),
|
|
805
839
|
});
|
|
806
840
|
}
|
|
807
841
|
cases.push({ case: k, variable, body });
|
|
808
842
|
}
|
|
809
843
|
return variant("Match", {
|
|
810
844
|
type: toEastTypeValue(ast.type),
|
|
811
|
-
location:
|
|
845
|
+
location: toLocationValues(ast.location),
|
|
812
846
|
variant: variant_expr,
|
|
813
847
|
cases,
|
|
814
848
|
});
|
|
@@ -816,7 +850,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
816
850
|
else if (ast.ast_type === "UnwrapRecursive") {
|
|
817
851
|
return variant("UnwrapRecursive", {
|
|
818
852
|
type: toEastTypeValue(ast.type),
|
|
819
|
-
location:
|
|
853
|
+
location: toLocationValues(ast.location),
|
|
820
854
|
value: ast_to_ir(ast.value, ctx),
|
|
821
855
|
});
|
|
822
856
|
}
|
|
@@ -827,14 +861,14 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
827
861
|
}
|
|
828
862
|
const existing = ctx.recursiveASTs.has(ast);
|
|
829
863
|
if (existing) {
|
|
830
|
-
throw new Error(`Circular reference detected when converting AST to IR at ${
|
|
864
|
+
throw new Error(`Circular reference detected when converting AST to IR at ${printLocations(ast.location)}`);
|
|
831
865
|
}
|
|
832
866
|
// Register before recursing (enables cycle detection)
|
|
833
867
|
ctx.recursiveASTs.add(ast);
|
|
834
868
|
// Create WrapRecursive IR node with placeholder
|
|
835
869
|
const wrapIR = variant("WrapRecursive", {
|
|
836
870
|
type: toEastTypeValue(ast.type),
|
|
837
|
-
location:
|
|
871
|
+
location: toLocationValues(ast.location),
|
|
838
872
|
value: ast_to_ir(ast.value, ctx),
|
|
839
873
|
});
|
|
840
874
|
// The user may alias this AST value elsewhere in the tree, just not with a circular reference
|
|
@@ -844,32 +878,32 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
844
878
|
else if (ast.ast_type === "Break") {
|
|
845
879
|
const label = ctx.loop_ctx.get(ast.label);
|
|
846
880
|
if (label === undefined) {
|
|
847
|
-
throw new Error(`Label defined at ${
|
|
881
|
+
throw new Error(`Label defined at ${printLocations(ast.label.location)} is not in scope at break at ${printLocations(ast.location)}`);
|
|
848
882
|
}
|
|
849
883
|
return variant("Break", {
|
|
850
884
|
type: variant("Never", null),
|
|
851
|
-
location:
|
|
885
|
+
location: toLocationValues(ast.location),
|
|
852
886
|
label,
|
|
853
887
|
});
|
|
854
888
|
}
|
|
855
889
|
else if (ast.ast_type === "Continue") {
|
|
856
890
|
const label = ctx.loop_ctx.get(ast.label);
|
|
857
891
|
if (label === undefined) {
|
|
858
|
-
throw new Error(`Label defined at ${
|
|
892
|
+
throw new Error(`Label defined at ${printLocations(ast.label.location)} is not in scope at continue at ${printLocations(ast.location)}`);
|
|
859
893
|
}
|
|
860
894
|
return variant("Continue", {
|
|
861
895
|
type: variant("Never", null),
|
|
862
|
-
location:
|
|
896
|
+
location: toLocationValues(ast.location),
|
|
863
897
|
label,
|
|
864
898
|
});
|
|
865
899
|
}
|
|
866
900
|
else if (ast.ast_type === "Return") {
|
|
867
901
|
if (!isSubtype(ast.value.type, ctx.output)) {
|
|
868
|
-
throw new Error(`Attempted to return value of type ${printType(ast.value.type)} at ${
|
|
902
|
+
throw new Error(`Attempted to return value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}, but function expected return type of ${printType(ctx.output)}`);
|
|
869
903
|
}
|
|
870
904
|
return variant("Return", {
|
|
871
905
|
type: variant("Never", null),
|
|
872
|
-
location:
|
|
906
|
+
location: toLocationValues(ast.location),
|
|
873
907
|
value: ast_to_ir(ast.value, ctx),
|
|
874
908
|
});
|
|
875
909
|
}
|
|
@@ -880,13 +914,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
880
914
|
catch (e) {
|
|
881
915
|
if (e instanceof Error) {
|
|
882
916
|
if (ast.ast_type === "Builtin") {
|
|
883
|
-
e.message += `\n at ${ast.ast_type} ${ast.builtin} node located at ${
|
|
917
|
+
e.message += `\n at ${ast.ast_type} ${ast.builtin} node located at ${printLocations(ast.location)}`;
|
|
884
918
|
}
|
|
885
919
|
else if (ast.ast_type === "Platform") {
|
|
886
|
-
e.message += `\n at ${ast.ast_type} ${ast.name} node located at ${
|
|
920
|
+
e.message += `\n at ${ast.ast_type} ${ast.name} node located at ${printLocations(ast.location)}`;
|
|
887
921
|
}
|
|
888
922
|
else {
|
|
889
|
-
e.message += `\n at ${ast.ast_type} node located at ${
|
|
923
|
+
e.message += `\n at ${ast.ast_type} node located at ${printLocations(ast.location)}`;
|
|
890
924
|
}
|
|
891
925
|
}
|
|
892
926
|
throw e;
|