UNPKG

js-slang

Version:

Javascript-based implementations of Source, written in Typescript

82 lines 3.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StepperLogicalExpression = void 0; const __1 = require("../.."); const generator_1 = require("../../generator"); const Literal_1 = require("./Literal"); class StepperLogicalExpression { constructor(operator, left, right, leadingComments, trailingComments, loc, range) { this.type = 'LogicalExpression'; this.operator = operator; this.left = left; this.right = right; this.leadingComments = leadingComments; this.trailingComments = trailingComments; this.loc = loc; this.range = range; } static create(node) { return new StepperLogicalExpression(node.operator, (0, generator_1.convert)(node.left), (0, generator_1.convert)(node.right), node.leadingComments, node.trailingComments, node.loc, node.range); } isContractible() { if (this.left.type === 'Literal') { const leftType = typeof this.left.value; if (leftType !== 'boolean') { throw new Error(`Line ${this.loc?.start.line || 0}: Expected boolean on left hand side of operation, got ${leftType}.`); } __1.redex.preRedex = [this]; return true; } return false; } isOneStepPossible() { return this.isContractible() || this.left.isOneStepPossible() || this.right.isOneStepPossible(); } contract() { __1.redex.preRedex = [this]; if (this.left.type !== 'Literal') throw new Error('Left operand must be a literal to contract'); const leftValue = this.left.value; if (this.operator === '&&' && !leftValue) { let ret = new Literal_1.StepperLiteral(false, undefined, this.leadingComments, this.trailingComments, this.loc, this.range); __1.redex.postRedex = [ret]; return ret; } else if (this.operator === '||' && leftValue) { let ret = new Literal_1.StepperLiteral(true, undefined, this.leadingComments, this.trailingComments, this.loc, this.range); __1.redex.postRedex = [ret]; return ret; } else { return this.right; } } oneStep() { if (this.isContractible()) { return this.contract(); } else if (this.left.isOneStepPossible()) { return new StepperLogicalExpression(this.operator, this.left.oneStep(), this.right, this.leadingComments, this.trailingComments, this.loc, this.range); } else if (this.right.isOneStepPossible()) { return new StepperLogicalExpression(this.operator, this.left, this.right.oneStep(), this.leadingComments, this.trailingComments, this.loc, this.range); } else { throw new Error('No step possible'); } } substitute(id, value) { return new StepperLogicalExpression(this.operator, this.left.substitute(id, value), this.right.substitute(id, value), this.leadingComments, this.trailingComments, this.loc, this.range); } freeNames() { return Array.from(new Set([this.left.freeNames(), this.right.freeNames()].flat())); } allNames() { return Array.from(new Set([this.left.allNames(), this.right.allNames()].flat())); } rename(before, after) { return new StepperLogicalExpression(this.operator, this.left.rename(before, after), this.right.rename(before, after), this.leadingComments, this.trailingComments, this.loc, this.range); } } exports.StepperLogicalExpression = StepperLogicalExpression; //# sourceMappingURL=LogicalExpression.js.map