Skip to main content

Module parse

Module parse 

Source
Expand description

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

Pulls tokens via the lex.rs free ported (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 function (or source-file) name, the compiled Eprog from parse_string, and the FDHF_* autoload-style flag word.

Constants§

CONDLEX_TESTLEX
ECBUF
ECBUF static.
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{e19b} 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
Port of COND_SEP() from Src/parse.c:2405 — C decl #define COND_SEP() (tok == SEPER && condlex != testlex && *zshlextext != ';'). C macro. COND_SEP() macro from Src/parse.c:2405: (tok == SEPER && condlex != testlex && *zshlextext != ';') A newline (but NOT a ;) between cond terms inside [[ … ]] is skippable whitespace; a ; is a parse error ([[ a ; ]]).
bin_zcompile
Port of bin_zcompile() from Src/parse.c:3180 — C decl bin_zcompile(char *nam, char **args, Options ops, UNUSED(int func)). 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() from Src/parse.c:547 — C signature bld_eprog(int heap). 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() from Src/parse.c:3536 — C decl build_cur_dump(char *nam, char *dump, char **names, int match, int map, int what). Serializes the currently-loaded shell functions (-c → what & 1) and/or autoloadable ones (-a → what & 2) into a .zwc dump. Shares write_dump with the source-file variant build_dump.
build_dump
Port of build_dump() from Src/parse.c:3397 — C signature build_dump(char *nam, char *dump, char **files, int ali, int map, int flags). Source-file → wordcode dump compiler: parses each source file via parse_string and serializes the resulting Eprogs through write_dump into <dump>.zwc.
check_cond
Port of check_cond() from Src/parse.c:2459 — C decl static int check_cond(const char *input, const char *cond). True iff input is the two-char -X form whose X matches cond — used by par_cond_2 to detect -a / -o n-ary chain operators and by build_dump for -k / -z. C: return !IS_DASH(input[0]) ? 0 : !strcmp(input+1, cond);.
check_dump_file
Port of check_dump_file() from Src/parse.c:3833 — C decl check_dump_file(char *file, struct stat *sbuf, char *name, int *ksh, int test_only). 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
Port of clear_hdocs() from Src/parse.c:591 — C signature clear_hdocs(void). Clear pending here-document list. 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() from Src/parse.c:4008 — C decl closedumps(void). The #else (non-USE_MMAP) twin is at c:4033. Walks dumps freeing every entry. Called on shell exit (exec.c:522).
condlex
Port of calling through condlex from Src/parse.c:2399: dispatches to testlex while CONDLEX_TESTLEX is set, otherwise to zshlex.
copy_ecstr
Port of copy_ecstr() from Src/parse.c:537 — C signature copy_ecstr(Eccstr s, char *p). 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() from Src/parse.c:3489 — C decl cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen, int what). Adds a shfunc to the in-build dump progs+names lists. Returns 1 after a zwarnnam when the function cannot be dumped; the caller removes the half-written dump.
decrdumpcount
Port of decrdumpcount() from Src/parse.c:3988 — C decl decrdumpcount(FuncDump f). The #else (non-USE_MMAP) twin is at c:4026. f->count--; if (!f->count) { unlink from dumps; freedump(f); }.
dump_autoload
Port of dump_autoload() from Src/parse.c:4042 — C decl dump_autoload(char *nam, char *file, int on, Options ops, int func). Registers every function in a .zwc for autoload via shfunctab.
dump_find_func
Port of dump_find_func() from Src/parse.c:3167 — C decl dump_find_func(Wordcode h, char *name). Walks the header table inside a loaded dump for a function with the given basename; returns the matching fdhead record (C returns the FDHead pointer).
dupeprog
Duplicate an Eprog. Direct port of zsh/Src/parse.c:2767 Port of dupeprog() from Src/parse.c:2767 — C decl dupeprog(Eprog p, int heap). 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
Port of ecadd() from Src/parse.c:397 — C signature ecadd(wordcode c). Append c to the wordcode buffer with grow-on-demand, return the new index.
ecadjusthere
Port of ecadjusthere() from Src/parse.c:360 — C signature ecadjusthere(int p, int d). 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() from Src/parse.c:3003 — C signature eccopyredirs(Estate s). 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
Port of ecdel() from Src/parse.c:413 — C signature ecdel(int p). Remove the wordcode at position p, shift later entries left by one, decrement ecused, adjust pending heredoc pointers.
ecgetarr
Port of ecgetarr() from Src/parse.c:2917 — C decl ecgetarr(Estate s, int num, int dup, int *tokflag). Reads num strings from wordcode at s->pc and OR-folds each entry’s token flag into *tokflag.
ecgetlist
Port of ecgetlist() from Src/parse.c:2937 — C decl ecgetlist(Estate s, int num, int dup, int *tokflag). Same shape as ecgetarr but C returns LinkList; zshrs uses Vec<String> for both.
ecgetredirs
Port of ecgetredirs() from Src/parse.c:2959 — C signature ecgetredirs(Estate s).
ecgetstr
Port of ecgetstr() from Src/parse.c:2855 — C signature ecgetstr(Estate s, int dup, int *tokflag). 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
Port of ecgetstr from Src/parse.c:2855 — C decl ecgetstr(Estate s, int dup, int *tokflag). Rust fn ecgetstr_wordcode is the wordcode-pipeline decoder variant; the AST-side ecgetstr is at parse.rs:3869. 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
Port of ecispace() from Src/parse.c:372 — C signature ecispace(int p, int n). Insert n empty wordcode slots at position p, shifting later entries right, growing the buffer as needed, adjusting heredoc pointers.
ecrawstr
Port of ecrawstr() from Src/parse.c:2891 — C decl ecrawstr(Eprog p, Wordcode pc, int *tokflag). Like ecgetstr but reads at the given pc without advancing — caller steps pc separately.
ecstr
Port of ecstr() from Src/parse.c:473 — C decl #define ecstr(S) ecadd(ecstrcode(S)). C macro. ecstr(s) helper — ecadd(ecstrcode(s)). Mirrors the C macro at Src/parse.c:473 used everywhere by the par_* emitters.
ecstrcode
Port of ecstrcode() from Src/parse.c:426 — C signature ecstrcode(char *s). 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 empty_eprog() from Src/parse.c:584 — C signature empty_eprog(Eprog p). 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() from Src/parse.c:3131 — C decl #define fdflags(f) fdbyte(f, 0). C macro (via fdbyte, c:3129). ) — low byte of the packed pre[1] word.
fdhbldflags
Port of fdhbldflags() from Src/parse.c:3147 — C decl #define fdhbldflags(f,t) ((f) | ((t) << 2)). C macro. ) — pack (flags, tail) into one u32 (low 2 bits = flags, high 30 = tail).
fdheaderlen
Port of fdheaderlen() from Src/parse.c:3125 — C decl #define fdheaderlen(f) (((Wordcode) (f))[FD_PRELEN]). C macro; the Rust port indexes a &[u32] where C does Wordcode pointer arithmetic. ) — header length in u32 words (read from prelude word FD_PRELEN).
fdhflags
Port of fdhflags() from Src/parse.c:3145 — C decl #define fdhflags(f) (((FDHead) (f))->flags). C macro. ) — low 2 bits of the header’s flags field (the kshload/zshload marker).
fdhtail
Port of fdhtail() from Src/parse.c:3146 — C decl #define fdhtail(f) (((FDHead) (f))->flags >> 2). C macro. ) — high 30 bits of flags, byte offset from the name start to its basename.
fdmagic
Port of fdmagic() from Src/parse.c:3127 — C decl #define fdmagic(f) (((Wordcode) (f))[0]). C macro. ) — first prelude word, either FD_MAGIC or FD_OMAGIC.
fdname
Port of fdname() from Src/parse.c:3152 — C decl #define fdname(f) ((char *) (((FDHead) (f)) + 1)). C macro; the Rust port copies the NUL-terminated name out of the dump buffer. ) — name string follows the fdhead record immediately. Reads bytes from the dump buffer until NUL.
fdother
Port of fdother() from Src/parse.c:3133 — C decl #define fdother(f) (fdbyte(f, 1) + (fdbyte(f, 2) << 8) + (fdbyte(f, 3) << 16)). C macro. ) — high 24 bits of pre[1], holds the byte-offset to the opposite-byte-order dump copy.
fdsetflags
Port of fdsetflags() from Src/parse.c:3132 — C decl #define fdsetflags(f,v) fdsetbyte(f, 0, v). C macro (via fdsetbyte, c:3128). ) — write the low byte of pre[1].
fdsetother
Port of fdsetother() from Src/parse.c:3134 — C decl #define fdsetother(f, o) do { fdsetbyte(f, 1, ((o) & 0xff)); fdsetbyte(f, 2, (((o) >> 8) & 0xff)); fdsetbyte(f, 3, (((o) >> 16) & 0xff)); } while (0). C macro. ).
fdswap
Port of fdswap() from Src/parse.c:3318 — C signature fdswap(Wordcode p, int n). 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() from Src/parse.c:3140 — C decl #define fdversion(f) ((char *) ((f) + 2)). C macro; the Rust port copies the NUL-terminated string out instead of returning a pointer into the dump. ) — read the ZSH_VERSION C-string from pre[2..].
firstfdhead_offset
Port of firstfdhead from Src/parse.c:3142 — C decl #define firstfdhead(f) ((FDHead) (((Wordcode) (f)) + FD_PRELEN)). Rust fn firstfdhead_offset returns the u32-word OFFSET of the first fdhead rather than a FDHead pointer. ) — pointer to the first struct fdhead past the prelude.
freedump
Port of freedump() from Src/parse.c:3976 — C signature freedump(FuncDump f). Public helper for the rare external caller; locks the dumps mutex and drops the entry with the given filename.
freeeprog
Port of freeeprog() from Src/parse.c:2823 — C signature freeeprog(Eprog p). 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() from Src/parse.c:2643 — C signature get_cond_num(char *tst). 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() from Src/parse.c:3970 — C decl incrdumpcount(FuncDump f). The #else (non-USE_MMAP) twin is at c: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() from Src/parse.c:3069 — C signature init_eprog(void). 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
Port of init_parse() from Src/parse.c:509. Initialize parser for a fresh 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
Port of init_parse_status() from Src/parse.c:491. Initialize parser 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() from Src/parse.c:3675 — C decl load_dump_file(char *dump, struct stat *sbuf, int other, int len). 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() from Src/parse.c:3258 — C decl load_dump_header(char *nam, char *name, int err). 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 from Src/parse.c:3143 — C decl #define nextfdhead(f) ((FDHead) (((Wordcode) (f)) + (f)->hlen)). Rust fn nextfdhead_offset returns the u32-word OFFSET of the next fdhead rather than a FDHead pointer. ) — advance to the next header by reading the current hlen slot.
par_arith_wordcode
!!! WARNING: RUST-ONLY HELPER !!!
par_case_wordcode
Port of par_case from Src/parse.c:1209 — C decl par_case(int *cmplx). Rust fn par_case_wordcode is the wordcode-emitting variant.
par_cmd_wordcode
Port of par_cmd from Src/parse.c:958 — C decl par_cmd(int *cmplx, int zsh_construct). Rust fn par_cmd_wordcode is the wordcode-emitting variant. 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_cond_1
Port of par_cond_1() from Src/parse.c:2434 — C signature par_cond_1(void). Parses one ||-separated cond expression. Emits WCB_COND(COND_AND, …) when an && is found and recurses.
par_cond_2
Port of par_cond_2() from Src/parse.c:2476 — C signature par_cond_2(void). 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() from Src/parse.c:2626 — C signature par_cond_double(char *a, char *b). Emits wordcode for unary cond [ -X b ] or modular [ -mod b ].
par_cond_multi
Port of par_cond_multi() from Src/parse.c:2716 — C signature par_cond_multi(char *a, LinkList l). Emits wordcode for [ -OP A B C … ] n-ary cond (alternation).
par_cond_top
Port of par_cond() from Src/parse.c:2409 — C signature par_cond(void). 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() from Src/parse.c:2659 — C decl par_cond_triple(char *a, char *b, char *c). Emits wordcode for the binary forms [ A op B ] — = / == / != / < / > / =~ / -X.
par_cond_wordcode
Port of par_dinbrack() from Src/parse.c:1810 — C signature par_dinbrack(void). Wraps par_cond (the cond-expression emitter at parse.c:2409) with the [[ ... ]] framing: incond/incmdpos toggles + DOUTBRACK expectation.
par_dinbrack
Port of par_dinbrack() from Src/parse.c:1810 — C signature par_dinbrack(void). Body parser inside [[ ... ]] — calls par_cond to emit the condition wordcode then advances past ]].
par_event
Port of par_event() from Src/parse.c:635.
par_event_wordcode
!!! WARNING: RUST-ONLY HELPER !!!
par_for_wordcode
Port of par_for from Src/parse.c:1087 — C decl par_for(int *cmplx). Rust fn par_for_wordcode is the wordcode-emitting variant.
par_funcdef_wordcode
Port of par_funcdef from Src/parse.c:1672 — C decl par_funcdef(int *cmplx). Rust fn par_funcdef_wordcode is the wordcode-emitting variant.
par_if_wordcode
Port of par_if from Src/parse.c:1411 — C decl par_if(int *cmplx). Rust fn par_if_wordcode is the wordcode-emitting variant.
par_list1
Port of par_list1() from Src/parse.c:808. Parse one list — non-recursing variant. 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 from Src/parse.c:808 — C decl par_list1(int *cmplx). Rust fn par_list1_wordcode is the wordcode-emitting variant. 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 from Src/parse.c:771 — C decl par_list(int *cmplx). Rust fn par_list_wordcode is the wordcode-emitting variant (the AST twin is par_list at parse.rs:1008). 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
Port of par_nl_wordlist() from Src/parse.c:2379 — C decl par_nl_wordlist(void). AST variant. 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 from Src/parse.c:894 — C decl par_pline(int *cmplx). Rust fn par_pipe_wordcode is the wordcode-emitting variant; named par_pipe_wordcode because the AST par_pline (parse.rs:1183) already owns the C name. 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. (Named par_pipe_wordcode to disambiguate from the AST par_pline at parse.rs:1183 — semantically the same pline production.)
par_repeat_wordcode
Port of par_repeat from Src/parse.c:1565 — C decl par_repeat(int *cmplx). Rust fn par_repeat_wordcode is the wordcode-emitting variant.
par_save_list1_wordcode
Port of par_save_list1 from Src/parse.c:481 — C decl #define par_save_list1(C) do { int eu = ecused; par_list1(C); if (eu == ecused) ecadd(WCB_END()); } while (0). Rust fn par_save_list1_wordcode is the wordcode-emitting variant of that C macro.
par_save_list_wordcode
Port of par_save_list from Src/parse.c:475 — C decl #define par_save_list(C) do { int eu = ecused; par_list(C); if (eu == ecused) ecadd(WCB_END()); } while (0). Rust fn par_save_list_wordcode is the wordcode-emitting variant of that C macro. do { int eu = ecused; par_list(C); if (eu == ecused) ecadd(WCB_END()); } while (0)
par_select_wordcode
!!! WARNING: RUST-ONLY HELPER !!!
par_simple_wordcode
Port of par_simple from Src/parse.c:1836 — C decl par_simple(int *cmplx, int nr). Rust fn par_simple_wordcode is the wordcode-emitting variant. 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() from Src/parse.c:869 — C signature par_sublist2(int *cmplx). 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 from Src/parse.c:825 — C decl par_sublist(int *cmplx). Rust fn par_sublist_wordcode is the wordcode-emitting variant. 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
Port of par_subsh from Src/parse.c:1619 — C decl par_subsh(int *cmplx, int zsh_construct). Rust fn par_subsh_wordcode is the wordcode-emitting variant; zsh_construct selects the {...} (cursh) shape as in C. 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() from Src/parse.c:1787 — C signature par_time(void). 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
!!! WARNING: RUST-ONLY HELPER !!!
par_while_wordcode
Port of par_while from Src/parse.c:1521 — C decl par_while(int *cmplx). Rust fn par_while_wordcode is the wordcode-emitting variant.
par_wordlist
Port of par_wordlist() from Src/parse.c:2362 — C decl par_wordlist(void). AST variant: returns the words instead of ecstr-ing them. 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
!!! WARNING: RUST-ONLY HELPER !!!
parse_cond
Port of parse_cond() from Src/parse.c:722 — C signature parse_cond(void). Only used by bin_test/bin_bracket for /bin/test/[ compat — the condlex global must already point at testlex before entry.
parse_context_restore
Port of parse_context_restore() from Src/parse.c:326 — C signature parse_context_restore(const struct parse_stack *ps, int toplevel). 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
Port of parse_context_save() from Src/parse.c:295 — C signature parse_context_save(struct parse_stack *ps, int toplevel). Snapshots the lexer-side file-statics plus the pending heredoc list, plus the wordcode-buffer state (ecbuf, ecstrs, ecused, …). 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
Port of parse_event() from Src/parse.c:614 (body c:615-631). Top-level parse-event entry. Reads one event from the lexer (a sublist optionally followed by SEPER/AMPER/AMPERBANG) and returns the resulting ZshProgram.
parse_init
!!! WARNING: RUST-ONLY HELPER !!!
parse_list
Port of parse_list() from Src/parse.c:697 — C signature parse_list(void). C-shape entry point: drives par_list and finalizes via bld_eprog. Returns None on syntax error.
read_fdhead
!!! WARNING: RUST-ONLY HELPER !!!
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() from Src/parse.c:755 — C signature set_sublist_code(int p, int type, int flags, int skip, int cmplx). 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() from Src/parse.c:3746 — C decl try_dump_file(char *path, char *name, char *file, int *ksh, int test_only). Tries to load function name from a .zwc digest (<path>.zwc) or per-function compiled file (<file>.zwc) when each is newer than its uncompiled source.
try_source_file
Port of try_source_file() from Src/parse.c:3795 — C signature try_source_file(char *file). Returns an Eprog (the wordcode dump body) if <file>.zwc exists and is newer than <file>, else None. The dump entry searched is the file’s basename (tail), matching how zcompile names source-file entries.
useeprog
Port of useeprog() from Src/parse.c:2813 — C signature useeprog(Eprog p). 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() from Src/parse.c:3334 — C decl write_dump(int dfd, LinkList progs, int map, int hlen, int tlen). 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. Port of yyerror() from Src/parse.c:2733 — C decl yyerror(int noerr).
zwcstat
Port of zwcstat() from Src/parse.c:3656 — C decl zwcstat(char *filename, struct stat *buf). 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
ParseStack type alias.