UNPKG

@informalsystems/quint

Version:

Core tool for the Quint specification language

116 lines 4.11 kB
"use strict"; /* ---------------------------------------------------------------------------------- * Copyright 2022 Informal Systems * Licensed under the Apache License, Version 2.0. * See LICENSE in the project root for license information. * --------------------------------------------------------------------------------- */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ToEffectVisitor = void 0; /** * An ANTLR4 listener that constructs Effect objects out of the abstract * syntax tree. */ class ToEffectVisitor { constructor() { // The resulting effect this.effect = undefined; // Stack of lists of effects, each list will hold the effects of an arrow effect this.arrowEffectsStack = []; this.entitiesStack = []; this.stateVars = []; this.idCounter = 0n; } pushEffect(effect) { this.effect = effect; // If inside an arrow effect, push it this effect to the arrow's effects list if (this.arrowEffectsStack.length > 0) { this.arrowEffectsStack[this.arrowEffectsStack.length - 1].push(effect); } } exitReadOnly() { const entity = this.entitiesStack.pop(); const effect = { kind: 'concrete', components: [{ kind: 'read', entity: entity }] }; this.pushEffect(effect); } exitUpdateOnly() { const entity = this.entitiesStack.pop(); const effect = { kind: 'concrete', components: [{ kind: 'update', entity: entity }] }; this.pushEffect(effect); } exitTemporalOnly() { const entity = this.entitiesStack.pop(); const effect = { kind: 'concrete', components: [{ kind: 'temporal', entity: entity }] }; this.pushEffect(effect); } exitReadAndUpdate() { const update = this.entitiesStack.pop(); const read = this.entitiesStack.pop(); const effect = { kind: 'concrete', components: [ { kind: 'read', entity: read }, { kind: 'update', entity: update }, ], }; this.pushEffect(effect); } exitReadAndTemporal() { const temporal = this.entitiesStack.pop(); const read = this.entitiesStack.pop(); const effect = { kind: 'concrete', components: [ { kind: 'read', entity: read }, { kind: 'temporal', entity: temporal }, ], }; this.pushEffect(effect); } exitPure() { const effect = { kind: 'concrete', components: [] }; this.pushEffect(effect); } exitVariableEffect(ctx) { const name = ctx.IDENTIFIER().text; const effect = { kind: 'variable', name }; this.pushEffect(effect); } enterArrowEffect() { this.arrowEffectsStack.push([]); } exitArrowEffect() { const effects = this.arrowEffectsStack.pop(); const result = effects.pop(); const effect = { kind: 'arrow', params: effects, result }; this.pushEffect(effect); } exitEntity(ctx) { const names = ctx.IDENTIFIER().map(i => i.text); const entityUnion = names.map(name => ({ kind: 'variable', name })); if (this.stateVars.length > 0) { entityUnion.push({ kind: 'concrete', stateVariables: this.stateVars.map(v => ({ name: v, reference: this.nextId() })), }); } if (entityUnion.length === 0) { this.entitiesStack.push({ kind: 'concrete', stateVariables: [] }); } else if (entityUnion.length === 1) { this.entitiesStack.push(entityUnion[0]); } else { this.entitiesStack.push({ kind: 'union', entities: entityUnion }); } this.stateVars = []; } exitStateVarRef(ctx) { const varRef = ctx.IDENTIFIER().text; this.stateVars.push(varRef); } nextId() { return ++this.idCounter; } } exports.ToEffectVisitor = ToEffectVisitor; //# sourceMappingURL=ToEffectVisitor.js.map