(** The AST: syntax with special forms recognised, before typing. Sugar is gone by this point. [when], [unless], [cond] and [and]/[or] are desugared into [If] and [Do]; they are compiler special forms until macros arrive at milestone 5, so there is nothing to preserve for a macroexpander to see yet. Types here are *surface* type expressions, not resolved types. [Ptr] and [Option] are still just names; the checker resolves them. *) (* ── Type expressions ──────────────────────────────────────────────── *) type texpr = { t : texpr_kind; tloc : Loc.t } and texpr_kind = | Tname of string (* i32 bool Cursor string *) | Tslice of texpr (* [u8] ptr+len *) | Tarray of len * texpr (* [4 f32] [rows [cols u32]] *) | Tmap of texpr * texpr (* {string i32} *) | Tapp of string * texpr list (* (Ptr Cursor) (Option f64) *) | Tfn of texpr list * texpr (* (Fn [a a] bool) *) (* An array length is an integer or a compile-time constant's name. *) and len = | Lint of int64 | Lname of string (* ── Expressions ───────────────────────────────────────────────────── *) type expr = { e : expr_kind; loc : Loc.t } and expr_kind = | Int of int64 | Float of float | Byte of int | Str of string | Kw of string (* :space — coerced at typed call sites *) | Quote of string (* 'skip-form — restart names *) | Var of string | Do of expr list | Let of binding list * expr list | If of expr * expr * expr option | While of expr * expr list | Return of expr option | Set of place * expr | Field of expr * string (* (.pos c) — auto-derefs one level *) | Call of expr * expr list | Match of expr * arm list | Struct of string * (string * expr) list (* (Cursor {:src s}) *) | Arr of expr list (* [0xE6B800FF ...] — a fixed array value *) (* These bind names or alter control flow, so none of them can be a call. *) | Fn of string list * expr list (* (fn [x y] ...) — non-escaping *) | Dotimes of string * expr * expr list (* (dotimes [i n] ...) *) | Defer of expr list (* runs on scope exit *) | Unwrap of unwrap * expr (* (some x) / (try x) *) (* Two unwrap operators, because they are two different things — plan.org. *) and unwrap = Usome | Utry and binding = { bname : string; bty : texpr option; bval : expr; bloc : Loc.t } (* The fixed list of assignable forms — spec-memory.md. Not setf. *) and place = | Pvar of string | Pfield of expr * string (* (set (.hp e) v) *) | Pindex of expr * expr list (* (set (at grid r c) v) *) | Pkey of expr * expr (* (set (get m k) v) *) | Pderef of expr (* (set (deref p) v) *) and arm = { pat : pattern; body : expr list; aloc : Loc.t } and pattern = | Pctor of string * string list (* (Some e) (Rect w h) None *) | Pwild (* _ :else *) (* ── Declarations ──────────────────────────────────────────────────── *) type field = { fname : string; fty : texpr; floc : Loc.t } type fn = { name : string; params : field list; ret : texpr option; (* None means Unit *) fbody : expr list; nloc : Loc.t; } type decl = { d : decl_kind; dloc : Loc.t } and decl_kind = | Package of string | Import of string * string (* alias, path *) | Defalias of string * texpr | Defstruct of string * field list | Defunion of string * variant list | Defn of fn (* value is optional: ZII. `uninit` opts out and is recorded as Uninit. *) | Defvar of string * texpr option * init | Defconst of string * texpr option * expr and variant = { vname : string; vfields : field list; vloc : Loc.t } and init = Zeroed | Uninit | Init of expr