Skip to main content

Module shell_parse

Module shell_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.

Structs§

CaseArm
HereDoc
Per-heredoc state collected by the lexer during <<EOF parsing. Held in the lexer-side HEREDOCS: Vec<HereDoc> thread_local for later attachment to ZshRedir entries (via heredoc_idx).
HereDocInfo
Heredoc body+metadata attached to a parsed ZshRedir. Carried through the AST and consumed by the compiler when emitting Op::HereDoc(idx) for the fusevm VM.
ListFlags
Redirect
Redirect
SimpleCommand
Simple command with assignments, words, and redirects
SublistFlags
ZshAssign
An assignment
ZshCase
Case statement
ZshFor
For loop
ZshFuncDef
Function definition
ZshIf
If statement
ZshList
A list is a sequence of sublists separated by ; or & or newline
ZshPipe
A pipeline is commands connected by |
ZshProgram
AST node for a complete program (list of commands)
ZshRedir
A redirection
ZshRepeat
Repeat loop
ZshSimple
A simple command (assignments, words, redirections)
ZshSublist
A sublist is pipelines connected by && or ||
ZshTry
Try/always block
ZshWhile
While/Until loop
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).

Enums§

CaseTerm
CaseTerminator
Case terminator
CompoundCommand
Compound command
ForList
ListOp
List operator (for shell command lists)
RedirectOp
Redirect operator
ShellCommand
Shell command - the old shell_ast compatible type
ShellWord
Shell word - can be simple literal or complex expansion
SublistOp
VarModifier
Variable modifier for parameter expansion
ZshAssignValue
ZshCommand
A command
ZshCond
Conditional expression [[ … ]]
ZshParamFlag
Zsh parameter expansion flags

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.
PARSER_GLOBAL_ITERATIONS
PARSER_RECURSION_DEPTH

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 check_dump_file(char *file, struct stat *sbuf, char *name, int *ksh, int test_only) from Src/parse.c:3833. Opens + validates a .zwc file, returning its loaded buffer or None.
clear_hdocs
Clear pending here-document list. Direct port of zsh/Src/parse.c:591 clear_hdocs. The C version walks the global hdocs linked list and frees each node. zshrs stores pending heredocs on the lexer’s heredocs Vec — truncating it has the same effect.
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 in-build string-eccstr tree and writes each entry to p[s->aoffs..]. The Rust port mirrors via the ECSTRS_REVERSE HashMap (eccstr-tree replacement) and writes into a Vec<u8> slice.
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:1209-1409.
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).
par_cmd_wordcode_noargs
Adapter: par_cmd_wordcode wrapper for sites that don’t supply the zsh_construct flag (defaults to false, matching the C par_cmd(cmplx, 0) call shape at c:902).
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(true). 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
P9c: wordcode-emission parser entry. Direct port of zsh’s parse_event(int endtok) from Src/parse.c:683-720. Emits a minimal wordcode stream for the parsed program into the live ECBUF thread_local via P9b’s ecadd / ecstrcode API and returns the start index of the emitted Eprog (matching C’s Eprog parse_event(...) return).
par_for_wordcode
P9c stub: direct port of par_for(int *complex) from Port of par_for(int *cmplx) from Src/parse.c:1087-1199.
par_funcdef_wordcode
Port of par_funcdef(int *cmplx) from Src/parse.c:1672-1786.
par_if_wordcode
Port of par_if(int *cmplx) from Src/parse.c:1411-1519.
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:805-816. 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:771-803. list : { SEPER } [ sublist [ { SEPER | AMPER | AMPERBANG } list ] ]. Drives the WCB_LIST chain — for each sublist, emits a WCB_LIST header, recurses into par_sublist, then patches the header with the right Z_SYNC/Z_ASYNC/Z_ASYNC|Z_DISOWN flag + Z_END marker on the last entry.
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.
par_repeat_wordcode
Port of par_repeat(int *cmplx) from Src/parse.c:1565-1618.
par_select_wordcode
select shares par_for body (c:1024 routes SELECT to par_for).
par_simple_wordcode
Wrapper for the par_cmd dispatch sites that don’t pass nr (matches C’s call shape at parse.c:1054 par_simple(cmplx, nr)).
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(false).
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:1521-1564.
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_cond_num
Read an integer from the next cond token. NOT a direct C port — the C get_cond_num(char *tst) (parse.c:2643) is the string-lookup helper ported below. This Rust-only helper exists to support the AST cond-walker (par_cond_* analogs) when it needs a numeric literal from the current lex position.
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.
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