import * as Expr from "./Expression";
import { Token, Identifier, Location, Lexeme } from "../lexer";
import { BrsType, BrsInvalid } from "../brsTypes";
/** A set of reasons why a `Block` stopped executing. */
export * from "./BlockEndReason";
export interface Visitor<T> {
    visitAssignment(statement: Assignment): BrsType;
    visitContinueFor(statement: ContinueFor): never;
    visitContinueWhile(statement: ContinueWhile): never;
    visitDim(statement: Dim): BrsType;
    visitExpression(statement: Expression): BrsType;
    visitExitFor(statement: ExitFor): never;
    visitExitWhile(statement: ExitWhile): never;
    visitPrint(statement: Print): BrsType;
    visitGoto(statement: Goto): never;
    visitIf(statement: If): BrsType;
    visitBlock(block: Block): BrsType;
    visitFor(statement: For): BrsType;
    visitForEach(statement: ForEach): BrsType;
    visitWhile(statement: While): BrsType;
    visitNamedFunction(statement: Function): BrsType;
    visitReturn(statement: Return): never;
    visitDottedSet(statement: DottedSet): BrsType;
    visitIndexedSet(statement: IndexedSet): BrsType;
    visitStop(statement: Stop): BrsType;
    visitIncrement(expression: Increment): BrsInvalid;
    visitLibrary(statement: Library): BrsInvalid;
    visitTryCatch(statement: TryCatch): BrsInvalid;
    visitThrow(statement: Throw): never;
}
/** A BrightScript statement */
export interface Statement {
    /**
     * Handles the enclosing `Statement` with `visitor`.
     * @param visitor the `Visitor` that will handle the enclosing `Statement`
     * @returns a BrightScript value (typically `invalid`) and the reason why
     *          the statement exited (typically `StopReason.End`)
     */
    accept<R>(visitor: Visitor<R>): BrsType;
    /** The starting and ending location of the expression. */
    location: Location;
}
export declare class Assignment implements Statement {
    readonly tokens: {
        equals: Token;
    };
    readonly name: Identifier;
    readonly value: Expr.Expression;
    constructor(tokens: {
        equals: Token;
    }, name: Identifier, value: Expr.Expression);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Dim implements Statement {
    readonly tokens: {
        dim: Token;
        closingBrace: Token;
    };
    readonly name: Identifier;
    readonly dimensions: Expr.Expression[];
    constructor(tokens: {
        dim: Token;
        closingBrace: Token;
    }, name: Identifier, dimensions: Expr.Expression[]);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Block implements Statement {
    readonly statements: Statement[];
    readonly location: Location;
    constructor(statements: Statement[], location: Location);
    accept<R>(visitor: Visitor<R>): BrsType;
}
export declare class Expression implements Statement {
    readonly expression: Expr.Expression;
    constructor(expression: Expr.Expression);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): Location;
}
export declare class ContinueFor implements Statement {
    readonly tokens: {
        continueFor: Token;
    };
    constructor(tokens: {
        continueFor: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): Location;
}
export declare class ContinueWhile implements Statement {
    readonly tokens: {
        continueWhile: Token;
    };
    constructor(tokens: {
        continueWhile: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): Location;
}
export declare class ExitFor implements Statement {
    readonly tokens: {
        exitFor: Token;
    };
    constructor(tokens: {
        exitFor: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): Location;
}
export declare class ExitWhile implements Statement {
    readonly tokens: {
        exitWhile: Token;
    };
    constructor(tokens: {
        exitWhile: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): Location;
}
export declare class Function implements Statement {
    readonly name: Identifier;
    readonly func: Expr.Function;
    constructor(name: Identifier, func: Expr.Function);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export interface ElseIf {
    condition: Expr.Expression;
    thenBranch: Block;
}
export declare class If implements Statement {
    readonly tokens: {
        if: Token;
        then?: Token;
        elseIfs?: Token[];
        else?: Token;
        endIf?: Token;
    };
    readonly condition: Expr.Expression;
    readonly thenBranch: Block;
    readonly elseIfs: ElseIf[];
    readonly elseBranch?: Block | undefined;
    constructor(tokens: {
        if: Token;
        then?: Token;
        elseIfs?: Token[];
        else?: Token;
        endIf?: Token;
    }, condition: Expr.Expression, thenBranch: Block, elseIfs: ElseIf[], elseBranch?: Block | undefined);
    accept<R>(visitor: Visitor<R>): BrsType;
    private getEndLocation;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Increment implements Statement {
    readonly value: Expr.Expression;
    readonly token: Token;
    constructor(value: Expr.Expression, token: Token);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
/** The set of all accepted `print` statement separators. */
export declare namespace PrintSeparator {
    /** Used to indent the current `print` position to the next 16-character-width output zone. */
    interface Tab extends Token {
        kind: Lexeme.Comma;
    }
    /** Used to insert a single whitespace character at the current `print` position. */
    interface Space extends Token {
        kind: Lexeme.Semicolon;
    }
}
/**
 * Represents a `print` statement within BrightScript.
 */
export declare class Print implements Statement {
    readonly tokens: {
        print: Token;
    };
    readonly expressions: (Expr.Expression | Token)[];
    /**
     * Creates a new internal representation of a BrightScript `print` statement.
     * @param expressions an array of expressions or `PrintSeparator`s to be
     *                    evaluated and printed.
     */
    constructor(tokens: {
        print: Token;
    }, expressions: (Expr.Expression | Token)[]);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Goto implements Statement {
    readonly tokens: {
        goto: Token;
        label: Token;
    };
    constructor(tokens: {
        goto: Token;
        label: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Label implements Statement {
    readonly tokens: {
        identifier: Token;
        colon: Token;
    };
    constructor(tokens: {
        identifier: Token;
        colon: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Return implements Statement {
    readonly tokens: {
        return: Token;
    };
    readonly value?: Expr.Expression | undefined;
    constructor(tokens: {
        return: Token;
    }, value?: Expr.Expression | undefined);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class End implements Statement {
    readonly tokens: {
        end: Token;
    };
    constructor(tokens: {
        end: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Stop implements Statement {
    readonly tokens: {
        stop: Token;
    };
    constructor(tokens: {
        stop: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class For implements Statement {
    readonly tokens: {
        for: Token;
        to: Token;
        step?: Token;
        endFor: Token;
    };
    readonly counterDeclaration: Assignment;
    readonly finalValue: Expr.Expression;
    readonly increment: Expr.Expression;
    readonly body: Block;
    constructor(tokens: {
        for: Token;
        to: Token;
        step?: Token;
        endFor: Token;
    }, counterDeclaration: Assignment, finalValue: Expr.Expression, increment: Expr.Expression, body: Block);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class ForEach implements Statement {
    readonly tokens: {
        forEach: Token;
        in: Token;
        endFor: Token;
    };
    readonly item: Token;
    readonly target: Expr.Expression;
    readonly body: Block;
    constructor(tokens: {
        forEach: Token;
        in: Token;
        endFor: Token;
    }, item: Token, target: Expr.Expression, body: Block);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class While implements Statement {
    readonly tokens: {
        while: Token;
        endWhile: Token;
    };
    readonly condition: Expr.Expression;
    readonly body: Block;
    constructor(tokens: {
        while: Token;
        endWhile: Token;
    }, condition: Expr.Expression, body: Block);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class DottedSet implements Statement {
    readonly obj: Expr.Expression;
    readonly name: Identifier;
    readonly value: Expr.Expression;
    constructor(obj: Expr.Expression, name: Identifier, value: Expr.Expression);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class IndexedSet implements Statement {
    readonly obj: Expr.Expression;
    readonly indexes: Expr.Expression[];
    readonly value: Expr.Expression;
    readonly closingSquare: Token;
    constructor(obj: Expr.Expression, indexes: Expr.Expression[], value: Expr.Expression, closingSquare: Token);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Library implements Statement {
    readonly tokens: {
        library: Token;
        filePath: Token | undefined;
    };
    constructor(tokens: {
        library: Token;
        filePath: Token | undefined;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class TryCatch implements Statement {
    readonly tryBlock: Block;
    readonly catchBlock: Block;
    readonly errorBinding: Expr.Variable;
    readonly tokens: {
        try: Token;
        catch: Token;
        endtry: Token;
    };
    constructor(tryBlock: Block, catchBlock: Block, errorBinding: Expr.Variable, tokens: {
        try: Token;
        catch: Token;
        endtry: Token;
    });
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
export declare class Throw implements Statement {
    readonly tokens: {
        throw: Token;
    };
    readonly value: Expr.Expression;
    constructor(tokens: {
        throw: Token;
    }, value: Expr.Expression);
    accept<R>(visitor: Visitor<R>): BrsType;
    get location(): {
        file: string;
        start: {
            line: number;
            column: number;
        };
        end: {
            line: number;
            column: number;
        };
    };
}
