/**
 * This interpreter implements an explicit-control evaluator.
 *
 * Heavily adapted from https://github.com/source-academy/JSpike/
 * and the legacy interpreter
 */
import type es from 'estree';
import type { IOptions } from '..';
import type { Context, Result, StatementSequence, Value } from '../types';
import { Transformer } from './patterns';
import { Stack } from './stack';
import { type ControlItem } from './types';
/**
 * The control is a list of commands that still needs to be executed by the machine.
 * It contains syntax tree nodes or instructions.
 */
export declare class Control extends Stack<ControlItem> {
    private numEnvDependentItems;
    constructor(program?: es.Program | StatementSequence);
    canAvoidEnvInstr(): boolean;
    getNumEnvDependentItems(): number;
    pop(): ControlItem | undefined;
    push(...items: ControlItem[]): void;
    /**
     * Before pushing block statements on the control stack, we check if the block statement has any declarations.
     * If not, the block is converted to a StatementSequence.
     * @param items The items being pushed on the control.
     * @returns The same set of control items, but with block statements without declarations converted to StatementSequences.
     * NOTE: this function handles any case where StatementSequence has to be converted back into BlockStatement due to type issues
     */
    private static simplifyBlocksWithoutDeclarations;
    copy(): Control;
}
/**
 * The stash is a list of values that stores intermediate results.
 */
export declare class Stash extends Stack<Value> {
    constructor();
    copy(): Stash;
}
/**
 * The T component is a dictionary of mappings from syntax names to
 * their corresponding syntax rule transformers (patterns).
 *
 * Similar to the E component, there is a matching
 * "T" environment tree that is used to store the transformers.
 * as such, we need to track the transformers and update them with the environment.
 */
export declare class Transformers {
    private parent;
    private items;
    constructor(parent?: Transformers);
    getPattern(name: string): Transformer[];
    hasPattern(name: string): boolean;
    addPattern(name: string, item: Transformer[]): void;
}
/**
 * Function to be called when a program is to be interpreted using
 * the explicit control evaluator.
 *
 * @param program The program to evaluate.
 * @param context The context to evaluate the program in.
 * @returns The result of running the CSE machine.
 */
export declare function evaluate(program: es.Program, context: Context, options: IOptions): Value;
/**
 * Function that is called when a user wishes to resume evaluation after
 * hitting a breakpoint.
 * This should only be called after the first 'evaluate' function has been called so that
 * context.runtime.control and context.runtime.stash are defined.
 * @param context The context to continue evaluating the program in.
 * @returns The result of running the CSE machine.
 */
export declare function resumeEvaluate(context: Context): any;
/**
 * Function that returns the appropriate Promise<Result> given the output of CSE machine evaluating, depending
 * on whether the program is finished evaluating, ran into a breakpoint or ran into an error.
 * @param context The context of the program.
 * @param value The value of CSE machine evaluating the program.
 * @returns The corresponding promise.
 */
export declare function CSEResultPromise(context: Context, value: Value): Promise<Result>;
export declare function generateCSEMachineStateStream(context: Context, control: Control, stash: Stash, envSteps: number, stepLimit: number, isPrelude?: boolean): Generator<{
    stash: Stash;
    control: Control;
    steps: number;
}, void, unknown>;
