import type { Environment } from "../env";
import { YoError } from "../error";
import type { Expr, FnCallExpr, PathCollection, ComptimeRef } from "../expr";
import type { FunctionValue } from "../function-value";
import type { Token } from "../token";
import type { FunctionType, TraitType, Type } from "../types/definitions";
import type { StructValue, TraitValue, Value } from "../value";
export interface FunctionEvaluationContext {
    kind: "function-body";
    type: FunctionType;
    value?: FunctionValue;
    evaluationEnv: Environment;
}
export type LoadModuleFn = (modulePath: string) => {
    moduleValue: StructValue;
    moduleError: Error | undefined;
};
export type EvaluateExpressionFn = ({ expr, env, context, }: {
    expr: Expr;
    env: Environment;
    context: EvaluatorContext;
}) => Expr;
export interface AsyncBlockEvaluationContext {
    kind: "async-block";
    evaluationEnv: Environment;
}
export interface TestBlockEvaluationContext {
    kind: "test-block";
    evaluationEnv: Environment;
}
export interface EvaluatorContext {
    isExecuting?: boolean;
    isValidatingFunctionDefinition?: boolean;
    expectedType?: {
        type: Type;
        env: Environment;
    };
    isEvaluatingFunctionBodyOrAsyncBlock?: FunctionEvaluationContext | AsyncBlockEvaluationContext | TestBlockEvaluationContext;
    isInsideImplBlock?: boolean;
    capturedVariables?: Map<string, CapturedVariableInfo>;
    ownConsumedCaptures?: Set<string>;
    isEvaluatingLoopBody?: {
        kind: "while" | "for";
        env: Environment;
    };
    SelfType?: Type;
    SelfTraitType?: Type;
    ReceiverType?: Type;
    isEvaluatingFunctionType?: boolean;
    loadModule?: (modulePath: string) => {
        moduleValue: StructValue;
        moduleError: Error | undefined;
    };
    stdPath: string;
    currentModulePath?: string;
    isUnsafeFunctionType?: boolean;
    unsafeContext?: boolean;
    isControlFunctionType?: boolean;
    enclosingFunctionReturnType?: Type;
    hasControlFunctionImplicitParams?: boolean;
    isInsideWhereClause?: boolean;
    isLhsOfAssignment?: boolean;
    functionReturnImplConcreteType?: Array<{
        concreteType: Type;
        env: Environment;
        token: Token;
    }>;
    forceCompileTimeBindings?: boolean;
    deferGenericFnTypeCheckToAssignment?: boolean;
    isAnalyzingCtfeCapability?: boolean;
    isInFunctionCallCheckingPhase?: boolean;
    isInsideIoAsyncCall?: boolean;
    isEvaluatingGenericImplSpecialization?: boolean;
    currentlySpecializingFunction?: {
        originalFuncId: string;
        specializedFuncId: string;
        specializedReturnType: Type;
        originalFunction: FunctionValue;
    };
    currentlySpecializingFunctionStack?: Array<{
        originalFuncId: string;
        specializedFuncId: string;
        specializedReturnType: Type;
        originalFunction: FunctionValue;
    }>;
    docCommentLookup?: Map<string, string>;
}
export interface ArgValues {
    forallArgs: {
        value: Value;
        parameterType: Type;
        argType: Type;
    }[];
    args: {
        value: Value | undefined;
        parameterType: Type;
        argType: Type;
    }[];
    implicitArgs?: {
        value: Value;
        parameterType: Type;
        argType: Type;
    }[];
    variadicArgs: {
        value: Value | undefined;
        argType: Type;
    }[];
}
export interface FunctionCallResult {
    calleeEnv: Environment;
    callerEnv: Environment;
    pathCollection: PathCollection;
    returnType: Type;
    returnValue: Value | undefined;
    argValues: ArgValues;
    runtimeArgExprsInOrder: Expr[];
    specializedFunctionValue?: FunctionValue;
    deferredDropExpressions?: Expr[];
}
export interface TypeCallResult {
    values: (Value | undefined)[];
    pathCollection: PathCollection;
    runtimeArgExprsInOrder: Expr[];
    callerEnv: Environment;
}
export interface RecordTypeCallResult {
    moduleValue: StructValue;
    callerEnv: Environment;
}
export interface TraitTypeCallResult {
    traitValue: TraitValue;
    callerEnv: Environment;
}
export interface TraitSpecializationResult {
    specializedTraitType: TraitType;
    callerEnv: Environment;
}
export interface MacroFunctionCallResult {
    calleeEnv: Environment;
    callerEnv: Environment;
    returnExpr: Expr;
}
export interface NumericTypeCallResult {
    expr: Expr;
    env: Environment;
}
export interface PointerTypeCallResult {
    expr: Expr;
    env: Environment;
}
export interface IndexCallResult {
    value: Value | undefined;
    type: Type;
    ptrType: Type;
    indexMethodType: FunctionType | undefined;
    indexMethodValue: Value | undefined;
    callerEnv: Environment;
    index?: number;
    comptimeRef?: ComptimeRef;
}
export interface FunctionToCall {
    type: Type;
    args?: Expr[];
    value?: Value;
    result: {
        kind: "function";
        result: FunctionCallResult;
    } | {
        kind: "type";
        result: TypeCallResult;
    } | {
        kind: "function-type";
    } | {
        kind: "array-type";
    } | {
        kind: "closure-type";
    } | {
        kind: "record-type";
        result: RecordTypeCallResult;
    } | {
        kind: "trait-type";
        result: TraitTypeCallResult;
    } | {
        kind: "trait-specialization";
        result: TraitSpecializationResult;
    } | {
        kind: "numeric-type";
        result: NumericTypeCallResult;
    } | {
        kind: "pointer-type";
        result: PointerTypeCallResult;
    } | {
        kind: "iso-value";
        result: FnCallExpr;
    } | {
        kind: "index";
        result: IndexCallResult;
    } | {
        kind: "error";
        error: Error | YoError;
    };
}
export declare function getFunctionCallResult(functionToCall: FunctionToCall): FunctionCallResult;
export declare function getTypeCallResult(functionToCall: FunctionToCall): TypeCallResult;
export declare function getRecordTypeCallResult(functionToCall: FunctionToCall): RecordTypeCallResult;
export declare function getTraitTypeCallResult(functionToCall: FunctionToCall): TraitTypeCallResult;
export declare function getIndexCallResult(functionToCall: FunctionToCall): IndexCallResult;
export declare function getPointerTypeCallResult(functionToCall: FunctionToCall): PointerTypeCallResult;
export type EvaluateExpression = ({ expr, env, context, }: {
    expr: Expr;
    env: Environment;
    context: EvaluatorContext;
}) => Expr;
export declare function trackVariableUsage(variableName: string, frameLevel: number, usageType: "read" | "write" | "own", token: Token, context: EvaluatorContext): void;
export interface CapturedVariableInfo {
    frameLevel: number;
    usageType: "read" | "write" | "own";
    token: Token;
}
