UNPKG

js-slang

Version:

Javascript-based implementations of Source, written in Typescript

101 lines 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StepperFunctionDeclaration = void 0; const __1 = require(".."); const generator_1 = require("../../generator"); const __2 = require("../.."); const ArrowFunctionExpression_1 = require("../Expression/ArrowFunctionExpression"); const utils_1 = require("../../utils"); class StepperFunctionDeclaration { constructor(id, body, params, generator, async, leadingComments, trailingComments, loc, range) { this.type = 'FunctionDeclaration'; this.id = id; this.params = params; this.generator = generator; this.async = async; this.leadingComments = leadingComments; this.trailingComments = trailingComments; this.loc = loc; this.range = range; /* const repeatedNames = body.scanAllDeclarationNames().filter(name => name === this.id.name); const newNames = getFreshName([this.id.name], repeatedNames) let currentBlockStatement = body for (var index in newNames) { currentBlockStatement = currentBlockStatement.rename(repeatedNames[index], newNames[index]) } */ this.body = body; } static create(node) { return new StepperFunctionDeclaration((0, generator_1.convert)(node.id), (0, generator_1.convert)(node.body), node.params.map(param => (0, generator_1.convert)(param)), node.generator, node.async, node.leadingComments, node.trailingComments, node.loc, node.range); } isContractible() { return false; } isOneStepPossible() { return false; } getArrowFunctionExpression() { return new ArrowFunctionExpression_1.StepperArrowFunctionExpression(this.params, this.body, this.id.name, // mu term false, this.async, this.generator); } contract() { __2.redex.preRedex = [this]; __2.redex.postRedex = []; return __1.undefinedNode; } contractEmpty() { __2.redex.preRedex = [this]; __2.redex.postRedex = []; } oneStep() { return this.contract(); } scanAllDeclarationNames() { const paramNames = this.params.map(param => param.name); const bodyDeclarations = this.body.body .filter(ast => ast.type === 'VariableDeclaration' || ast.type === 'FunctionDeclaration') .flatMap((ast) => { if (ast.type === 'VariableDeclaration') { return ast.declarations.map(ast => ast.id.name); } else { // Function Declaration return [ast.id.name]; } }); return [...paramNames, ...bodyDeclarations]; } substitute(id, value, upperBoundName) { const valueFreeNames = value.freeNames(); const scopeNames = this.scanAllDeclarationNames(); const repeatedNames = valueFreeNames.filter(name => scopeNames.includes(name)); let protectedNamesSet = new Set([this.allNames(), upperBoundName ?? []].flat()); repeatedNames.forEach(name => protectedNamesSet.delete(name)); const protectedNames = Array.from(protectedNamesSet); const newNames = (0, utils_1.getFreshName)(repeatedNames, protectedNames); const currentFunction = newNames.reduce((current, name, index) => current.rename(repeatedNames[index], name), this); if (currentFunction.scanAllDeclarationNames().includes(id.name)) { return currentFunction; } return new StepperFunctionDeclaration(this.id, currentFunction.body.substitute(id, value, currentFunction.params.flatMap(p => p.allNames())), currentFunction.params, this.generator, this.async, this.leadingComments, this.trailingComments, this.loc, this.range); } freeNames() { const paramNames = this.params .filter(param => param.type === 'Identifier') .map(param => param.name); return this.body.freeNames().filter(name => !paramNames.includes(name)); } allNames() { const paramNames = this.params .filter(param => param.type === 'Identifier') .map(param => param.name); return Array.from(new Set([paramNames, this.body.allNames()].flat())); } rename(before, after) { return new StepperFunctionDeclaration(this.id.rename(before, after), this.body.rename(before, after), this.params.map(param => param.rename(before, after)), this.generator, this.async, this.leadingComments, this.trailingComments, this.loc, this.range); } } exports.StepperFunctionDeclaration = StepperFunctionDeclaration; //# sourceMappingURL=FunctionDeclaration.js.map