UNPKG

nisp

Version:

A language that for easily build cross-language language

102 lines (101 loc) 2.91 kB
"use strict"; exports.__esModule = true; var utils_1 = require("./utils"); // To safely mark a function as macro function function macro(fn) { return Object.defineProperty(fn, 'macro', { configurable: false, value: true }); } exports.macro = macro; function apply(fn, ctx) { if (fn.macro) return fn(ctx); var args = [], len = ctx.ast.length; for (var i = 1; i < len; i++) { args[i - 1] = arg(ctx, i); } return fn.apply(ctx, args); } /** * Get nth argument value */ function arg(ctx, index) { return nisp({ ast: ctx.ast[index], sandbox: ctx.sandbox, env: ctx.env, parent: ctx, index: index }); } exports.arg = arg; var NispError = (function () { function NispError(msg, stack) { this.name = 'NispError'; this.stack = stack; this.message = msg; } NispError.prototype.toString = function () { return "NispError: " + this.message + "\n" + "stack: " + JSON.stringify(this.stack, null, 4); }; return NispError; }()); exports.NispError = NispError; /** * Throw error with stack info */ exports.error = function (ctx, msg) { var stack = []; var node = ctx; var max = 100; while (node && max-- > 0) { stack.push(node.ast[0], node.index); node = node.parent; } throw new NispError(msg, stack); }; function nisp(ctx) { if (!ctx) exports.error(ctx, "ctx is required"); var sandbox = ctx.sandbox, ast = ctx.ast; if (!sandbox) exports.error(ctx, "sandbox is required"); if (utils_1.isArray(ast)) { if (ast.length === 0) return; var action = arg(ctx, 0); if (utils_1.isFunction(action)) { return apply(action, ctx); } if (action in sandbox) { var fn = sandbox[action]; return utils_1.isFunction(fn) ? apply(fn, ctx) : fn; } else { exports.error(ctx, "function \"" + action + "\" is undefined"); } } else { return ast; } } /** * Eval an nisp ast * @param {any} ast The abstract syntax tree of nisp. * It's a common flaw that array cannot carry plain data, * such as `['foo', [1,2]]`, The `1` will be treat as a function name. * So it's recommended to use object to carry plain data, * such as translate the example to `['foo', { data: [1, 2] }]`. * @param {Sandbox} sandbox The interface to the real world. * It defined functions to reduce the data of each expression. * @param {any} env The system space of the vm. * @param {any} parent Parent context, it is used to back trace the execution stack. */ function default_1(ast, sandbox, env, parent, index) { if (index === void 0) { index = 0; } return nisp({ ast: ast, sandbox: sandbox, env: env, parent: parent, index: index }); } exports["default"] = default_1;