UNPKG

expression-evaluation

Version:
56 lines (55 loc) 2.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CallNode = void 0; const Node_js_1 = require("../Node.js"); const ConstantNode_js_1 = require("./ConstantNode.js"); const Type_js_1 = require("../Type.js"); class CallNode extends Node_js_1.Node { _fnode; _subnodes; _type; constructor(frame, _fnode, _subnodes) { super(frame); this._fnode = _fnode; this._subnodes = _subnodes; this._type = _fnode.signature?.type ?? Type_js_1.typeUnknown; } get type() { return this._type; } compile(type) { this._fnode = this._fnode.compile(Type_js_1.typeFunction); this._type = this._fnode.signature?.type ?? Type_js_1.typeUnknown; this._type = this.reduceType(type); const signature = this._fnode.signature; if (signature) { if (this._subnodes.length < signature.minArity) { this.throwError(`insufficient number of arguments ${this._subnodes.length} is less than ${signature.minArity} that function requires`); } if (this._subnodes.length > signature.maxArity) { this.throwError(`excessive number of arguments ${this._subnodes.length} is more than ${signature.maxArity} that function requires`); } } let constant = signature?.pure; for (let i = 0; i < this._subnodes.length; ++i) { const argTypeInference = signature?.argTypeInference(this.type, i) ?? Type_js_1.typeUnknown; if (!argTypeInference) { this.throwTypeError(type); } this._subnodes[i] = this._subnodes[i].compile(argTypeInference); constant &&= this._subnodes[i].constant; } return constant && this._fnode.constant ? new ConstantNode_js_1.ConstantNode(this, this._fnode.evaluate()(...this._subnodes.map((node) => node.evaluate()))) : this; } evaluate() { return this._fnode.evaluate()(...this._subnodes.map((node) => node.evaluate())); } toString(ident = 0) { return `${super.toString(ident)} call node` + `, fnode:${this._fnode.toString(ident + 1)}` + `, subnodes:\n${this._subnodes.map((s) => s.toString(ident + 1)).join('\n')}`; } } exports.CallNode = CallNode;