import { Context } from './Encoding';
export type Option = string | number | boolean | Record<string, any>;
export interface OptionsStanza {
    options: {
        [key: string]: Option;
    };
    context: {
        [key: string]: Option;
    };
}
export interface OptionsAST {
    expressions: {
        [key: string]: Expr[];
    };
    simpleOptions: {
        [key: string]: Option;
    };
    context: {
        [key: string]: Option;
    };
}
/**
 * Notice that the AST has an identical top-level structure to the Encoding. This is because ALL the AST does
 * is parse the DSL expressions, and represent them as Field objects. An AST will look like
 * Example:
 *  {
 *    context:{
 *        gradientContext:["red", "yellow", "green"]
 *
 *    },
 *
 *    fields:{
 *        field1:{
 *            value:[{op:"selectByPosition", args:["FIRST"]},{op:"expects", args:["NUMERIC"]}]
 *        },
 *        field2:{
 *            value:[{op:"selectByPosition", args:["SECOND"]},{op:"expects", args:["NUMERIC"]}],
 *            computed:{
 *                color:[{op:"gradient", args:["gradientContext"]},{op:"toRgb", args:[]}],
 *                smell: [{op:"odor", args:["'delicious"]}]
 *            }
 *        }
 *
 *    }
 *
 *  }
 *
 *  So, ALL that happened is we converted DSL which is pipe-separated method calls into arrays of operations
 *  (ops) and their arguments. Other than that the AST is the same as Encoding. Which of course makes perfect
 *  sense because by definition an AST is simply a way to structure the information in a DSL.
 */
export interface AST {
    dimensions: {
        [key: string]: Dimension;
    };
    context: {
        [key: string]: Context;
    };
}
export interface DimensionEncoding {
    value: ExpressionDSL;
}
export type ExpressionDSL = string;
export interface Dimension {
    value: Expr[];
}
export type Expr = Method | ParserSymbol;
export interface Method {
    type: 'method';
    name: string;
    args: ParserSymbol[];
}
export interface ParserSymbol {
    type: 'number' | 'string' | 'identifier';
    v: number | string;
}
export interface LiteralSymbol {
    type: 'number' | 'string';
    v: number | string;
}
export declare const LITERAL_TYPES: string[];
