// SOURCE: ARCHITECTURE/32-LANGUAGE-OFFICIAL-13-IMPLEMENTATION-11.md
// AUTO-EXTRACTED - Do not edit directly. Edit the source document.

// LitValue includes character literals as { $char: string }
export type LitValue = number | string | boolean | null | { $char: string };

export type Expr =
  | { tag: "Lit"; value: LitValue }
  | { tag: "Var"; name: string }
  | { tag: "Lambda"; params: string[]; rest?: string; body: Expr }
  | { tag: "OracleLambda"; params: string[]; spec: Expr }  // oracle-lambda: first-class inference procedure
  | { tag: "If"; test: Expr; conseq: Expr; alt: Expr }
  | { tag: "Begin"; exprs: Expr[] }
  | { tag: "Define"; name: string; rhs: Expr }
  | { tag: "Set"; name: string; rhs: Expr }
  | { tag: "App"; fn: Expr; args: Expr[] }
  | { tag: "Quote"; datum: unknown }
  | { tag: "QuoteSyntax"; datum: unknown }
  | { tag: "Let"; bindings: Array<{ name: string; init: Expr }>; body: Expr }
  | { tag: "Letrec"; bindings: Array<{ name: string; init: Expr }>; body: Expr }
  | { tag: "Effect"; op: string; args: Expr[] }
  | { tag: "Handle"; body: Expr; handler: HandlerExpr }
  | { tag: "Match"; scrutinee: Expr; clauses: Array<{ pat: Pattern; body: Expr }> }
  | { tag: "TryCatch"; body: Expr; errVar: string; handler: Expr };

export type Pattern =
  | { tag: "PWild" }
  | { tag: "PVar"; name: string } // binder name (already internalized by lowering)
  | { tag: "PLit"; value: number | string | boolean | null }
  | { tag: "PVector"; items: Pattern[] };

export type HandlerExpr = {
  on: Array<{ op: string; params: string[]; k: string; body: Expr }>;
  ret?: { v: string; body: Expr };
  fin?: { body: Expr };
};
