Skip to main content

Module parse

Module parse 

Source
Expand description

Zsh parser — direct port from zsh/Src/parse.c.

Pulls tokens via the lex.rs free fns (zshlex/tok/tokstr) and builds an AST tree (relocated to src/extensions/zsh_ast.rs as a Rust-only IR) plus emits wordcode into ECBUF via the P9b/P9c pipeline. Follows the zsh grammar closely; productions match par_* in Src/parse.c.

Re-exports§

pub use crate::heredoc_ast::HereDoc;
pub use crate::zsh_ast::CaseArm;
pub use crate::zsh_ast::CaseTerm;
pub use crate::zsh_ast::CaseTerminator;
pub use crate::zsh_ast::CompoundCommand;
pub use crate::zsh_ast::ForList;
pub use crate::zsh_ast::HereDocInfo;
pub use crate::zsh_ast::ListFlags;
pub use crate::zsh_ast::ListOp;
pub use crate::zsh_ast::Redirect;
pub use crate::zsh_ast::RedirectOp;
pub use crate::zsh_ast::ShellCommand;
pub use crate::zsh_ast::ShellWord;
pub use crate::zsh_ast::SimpleCommand;
pub use crate::zsh_ast::SublistFlags;
pub use crate::zsh_ast::SublistOp;
pub use crate::zsh_ast::VarModifier;
pub use crate::zsh_ast::ZshAssign;
pub use crate::zsh_ast::ZshAssignValue;
pub use crate::zsh_ast::ZshCase;
pub use crate::zsh_ast::ZshCommand;
pub use crate::zsh_ast::ZshCond;
pub use crate::zsh_ast::ZshFor;
pub use crate::zsh_ast::ZshFuncDef;
pub use crate::zsh_ast::ZshIf;
pub use crate::zsh_ast::ZshList;
pub use crate::zsh_ast::ZshParamFlag;
pub use crate::zsh_ast::ZshPipe;
pub use crate::zsh_ast::ZshProgram;
pub use crate::zsh_ast::ZshRedir;
pub use crate::zsh_ast::ZshRepeat;
pub use crate::zsh_ast::ZshSimple;
pub use crate::zsh_ast::ZshSublist;
pub use crate::zsh_ast::ZshTry;
pub use crate::zsh_ast::ZshWhile;

Structs§

fdhead
Port of struct fdhead from Src/parse.c:3116. One per function inside a wordcode dump. All fields are wordcode (u32).
parse_stack
Direct port of struct parse_stack at Src/zsh.h:3099-3109. Used by parse_context_save / parse_context_restore (parse.c:295-355) to snapshot per-parse-call state so a nested parse (e.g. inside command substitution) doesn’t clobber the outer parse.
wcfunc
Port of struct wcfunc from Src/parse.c:3158. Build-time per-function aggregate before write_dump emits it. The Rust port stores the source-text body inline since the C-side Eprogparse_string chain isn’t fully wired through this layer yet (build_dump falls back to source-text caching).

Constants§

ECBUF
ECSTRS_REVERSE
Reverse index for ecgetstr: offs → owned string. Populated at ecstrcode time so the consumer can recover the string from the wordcode offs without walking the encode-time HashMap. Stores the METAFIED BYTE form of each long-string, exactly matching what C’s strs region holds. String would not work here because Rust strings carry UTF-8-encoded chars (e.g. the Dash marker \u{9b} UTF-8-encodes to two bytes \xc2 \x9b) while C stores zsh markers as single bytes (raw \x9b). Storing Vec lets us write byte-for-byte what C writes after metafy.
FDF_MAP
#define FDF_MAP 1 from Src/parse.c:3111. Bit set when the dump should be mmap()-ed (-M flag) vs read normally (-R).
FDF_OTHER
#define FDF_OTHER 2 from Src/parse.c:3112. Bit indicating this dump has an opposite-byte-order copy at fdother(f).
FDHEAD_WORDS
Size of struct fdhead in wordcode (u32) units. Used by all the header-walk macros below.
FDHF_KSHLOAD
#define FDHF_KSHLOAD 1 from Src/parse.c:3149. Function-header flag word — -k ksh-style autoload marker.
FDHF_ZSHLOAD
#define FDHF_ZSHLOAD 2 from Src/parse.c:3150. -z zsh-style autoload marker.
FD_EXT
#define FD_EXT ".zwc" from Src/parse.c:3104.
FD_MAGIC
#define FD_MAGIC 0x04050607 from Src/parse.c:3108. Sentinel for native-byte-order dumps.
FD_MINMAP
#define FD_MINMAP 4096 from Src/parse.c:3105. mmap threshold — -M mode only kicks in when the wordcode body is at least this many bytes (otherwise read(2) is preferred).
FD_OMAGIC
#define FD_OMAGIC 0x07060504 from Src/parse.c:3109. Sentinel for opposite-byte-order dumps (byte-swapped FD_MAGIC).
FD_PRELEN
#define FD_PRELEN 12 from Src/parse.c:3107. File-header length in u32 words: magic + packed-flags-byte + 10 version words.
HDOCS
Port of file-static struct heredocs *hdocs; from Src/parse.c:84.

