UNPKG

subscript

Version:

Modular expression parser & evaluator

38 lines (35 loc) 1.26 kB
// Function declarations and expressions - eval half import { operator, compile } from '../parse.js'; import { RETURN } from './op/arrow.js'; operator('function', (name, params, body) => { body = body ? compile(body) : () => undefined; // Normalize params: null → [], 'x' → ['x'], [',', 'a', 'b'] → ['a', 'b'] const ps = !params ? [] : params[0] === ',' ? params.slice(1) : [params]; // Check for rest param let restName = null, restIdx = -1; const last = ps[ps.length - 1]; if (Array.isArray(last) && last[0] === '...') { restIdx = ps.length - 1; restName = last[1]; ps.length--; } return ctx => { const fn = (...args) => { const l = {}; ps.forEach((p, i) => l[p] = args[i]); if (restName) l[restName] = args.slice(restIdx); const fnCtx = new Proxy(l, { get: (l, k) => k in l ? l[k] : ctx[k], set: (l, k, v) => ((k in l ? l : ctx)[k] = v, true), has: (l, k) => k in l || k in ctx }); try { return body(fnCtx); } catch (e) { if (e === RETURN) return e[0]; throw e; } }; if (name) ctx[name] = fn; return fn; }; }); operator('function*', (name, params, body) => { throw Error('Generator functions are not supported in evaluation'); });