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 fdheadfromSrc/parse.c:3116. One per function inside a wordcode dump. All fields arewordcode(u32). - parse_
stack - Direct port of
struct parse_stackatSrc/zsh.h:3099-3109. Used byparse_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 wcfuncfromSrc/parse.c:3158. Build-time per-function aggregate before write_dump emits it: the function (or source-file) name, the compiledEprogfromparse_string, and the FDHF_* autoload-style flag word.
Constants§
- CONDLEX_
TESTLEX - ECBUF
ECBUFstatic.- 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.Stringwould 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 Veclets us write byte-for-byte what C writes after metafy. - FDF_MAP
#define FDF_MAP 1fromSrc/parse.c:3111. Bit set when the dump should bemmap()-ed (-Mflag) vs read normally (-R).- FDF_
OTHER #define FDF_OTHER 2fromSrc/parse.c:3112. Bit indicating this dump has an opposite-byte-order copy atfdother(f).- FDHEAD_
WORDS - Size of
struct fdheadinwordcode(u32) units. Used by all the header-walk macros below. - FDHF_
KSHLOAD #define FDHF_KSHLOAD 1fromSrc/parse.c:3149. Function-header flag word —-kksh-style autoload marker.- FDHF_
ZSHLOAD #define FDHF_ZSHLOAD 2fromSrc/parse.c:3150.-zzsh-style autoload marker.- FD_EXT
#define FD_EXT ".zwc"fromSrc/parse.c:3104.- FD_
MAGIC #define FD_MAGIC 0x04050607fromSrc/parse.c:3108. Sentinel for native-byte-order dumps.- FD_
MINMAP #define FD_MINMAP 4096fromSrc/parse.c:3105. mmap threshold —-Mmode only kicks in when the wordcode body is at least this many bytes (otherwise read(2) is preferred).- FD_
OMAGIC #define FD_OMAGIC 0x07060504fromSrc/parse.c:3109. Sentinel for opposite-byte-order dumps (byte-swapped FD_MAGIC).- FD_
PRELEN #define FD_PRELEN 12fromSrc/parse.c:3107. File-header length in u32 words: magic + packed-flags-byte + 10 version words.- HDOCS
- Port of file-static
struct heredocs *hdocs;fromSrc/parse.c:84.
Statics§
- DUMMY_
EPROG mod_export struct eprog dummy_eprog;fromSrc/parse.c:3066. Placeholder Eprog used byshf->funcdef = &dummy_eprog;in builtin.c when clearing a stale autoload stub. Held in a Mutex soinit_eprogcan set it once at shell startup.- DUMPS
static FuncDump dumps;fromSrc/parse.c:3652— head of the loaded-.zwclinked list. C walksdumps/p->nextdirectly; the Rust port uses aMutex<Vec<funcdump>>indexed by filename so refcount ops can find an entry without raw-pointer compare.
Functions§
- COND_
SEP - Port of
COND_SEP()fromSrc/parse.c:2405— C decl#define COND_SEP() (tok == SEPER && condlex != testlex && *zshlextext != ';'). C macro.COND_SEP()macro fromSrc/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()fromSrc/parse.c:3180— C declbin_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()fromSrc/parse.c:547— C signaturebld_eprog(int heap). Finalizes the in-buildECBUF/ECSTRS/ECNPATSstate into anEprog. Resets the build state so a new parse can start. - build_
cur_ dump - Port of
build_cur_dump()fromSrc/parse.c:3536— C declbuild_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.zwcdump. Shareswrite_dumpwith the source-file variantbuild_dump. - build_
dump - Port of
build_dump()fromSrc/parse.c:3397— C signaturebuild_dump(char *nam, char *dump, char **files, int ali, int map, int flags). Source-file → wordcode dump compiler: parses each source file viaparse_stringand serializes the resultingEprogs throughwrite_dumpinto<dump>.zwc. - check_
cond - Port of
check_cond()fromSrc/parse.c:2459— C declstatic int check_cond(const char *input, const char *cond). True iffinputis the two-char-Xform whoseXmatchescond— used by par_cond_2 to detect-a/-on-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()fromSrc/parse.c:3833— C declcheck_dump_file(char *file, struct stat *sbuf, char *name, int *ksh, int test_only). Walks thedumpsmmap list looking for(dev, ino)matchingsbuf; on miss, callsload_dump_headerto read the .zwc header. Thendump_find_func(d, name)locates the function table entry. Returns the wordcode slice + ksh-load flag. - clear_
hdocs - Port of
clear_hdocs()fromSrc/parse.c:591— C signatureclear_hdocs(void). Clear pending here-document list. The C version walkshdocsand frees each node; Rust drops theBox<heredocs>chain automatically when the head is replaced with None. - closedumps
- Port of
closedumps()fromSrc/parse.c:4008— C declclosedumps(void). The#else(non-USE_MMAP) twin is at c:4033. Walksdumpsfreeing every entry. Called on shell exit (exec.c:522). - condlex
- Port of calling through
condlexfromSrc/parse.c:2399: dispatches totestlexwhileCONDLEX_TESTLEXis set, otherwise tozshlex. - copy_
ecstr - Port of
copy_ecstr()fromSrc/parse.c:537— C signaturecopy_ecstr(Eccstr s, char *p). Walks the BST and writes each entry top[s->aoffs..]matching C’s recursive in-order traversal exactly. The old impl used theECSTRS_REVERSEHashMap keyed byoffs(= 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()fromSrc/parse.c:3489— C declcur_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 azwarnnamwhen the function cannot be dumped; the caller removes the half-written dump. - decrdumpcount
- Port of
decrdumpcount()fromSrc/parse.c:3988— C decldecrdumpcount(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()fromSrc/parse.c:4042— C decldump_autoload(char *nam, char *file, int on, Options ops, int func). Registers every function in a.zwcfor autoload viashfunctab. - dump_
find_ func - Port of
dump_find_func()fromSrc/parse.c:3167— C decldump_find_func(Wordcode h, char *name). Walks the header table inside a loaded dump for a function with the given basename; returns the matchingfdheadrecord (C returns theFDHeadpointer). - dupeprog
- Duplicate an Eprog. Direct port of zsh/Src/parse.c:2767
Port of
dupeprog()fromSrc/parse.c:2767— C decldupeprog(Eprog p, int heap). Deep-copies the wordcode array, string table, and pattern-prog slots.dummy_eprogis returned unchanged.heap-allocated copies getnref = -1(never freed); real ones getnref = 1. - ecadd
- Port of
ecadd()fromSrc/parse.c:397— C signatureecadd(wordcode c). Appendcto the wordcode buffer with grow-on-demand, return the new index. - ecadjusthere
- Port of
ecadjusthere()fromSrc/parse.c:360— C signatureecadjusthere(int p, int d). Walk the pending-heredocs list and bump eachpcbydif it’s at or after positionp. Called byecispace/ecdelwhen wordcodes shift. - eccopyredirs
- Port of
eccopyredirs()fromSrc/parse.c:3003— C signatureeccopyredirs(Estate s). Reads the WC_REDIR run ats->pc, counts the wordcodes needed, reserves space inecbufviaecispace, then re-walkss->pcre-emitting each redir’s wordcodes into the reserved slot — finally callsbld_eprog(0)to package the result as an Eprog. - ecdel
- Port of
ecdel()fromSrc/parse.c:413— C signatureecdel(int p). Remove the wordcode at positionp, shift later entries left by one, decrement ecused, adjust pending heredoc pointers. - ecgetarr
- Port of
ecgetarr()fromSrc/parse.c:2917— C declecgetarr(Estate s, int num, int dup, int *tokflag). Readsnumstrings from wordcode ats->pcand OR-folds each entry’s token flag into*tokflag. - ecgetlist
- Port of
ecgetlist()fromSrc/parse.c:2937— C declecgetlist(Estate s, int num, int dup, int *tokflag). Same shape asecgetarrbut C returnsLinkList; zshrs usesVec<String>for both. - ecgetredirs
- Port of
ecgetredirs()fromSrc/parse.c:2959— C signatureecgetredirs(Estate s). - ecgetstr
- Port of
ecgetstr()fromSrc/parse.c:2855— C signatureecgetstr(Estate s, int dup, int *tokflag).s->pcadvances through the wordcode buffer;s->strsindexes the string pool. Returns the interned string (or a 1-3-char literal inlined directly into the wordcode word). - ecgetstr_
wordcode - Port of
ecgetstrfromSrc/parse.c:2855— C declecgetstr(Estate s, int dup, int *tokflag). Rust fnecgetstr_wordcodeis the wordcode-pipeline decoder variant; the AST-sideecgetstris at parse.rs:3869. P9b decoder (wordcode-pipeline variant): direct port ofecgetstr(Estate s, int dup, int *tokflag)fromSrc/parse.c:2855-2890. Reads a wordcode atpc, decodes the encoded string back to owned String. Returns (string, pc_after_consumed). Distinct from the existingecgetstr(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()fromSrc/parse.c:372— C signatureecispace(int p, int n). Insertnempty wordcode slots at positionp, shifting later entries right, growing the buffer as needed, adjusting heredoc pointers. - ecrawstr
- Port of
ecrawstr()fromSrc/parse.c:2891— C declecrawstr(Eprog p, Wordcode pc, int *tokflag). Likeecgetstrbut reads at the given pc without advancing — caller stepspcseparately. - ecstr
- Port of
ecstr()fromSrc/parse.c:473— C decl#define ecstr(S) ecadd(ecstrcode(S)). C macro.ecstr(s)helper —ecadd(ecstrcode(s)). Mirrors the C macro atSrc/parse.c:473used everywhere by the par_* emitters. - ecstrcode
- Port of
ecstrcode()fromSrc/parse.c:426— C signatureecstrcode(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()fromSrc/parse.c:584— C signatureempty_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()fromSrc/parse.c:3131— C decl#define fdflags(f) fdbyte(f, 0). C macro (viafdbyte, c:3129). ) — low byte of the packedpre[1]word. - fdhbldflags
- Port of
fdhbldflags()fromSrc/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()fromSrc/parse.c:3125— C decl#define fdheaderlen(f) (((Wordcode) (f))[FD_PRELEN]). C macro; the Rust port indexes a&[u32]where C doesWordcodepointer arithmetic. ) — header length in u32 words (read from prelude wordFD_PRELEN). - fdhflags
- Port of
fdhflags()fromSrc/parse.c:3145— C decl#define fdhflags(f) (((FDHead) (f))->flags). C macro. ) — low 2 bits of the header’sflagsfield (the kshload/zshload marker). - fdhtail
- Port of
fdhtail()fromSrc/parse.c:3146— C decl#define fdhtail(f) (((FDHead) (f))->flags >> 2). C macro. ) — high 30 bits offlags, byte offset from the name start to its basename. - fdmagic
- Port of
fdmagic()fromSrc/parse.c:3127— C decl#define fdmagic(f) (((Wordcode) (f))[0]). C macro. ) — first prelude word, eitherFD_MAGICorFD_OMAGIC. - fdname
- Port of
fdname()fromSrc/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()fromSrc/parse.c:3133— C decl#define fdother(f) (fdbyte(f, 1) + (fdbyte(f, 2) << 8) + (fdbyte(f, 3) << 16)). C macro. ) — high 24 bits ofpre[1], holds the byte-offset to the opposite-byte-order dump copy. - fdsetflags
- Port of
fdsetflags()fromSrc/parse.c:3132— C decl#define fdsetflags(f,v) fdsetbyte(f, 0, v). C macro (viafdsetbyte, c:3128). ) — write the low byte ofpre[1]. - fdsetother
- Port of
fdsetother()fromSrc/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()fromSrc/parse.c:3318— C signaturefdswap(Wordcode p, int n). Byte-swap each u32 inp[..n]in place. Used when writing the opposite-byte-order copy of a wordcode dump. - fdversion
- Port of
fdversion()fromSrc/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 theZSH_VERSIONC-string frompre[2..]. - firstfdhead_
offset - Port of
firstfdheadfromSrc/parse.c:3142— C decl#define firstfdhead(f) ((FDHead) (((Wordcode) (f)) + FD_PRELEN)). Rust fnfirstfdhead_offsetreturns the u32-word OFFSET of the firstfdheadrather than aFDHeadpointer. ) — pointer to the firststruct fdheadpast the prelude. - freedump
- Port of
freedump()fromSrc/parse.c:3976— C signaturefreedump(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()fromSrc/parse.c:2823— C signaturefreeeprog(Eprog p). Refcount-decrement; when it hits zero, drops the pattern progs, decrements the dump refcount if any, and releases the eprog.dummy_eprogis 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()fromSrc/parse.c:2643— C signatureget_cond_num(char *tst). Returns the index oftstin{"nt","ot","ef","eq","ne","lt","gt","le","ge"}or-1if not a recognized binary cond operator. - incrdumpcount
- Port of
incrdumpcount()fromSrc/parse.c:3970— C declincrdumpcount(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 byfilenamebecause Rust can’t raw-pointer-compare funcdump values inside aMutex<Vec<...>>; same observable effect (the count of the matching entry increments). - init_
eprog - Port of
init_eprog()fromSrc/parse.c:3069— C signatureinit_eprog(void). Sets updummy_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()fromSrc/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()fromSrc/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()fromSrc/parse.c:3675— C declload_dump_file(char *dump, struct stat *sbuf, int other, int len). Reads (or mmap()’s) a complete.zwcfile into memory. Returns the u32 buffer or None on I/O error. - load_
dump_ header - Port of
load_dump_header()fromSrc/parse.c:3258— C declload_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 whenerr != 0). - nextfdhead_
offset - Port of
nextfdheadfromSrc/parse.c:3143— C decl#define nextfdhead(f) ((FDHead) (((Wordcode) (f)) + (f)->hlen)). Rust fnnextfdhead_offsetreturns the u32-word OFFSET of the nextfdheadrather than aFDHeadpointer. ) — advance to the next header by reading the currenthlenslot. - par_
arith_ wordcode - !!! WARNING: RUST-ONLY HELPER !!!
- par_
case_ wordcode - Port of
par_casefromSrc/parse.c:1209— C declpar_case(int *cmplx). Rust fnpar_case_wordcodeis the wordcode-emitting variant. - par_
cmd_ wordcode - Port of
par_cmdfromSrc/parse.c:958— C declpar_cmd(int *cmplx, int zsh_construct). Rust fnpar_cmd_wordcodeis 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()fromSrc/parse.c:2434— C signaturepar_cond_1(void). Parses one||-separated cond expression. EmitsWCB_COND(COND_AND, …)when an&&is found and recurses. - par_
cond_ 2 - Port of
par_cond_2()fromSrc/parse.c:2476— C signaturepar_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()fromSrc/parse.c:2626— C signaturepar_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()fromSrc/parse.c:2716— C signaturepar_cond_multi(char *a, LinkList l). Emits wordcode for[ -OP A B C … ]n-ary cond (alternation). - par_
cond_ top - Port of
par_cond()fromSrc/parse.c:2409— C signaturepar_cond(void). Top-level cond OR-chain — drivespar_cond_1and stitches||-separated terms withWCB_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 inecbuf. Without this, the wordcode emitter for[[ ... ]]produced zero words and parity dropped 148 words on/etc/zshrcalone. - par_
cond_ triple - Port of
par_cond_triple()fromSrc/parse.c:2659— C declpar_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()fromSrc/parse.c:1810— C signaturepar_dinbrack(void). Wrapspar_cond(the cond-expression emitter at parse.c:2409) with the[[ ... ]]framing: incond/incmdpos toggles + DOUTBRACK expectation. - par_
dinbrack - Port of
par_dinbrack()fromSrc/parse.c:1810— C signaturepar_dinbrack(void). Body parser inside[[ ... ]]— callspar_condto emit the condition wordcode then advances past]]. - par_
event - Port of
par_event()fromSrc/parse.c:635. - par_
event_ wordcode - !!! WARNING: RUST-ONLY HELPER !!!
- par_
for_ wordcode - Port of
par_forfromSrc/parse.c:1087— C declpar_for(int *cmplx). Rust fnpar_for_wordcodeis the wordcode-emitting variant. - par_
funcdef_ wordcode - Port of
par_funcdeffromSrc/parse.c:1672— C declpar_funcdef(int *cmplx). Rust fnpar_funcdef_wordcodeis the wordcode-emitting variant. - par_
if_ wordcode - Port of
par_iffromSrc/parse.c:1411— C declpar_if(int *cmplx). Rust fnpar_if_wordcodeis the wordcode-emitting variant. - par_
list1 - Port of
par_list1()fromSrc/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_list1fromSrc/parse.c:808— C declpar_list1(int *cmplx). Rust fnpar_list1_wordcodeis the wordcode-emitting variant. Single-sublist variant used by funcdef bodies and the shortfor/while/repeatforms — exactly one sublist withZ_SYNC|Z_END, no chain. - par_
list_ wordcode - Port of
par_listfromSrc/parse.c:771— C declpar_list(int *cmplx). Rust fnpar_list_wordcodeis the wordcode-emitting variant (the AST twin ispar_listat parse.rs:1008).list : { SEPER } [ sublist [ { SEPER | AMPER | AMPERBANG } list ] ]. True line-by-line port: takescmplx: &mut i32matching C’sint *cmplxout-parameter, uses stack-localcper iteration like C (so inner sublist cmplx is independent of outer). - par_
nl_ wordlist - Port of
par_nl_wordlist()fromSrc/parse.c:2379— C declpar_nl_wordlist(void). AST variant. Parse a newline-separated wordlist. Direct port of zsh/Src/parse.c:2379par_nl_wordlist. Like par_wordlist but tolerates leading/trailing newlines. - par_
pipe_ wordcode - Port of
par_plinefromSrc/parse.c:894— C declpar_pline(int *cmplx). Rust fnpar_pipe_wordcodeis the wordcode-emitting variant; namedpar_pipe_wordcodebecause the ASTpar_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 BARAMP2>&1synthetic redir. (Namedpar_pipe_wordcodeto disambiguate from the ASTpar_plineat parse.rs:1183 — semantically the sameplineproduction.) - par_
repeat_ wordcode - Port of
par_repeatfromSrc/parse.c:1565— C declpar_repeat(int *cmplx). Rust fnpar_repeat_wordcodeis the wordcode-emitting variant. - par_
save_ list1_ wordcode - Port of
par_save_list1fromSrc/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 fnpar_save_list1_wordcodeis the wordcode-emitting variant of that C macro. - par_
save_ list_ wordcode - Port of
par_save_listfromSrc/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 fnpar_save_list_wordcodeis 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_simplefromSrc/parse.c:1836— C declpar_simple(int *cmplx, int nr). Rust fnpar_simple_wordcodeis the wordcode-emitting variant. Emits WC_SIMPLE + word count + interned string offsets. Returns0when nothing was emitted, otherwise1 + (number of code words consumed by redirections). The full C body handles assignments (ENVSTRING/ENVARRAY), inline{var}>filebrace-FDs, prefix modifiers (NOCORRECT etc), andname() { body }funcdef detection — those paths are progressively wired into the AST parser; this wordcode-emitter covers the simplecmd args...case + interleaved redirs. - par_
sublist2 - Port of
par_sublist2()fromSrc/parse.c:869— C signaturepar_sublist2(int *cmplx). Secondary-sublist arm: handles theCOPROC/Bangprefix in front of a pline. Returns the WC_SUBLIST flag word added. - par_
sublist_ wordcode - Port of
par_sublistfromSrc/parse.c:825— C declpar_sublist(int *cmplx). Rust fnpar_sublist_wordcodeis 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_subshfromSrc/parse.c:1619— C declpar_subsh(int *cmplx, int zsh_construct). Rust fnpar_subsh_wordcodeis the wordcode-emitting variant;zsh_constructselects the{...}(cursh) shape as in C.Src/parse.c:1619-1665. Handles both(...)subshell and{...}brace group (cursh) plus optionalalways { ... }trailing block. C uses a single function withzsh_construct=1for{...}and 0 for(...). - par_
time_ wordcode - Port of
par_time()fromSrc/parse.c:1787— C signaturepar_time(void).time PIPEemits WCB_TIMED(WC_TIMED_PIPE) + the sublist code; baretimewith no pipeline emits WCB_TIMED(WC_TIMED_EMPTY). - par_
until_ wordcode - !!! WARNING: RUST-ONLY HELPER !!!
- par_
while_ wordcode - Port of
par_whilefromSrc/parse.c:1521— C declpar_while(int *cmplx). Rust fnpar_while_wordcodeis the wordcode-emitting variant. - par_
wordlist - Port of
par_wordlist()fromSrc/parse.c:2362— C declpar_wordlist(void). AST variant: returns the words instead ofecstr-ing them. Parse a wordlist forfor ... in WORDS;. Direct port of zsh/Src/parse.c:2362par_wordlist. Reads STRING tokens until the next SEPER / SEMI / NEWLIN. - parse
- !!! WARNING: RUST-ONLY HELPER !!!
- parse_
cond - Port of
parse_cond()fromSrc/parse.c:722— C signatureparse_cond(void). Only used bybin_test/bin_bracketfor/bin/test/[compat — thecondlexglobal must already point attestlexbefore entry. - parse_
context_ restore - Port of
parse_context_restore()fromSrc/parse.c:326— C signatureparse_context_restore(const struct parse_stack *ps, int toplevel). Inverse ofparse_context_save. Restores lexer-side state + pending heredocs + Rust-only counters fromps, then clearserrflag & ERRFLAG_ERRORper parse.c:354. WARNING: param names don’t match C — Rust=(ps) vs C=(ps, toplevel) - parse_
context_ save - Port of
parse_context_save()fromSrc/parse.c:295— C signatureparse_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()fromSrc/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()fromSrc/parse.c:697— C signatureparse_list(void). C-shape entry point: drivespar_listand finalizes viabld_eprog. ReturnsNoneon 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 anecadd(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()fromSrc/parse.c:755— C signatureset_sublist_code(int p, int type, int flags, int skip, int cmplx). Patches the WCB_SUBLIST header atp. When the sublist is non-complex (single command, no pipeline), sets WC_SUBLIST_SIMPLE and rewrites the following slot toWC_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()fromSrc/parse.c:3746— C decltry_dump_file(char *path, char *name, char *file, int *ksh, int test_only). Tries to load functionnamefrom a.zwcdigest (<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()fromSrc/parse.c:3795— C signaturetry_source_file(char *file). Returns an Eprog (the wordcode dump body) if<file>.zwcexists and is newer than<file>, else None. The dump entry searched is the file’s basename (tail), matching howzcompilenames source-file entries. - useeprog
- Port of
useeprog()fromSrc/parse.c:2813— C signatureuseeprog(Eprog p).if (p && p != &dummy_eprog && p->nref >= 0) p->nref++;— pin a real (non-heap, non-dummy) Eprog so it survives the nextfreeeprog. - write_
dump - Port of
write_dump()fromSrc/parse.c:3334— C declwrite_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 ofyyerror()fromSrc/parse.c:2733— C declyyerror(int noerr). - zwcstat
- Port of
zwcstat()fromSrc/parse.c:3656— C declzwcstat(char *filename, struct stat *buf). Stats a.zwcfile, falling back to.zwc.oldif the primary doesn’t exist (zsh uses the.oldsuffix to keep a previous dump readable while a rewrite is in progress).
Type Aliases§
- Parse
Stack ParseStacktype alias.