Statics§

DUMMY_EPROG
mod_export struct eprog dummy_eprog; from Src/parse.c:3066. Placeholder Eprog used by shf->funcdef = &dummy_eprog; in builtin.c when clearing a stale autoload stub. Held in a Mutex so init_eprog can set it once at shell startup.
DUMPS
static FuncDump dumps; from Src/parse.c:3652 — head of the loaded-.zwc linked list. C walks dumps/p->next directly; the Rust port uses a Mutex<Vec<funcdump>> indexed by filename so refcount ops can find an entry without raw-pointer compare.

Functions§

COND_SEP
COND_SEP() macro from Src/parse.c:2433. True when the current token is a separator usable inside [[ … ]] (newline / semi / &). C uses it to skip optional whitespace between cond terms.
bin_zcompile
Port of bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func)) from Src/parse.c:3180. Validates the option set, then dispatches to one of: -t (test/list), -c/-a (dump current functions), or the default (compile source files to .zwc).
bld_eprog
Port of bld_eprog(int heap) from Src/parse.c:547. Finalizes the in-build ECBUF/ECSTRS/ECNPATS state into an Eprog. Resets the build state so a new parse can start.
build_cur_dump
Port of build_cur_dump(char *nam, char *dump, char **names, int match, int map, int what) from Src/parse.c:3536. Compiles currently-loaded functions (-c for functions, -a for aliases) into a .zwc dump. Same wordcode-emit dependency as build_dump.
build_dump
Port of build_dump(char *nam, char *dump, char **files, int ali, int map, int flags) from Src/parse.c:3397. Source-file → wordcode dump compiler.
check_dump_file
Port of Eprog check_dump_file(char *file, struct stat *sbuf, char *name, int *ksh, int test_only) from Src/parse.c:3833. Walks the dumps mmap list looking for (dev, ino) matching sbuf; on miss, calls load_dump_header to read the .zwc header. Then dump_find_func(d, name) locates the function table entry. Returns the wordcode slice + ksh-load flag.
clear_hdocs
Clear pending here-document list. Direct port of clear_hdocs(void) from Src/parse.c:591. The C version walks hdocs and frees each node; Rust drops the Box<heredocs> chain automatically when the head is replaced with None.
closedumps
Port of closedumps(void) from Src/parse.c:4008/4033. Walks dumps freeing every entry. Called on shell exit (exec.c:522).
condlex
Port of condlex function-pointer global from Src/parse.c. C flips this between zshlex and testlex depending on whether we’re inside [[ ]] vs /bin/test builtin. zshrs has no separate testlex yet, so this just defers to zshlex.
copy_ecstr
Port of copy_ecstr(Eccstr s, char *p) from Src/parse.c:537. Walks the BST and writes each entry to p[s->aoffs..] matching C’s recursive in-order traversal exactly. The old impl used the ECSTRS_REVERSE HashMap keyed by offs (= ecssub-relative wordcode-encoded offset), which collides across funcdef scopes: a string at relative offs=0 inside funcdef A and another at relative offs=0 inside funcdef B share the same key, so one overwrites the other.
cur_add_func
Port of cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen, int what) from Src/parse.c:3489. Adds a shfunc to the in-build dump progs+names lists. Stub: Eprog for the function body isn’t yet wired through shfunc.funcdef to be serializable here.
decrdumpcount
Port of decrdumpcount(FuncDump f) from Src/parse.c:3988/4026. f->count--; if (!f->count) { unlink from dumps; freedump(f); }.
dump_autoload
Port of dump_autoload(char *nam, char *file, int on, Options ops, int func) from Src/parse.c:4042. Registers every function in a .zwc for autoload via shfunctab. Stub: returns 1 (error) until the dump-cache port lands.
dump_find_func
Port of dump_find_func(Wordcode h, char *name) from Src/parse.c:3167. Walks the header table inside a loaded dump for a function with the given basename; returns true on hit.
dupeprog
Duplicate an Eprog. Direct port of zsh/Src/parse.c:2813 Port of Eprog dupeprog(Eprog p, int heap) from Src/parse.c:2767. Deep-copies the wordcode array, string table, and pattern-prog slots. dummy_eprog is returned unchanged. heap-allocated copies get nref = -1 (never freed); real ones get nref = 1.
ecadd
Direct port of ecadd(wordcode c) at Src/parse.c:397. Append c to the wordcode buffer with grow-on-demand, return the new index.
ecadjusthere
Direct port of ecadjusthere(int p, int d) at Src/parse.c:360. Walk the pending-heredocs list and bump each pc by d if it’s at or after position p. Called by ecispace / ecdel when wordcodes shift.
eccopyredirs
Port of eccopyredirs(Estate s) from Src/parse.c:3003. Reads the WC_REDIR run at s->pc, counts the wordcodes needed, reserves space in ecbuf via ecispace, then re-walks s->pc re-emitting each redir’s wordcodes into the reserved slot — finally calls bld_eprog(0) to package the result as an Eprog.
ecdel
Direct port of ecdel(int p) at Src/parse.c:413. Remove the wordcode at position p, shift later entries left by one, decrement ecused, adjust pending heredoc pointers.
ecgetarr
Port of ecgetarr(Estate s, int num, int dup, int *tokflag) from Src/parse.c:2917. Reads num strings from wordcode at s->pc and OR-folds each entry’s token flag into *tokflag.
ecgetlist
Port of ecgetlist(Estate s, int num, int dup, int *tokflag) from Src/parse.c:2937. Same shape as ecgetarr but C returns LinkList; zshrs uses Vec<String> for both.
ecgetredirs
Port of ecgetredirs(Estate s) from Src/parse.c:2959.
ecgetstr
Port of ecgetstr(Estate s, int dup, int *tokflag) from Src/parse.c:2855. s->pc advances through the wordcode buffer; s->strs indexes the string pool. Returns the interned string (or a 1-3-char literal inlined directly into the wordcode word).
ecgetstr_wordcode
P9b decoder (wordcode-pipeline variant): direct port of ecgetstr(Estate s, int dup, int *tokflag) from Src/parse.c:2855-2890. Reads a wordcode at pc, decodes the encoded string back to owned String. Returns (string, pc_after_consumed). Distinct from the existing ecgetstr (which takes a separate strs buffer for text.rs) — this variant uses the live ECSTRS_REVERSE HashMap populated at ecstrcode time.
ecispace
Direct port of ecispace(int p, int n) at Src/parse.c:372. Insert n empty wordcode slots at position p, shifting later entries right, growing the buffer as needed, adjusting heredoc pointers.
ecrawstr
Port of ecrawstr(Eprog p, Wordcode pc, int *tokflag) from Src/parse.c:2891. Like ecgetstr but reads at the given pc without advancing — caller steps pc separately.
ecstr
ecstr(s) helper — ecadd(ecstrcode(s)). Mirrors the C macro at Src/parse.c:482 used everywhere by the par_* emitters.
ecstrcode
Direct port of ecstrcode(char *s) at Src/parse.c:426. Encode a string into a single wordcode (short strings ≤4 bytes packed inline; longer strings get an offset into the deduped registry).
empty_eprog
Port of int empty_eprog(Eprog p) from Src/parse.c:584. C body: return (!p || !p->prog || *p->prog == WCB_END()); — the eprog is empty when its prog buffer is missing or the first wordcode is the WC_END marker. Used by signal handlers (Src/signals.c:712) to short-circuit a trap that resolves to an empty program.
fdflags
Port of fdflags(f) macro (Src/parse.c:3131) — low byte of the packed pre[1] word.
fdhbldflags
Port of fdhbldflags(f, t) macro (Src/parse.c:3147) — pack (flags, tail) into one u32 (low 2 bits = flags, high 30 = tail).
fdheaderlen
Port of fdheaderlen(f) macro (Src/parse.c:3125) — header length in u32 words (read from prelude word FD_PRELEN).
fdhflags
Port of fdhflags(f) macro (Src/parse.c:3145) — low 2 bits of the header’s flags field (the kshload/zshload marker).
fdhtail
Port of fdhtail(f) macro (Src/parse.c:3146) — high 30 bits of flags, byte offset from the name start to its basename.
fdmagic
Port of fdmagic(f) macro (Src/parse.c:3127) — first prelude word, either FD_MAGIC or FD_OMAGIC.
fdname
Port of fdname(f) macro (Src/parse.c:3152) — name string follows the fdhead record immediately. Reads bytes from the dump buffer until NUL.
fdother
Port of fdother(f) macro (Src/parse.c:3133) — high 24 bits of pre[1], holds the byte-offset to the opposite-byte-order dump copy.
fdsetflags
Port of fdsetflags(f, v) macro (Src/parse.c:3132) — write the low byte of pre[1].
fdsetother
Port of fdsetother(f, o) macro (Src/parse.c:3134).
fdswap
Port of fdswap(Wordcode p, int n) from Src/parse.c:3318. Byte-swap each u32 in p[..n] in place. Used when writing the opposite-byte-order copy of a wordcode dump.
fdversion
Port of fdversion(f) macro (Src/parse.c:3140) — read the ZSH_VERSION C-string from pre[2..].
firstfdhead_offset
Port of firstfdhead(f) macro (Src/parse.c:3142) — pointer to the first struct fdhead past the prelude.
freedump
Port of freedump(FuncDump f) from Src/parse.c:3976. Public helper for the rare external caller; locks the dumps mutex and drops the entry with the given filename.
freeeprog
Port of void freeeprog(Eprog p) from Src/parse.c:2823. Refcount-decrement; when it hits zero, drops the pattern progs, decrements the dump refcount if any, and releases the eprog. dummy_eprog is never freed. Heap-eprogs (nref < 0) are never freed either — they live as long as the heap arena.
get_cond_num
Port of get_cond_num(char *tst) from Src/parse.c:2643. Returns the index of tst in {"nt","ot","ef","eq","ne","lt","gt","le","ge"} or -1 if not a recognized binary cond operator.
incrdumpcount
Port of incrdumpcount(FuncDump f) from Src/parse.c:3970/4021. f->count++; — refcount-up a loaded dump entry. The Rust port keys lookup by filename because Rust can’t raw-pointer-compare funcdump values inside a Mutex<Vec<...>>; same observable effect (the count of the matching entry increments).
init_eprog
Port of init_eprog(void) from Src/parse.c:3069. Sets up dummy_eprog_code = WCB_END(); dummy_eprog.len = sizeof(wordcode); dummy_eprog.prog = &dummy_eprog_code; dummy_eprog.strs = NULL;. Called once at shell startup (init_main → init_misc → init_eprog).
init_parse
Initialize parser for a fresh parse. Direct port of zsh/Src/parse.c:509 init_parse. C source allocates a fresh wordcode buffer (ecbuf) sized EC_INIT_SIZE, resets the per-parse-call counters, and calls init_parse_status. zshrs has no flat wordcode buffer (AST is built inline) so this function reduces to init_parse_status + recursion_depth/ global_iterations clear.
init_parse_status
Initialize parser status. Direct port of zsh/Src/parse.c:491 init_parse_status. Clears the per-parse-call lexer flags so a fresh parse starts from cmd-position with no nesting state inherited from a prior parse.
load_dump_file
Port of load_dump_file(char *dump, struct stat *sbuf, int other, int len) from Src/parse.c:3675. Reads (or mmap()’s) a complete .zwc file into memory. Returns the u32 buffer or None on I/O error.
load_dump_header
Port of load_dump_header(char *nam, char *name, int err) from Src/parse.c:3258. Opens the file, reads + validates the magic and version, then slurps the full header table into memory. Returns the header u32-array on success or None on any failure (emitting C-shaped warnings when err != 0).
nextfdhead_offset
Port of nextfdhead(f) macro (Src/parse.c:3143) — advance to the next header by reading the current hlen slot.
par_arith_wordcode
Port of the case DINPAR: arm of par_cmd from Src/parse.c:1031-1034:
par_case_wordcode
Port of par_case(int *cmplx) from Src/parse.c:1208-1400.
par_cmd_wordcode
Port of par_cmd(int *cmplx, int zsh_construct) from Src/parse.c:958-1085. Parses leading + trailing redirs and dispatches on the current token to the right par_* builder. Returns false only when no command was emitted (no redirs + par_simple returned 0). Port of par_cmd(int *cmplx, int zsh_construct) from Src/parse.c:957-1077.
par_cond_1
Port of par_cond_1(void) from Src/parse.c:2434. Parses one ||-separated cond expression. Emits WCB_COND(COND_AND, …) when an && is found and recurses.
par_cond_2
Port of par_cond_2(void) from Src/parse.c:2476. The heavy cond-term parser: handles ! cond, (cond), unary [ -X arg ], binary [ A op B ], and [ A op1 B op2 C … ] n-ary chains.
par_cond_double
Port of par_cond_double(char *a, char *b) from Src/parse.c:2626. Emits wordcode for unary cond [ -X b ] or modular [ -mod b ].
par_cond_multi
Port of par_cond_multi(char *a, LinkList l) from Src/parse.c:2716. Emits wordcode for [ -OP A B C … ] n-ary cond (alternation).
par_cond_top
Port of par_cond(void) from Src/parse.c:2409. Top-level cond OR-chain — drives par_cond_1 and stitches ||-separated terms with WCB_COND(COND_OR, …). This is the missing top of the wordcode cond chain: par_cond_wordcode (the par_dinbrack port) must call into HERE so that [[ a || b ]] and friends land real WC_COND opcodes in ecbuf. Without this, the wordcode emitter for [[ ... ]] produced zero words and parity dropped 148 words on /etc/zshrc alone.
par_cond_triple
Port of par_cond_triple(char *a, char *b, char *c) from Src/parse.c:2659. Emits wordcode for the binary forms [ A op B ]= / == / != / < / > / =~ / -X.
par_cond_wordcode
Port of par_dinbrack(void) from Src/parse.c:1810. Wraps par_cond (the cond-expression emitter at parse.c:2409) with the [[ ... ]] framing: incond/incmdpos toggles + DOUTBRACK expectation.
par_cursh_wordcode
Wrapper for {...} brace group (cursh) — calls par_subsh_wordcode_impl(1). C uses the same par_subsh function with zsh_construct=1; the Rust split exists because the par_cmd dispatch at parse.rs:1446 already named them separately.
par_dinbrack
Port of par_dinbrack(void) from Src/parse.c:1810. Body parser inside [[ ... ]] — calls par_cond to emit the condition wordcode then advances past ]].
par_event
Parse one event (sublist with optional separator). Direct port of zsh/Src/parse.c:635 par_event. Returns true if an event was successfully parsed, false on EOF / endtok.
par_event_wordcode
Wordcode-emission top-level driver. Closest C analog is parse_list(void) at Src/parse.c:697-712: init_parse + zshlex + par_list(&c) + bld_eprog. This entry omits init_parse and bld_eprog (caller responsibilities) and inlines a guard loop around par_list_wordcode for cases where the lexer leaves a non-ENDINPUT terminator (LEXERR, missing close-token, etc.).
par_for_wordcode
Port of par_for(int *cmplx) from Src/parse.c:1086-1198.
par_funcdef_wordcode
Port of par_funcdef(int *cmplx) from Src/parse.c:1672-1779.
par_if_wordcode
Port of par_if(int *cmplx) from Src/parse.c:1410-1512.
par_list1
Parse one list — non-recursing variant. Direct port of zsh/Src/parse.c:808 par_list1. Like par_list but doesn’t recurse on the trailing-separator path; used by callers that only want one statement (e.g. each arm of a case body).
par_list1_wordcode
Port of par_list1(int *cmplx) from Src/parse.c:806-817. Single-sublist variant used by funcdef bodies and the short for/while/repeat forms — exactly one sublist with Z_SYNC|Z_END, no chain.
par_list_wordcode
Port of par_list(int *cmplx) from Src/parse.c:769-803. list : { SEPER } [ sublist [ { SEPER | AMPER | AMPERBANG } list ] ]. True line-by-line port: takes cmplx: &mut i32 matching C’s int *cmplx out-parameter, uses stack-local c per iteration like C (so inner sublist cmplx is independent of outer).
par_nl_wordlist
Parse a newline-separated wordlist. Direct port of zsh/Src/parse.c:2379 par_nl_wordlist. Like par_wordlist but tolerates leading/trailing newlines.
par_pipe_wordcode
Port of par_pline(int *cmplx) from Src/parse.c:894-955. pline : cmd [ ( BAR | BARAMP ) { SEPER } pline ]. Emits a WCB_PIPE header (mid for chain links, end for the last cmd) plus the optional BARAMP 2>&1 synthetic redir. Port of par_pline(int *cmplx) from Src/parse.c:893-947. (Named par_pipe_wordcode to disambiguate from the AST par_pline at parse.rs:3744 — semantically the same pline production.)
par_repeat_wordcode
Port of par_repeat(int *cmplx) from Src/parse.c:1564-1606.
par_save_list1_wordcode
Port of par_save_list1(C) macro from Src/parse.c:481-486.
par_save_list_wordcode
Port of par_save_list(C) macro from Src/parse.c:475-480. do { int eu = ecused; par_list(C); if (eu == ecused) ecadd(WCB_END()); } while (0)
par_select_wordcode
select shares par_for body (c:983-985 routes SELECT to par_for).
par_simple_wordcode
Wrapper for callers without a cmplx accumulator. Allocates a local cmplx and ignores it — only used by legacy dispatch sites.
par_simple_wordcode_impl
Port of par_simple(int *cmplx, int nr) from Src/parse.c:1836-2227. Emits WC_SIMPLE + word count + interned string offsets. Returns 0 when nothing was emitted, otherwise 1 + (number of code words consumed by redirections). The full C body handles assignments (ENVSTRING/ENVARRAY), inline {var}>file brace-FDs, prefix modifiers (NOCORRECT etc), and name() { body } funcdef detection — those paths are progressively wired into the AST parser; this wordcode-emitter covers the simple cmd args... case + interleaved redirs.
par_sublist2
Port of par_sublist2(int *cmplx) from Src/parse.c:869. Secondary-sublist arm: handles the COPROC/Bang prefix in front of a pline. Returns the WC_SUBLIST flag word added.
par_sublist_wordcode
Port of par_sublist(int *cmplx) from Src/parse.c:823-865. sublist : sublist2 [ ( DBAR | DAMPER ) { SEPER } sublist ]. Emits a WCB_SUBLIST header, recurses into par_sublist2 for the !/coproc prefix + pipeline, then chains via DBAR (||) or DAMPER (&&) recursively. Returns true if at least one pipeline was emitted.
par_subsh_wordcode
Wrapper for (...) subshell — calls par_subsh_wordcode_impl(0).
par_subsh_wordcode_impl
Src/parse.c:1619-1665. Handles both (...) subshell and {...} brace group (cursh) plus optional always { ... } trailing block. C uses a single function with zsh_construct=1 for {...} and 0 for (...).
par_time_wordcode
Port of par_time(void) from Src/parse.c:1787. time PIPE emits WCB_TIMED(WC_TIMED_PIPE) + the sublist code; bare time with no pipeline emits WCB_TIMED(WC_TIMED_EMPTY).
par_until_wordcode
until shares par_while body — tok==UNTIL flips the type.
par_while_wordcode
Port of par_while(int *cmplx) from Src/parse.c:1520-1557.
par_wordlist
Parse a wordlist for for ... in WORDS;. Direct port of zsh/Src/parse.c:2362 par_wordlist. Reads STRING tokens until the next SEPER / SEMI / NEWLIN.
parse
Parse the complete input. Direct port of parse_event / par_list from Src/parse.c:614-720. On syntax error, sets errflag |= ERRFLAG_ERROR (via zerr) and returns the partial program — callers check errflag to detect failure, matching C’s Eprog parse_event(...) + if (errflag) {...}.
parse_cond
Port of parse_cond(void) from Src/parse.c:722. Only used by bin_test/bin_bracket for /bin/test/[ compat — the condlex global must already point at testlex before entry.
parse_context_restore
Direct port of parse_context_restore(const struct parse_stack *ps, int toplevel) at Src/parse.c:326. Inverse of parse_context_save. Restores lexer-side state + pending heredocs + Rust-only counters from ps, then clears errflag & ERRFLAG_ERROR per parse.c:354. WARNING: param names don’t match C — Rust=(ps) vs C=(ps, toplevel)
parse_context_save
Direct port of parse_context_save(struct parse_stack *ps, int toplevel) at Src/parse.c:295. Snapshots the lexer-side file-statics (which currently live on lexer until Phase 7 dissolution makes them file-scope thread_local!s) plus the pending heredoc list, plus the wordcode-buffer state (STUB until Phase 9b). Saves Rust-only recursion counters too so nested parses get fresh limits. WARNING: param names don’t match C — Rust=(ps) vs C=(ps, toplevel)
parse_event
Top-level parse-event entry. Direct port of zsh/Src/parse.c: 612-631 parse_event. Reads one event from the lexer (a sublist optionally followed by SEPER/AMPER/AMPERBANG) and returns the resulting ZshProgram.
parse_init
Initialize parser state for a fresh parse of input. Free-fn entry point — resets parser thread_locals and loads input.
parse_list
Port of parse_list(void) from Src/parse.c:697. C-shape entry point: drives par_list and finalizes via bld_eprog. Returns None on syntax error.
read_fdhead
Decode a fdhead record at the given u32-word offset in the dump buffer. Used by the header-walk loops in bin_zcompile -t.
set_list_code
Patch a list-placeholder wordcode with its actual opcode + jump distance. Direct port of zsh/Src/parse.c:738 set_list_code. zsh emits an ecadd(0) placeholder before par_sublist runs, then comes back through set_list_code to rewrite the slot with WCB_LIST(type, distance) once the sublist’s final length is known.
set_sublist_code
Port of set_sublist_code(int p, int type, int flags, int skip, int cmplx) from Src/parse.c:755. Patches the WCB_SUBLIST header at p. When the sublist is non-complex (single command, no pipeline), sets WC_SUBLIST_SIMPLE and rewrites the following slot to WC_PIPE_LINENO.
setheredoc
Wire a here-document body onto the redirection token that requested it. Direct port of zsh/Src/parse.c:2347 setheredoc. Called when a heredoc terminator has been matched and the body is ready to be attached to the redir.
try_dump_file
Port of try_dump_file(char *path, char *name, char *file, int *ksh, int test_only) from Src/parse.c:3746. Tries to load a function from a .zwc in the given fpath directory. Returns (found, ksh_load) — stub: returns false until the dump-cache port (FuncDump) lands.
try_source_file
Port of try_source_file(char *file) from Src/parse.c:3795. Tries source <file> then falls back to source <file>.zwc. Returns the resolved path on hit. Stub: returns None until the dump-cache port lands.
useeprog
Port of void useeprog(Eprog p) from Src/parse.c:2813. if (p && p != &dummy_eprog && p->nref >= 0) p->nref++; — pin a real (non-heap, non-dummy) Eprog so it survives the next freeeprog.
write_dump
Port of write_dump(int dfd, LinkList progs, int map, int hlen, int tlen) from Src/parse.c:3334. Writes the prelude + header records + body wordcode bytes to the dump file descriptor.
yyerror
Emit a parser-level error. Direct port of zsh/Src/parse.c 2733-2766 yyerror. C version fills a per-event error buffer and sets errflag. zshrs pushes onto errors which the caller drains via parse()’s Result return. WARNING: param-name divergence — Rust takes &str message, C takes int noerr. The Rust callers pass user-meaningful messages ("missing ]]", "condition expected"); the C body collects the offending token via dupstring(zshlextext) for the error string. This Rust adapter:
zwcstat
Port of zwcstat(char *filename, struct stat *buf) from Src/parse.c:3656. Stats a .zwc file, falling back to .zwc.old if the primary doesn’t exist (zsh uses the .old suffix to keep a previous dump readable while a rewrite is in progress).

Type Aliases§

ParseStack