@elaraai/east 0.0.1-beta.3 → 0.0.1-beta.30
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 +52 -13
- package/dist/src/analyze.js.map +1 -1
- package/dist/src/ast.d.ts +34 -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 +134 -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 +374 -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.map +1 -1
- package/dist/src/eastir.js +21 -5
- 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 +206 -8
- package/dist/src/expr/block.d.ts.map +1 -1
- package/dist/src/expr/block.js +623 -136
- 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 +1547 -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,12 +156,13 @@ 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,
|
|
159
168
|
});
|
|
@@ -161,24 +170,24 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
161
170
|
else if (ast.ast_type === "Struct") {
|
|
162
171
|
return variant("Struct", {
|
|
163
172
|
type: toEastTypeValue(ast.type),
|
|
164
|
-
location:
|
|
173
|
+
location: toLocationValues(ast.location),
|
|
165
174
|
fields: Object.entries(ast.fields).map(([name, fieldAst]) => {
|
|
166
175
|
let value = ast_to_ir(fieldAst, ctx);
|
|
167
176
|
const expectedType = ast.type.fields[name];
|
|
168
177
|
if (!expectedType) {
|
|
169
|
-
throw new Error(`Struct type does not have field '${name}' at ${
|
|
178
|
+
throw new Error(`Struct type does not have field '${name}' at ${printLocations(ast.location)}`);
|
|
170
179
|
}
|
|
171
180
|
if (!isTypeEqual(fieldAst.type, expectedType)) {
|
|
172
181
|
if (isSubtype(fieldAst.type, expectedType)) {
|
|
173
182
|
value = variant("As", {
|
|
174
183
|
type: toEastTypeValue(expectedType),
|
|
175
184
|
value,
|
|
176
|
-
location:
|
|
185
|
+
location: toLocationValues(ast.location),
|
|
177
186
|
});
|
|
178
187
|
}
|
|
179
188
|
else {
|
|
180
189
|
throw new Error(`Cannot assign field '${name}' of type ${printType(ast.type.fields[name])} ` +
|
|
181
|
-
`with value of type ${printType(fieldAst.type)} at ${
|
|
190
|
+
`with value of type ${printType(fieldAst.type)} at ${printLocations(ast.location)}`);
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
193
|
return { name, value };
|
|
@@ -188,7 +197,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
188
197
|
else if (ast.ast_type === "GetField") {
|
|
189
198
|
return variant("GetField", {
|
|
190
199
|
type: toEastTypeValue(ast.type),
|
|
191
|
-
location:
|
|
200
|
+
location: toLocationValues(ast.location),
|
|
192
201
|
struct: ast_to_ir(ast.struct, ctx),
|
|
193
202
|
field: ast.field,
|
|
194
203
|
});
|
|
@@ -201,17 +210,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
201
210
|
value = variant("As", {
|
|
202
211
|
type: toEastTypeValue(expectedType),
|
|
203
212
|
value,
|
|
204
|
-
location:
|
|
213
|
+
location: toLocationValues(ast.location),
|
|
205
214
|
});
|
|
206
215
|
}
|
|
207
216
|
else {
|
|
208
217
|
throw new Error(`Cannot assign case '${ast.case}' of type ${printType(expectedType)} ` +
|
|
209
|
-
`with value of type ${printType(ast.value.type)} at ${
|
|
218
|
+
`with value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}`);
|
|
210
219
|
}
|
|
211
220
|
}
|
|
212
221
|
return variant("Variant", {
|
|
213
222
|
type: toEastTypeValue(ast.type),
|
|
214
|
-
location:
|
|
223
|
+
location: toLocationValues(ast.location),
|
|
215
224
|
case: ast.case,
|
|
216
225
|
value,
|
|
217
226
|
});
|
|
@@ -221,7 +230,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
221
230
|
const param = variant("Variable", {
|
|
222
231
|
type: toEastTypeValue(parameter.type),
|
|
223
232
|
name: `_${ctx.n_vars}`,
|
|
224
|
-
location:
|
|
233
|
+
location: toLocationValues(parameter.location),
|
|
225
234
|
mutable: parameter.mutable, // false...
|
|
226
235
|
captured: false,
|
|
227
236
|
});
|
|
@@ -235,9 +244,21 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
235
244
|
const body = ast_to_ir(ast.body, ctx2);
|
|
236
245
|
ctx.n_vars = ctx2.n_vars;
|
|
237
246
|
ctx.n_loops = ctx2.n_loops;
|
|
247
|
+
// Propagate captures: if this function captured something from ctx.parent_ctx,
|
|
248
|
+
// then the enclosing function also needs to capture it
|
|
249
|
+
for (const capturedVar of captures) {
|
|
250
|
+
// Check if this variable came from our parent context (not defined locally in enclosing function)
|
|
251
|
+
for (const [_astVar, ir] of ctx.parent_ctx) {
|
|
252
|
+
if (ir === capturedVar) {
|
|
253
|
+
// This capture came from an outer scope, so enclosing function must also capture it
|
|
254
|
+
ctx.captures.add(capturedVar);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
238
259
|
return variant("Function", {
|
|
239
260
|
type: toEastTypeValue(ast.type),
|
|
240
|
-
location:
|
|
261
|
+
location: toLocationValues(ast.location),
|
|
241
262
|
parameters,
|
|
242
263
|
captures: [...captures],
|
|
243
264
|
body,
|
|
@@ -248,7 +269,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
248
269
|
const param = variant("Variable", {
|
|
249
270
|
type: toEastTypeValue(parameter.type),
|
|
250
271
|
name: `_${ctx.n_vars}`,
|
|
251
|
-
location:
|
|
272
|
+
location: toLocationValues(parameter.location),
|
|
252
273
|
mutable: parameter.mutable, // false...
|
|
253
274
|
captured: false,
|
|
254
275
|
});
|
|
@@ -262,9 +283,21 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
262
283
|
const body = ast_to_ir(ast.body, ctx2);
|
|
263
284
|
ctx.n_vars = ctx2.n_vars;
|
|
264
285
|
ctx.n_loops = ctx2.n_loops;
|
|
286
|
+
// Propagate captures: if this function captured something from ctx.parent_ctx,
|
|
287
|
+
// then the enclosing function also needs to capture it
|
|
288
|
+
for (const capturedVar of captures) {
|
|
289
|
+
// Check if this variable came from our parent context (not defined locally in enclosing function)
|
|
290
|
+
for (const [_astVar, ir] of ctx.parent_ctx) {
|
|
291
|
+
if (ir === capturedVar) {
|
|
292
|
+
// This capture came from an outer scope, so enclosing function must also capture it
|
|
293
|
+
ctx.captures.add(capturedVar);
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
265
298
|
return variant("AsyncFunction", {
|
|
266
299
|
type: toEastTypeValue(ast.type),
|
|
267
|
-
location:
|
|
300
|
+
location: toLocationValues(ast.location),
|
|
268
301
|
parameters,
|
|
269
302
|
captures: [...captures],
|
|
270
303
|
body,
|
|
@@ -275,19 +308,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
275
308
|
// TODO - what about widening the result with As?
|
|
276
309
|
return variant("Call", {
|
|
277
310
|
type: toEastTypeValue(ast.type),
|
|
278
|
-
location:
|
|
311
|
+
location: toLocationValues(ast.location),
|
|
279
312
|
function: ast_to_ir(ast.function, ctx),
|
|
280
313
|
arguments: ast.arguments.map((argument, i) => {
|
|
281
314
|
let arg = ast_to_ir(argument, ctx);
|
|
282
315
|
const expectedType = ast.function.type.inputs[i];
|
|
283
316
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
284
317
|
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 ${
|
|
318
|
+
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${printLocations(ast.location)}`);
|
|
286
319
|
}
|
|
287
320
|
arg = variant("As", {
|
|
288
321
|
type: toEastTypeValue(expectedType),
|
|
289
322
|
value: arg,
|
|
290
|
-
location:
|
|
323
|
+
location: toLocationValues(ast.location),
|
|
291
324
|
});
|
|
292
325
|
}
|
|
293
326
|
return arg;
|
|
@@ -296,25 +329,25 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
296
329
|
}
|
|
297
330
|
else if (ast.ast_type === "CallAsync") {
|
|
298
331
|
if (ctx.async === false) {
|
|
299
|
-
throw new Error(`Async function call not allowed outside async function at ${
|
|
332
|
+
throw new Error(`Async function call not allowed outside async function at ${printLocations(ast.location)}`);
|
|
300
333
|
}
|
|
301
334
|
// TODO - type equality could have been handled at Expr/AST level instead
|
|
302
335
|
// TODO - what about widening the result with As?
|
|
303
336
|
return variant("CallAsync", {
|
|
304
337
|
type: toEastTypeValue(ast.type),
|
|
305
|
-
location:
|
|
338
|
+
location: toLocationValues(ast.location),
|
|
306
339
|
function: ast_to_ir(ast.function, ctx),
|
|
307
340
|
arguments: ast.arguments.map((argument, i) => {
|
|
308
341
|
let arg = ast_to_ir(argument, ctx);
|
|
309
342
|
const expectedType = ast.function.type.inputs[i];
|
|
310
343
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
311
344
|
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 ${
|
|
345
|
+
throw new Error(`Argument ${i} of type ${printType(argument.type)} is not compatible with expected type ${printType(expectedType)} at ${printLocations(ast.location)}`);
|
|
313
346
|
}
|
|
314
347
|
arg = variant("As", {
|
|
315
348
|
type: toEastTypeValue(expectedType),
|
|
316
349
|
value: arg,
|
|
317
|
-
location:
|
|
350
|
+
location: toLocationValues(ast.location),
|
|
318
351
|
});
|
|
319
352
|
}
|
|
320
353
|
return arg;
|
|
@@ -326,17 +359,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
326
359
|
let value = ast_to_ir(ast.value, ctx);
|
|
327
360
|
if (!isTypeEqual(ast.value.type, valueType)) {
|
|
328
361
|
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 ${
|
|
362
|
+
throw new Error(`Ref value of type ${printType(ast.value.type)} is not compatible with expected type ${printType(valueType)} at ${printLocations(ast.location)}`);
|
|
330
363
|
}
|
|
331
364
|
value = variant("As", {
|
|
332
365
|
type: toEastTypeValue(valueType),
|
|
333
366
|
value,
|
|
334
|
-
location:
|
|
367
|
+
location: toLocationValues(ast.location),
|
|
335
368
|
});
|
|
336
369
|
}
|
|
337
370
|
return variant("NewRef", {
|
|
338
371
|
type: toEastTypeValue(ast.type),
|
|
339
|
-
location:
|
|
372
|
+
location: toLocationValues(ast.location),
|
|
340
373
|
value,
|
|
341
374
|
});
|
|
342
375
|
}
|
|
@@ -344,17 +377,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
344
377
|
const valueType = ast.type.value;
|
|
345
378
|
return variant("NewArray", {
|
|
346
379
|
type: toEastTypeValue(ast.type),
|
|
347
|
-
location:
|
|
380
|
+
location: toLocationValues(ast.location),
|
|
348
381
|
values: ast.values.map((v, i) => {
|
|
349
382
|
let value = ast_to_ir(v, ctx);
|
|
350
383
|
if (!isTypeEqual(v.type, valueType)) {
|
|
351
384
|
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 ${
|
|
385
|
+
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
386
|
}
|
|
354
387
|
value = variant("As", {
|
|
355
388
|
type: toEastTypeValue(valueType),
|
|
356
389
|
value,
|
|
357
|
-
location:
|
|
390
|
+
location: toLocationValues(ast.location),
|
|
358
391
|
});
|
|
359
392
|
}
|
|
360
393
|
return value;
|
|
@@ -365,17 +398,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
365
398
|
const keyType = ast.type.key;
|
|
366
399
|
return variant("NewSet", {
|
|
367
400
|
type: toEastTypeValue(ast.type),
|
|
368
|
-
location:
|
|
401
|
+
location: toLocationValues(ast.location),
|
|
369
402
|
values: ast.values.map((k, i) => {
|
|
370
403
|
let key = ast_to_ir(k, ctx);
|
|
371
404
|
if (!isTypeEqual(k.type, keyType)) {
|
|
372
405
|
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 ${
|
|
406
|
+
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
407
|
}
|
|
375
408
|
key = variant("As", {
|
|
376
409
|
type: toEastTypeValue(keyType),
|
|
377
410
|
value: key,
|
|
378
|
-
location:
|
|
411
|
+
location: toLocationValues(ast.location),
|
|
379
412
|
});
|
|
380
413
|
}
|
|
381
414
|
return key;
|
|
@@ -387,28 +420,28 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
387
420
|
const valueType = ast.type.value;
|
|
388
421
|
return variant("NewDict", {
|
|
389
422
|
type: toEastTypeValue(ast.type),
|
|
390
|
-
location:
|
|
423
|
+
location: toLocationValues(ast.location),
|
|
391
424
|
values: ast.values.map(([k, v], i) => {
|
|
392
425
|
let key = ast_to_ir(k, ctx);
|
|
393
426
|
if (!isTypeEqual(k.type, keyType)) {
|
|
394
427
|
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 ${
|
|
428
|
+
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
429
|
}
|
|
397
430
|
key = variant("As", {
|
|
398
431
|
type: toEastTypeValue(keyType),
|
|
399
432
|
value: key,
|
|
400
|
-
location:
|
|
433
|
+
location: toLocationValues(ast.location),
|
|
401
434
|
});
|
|
402
435
|
}
|
|
403
436
|
let value = ast_to_ir(v, ctx);
|
|
404
437
|
if (!isTypeEqual(v.type, valueType)) {
|
|
405
438
|
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 ${
|
|
439
|
+
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
440
|
}
|
|
408
441
|
value = variant("As", {
|
|
409
442
|
type: toEastTypeValue(valueType),
|
|
410
443
|
value,
|
|
411
|
-
location:
|
|
444
|
+
location: toLocationValues(ast.location),
|
|
412
445
|
});
|
|
413
446
|
}
|
|
414
447
|
;
|
|
@@ -435,12 +468,12 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
435
468
|
ctx.n_loops = ctx_branch.n_loops;
|
|
436
469
|
if (branch.body.type.type !== "Never" && !isTypeEqual(branch.body.type, ast.type)) {
|
|
437
470
|
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 ${
|
|
471
|
+
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
472
|
}
|
|
440
473
|
branch_body = variant("As", {
|
|
441
474
|
type: toEastTypeValue(ast.type),
|
|
442
475
|
value: branch_body,
|
|
443
|
-
location:
|
|
476
|
+
location: toLocationValues(ast.location),
|
|
444
477
|
});
|
|
445
478
|
}
|
|
446
479
|
return { predicate, body: branch_body };
|
|
@@ -461,17 +494,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
461
494
|
ctx.n_loops = ctx_else.n_loops;
|
|
462
495
|
if (ast.else_body.type.type !== "Never" && !isTypeEqual(ast.else_body.type, ast.type)) {
|
|
463
496
|
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 ${
|
|
497
|
+
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
498
|
}
|
|
466
499
|
else_body = variant("As", {
|
|
467
500
|
type: toEastTypeValue(ast.type),
|
|
468
501
|
value: else_body,
|
|
469
|
-
location:
|
|
502
|
+
location: toLocationValues(ast.location),
|
|
470
503
|
});
|
|
471
504
|
}
|
|
472
505
|
return variant("IfElse", {
|
|
473
506
|
type: toEastTypeValue(ast.type),
|
|
474
|
-
location:
|
|
507
|
+
location: toLocationValues(ast.location),
|
|
475
508
|
ifs,
|
|
476
509
|
else_body,
|
|
477
510
|
});
|
|
@@ -479,7 +512,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
479
512
|
else if (ast.ast_type === "Error") {
|
|
480
513
|
return variant("Error", {
|
|
481
514
|
type: variant("Never", null),
|
|
482
|
-
location:
|
|
515
|
+
location: toLocationValues(ast.location),
|
|
483
516
|
message: ast_to_ir(ast.message, ctx),
|
|
484
517
|
});
|
|
485
518
|
}
|
|
@@ -502,7 +535,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
502
535
|
const message = variant("Variable", {
|
|
503
536
|
type: toEastTypeValue(ast.message.type),
|
|
504
537
|
name: `_${ctx.n_vars}`,
|
|
505
|
-
location:
|
|
538
|
+
location: toLocationValues(ast.message.location),
|
|
506
539
|
mutable: ast.message.mutable, // false...
|
|
507
540
|
captured: false,
|
|
508
541
|
});
|
|
@@ -510,7 +543,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
510
543
|
const stack = variant("Variable", {
|
|
511
544
|
type: toEastTypeValue(ast.stack.type),
|
|
512
545
|
name: `_${ctx.n_vars}`,
|
|
513
|
-
location:
|
|
546
|
+
location: toLocationValues(ast.stack.location),
|
|
514
547
|
mutable: ast.stack.mutable, // false...
|
|
515
548
|
captured: false,
|
|
516
549
|
});
|
|
@@ -550,13 +583,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
550
583
|
else {
|
|
551
584
|
finally_body = variant("Value", {
|
|
552
585
|
type: toEastTypeValue(NullType),
|
|
553
|
-
location:
|
|
586
|
+
location: toLocationValues(ast.location),
|
|
554
587
|
value: variant("Null", null),
|
|
555
588
|
});
|
|
556
589
|
}
|
|
557
590
|
return variant("TryCatch", {
|
|
558
591
|
type: toEastTypeValue(ast.type),
|
|
559
|
-
location:
|
|
592
|
+
location: toLocationValues(ast.location),
|
|
560
593
|
try_body,
|
|
561
594
|
catch_body,
|
|
562
595
|
message,
|
|
@@ -592,18 +625,18 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
592
625
|
throw new Error(`Unsupported literal value type: ${typeof ast.value} (expected ${printType(ast.type)})`);
|
|
593
626
|
}
|
|
594
627
|
if (type.type !== value.type) {
|
|
595
|
-
throw new Error(`Literal value type mismatch at ${
|
|
628
|
+
throw new Error(`Literal value type mismatch at ${printLocations(ast.location)}: expected .${type.type} but got .${value.type}`);
|
|
596
629
|
}
|
|
597
630
|
return variant("Value", {
|
|
598
631
|
type,
|
|
599
|
-
location:
|
|
632
|
+
location: toLocationValues(ast.location),
|
|
600
633
|
value,
|
|
601
634
|
});
|
|
602
635
|
}
|
|
603
636
|
else if (ast.ast_type === "As") {
|
|
604
637
|
return variant("As", {
|
|
605
638
|
type: toEastTypeValue(ast.type),
|
|
606
|
-
location:
|
|
639
|
+
location: toLocationValues(ast.location),
|
|
607
640
|
value: ast_to_ir(ast.value, ctx),
|
|
608
641
|
});
|
|
609
642
|
}
|
|
@@ -611,7 +644,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
611
644
|
const predicate = ast_to_ir(ast.predicate, ctx);
|
|
612
645
|
const label = {
|
|
613
646
|
name: `_${ctx.n_loops}`,
|
|
614
|
-
location:
|
|
647
|
+
location: toLocationValues(ast.label.location),
|
|
615
648
|
};
|
|
616
649
|
ctx.n_loops += 1;
|
|
617
650
|
const ctx2 = {
|
|
@@ -630,7 +663,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
630
663
|
ctx.n_loops = ctx2.n_loops;
|
|
631
664
|
return variant("While", {
|
|
632
665
|
type: variant("Null", null),
|
|
633
|
-
location:
|
|
666
|
+
location: toLocationValues(ast.location),
|
|
634
667
|
label,
|
|
635
668
|
predicate,
|
|
636
669
|
body,
|
|
@@ -640,13 +673,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
640
673
|
const array = ast_to_ir(ast.array, ctx);
|
|
641
674
|
const label = {
|
|
642
675
|
name: `_${ctx.n_loops}`,
|
|
643
|
-
location:
|
|
676
|
+
location: toLocationValues(ast.label.location),
|
|
644
677
|
};
|
|
645
678
|
ctx.n_loops += 1;
|
|
646
679
|
const value = variant("Variable", {
|
|
647
680
|
type: toEastTypeValue(ast.value.type),
|
|
648
681
|
name: `_${ctx.n_vars}`,
|
|
649
|
-
location:
|
|
682
|
+
location: toLocationValues(ast.value.location),
|
|
650
683
|
mutable: ast.value.mutable, // false...
|
|
651
684
|
captured: false,
|
|
652
685
|
});
|
|
@@ -654,7 +687,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
654
687
|
const key = variant("Variable", {
|
|
655
688
|
type: toEastTypeValue(ast.key.type),
|
|
656
689
|
name: `_${ctx.n_vars}`,
|
|
657
|
-
location:
|
|
690
|
+
location: toLocationValues(ast.key.location),
|
|
658
691
|
mutable: ast.key.mutable, // false...
|
|
659
692
|
captured: false,
|
|
660
693
|
});
|
|
@@ -675,7 +708,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
675
708
|
ctx.n_loops = ctx2.n_loops;
|
|
676
709
|
return variant("ForArray", {
|
|
677
710
|
type: variant("Null", null),
|
|
678
|
-
location:
|
|
711
|
+
location: toLocationValues(ast.location),
|
|
679
712
|
label,
|
|
680
713
|
key,
|
|
681
714
|
value,
|
|
@@ -687,13 +720,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
687
720
|
const set = ast_to_ir(ast.set, ctx);
|
|
688
721
|
const label = {
|
|
689
722
|
name: `_${ctx.n_loops}`,
|
|
690
|
-
location:
|
|
723
|
+
location: toLocationValues(ast.label.location),
|
|
691
724
|
};
|
|
692
725
|
ctx.n_loops += 1;
|
|
693
726
|
const key = variant("Variable", {
|
|
694
727
|
type: toEastTypeValue(ast.key.type),
|
|
695
728
|
name: `_${ctx.n_vars}`,
|
|
696
|
-
location:
|
|
729
|
+
location: toLocationValues(ast.key.location),
|
|
697
730
|
mutable: ast.key.mutable, // false...
|
|
698
731
|
captured: false,
|
|
699
732
|
});
|
|
@@ -714,7 +747,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
714
747
|
ctx.n_loops = ctx2.n_loops;
|
|
715
748
|
return variant("ForSet", {
|
|
716
749
|
type: variant("Null", null),
|
|
717
|
-
location:
|
|
750
|
+
location: toLocationValues(ast.location),
|
|
718
751
|
label,
|
|
719
752
|
key,
|
|
720
753
|
set,
|
|
@@ -725,13 +758,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
725
758
|
const dict = ast_to_ir(ast.dict, ctx);
|
|
726
759
|
const label = {
|
|
727
760
|
name: `_${ctx.n_loops}`,
|
|
728
|
-
location:
|
|
761
|
+
location: toLocationValues(ast.label.location),
|
|
729
762
|
};
|
|
730
763
|
ctx.n_loops += 1;
|
|
731
764
|
const value = variant("Variable", {
|
|
732
765
|
type: toEastTypeValue(ast.value.type),
|
|
733
766
|
name: `_${ctx.n_vars}`,
|
|
734
|
-
location:
|
|
767
|
+
location: toLocationValues(ast.value.location),
|
|
735
768
|
mutable: ast.value.mutable, // false...
|
|
736
769
|
captured: false,
|
|
737
770
|
});
|
|
@@ -739,7 +772,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
739
772
|
const key = variant("Variable", {
|
|
740
773
|
type: toEastTypeValue(ast.key.type),
|
|
741
774
|
name: `_${ctx.n_vars}`,
|
|
742
|
-
location:
|
|
775
|
+
location: toLocationValues(ast.key.location),
|
|
743
776
|
mutable: ast.key.mutable, // false...
|
|
744
777
|
captured: false,
|
|
745
778
|
});
|
|
@@ -760,7 +793,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
760
793
|
ctx.n_loops = ctx2.n_loops;
|
|
761
794
|
return variant("ForDict", {
|
|
762
795
|
type: variant("Null", null),
|
|
763
|
-
location:
|
|
796
|
+
location: toLocationValues(ast.location),
|
|
764
797
|
label,
|
|
765
798
|
key,
|
|
766
799
|
value,
|
|
@@ -775,7 +808,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
775
808
|
const variable = variant("Variable", {
|
|
776
809
|
type: toEastTypeValue(v.variable.type),
|
|
777
810
|
name: `_${ctx.n_vars}`,
|
|
778
|
-
location:
|
|
811
|
+
location: toLocationValues(v.variable.location),
|
|
779
812
|
mutable: v.variable.mutable, // false...
|
|
780
813
|
captured: false,
|
|
781
814
|
});
|
|
@@ -796,19 +829,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
796
829
|
ctx.n_loops = ctx2.n_loops;
|
|
797
830
|
if (v.body.type.type !== "Never" && !isTypeEqual(v.body.type, ast.type)) {
|
|
798
831
|
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 ${
|
|
832
|
+
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
833
|
}
|
|
801
834
|
body = variant("As", {
|
|
802
835
|
type: toEastTypeValue(ast.type),
|
|
803
836
|
value: body,
|
|
804
|
-
location:
|
|
837
|
+
location: toLocationValues(ast.location),
|
|
805
838
|
});
|
|
806
839
|
}
|
|
807
840
|
cases.push({ case: k, variable, body });
|
|
808
841
|
}
|
|
809
842
|
return variant("Match", {
|
|
810
843
|
type: toEastTypeValue(ast.type),
|
|
811
|
-
location:
|
|
844
|
+
location: toLocationValues(ast.location),
|
|
812
845
|
variant: variant_expr,
|
|
813
846
|
cases,
|
|
814
847
|
});
|
|
@@ -816,7 +849,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
816
849
|
else if (ast.ast_type === "UnwrapRecursive") {
|
|
817
850
|
return variant("UnwrapRecursive", {
|
|
818
851
|
type: toEastTypeValue(ast.type),
|
|
819
|
-
location:
|
|
852
|
+
location: toLocationValues(ast.location),
|
|
820
853
|
value: ast_to_ir(ast.value, ctx),
|
|
821
854
|
});
|
|
822
855
|
}
|
|
@@ -827,14 +860,14 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
827
860
|
}
|
|
828
861
|
const existing = ctx.recursiveASTs.has(ast);
|
|
829
862
|
if (existing) {
|
|
830
|
-
throw new Error(`Circular reference detected when converting AST to IR at ${
|
|
863
|
+
throw new Error(`Circular reference detected when converting AST to IR at ${printLocations(ast.location)}`);
|
|
831
864
|
}
|
|
832
865
|
// Register before recursing (enables cycle detection)
|
|
833
866
|
ctx.recursiveASTs.add(ast);
|
|
834
867
|
// Create WrapRecursive IR node with placeholder
|
|
835
868
|
const wrapIR = variant("WrapRecursive", {
|
|
836
869
|
type: toEastTypeValue(ast.type),
|
|
837
|
-
location:
|
|
870
|
+
location: toLocationValues(ast.location),
|
|
838
871
|
value: ast_to_ir(ast.value, ctx),
|
|
839
872
|
});
|
|
840
873
|
// The user may alias this AST value elsewhere in the tree, just not with a circular reference
|
|
@@ -844,32 +877,32 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
844
877
|
else if (ast.ast_type === "Break") {
|
|
845
878
|
const label = ctx.loop_ctx.get(ast.label);
|
|
846
879
|
if (label === undefined) {
|
|
847
|
-
throw new Error(`Label defined at ${
|
|
880
|
+
throw new Error(`Label defined at ${printLocations(ast.label.location)} is not in scope at break at ${printLocations(ast.location)}`);
|
|
848
881
|
}
|
|
849
882
|
return variant("Break", {
|
|
850
883
|
type: variant("Never", null),
|
|
851
|
-
location:
|
|
884
|
+
location: toLocationValues(ast.location),
|
|
852
885
|
label,
|
|
853
886
|
});
|
|
854
887
|
}
|
|
855
888
|
else if (ast.ast_type === "Continue") {
|
|
856
889
|
const label = ctx.loop_ctx.get(ast.label);
|
|
857
890
|
if (label === undefined) {
|
|
858
|
-
throw new Error(`Label defined at ${
|
|
891
|
+
throw new Error(`Label defined at ${printLocations(ast.label.location)} is not in scope at continue at ${printLocations(ast.location)}`);
|
|
859
892
|
}
|
|
860
893
|
return variant("Continue", {
|
|
861
894
|
type: variant("Never", null),
|
|
862
|
-
location:
|
|
895
|
+
location: toLocationValues(ast.location),
|
|
863
896
|
label,
|
|
864
897
|
});
|
|
865
898
|
}
|
|
866
899
|
else if (ast.ast_type === "Return") {
|
|
867
900
|
if (!isSubtype(ast.value.type, ctx.output)) {
|
|
868
|
-
throw new Error(`Attempted to return value of type ${printType(ast.value.type)} at ${
|
|
901
|
+
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
902
|
}
|
|
870
903
|
return variant("Return", {
|
|
871
904
|
type: variant("Never", null),
|
|
872
|
-
location:
|
|
905
|
+
location: toLocationValues(ast.location),
|
|
873
906
|
value: ast_to_ir(ast.value, ctx),
|
|
874
907
|
});
|
|
875
908
|
}
|
|
@@ -880,13 +913,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
880
913
|
catch (e) {
|
|
881
914
|
if (e instanceof Error) {
|
|
882
915
|
if (ast.ast_type === "Builtin") {
|
|
883
|
-
e.message += `\n at ${ast.ast_type} ${ast.builtin} node located at ${
|
|
916
|
+
e.message += `\n at ${ast.ast_type} ${ast.builtin} node located at ${printLocations(ast.location)}`;
|
|
884
917
|
}
|
|
885
918
|
else if (ast.ast_type === "Platform") {
|
|
886
|
-
e.message += `\n at ${ast.ast_type} ${ast.name} node located at ${
|
|
919
|
+
e.message += `\n at ${ast.ast_type} ${ast.name} node located at ${printLocations(ast.location)}`;
|
|
887
920
|
}
|
|
888
921
|
else {
|
|
889
|
-
e.message += `\n at ${ast.ast_type} node located at ${
|
|
922
|
+
e.message += `\n at ${ast.ast_type} node located at ${printLocations(ast.location)}`;
|
|
890
923
|
}
|
|
891
924
|
}
|
|
892
925
|
throw e;
|