@jplorg/jpl
Version:
JPL interpreter
125 lines (124 loc) • 4.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _library = require("../../../library");
var _utils = require("../utils");
var _default = exports.default = {
/** { pipe: [op], optional: boolean } */
async op(runtime, input, target, params, scope, next) {
let items;
const vt = runtime.unwrapValue(target);
const tt = runtime.type(target);
switch (tt) {
case 'null':
case 'object':
case 'array':
items = vt;
break;
case 'string':
items = [...vt];
break;
default:
if (params.optional) return [undefined];
throw new _library.JPLTypeError('cannot access fields of %s (%*<100v) (assignment)', tt, vt);
}
const fields = await runtime.executeInstructions(params.pipe ?? [], [input], scope, output => [output]);
const iter = async (from, source) => {
// Call stack decoupling - This is necessary as some browsers (i.e. Safari) have very limited call stack sizes which result in stack overflow exceptions in certain situations.
await undefined;
scope.signal.checkHealth();
if (from >= fields.length) return [source];
const t = tt === 'string' ? tt : runtime.type(source);
const field = runtime.unwrapValue(fields[from]);
const tf = runtime.type(field);
switch (t) {
case 'null':
{
switch (tf) {
case 'string':
return runtime.muxAll([await next(null)], output => {
if (output === undefined) return iter(from + 1, source);
return iter(from + 1, {
[field]: output
});
});
case 'number':
{
const i = Math.trunc(field);
return runtime.muxAll([await next(null)], output => {
if (output === undefined) return iter(from + 1, source);
return iter(from + 1, (0, _library.applyArray)([], [[i, output]]));
});
}
default:
}
break;
}
case 'object':
if (tf === 'string') {
const item = source[field];
return runtime.muxAll([await next(item ?? null)], output => {
if (output === undefined) return iter(from + 1, source);
return iter(from + 1, (0, _library.applyObject)(source, [[field, output]]));
});
}
break;
case 'array':
if (tf === 'number') {
const i = Math.trunc(field);
const item = source[i >= 0 ? i : source.length + i];
return runtime.muxAll([await next(item ?? null)], output => {
if (output === undefined) return iter(from + 1, source);
return iter(from + 1, (0, _library.applyArray)(source, [[i, output]]));
});
}
break;
case 'string':
if (tf === 'number') {
const i = Math.trunc(field);
const item = source[i >= 0 ? i : source.length + i];
return runtime.muxAll([await next(item ?? null)], output => {
if (output === undefined) return iter(from + 1, source);
const r = runtime.unwrapValue(output);
const tr = runtime.type(r);
switch (tr) {
case 'null':
case 'string':
return iter(from + 1, (0, _library.applyArray)(source, [[i, output ?? ' ']], ' '));
default:
}
throw new _library.JPLTypeError('cannot assign %s (%*<100v) to string (%*<100v)', tr, r, source.join(''));
});
}
break;
default:
}
if (params.optional) return iter(from + 1, source);
throw new _library.JPLTypeError('cannot access field of %s (%*<100v) with %s (%*<100v) (assignment)', t, t === 'string' ? source.join('') : source, tf, field);
};
return runtime.muxAsync([await iter(0, items)], results => {
if (items === results) return target;
const t = tt === 'string' ? tt : runtime.type(results);
switch (t) {
case 'null':
return undefined;
case 'object':
case 'array':
return runtime.alterValue(target, () => results);
case 'string':
return runtime.alterValue(target, () => results.join(''));
default:
}
return undefined;
});
},
/** { pipe: function, optional: boolean } */
map(runtime, params) {
return {
pipe: (0, _utils.call)(params.pipe),
optional: runtime.assertType(params.optional, 'boolean')
};
}
};