-
Notifications
You must be signed in to change notification settings - Fork 0
/
runtime-helpers.js
62 lines (56 loc) · 1.43 KB
/
runtime-helpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { RuntimeError } from "./errors";
function asString(input) {
if (typeof input === "function") {
return input.name;
}
return String(input);
}
function checkArgs(def, args, context) {
if (!def.args) {
return;
}
// Check number of arguments...
if (def.args.length && args.length !== def.args.length) {
throw new RuntimeError(
`'${def.name}' expects ${def.args.length} args, found ${args.length}`,
{
path: context.path,
}
);
}
// Check types of arguments...
if (def.args.def) {
const errAt = def.args.def.findIndex((t, idx) => {
if (typeof t === "function" && t.prototype) {
return !(args[idx] instanceof t);
}
if (t === "*") {
return false;
}
if (t === "Array") {
return !Array.isArray(args[idx]);
}
return typeof args[idx] !== t;
});
if (errAt > -1) {
const expectedType = asString(def.args.def[errAt]);
let message = `Argument ${errAt} must be ${expectedType}`;
if (def.args.binaryExpression) {
message = `Expected ${expectedType}`;
}
throw new RuntimeError(message, {
path: context.path.concat(errAt),
});
}
}
}
export function generateValidatedOperators(ops = []) {
const out = {};
ops.forEach((op) => {
out[op.name] = function (...args) {
checkArgs(op, args, this);
return op.handler.apply(this, args);
};
});
return out;
}