export type Type = "number" | "string" | "boolean" | "null" | "undefined" | "bigint" | "symbol" | "void" | "any" | {
    kind: "function";
    paramTypes: Type[];
    returnType: Type;
} | {
    kind: "array";
    elementType: Type;
} | {
    kind: "object";
    properties: Record<string, Type>;
} | {
    kind: "pointer";
    to: Type;
};
export type varTypes = "number" | "string" | "boolean" | "null" | "undefined" | "bigint" | "symbol" | "void" | "any" | "function" | "array" | "object" | "pointer";
export declare function compareTypes(a: Type, b: Type): boolean;
export declare function typeToString(t: Type): string;
export declare class TypeEnvironment {
    private types;
    parent?: TypeEnvironment;
    constructor(parent?: TypeEnvironment);
    getType(name: string): Type;
    setType(name: string, type: Type): void;
    createChild(): TypeEnvironment;
}
export declare class ExecutionContext {
    private variables;
    parent?: ExecutionContext;
    breakSignal: boolean;
    continueSignal: boolean;
    constructor(parent?: ExecutionContext);
    private injectBuiltIns;
    getVariable(name: string): any;
    setVariable(name: string, value: any): void;
    createChildContext(): ExecutionContext;
}
export declare abstract class ASTNode {
    abstract execute(context: ExecutionContext): any;
    abstract inferType(env: TypeEnvironment): Type;
}
export declare const CustomASTNode: (exec: (context: ExecutionContext) => any, type: "number" | "string" | "boolean" | "null" | "undefined" | "bigint" | "symbol" | "void" | "any" | {
    kind: "function";
    paramTypes: Type[];
    returnType: Type;
} | {
    kind: "array";
    elementType: Type;
} | {
    kind: "object";
    properties: Record<string, Type>;
} | ((env: TypeEnvironment) => Type)) => {
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
};
export declare class VariableDeclarationNode extends ASTNode {
    varType: varTypes;
    name: string;
    expression: ASTNode;
    constructor(varType: varTypes, name: string, expression: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class AssignmentNode extends ASTNode {
    name: string;
    expression: ASTNode;
    constructor(name: string, expression: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ReturnSignal {
    value: any;
    constructor(value: any);
}
export declare class BreakSignal {
}
export declare class ContinueSignal {
}
export declare class ReturnNode extends ASTNode {
    expression: ASTNode;
    constructor(expression: ASTNode);
    execute(ctx: ExecutionContext): void;
    inferType(env: TypeEnvironment): Type;
}
export declare class BreakNode extends ASTNode {
    execute(ctx: ExecutionContext): void;
    inferType(env: TypeEnvironment): Type;
}
export declare class ContinueNode extends ASTNode {
    execute(ctx: ExecutionContext): void;
    inferType(env: TypeEnvironment): Type;
}
export declare class ErrorNode extends ASTNode {
    message: ASTNode;
    constructor(message: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class FunctionLiteralNode extends ASTNode {
    name: string | null;
    params: string[];
    body: ASTNode[];
    declaredParamTypes?: Type[] | undefined;
    declaredReturnType?: Type | undefined;
    pure: boolean;
    constructor(name: string | null, params: string[], body: ASTNode[], declaredParamTypes?: Type[] | undefined, declaredReturnType?: Type | undefined, pure?: boolean);
    execute(context: ExecutionContext): any;
    toFunction(outerContext: ExecutionContext): (...args: any[]) => any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ArrowFunctionNode extends ASTNode {
    paramNames: string[];
    body: ASTNode;
    constructor(paramNames: string[], body: ASTNode);
    execute(context: ExecutionContext): any;
    toFunction(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class FunctionCallNode extends ASTNode {
    functionName: string;
    args: ASTNode[];
    constructor(functionName: string, args: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class LiteralNode extends ASTNode {
    value: any;
    constructor(value: any);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class VariableReferenceNode extends ASTNode {
    name: string;
    constructor(name: string);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
    toReference(ctx: ExecutionContext): {
        __isPtr: true;
        get: () => any;
        set: (v: any) => void;
    };
}
export declare class OperatorNode extends ASTNode {
    operator: string;
    operands: [ASTNode, ASTNode];
    constructor(operator: string, operands: [ASTNode, ASTNode]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class MethodCallNode extends ASTNode {
    target: ASTNode;
    methodName: string;
    args: ASTNode[];
    constructor(target: ASTNode, methodName: string, args: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ParameterNode extends ASTNode {
    name: string;
    constructor(name: string);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ArrayLiteralNode extends ASTNode {
    elements: ASTNode[];
    constructor(elements: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class IndexAssignmentNode extends ASTNode {
    target: ASTNode;
    index: ASTNode;
    value: ASTNode;
    constructor(target: ASTNode, // e.g., VariableReferenceNode for "arr"
    index: ASTNode, // e.g., LiteralNode(0)
    value: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class IndexAccessNode extends ASTNode {
    array: ASTNode;
    index: ASTNode;
    constructor(array: ASTNode, index: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
    toReference(context: ExecutionContext): {
        __isPtr: true;
        get: () => any;
        set: (v: any) => void;
    };
}
export declare class ObjectLiteralNode extends ASTNode {
    properties: Record<string, ASTNode>;
    constructor(properties: Record<string, ASTNode>);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class PropertyAccessNode extends ASTNode {
    object: ASTNode;
    property: string | ASTNode;
    constructor(object: ASTNode, property: string | ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
    toReference(context: ExecutionContext): {
        __isPtr: true;
        get: () => any;
        set: (v: any) => void;
    };
}
export declare class BlockNode extends ASTNode {
    statements: ASTNode[];
    constructor(statements: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class IfNode extends ASTNode {
    condition: ASTNode;
    thenBranch: ASTNode[];
    elseBranch?: ASTNode[] | undefined;
    constructor(condition: ASTNode, thenBranch: ASTNode[], elseBranch?: ASTNode[] | undefined);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class SignalNode extends ASTNode {
    signal: "break" | "continue";
    constructor(signal: "break" | "continue");
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class WhileNode extends ASTNode {
    condition: ASTNode;
    body: ASTNode[];
    constructor(condition: ASTNode, body: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ForNode extends ASTNode {
    init: ASTNode;
    condition: ASTNode;
    update: ASTNode;
    body: ASTNode[];
    constructor(init: ASTNode, condition: ASTNode, update: ASTNode, body: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class SwitchNode extends ASTNode {
    expression: ASTNode;
    cases: {
        match: ASTNode;
        body: ASTNode[];
    }[];
    defaultCase?: ASTNode[] | undefined;
    constructor(expression: ASTNode, cases: {
        match: ASTNode;
        body: ASTNode[];
    }[], defaultCase?: ASTNode[] | undefined);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class DoWhileNode extends ASTNode {
    body: ASTNode[];
    condition: ASTNode;
    constructor(body: ASTNode[], condition: ASTNode);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class ForEachNode extends ASTNode {
    itemName: string;
    iterable: ASTNode;
    body: ASTNode[];
    constructor(itemName: string, iterable: ASTNode, body: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class TryCatchNode extends ASTNode {
    tryBlock: ASTNode[];
    catchVar: string;
    catchBlock: ASTNode[];
    constructor(tryBlock: ASTNode[], catchVar: string, catchBlock: ASTNode[]);
    execute(context: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class AddressOfNode extends ASTNode {
    target: ASTNode;
    constructor(target: ASTNode);
    execute(ctx: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class DereferenceNode extends ASTNode {
    ptrExpr: ASTNode;
    constructor(ptrExpr: ASTNode);
    execute(ctx: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class PointerAssignmentNode extends ASTNode {
    ptrExpr: ASTNode;
    valueExpr: ASTNode;
    constructor(ptrExpr: ASTNode, valueExpr: ASTNode);
    execute(ctx: ExecutionContext): any;
    inferType(env: TypeEnvironment): Type;
}
export declare class Interpreter {
    nodes: ASTNode[];
    constructor(Nodes: any[]);
    execute(): ExecutionContext;
}
export declare const App: (nodes: ASTNode[], contextFn?: (context: ExecutionContext) => any) => any;
