js-slang
Version:
Javascript-based implementations of Source, written in Typescript
101 lines • 4.66 kB
JavaScript
"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