@elaraai/east 0.0.1-beta.27 → 0.0.1-beta.29
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/dist/src/analyze.d.ts.map +1 -1
- package/dist/src/analyze.js +12 -4
- package/dist/src/analyze.js.map +1 -1
- package/dist/src/ast.d.ts +33 -33
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast_to_ir.d.ts +2 -2
- package/dist/src/ast_to_ir.d.ts.map +1 -1
- package/dist/src/ast_to_ir.js +100 -100
- package/dist/src/ast_to_ir.js.map +1 -1
- package/dist/src/compile.d.ts +20 -1
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +103 -84
- package/dist/src/compile.js.map +1 -1
- package/dist/src/error.d.ts +8 -1
- package/dist/src/error.d.ts.map +1 -1
- package/dist/src/error.js +11 -1
- package/dist/src/error.js.map +1 -1
- package/dist/src/expr/array.js +48 -48
- 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 +14 -14
- 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.js +7 -7
- package/dist/src/expr/blob.js.map +1 -1
- package/dist/src/expr/block.d.ts +2 -2
- package/dist/src/expr/block.d.ts.map +1 -1
- package/dist/src/expr/block.js +131 -131
- package/dist/src/expr/block.js.map +1 -1
- package/dist/src/expr/boolean.js +5 -5
- package/dist/src/expr/boolean.js.map +1 -1
- package/dist/src/expr/datetime.js +33 -33
- package/dist/src/expr/datetime.js.map +1 -1
- package/dist/src/expr/dict.js +55 -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.js +16 -16
- package/dist/src/expr/float.js.map +1 -1
- package/dist/src/expr/function.js +1 -1
- package/dist/src/expr/function.js.map +1 -1
- package/dist/src/expr/integer.js +17 -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/string.js +1 -1
- package/dist/src/expr/libs/string.js.map +1 -1
- package/dist/src/expr/recursive.js +2 -2
- package/dist/src/expr/recursive.js.map +1 -1
- package/dist/src/expr/ref.js +3 -3
- package/dist/src/expr/ref.js.map +1 -1
- package/dist/src/expr/set.js +45 -45
- package/dist/src/expr/set.js.map +1 -1
- package/dist/src/expr/string.js +22 -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/variant.js +2 -2
- package/dist/src/expr/variant.js.map +1 -1
- package/dist/src/internal.d.ts +1 -1
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +1 -1
- package/dist/src/internal.js.map +1 -1
- package/dist/src/ir.d.ts +121 -114
- 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/serialization/beast2.d.ts +1 -1
- package/dist/src/serialization/beast2.d.ts.map +1 -1
- package/dist/src/serialization/beast2.js +131 -22
- package/dist/src/serialization/beast2.js.map +1 -1
- package/dist/src/serialization/index.d.ts +1 -1
- package/dist/src/serialization/index.d.ts.map +1 -1
- package/dist/src/serialization/index.js +1 -1
- package/dist/src/serialization/index.js.map +1 -1
- package/package.json +1 -1
package/dist/src/ast_to_ir.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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";
|
|
@@ -8,17 +8,17 @@ import { applyTypeParameters, Builtins } from "./builtins.js";
|
|
|
8
8
|
export class OutOfScopeException extends Error {
|
|
9
9
|
definedLocation;
|
|
10
10
|
constructor(definedLocation) {
|
|
11
|
-
super(`Variable defined at ${
|
|
11
|
+
super(`Variable defined at ${printLocations(definedLocation)} is out of scope here`);
|
|
12
12
|
this.definedLocation = definedLocation;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
// TODO we should probably redo type checking exhaustively here?
|
|
16
|
-
function
|
|
17
|
-
return {
|
|
18
|
-
filename:
|
|
19
|
-
line: BigInt(
|
|
20
|
-
column: BigInt(
|
|
21
|
-
};
|
|
16
|
+
function toLocationValues(locations) {
|
|
17
|
+
return locations.map(loc => ({
|
|
18
|
+
filename: loc.filename,
|
|
19
|
+
line: BigInt(loc.line),
|
|
20
|
+
column: BigInt(loc.column),
|
|
21
|
+
}));
|
|
22
22
|
}
|
|
23
23
|
/** Perform scope resolution and type checking on `AST`, produce `IR` ready for serialization, compilation or evaluation.
|
|
24
24
|
*
|
|
@@ -47,7 +47,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
47
47
|
const variable = variant("Variable", {
|
|
48
48
|
type: toEastTypeValue(ast.variable.type),
|
|
49
49
|
name: `_${ctx.n_vars}`,
|
|
50
|
-
location:
|
|
50
|
+
location: toLocationValues(ast.variable.location),
|
|
51
51
|
mutable: ast.variable.mutable,
|
|
52
52
|
captured: false,
|
|
53
53
|
});
|
|
@@ -58,19 +58,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
58
58
|
// This catches type errors early at AST level
|
|
59
59
|
if (!isSubtype(ast.value.type, ast.variable.type)) {
|
|
60
60
|
throw new Error(`Cannot initialize variable of type ${printType(ast.variable.type)} ` +
|
|
61
|
-
`with value of type ${printType(ast.value.type)} at ${
|
|
61
|
+
`with value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}`);
|
|
62
62
|
}
|
|
63
63
|
value = variant("As", {
|
|
64
64
|
type: toEastTypeValue(ast.variable.type),
|
|
65
65
|
value,
|
|
66
|
-
location:
|
|
66
|
+
location: toLocationValues(ast.location),
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
ctx.n_vars += 1;
|
|
70
70
|
ctx.local_ctx.set(ast.variable, variable);
|
|
71
71
|
return variant("Let", {
|
|
72
72
|
type: toEastTypeValue(ast.type),
|
|
73
|
-
location:
|
|
73
|
+
location: toLocationValues(ast.location),
|
|
74
74
|
variable,
|
|
75
75
|
value,
|
|
76
76
|
});
|
|
@@ -79,7 +79,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
79
79
|
// Fetch the variable from context
|
|
80
80
|
const variable = ast_to_ir(ast.variable, ctx);
|
|
81
81
|
if (!variable.value.mutable) {
|
|
82
|
-
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)}`);
|
|
83
83
|
}
|
|
84
84
|
let value = ast_to_ir(ast.value, ctx);
|
|
85
85
|
// Get the variable's type from the IR node
|
|
@@ -90,17 +90,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
90
90
|
// Validate subtype relationship before inserting As node
|
|
91
91
|
if (!isSubtype(ast.value.type, ast.variable.type)) {
|
|
92
92
|
throw new Error(`Cannot assign value of type ${printType(ast.value.type)} ` +
|
|
93
|
-
`to variable of type ${printType(ast.variable.type)} at ${
|
|
93
|
+
`to variable of type ${printType(ast.variable.type)} at ${printLocations(ast.location)}`);
|
|
94
94
|
}
|
|
95
95
|
value = variant("As", {
|
|
96
96
|
type: variableType,
|
|
97
97
|
value,
|
|
98
|
-
location:
|
|
98
|
+
location: toLocationValues(ast.location),
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
return variant("Assign", {
|
|
102
102
|
type: toEastTypeValue(ast.type),
|
|
103
|
-
location:
|
|
103
|
+
location: toLocationValues(ast.location),
|
|
104
104
|
variable,
|
|
105
105
|
value,
|
|
106
106
|
});
|
|
@@ -113,7 +113,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
113
113
|
ctx.n_loops = ctx2.n_loops;
|
|
114
114
|
return variant("Block", {
|
|
115
115
|
type: toEastTypeValue(ast.type),
|
|
116
|
-
location:
|
|
116
|
+
location: toLocationValues(ast.location),
|
|
117
117
|
statements,
|
|
118
118
|
});
|
|
119
119
|
}
|
|
@@ -122,18 +122,18 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
122
122
|
const builtin_name = ast.builtin;
|
|
123
123
|
const builtin_def = Builtins[builtin_name];
|
|
124
124
|
if (!builtin_def) {
|
|
125
|
-
throw new Error(`Unknown builtin function '${builtin_name}' at ${
|
|
125
|
+
throw new Error(`Unknown builtin function '${builtin_name}' at ${printLocations(ast.location)}`);
|
|
126
126
|
}
|
|
127
127
|
if (builtin_def.type_parameters.length !== ast.type_parameters.length) {
|
|
128
|
-
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)}`);
|
|
129
129
|
}
|
|
130
130
|
const type_map = new Map(builtin_def.type_parameters.map((name, i) => [name, ast.type_parameters[i]]));
|
|
131
131
|
if (ast.arguments.length !== builtin_def.inputs.length) {
|
|
132
|
-
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)}`);
|
|
133
133
|
}
|
|
134
134
|
return variant("Builtin", {
|
|
135
135
|
type: toEastTypeValue(ast.type),
|
|
136
|
-
location:
|
|
136
|
+
location: toLocationValues(ast.location),
|
|
137
137
|
builtin: ast.builtin,
|
|
138
138
|
type_parameters: ast.type_parameters.map(tp => toEastTypeValue(tp)),
|
|
139
139
|
arguments: ast.arguments.map((arg, i) => {
|
|
@@ -142,12 +142,12 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
142
142
|
// Now check type compatibility
|
|
143
143
|
if (arg.type.type !== "Never" && !isTypeEqual(arg.type, expectedType)) {
|
|
144
144
|
if (!isSubtype(arg.type, expectedType)) {
|
|
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 ${
|
|
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)}`);
|
|
146
146
|
}
|
|
147
147
|
arg_ir = variant("As", {
|
|
148
148
|
type: toEastTypeValue(expectedType),
|
|
149
149
|
value: arg_ir,
|
|
150
|
-
location:
|
|
150
|
+
location: toLocationValues(ast.location),
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
return arg_ir;
|
|
@@ -156,11 +156,11 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
156
156
|
}
|
|
157
157
|
else if (ast.ast_type === "Platform") {
|
|
158
158
|
if (ctx.async === false && ast.async === true) {
|
|
159
|
-
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)}`);
|
|
160
160
|
}
|
|
161
161
|
return variant("Platform", {
|
|
162
162
|
type: toEastTypeValue(ast.type),
|
|
163
|
-
location:
|
|
163
|
+
location: toLocationValues(ast.location),
|
|
164
164
|
name: ast.name,
|
|
165
165
|
type_parameters: ast.type_parameters.map(tp => toEastTypeValue(tp)),
|
|
166
166
|
arguments: ast.arguments.map(ast => ast_to_ir(ast, ctx)), // type equality handled at Expr/AST level
|
|
@@ -170,24 +170,24 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
170
170
|
else if (ast.ast_type === "Struct") {
|
|
171
171
|
return variant("Struct", {
|
|
172
172
|
type: toEastTypeValue(ast.type),
|
|
173
|
-
location:
|
|
173
|
+
location: toLocationValues(ast.location),
|
|
174
174
|
fields: Object.entries(ast.fields).map(([name, fieldAst]) => {
|
|
175
175
|
let value = ast_to_ir(fieldAst, ctx);
|
|
176
176
|
const expectedType = ast.type.fields[name];
|
|
177
177
|
if (!expectedType) {
|
|
178
|
-
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)}`);
|
|
179
179
|
}
|
|
180
180
|
if (!isTypeEqual(fieldAst.type, expectedType)) {
|
|
181
181
|
if (isSubtype(fieldAst.type, expectedType)) {
|
|
182
182
|
value = variant("As", {
|
|
183
183
|
type: toEastTypeValue(expectedType),
|
|
184
184
|
value,
|
|
185
|
-
location:
|
|
185
|
+
location: toLocationValues(ast.location),
|
|
186
186
|
});
|
|
187
187
|
}
|
|
188
188
|
else {
|
|
189
189
|
throw new Error(`Cannot assign field '${name}' of type ${printType(ast.type.fields[name])} ` +
|
|
190
|
-
`with value of type ${printType(fieldAst.type)} at ${
|
|
190
|
+
`with value of type ${printType(fieldAst.type)} at ${printLocations(ast.location)}`);
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
return { name, value };
|
|
@@ -197,7 +197,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
197
197
|
else if (ast.ast_type === "GetField") {
|
|
198
198
|
return variant("GetField", {
|
|
199
199
|
type: toEastTypeValue(ast.type),
|
|
200
|
-
location:
|
|
200
|
+
location: toLocationValues(ast.location),
|
|
201
201
|
struct: ast_to_ir(ast.struct, ctx),
|
|
202
202
|
field: ast.field,
|
|
203
203
|
});
|
|
@@ -210,17 +210,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
210
210
|
value = variant("As", {
|
|
211
211
|
type: toEastTypeValue(expectedType),
|
|
212
212
|
value,
|
|
213
|
-
location:
|
|
213
|
+
location: toLocationValues(ast.location),
|
|
214
214
|
});
|
|
215
215
|
}
|
|
216
216
|
else {
|
|
217
217
|
throw new Error(`Cannot assign case '${ast.case}' of type ${printType(expectedType)} ` +
|
|
218
|
-
`with value of type ${printType(ast.value.type)} at ${
|
|
218
|
+
`with value of type ${printType(ast.value.type)} at ${printLocations(ast.location)}`);
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
return variant("Variant", {
|
|
222
222
|
type: toEastTypeValue(ast.type),
|
|
223
|
-
location:
|
|
223
|
+
location: toLocationValues(ast.location),
|
|
224
224
|
case: ast.case,
|
|
225
225
|
value,
|
|
226
226
|
});
|
|
@@ -230,7 +230,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
230
230
|
const param = variant("Variable", {
|
|
231
231
|
type: toEastTypeValue(parameter.type),
|
|
232
232
|
name: `_${ctx.n_vars}`,
|
|
233
|
-
location:
|
|
233
|
+
location: toLocationValues(parameter.location),
|
|
234
234
|
mutable: parameter.mutable, // false...
|
|
235
235
|
captured: false,
|
|
236
236
|
});
|
|
@@ -258,7 +258,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
258
258
|
}
|
|
259
259
|
return variant("Function", {
|
|
260
260
|
type: toEastTypeValue(ast.type),
|
|
261
|
-
location:
|
|
261
|
+
location: toLocationValues(ast.location),
|
|
262
262
|
parameters,
|
|
263
263
|
captures: [...captures],
|
|
264
264
|
body,
|
|
@@ -269,7 +269,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
269
269
|
const param = variant("Variable", {
|
|
270
270
|
type: toEastTypeValue(parameter.type),
|
|
271
271
|
name: `_${ctx.n_vars}`,
|
|
272
|
-
location:
|
|
272
|
+
location: toLocationValues(parameter.location),
|
|
273
273
|
mutable: parameter.mutable, // false...
|
|
274
274
|
captured: false,
|
|
275
275
|
});
|
|
@@ -297,7 +297,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
297
297
|
}
|
|
298
298
|
return variant("AsyncFunction", {
|
|
299
299
|
type: toEastTypeValue(ast.type),
|
|
300
|
-
location:
|
|
300
|
+
location: toLocationValues(ast.location),
|
|
301
301
|
parameters,
|
|
302
302
|
captures: [...captures],
|
|
303
303
|
body,
|
|
@@ -308,19 +308,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
308
308
|
// TODO - what about widening the result with As?
|
|
309
309
|
return variant("Call", {
|
|
310
310
|
type: toEastTypeValue(ast.type),
|
|
311
|
-
location:
|
|
311
|
+
location: toLocationValues(ast.location),
|
|
312
312
|
function: ast_to_ir(ast.function, ctx),
|
|
313
313
|
arguments: ast.arguments.map((argument, i) => {
|
|
314
314
|
let arg = ast_to_ir(argument, ctx);
|
|
315
315
|
const expectedType = ast.function.type.inputs[i];
|
|
316
316
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
317
317
|
if (!isSubtype(argument.type, expectedType)) {
|
|
318
|
-
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)}`);
|
|
319
319
|
}
|
|
320
320
|
arg = variant("As", {
|
|
321
321
|
type: toEastTypeValue(expectedType),
|
|
322
322
|
value: arg,
|
|
323
|
-
location:
|
|
323
|
+
location: toLocationValues(ast.location),
|
|
324
324
|
});
|
|
325
325
|
}
|
|
326
326
|
return arg;
|
|
@@ -329,25 +329,25 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
329
329
|
}
|
|
330
330
|
else if (ast.ast_type === "CallAsync") {
|
|
331
331
|
if (ctx.async === false) {
|
|
332
|
-
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)}`);
|
|
333
333
|
}
|
|
334
334
|
// TODO - type equality could have been handled at Expr/AST level instead
|
|
335
335
|
// TODO - what about widening the result with As?
|
|
336
336
|
return variant("CallAsync", {
|
|
337
337
|
type: toEastTypeValue(ast.type),
|
|
338
|
-
location:
|
|
338
|
+
location: toLocationValues(ast.location),
|
|
339
339
|
function: ast_to_ir(ast.function, ctx),
|
|
340
340
|
arguments: ast.arguments.map((argument, i) => {
|
|
341
341
|
let arg = ast_to_ir(argument, ctx);
|
|
342
342
|
const expectedType = ast.function.type.inputs[i];
|
|
343
343
|
if (!isTypeEqual(argument.type, expectedType)) {
|
|
344
344
|
if (!isSubtype(argument.type, expectedType)) {
|
|
345
|
-
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)}`);
|
|
346
346
|
}
|
|
347
347
|
arg = variant("As", {
|
|
348
348
|
type: toEastTypeValue(expectedType),
|
|
349
349
|
value: arg,
|
|
350
|
-
location:
|
|
350
|
+
location: toLocationValues(ast.location),
|
|
351
351
|
});
|
|
352
352
|
}
|
|
353
353
|
return arg;
|
|
@@ -359,17 +359,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
359
359
|
let value = ast_to_ir(ast.value, ctx);
|
|
360
360
|
if (!isTypeEqual(ast.value.type, valueType)) {
|
|
361
361
|
if (!isSubtype(ast.value.type, valueType)) {
|
|
362
|
-
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)}`);
|
|
363
363
|
}
|
|
364
364
|
value = variant("As", {
|
|
365
365
|
type: toEastTypeValue(valueType),
|
|
366
366
|
value,
|
|
367
|
-
location:
|
|
367
|
+
location: toLocationValues(ast.location),
|
|
368
368
|
});
|
|
369
369
|
}
|
|
370
370
|
return variant("NewRef", {
|
|
371
371
|
type: toEastTypeValue(ast.type),
|
|
372
|
-
location:
|
|
372
|
+
location: toLocationValues(ast.location),
|
|
373
373
|
value,
|
|
374
374
|
});
|
|
375
375
|
}
|
|
@@ -377,17 +377,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
377
377
|
const valueType = ast.type.value;
|
|
378
378
|
return variant("NewArray", {
|
|
379
379
|
type: toEastTypeValue(ast.type),
|
|
380
|
-
location:
|
|
380
|
+
location: toLocationValues(ast.location),
|
|
381
381
|
values: ast.values.map((v, i) => {
|
|
382
382
|
let value = ast_to_ir(v, ctx);
|
|
383
383
|
if (!isTypeEqual(v.type, valueType)) {
|
|
384
384
|
if (!isSubtype(v.type, valueType)) {
|
|
385
|
-
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)}`);
|
|
386
386
|
}
|
|
387
387
|
value = variant("As", {
|
|
388
388
|
type: toEastTypeValue(valueType),
|
|
389
389
|
value,
|
|
390
|
-
location:
|
|
390
|
+
location: toLocationValues(ast.location),
|
|
391
391
|
});
|
|
392
392
|
}
|
|
393
393
|
return value;
|
|
@@ -398,17 +398,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
398
398
|
const keyType = ast.type.key;
|
|
399
399
|
return variant("NewSet", {
|
|
400
400
|
type: toEastTypeValue(ast.type),
|
|
401
|
-
location:
|
|
401
|
+
location: toLocationValues(ast.location),
|
|
402
402
|
values: ast.values.map((k, i) => {
|
|
403
403
|
let key = ast_to_ir(k, ctx);
|
|
404
404
|
if (!isTypeEqual(k.type, keyType)) {
|
|
405
405
|
if (!isSubtype(k.type, keyType)) {
|
|
406
|
-
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)}`);
|
|
407
407
|
}
|
|
408
408
|
key = variant("As", {
|
|
409
409
|
type: toEastTypeValue(keyType),
|
|
410
410
|
value: key,
|
|
411
|
-
location:
|
|
411
|
+
location: toLocationValues(ast.location),
|
|
412
412
|
});
|
|
413
413
|
}
|
|
414
414
|
return key;
|
|
@@ -420,28 +420,28 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
420
420
|
const valueType = ast.type.value;
|
|
421
421
|
return variant("NewDict", {
|
|
422
422
|
type: toEastTypeValue(ast.type),
|
|
423
|
-
location:
|
|
423
|
+
location: toLocationValues(ast.location),
|
|
424
424
|
values: ast.values.map(([k, v], i) => {
|
|
425
425
|
let key = ast_to_ir(k, ctx);
|
|
426
426
|
if (!isTypeEqual(k.type, keyType)) {
|
|
427
427
|
if (!isSubtype(k.type, keyType)) {
|
|
428
|
-
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)}`);
|
|
429
429
|
}
|
|
430
430
|
key = variant("As", {
|
|
431
431
|
type: toEastTypeValue(keyType),
|
|
432
432
|
value: key,
|
|
433
|
-
location:
|
|
433
|
+
location: toLocationValues(ast.location),
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
436
|
let value = ast_to_ir(v, ctx);
|
|
437
437
|
if (!isTypeEqual(v.type, valueType)) {
|
|
438
438
|
if (!isSubtype(v.type, valueType)) {
|
|
439
|
-
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)}`);
|
|
440
440
|
}
|
|
441
441
|
value = variant("As", {
|
|
442
442
|
type: toEastTypeValue(valueType),
|
|
443
443
|
value,
|
|
444
|
-
location:
|
|
444
|
+
location: toLocationValues(ast.location),
|
|
445
445
|
});
|
|
446
446
|
}
|
|
447
447
|
;
|
|
@@ -468,12 +468,12 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
468
468
|
ctx.n_loops = ctx_branch.n_loops;
|
|
469
469
|
if (branch.body.type.type !== "Never" && !isTypeEqual(branch.body.type, ast.type)) {
|
|
470
470
|
if (!isSubtype(branch.body.type, ast.type)) {
|
|
471
|
-
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)}`);
|
|
472
472
|
}
|
|
473
473
|
branch_body = variant("As", {
|
|
474
474
|
type: toEastTypeValue(ast.type),
|
|
475
475
|
value: branch_body,
|
|
476
|
-
location:
|
|
476
|
+
location: toLocationValues(ast.location),
|
|
477
477
|
});
|
|
478
478
|
}
|
|
479
479
|
return { predicate, body: branch_body };
|
|
@@ -494,17 +494,17 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
494
494
|
ctx.n_loops = ctx_else.n_loops;
|
|
495
495
|
if (ast.else_body.type.type !== "Never" && !isTypeEqual(ast.else_body.type, ast.type)) {
|
|
496
496
|
if (!isSubtype(ast.else_body.type, ast.type)) {
|
|
497
|
-
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)}`);
|
|
498
498
|
}
|
|
499
499
|
else_body = variant("As", {
|
|
500
500
|
type: toEastTypeValue(ast.type),
|
|
501
501
|
value: else_body,
|
|
502
|
-
location:
|
|
502
|
+
location: toLocationValues(ast.location),
|
|
503
503
|
});
|
|
504
504
|
}
|
|
505
505
|
return variant("IfElse", {
|
|
506
506
|
type: toEastTypeValue(ast.type),
|
|
507
|
-
location:
|
|
507
|
+
location: toLocationValues(ast.location),
|
|
508
508
|
ifs,
|
|
509
509
|
else_body,
|
|
510
510
|
});
|
|
@@ -512,7 +512,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
512
512
|
else if (ast.ast_type === "Error") {
|
|
513
513
|
return variant("Error", {
|
|
514
514
|
type: variant("Never", null),
|
|
515
|
-
location:
|
|
515
|
+
location: toLocationValues(ast.location),
|
|
516
516
|
message: ast_to_ir(ast.message, ctx),
|
|
517
517
|
});
|
|
518
518
|
}
|
|
@@ -535,7 +535,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
535
535
|
const message = variant("Variable", {
|
|
536
536
|
type: toEastTypeValue(ast.message.type),
|
|
537
537
|
name: `_${ctx.n_vars}`,
|
|
538
|
-
location:
|
|
538
|
+
location: toLocationValues(ast.message.location),
|
|
539
539
|
mutable: ast.message.mutable, // false...
|
|
540
540
|
captured: false,
|
|
541
541
|
});
|
|
@@ -543,7 +543,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
543
543
|
const stack = variant("Variable", {
|
|
544
544
|
type: toEastTypeValue(ast.stack.type),
|
|
545
545
|
name: `_${ctx.n_vars}`,
|
|
546
|
-
location:
|
|
546
|
+
location: toLocationValues(ast.stack.location),
|
|
547
547
|
mutable: ast.stack.mutable, // false...
|
|
548
548
|
captured: false,
|
|
549
549
|
});
|
|
@@ -583,13 +583,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
583
583
|
else {
|
|
584
584
|
finally_body = variant("Value", {
|
|
585
585
|
type: toEastTypeValue(NullType),
|
|
586
|
-
location:
|
|
586
|
+
location: toLocationValues(ast.location),
|
|
587
587
|
value: variant("Null", null),
|
|
588
588
|
});
|
|
589
589
|
}
|
|
590
590
|
return variant("TryCatch", {
|
|
591
591
|
type: toEastTypeValue(ast.type),
|
|
592
|
-
location:
|
|
592
|
+
location: toLocationValues(ast.location),
|
|
593
593
|
try_body,
|
|
594
594
|
catch_body,
|
|
595
595
|
message,
|
|
@@ -625,18 +625,18 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
625
625
|
throw new Error(`Unsupported literal value type: ${typeof ast.value} (expected ${printType(ast.type)})`);
|
|
626
626
|
}
|
|
627
627
|
if (type.type !== value.type) {
|
|
628
|
-
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}`);
|
|
629
629
|
}
|
|
630
630
|
return variant("Value", {
|
|
631
631
|
type,
|
|
632
|
-
location:
|
|
632
|
+
location: toLocationValues(ast.location),
|
|
633
633
|
value,
|
|
634
634
|
});
|
|
635
635
|
}
|
|
636
636
|
else if (ast.ast_type === "As") {
|
|
637
637
|
return variant("As", {
|
|
638
638
|
type: toEastTypeValue(ast.type),
|
|
639
|
-
location:
|
|
639
|
+
location: toLocationValues(ast.location),
|
|
640
640
|
value: ast_to_ir(ast.value, ctx),
|
|
641
641
|
});
|
|
642
642
|
}
|
|
@@ -644,7 +644,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
644
644
|
const predicate = ast_to_ir(ast.predicate, ctx);
|
|
645
645
|
const label = {
|
|
646
646
|
name: `_${ctx.n_loops}`,
|
|
647
|
-
location:
|
|
647
|
+
location: toLocationValues(ast.label.location),
|
|
648
648
|
};
|
|
649
649
|
ctx.n_loops += 1;
|
|
650
650
|
const ctx2 = {
|
|
@@ -663,7 +663,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
663
663
|
ctx.n_loops = ctx2.n_loops;
|
|
664
664
|
return variant("While", {
|
|
665
665
|
type: variant("Null", null),
|
|
666
|
-
location:
|
|
666
|
+
location: toLocationValues(ast.location),
|
|
667
667
|
label,
|
|
668
668
|
predicate,
|
|
669
669
|
body,
|
|
@@ -673,13 +673,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
673
673
|
const array = ast_to_ir(ast.array, ctx);
|
|
674
674
|
const label = {
|
|
675
675
|
name: `_${ctx.n_loops}`,
|
|
676
|
-
location:
|
|
676
|
+
location: toLocationValues(ast.label.location),
|
|
677
677
|
};
|
|
678
678
|
ctx.n_loops += 1;
|
|
679
679
|
const value = variant("Variable", {
|
|
680
680
|
type: toEastTypeValue(ast.value.type),
|
|
681
681
|
name: `_${ctx.n_vars}`,
|
|
682
|
-
location:
|
|
682
|
+
location: toLocationValues(ast.value.location),
|
|
683
683
|
mutable: ast.value.mutable, // false...
|
|
684
684
|
captured: false,
|
|
685
685
|
});
|
|
@@ -687,7 +687,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
687
687
|
const key = variant("Variable", {
|
|
688
688
|
type: toEastTypeValue(ast.key.type),
|
|
689
689
|
name: `_${ctx.n_vars}`,
|
|
690
|
-
location:
|
|
690
|
+
location: toLocationValues(ast.key.location),
|
|
691
691
|
mutable: ast.key.mutable, // false...
|
|
692
692
|
captured: false,
|
|
693
693
|
});
|
|
@@ -708,7 +708,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
708
708
|
ctx.n_loops = ctx2.n_loops;
|
|
709
709
|
return variant("ForArray", {
|
|
710
710
|
type: variant("Null", null),
|
|
711
|
-
location:
|
|
711
|
+
location: toLocationValues(ast.location),
|
|
712
712
|
label,
|
|
713
713
|
key,
|
|
714
714
|
value,
|
|
@@ -720,13 +720,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
720
720
|
const set = ast_to_ir(ast.set, ctx);
|
|
721
721
|
const label = {
|
|
722
722
|
name: `_${ctx.n_loops}`,
|
|
723
|
-
location:
|
|
723
|
+
location: toLocationValues(ast.label.location),
|
|
724
724
|
};
|
|
725
725
|
ctx.n_loops += 1;
|
|
726
726
|
const key = variant("Variable", {
|
|
727
727
|
type: toEastTypeValue(ast.key.type),
|
|
728
728
|
name: `_${ctx.n_vars}`,
|
|
729
|
-
location:
|
|
729
|
+
location: toLocationValues(ast.key.location),
|
|
730
730
|
mutable: ast.key.mutable, // false...
|
|
731
731
|
captured: false,
|
|
732
732
|
});
|
|
@@ -747,7 +747,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
747
747
|
ctx.n_loops = ctx2.n_loops;
|
|
748
748
|
return variant("ForSet", {
|
|
749
749
|
type: variant("Null", null),
|
|
750
|
-
location:
|
|
750
|
+
location: toLocationValues(ast.location),
|
|
751
751
|
label,
|
|
752
752
|
key,
|
|
753
753
|
set,
|
|
@@ -758,13 +758,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
758
758
|
const dict = ast_to_ir(ast.dict, ctx);
|
|
759
759
|
const label = {
|
|
760
760
|
name: `_${ctx.n_loops}`,
|
|
761
|
-
location:
|
|
761
|
+
location: toLocationValues(ast.label.location),
|
|
762
762
|
};
|
|
763
763
|
ctx.n_loops += 1;
|
|
764
764
|
const value = variant("Variable", {
|
|
765
765
|
type: toEastTypeValue(ast.value.type),
|
|
766
766
|
name: `_${ctx.n_vars}`,
|
|
767
|
-
location:
|
|
767
|
+
location: toLocationValues(ast.value.location),
|
|
768
768
|
mutable: ast.value.mutable, // false...
|
|
769
769
|
captured: false,
|
|
770
770
|
});
|
|
@@ -772,7 +772,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
772
772
|
const key = variant("Variable", {
|
|
773
773
|
type: toEastTypeValue(ast.key.type),
|
|
774
774
|
name: `_${ctx.n_vars}`,
|
|
775
|
-
location:
|
|
775
|
+
location: toLocationValues(ast.key.location),
|
|
776
776
|
mutable: ast.key.mutable, // false...
|
|
777
777
|
captured: false,
|
|
778
778
|
});
|
|
@@ -793,7 +793,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
793
793
|
ctx.n_loops = ctx2.n_loops;
|
|
794
794
|
return variant("ForDict", {
|
|
795
795
|
type: variant("Null", null),
|
|
796
|
-
location:
|
|
796
|
+
location: toLocationValues(ast.location),
|
|
797
797
|
label,
|
|
798
798
|
key,
|
|
799
799
|
value,
|
|
@@ -808,7 +808,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
808
808
|
const variable = variant("Variable", {
|
|
809
809
|
type: toEastTypeValue(v.variable.type),
|
|
810
810
|
name: `_${ctx.n_vars}`,
|
|
811
|
-
location:
|
|
811
|
+
location: toLocationValues(v.variable.location),
|
|
812
812
|
mutable: v.variable.mutable, // false...
|
|
813
813
|
captured: false,
|
|
814
814
|
});
|
|
@@ -829,19 +829,19 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
829
829
|
ctx.n_loops = ctx2.n_loops;
|
|
830
830
|
if (v.body.type.type !== "Never" && !isTypeEqual(v.body.type, ast.type)) {
|
|
831
831
|
if (!isSubtype(v.body.type, ast.type)) {
|
|
832
|
-
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)}`);
|
|
833
833
|
}
|
|
834
834
|
body = variant("As", {
|
|
835
835
|
type: toEastTypeValue(ast.type),
|
|
836
836
|
value: body,
|
|
837
|
-
location:
|
|
837
|
+
location: toLocationValues(ast.location),
|
|
838
838
|
});
|
|
839
839
|
}
|
|
840
840
|
cases.push({ case: k, variable, body });
|
|
841
841
|
}
|
|
842
842
|
return variant("Match", {
|
|
843
843
|
type: toEastTypeValue(ast.type),
|
|
844
|
-
location:
|
|
844
|
+
location: toLocationValues(ast.location),
|
|
845
845
|
variant: variant_expr,
|
|
846
846
|
cases,
|
|
847
847
|
});
|
|
@@ -849,7 +849,7 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
849
849
|
else if (ast.ast_type === "UnwrapRecursive") {
|
|
850
850
|
return variant("UnwrapRecursive", {
|
|
851
851
|
type: toEastTypeValue(ast.type),
|
|
852
|
-
location:
|
|
852
|
+
location: toLocationValues(ast.location),
|
|
853
853
|
value: ast_to_ir(ast.value, ctx),
|
|
854
854
|
});
|
|
855
855
|
}
|
|
@@ -860,14 +860,14 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
860
860
|
}
|
|
861
861
|
const existing = ctx.recursiveASTs.has(ast);
|
|
862
862
|
if (existing) {
|
|
863
|
-
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)}`);
|
|
864
864
|
}
|
|
865
865
|
// Register before recursing (enables cycle detection)
|
|
866
866
|
ctx.recursiveASTs.add(ast);
|
|
867
867
|
// Create WrapRecursive IR node with placeholder
|
|
868
868
|
const wrapIR = variant("WrapRecursive", {
|
|
869
869
|
type: toEastTypeValue(ast.type),
|
|
870
|
-
location:
|
|
870
|
+
location: toLocationValues(ast.location),
|
|
871
871
|
value: ast_to_ir(ast.value, ctx),
|
|
872
872
|
});
|
|
873
873
|
// The user may alias this AST value elsewhere in the tree, just not with a circular reference
|
|
@@ -877,32 +877,32 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
877
877
|
else if (ast.ast_type === "Break") {
|
|
878
878
|
const label = ctx.loop_ctx.get(ast.label);
|
|
879
879
|
if (label === undefined) {
|
|
880
|
-
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)}`);
|
|
881
881
|
}
|
|
882
882
|
return variant("Break", {
|
|
883
883
|
type: variant("Never", null),
|
|
884
|
-
location:
|
|
884
|
+
location: toLocationValues(ast.location),
|
|
885
885
|
label,
|
|
886
886
|
});
|
|
887
887
|
}
|
|
888
888
|
else if (ast.ast_type === "Continue") {
|
|
889
889
|
const label = ctx.loop_ctx.get(ast.label);
|
|
890
890
|
if (label === undefined) {
|
|
891
|
-
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)}`);
|
|
892
892
|
}
|
|
893
893
|
return variant("Continue", {
|
|
894
894
|
type: variant("Never", null),
|
|
895
|
-
location:
|
|
895
|
+
location: toLocationValues(ast.location),
|
|
896
896
|
label,
|
|
897
897
|
});
|
|
898
898
|
}
|
|
899
899
|
else if (ast.ast_type === "Return") {
|
|
900
900
|
if (!isSubtype(ast.value.type, ctx.output)) {
|
|
901
|
-
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)}`);
|
|
902
902
|
}
|
|
903
903
|
return variant("Return", {
|
|
904
904
|
type: variant("Never", null),
|
|
905
|
-
location:
|
|
905
|
+
location: toLocationValues(ast.location),
|
|
906
906
|
value: ast_to_ir(ast.value, ctx),
|
|
907
907
|
});
|
|
908
908
|
}
|
|
@@ -913,13 +913,13 @@ export function ast_to_ir(ast, ctx = { local_ctx: new Map(), parent_ctx: new Map
|
|
|
913
913
|
catch (e) {
|
|
914
914
|
if (e instanceof Error) {
|
|
915
915
|
if (ast.ast_type === "Builtin") {
|
|
916
|
-
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)}`;
|
|
917
917
|
}
|
|
918
918
|
else if (ast.ast_type === "Platform") {
|
|
919
|
-
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)}`;
|
|
920
920
|
}
|
|
921
921
|
else {
|
|
922
|
-
e.message += `\n at ${ast.ast_type} node located at ${
|
|
922
|
+
e.message += `\n at ${ast.ast_type} node located at ${printLocations(ast.location)}`;
|
|
923
923
|
}
|
|
924
924
|
}
|
|
925
925
|
throw e;
|