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
<<EOFparsing. Held in the lexer-sideHEREDOCS: Vec<HereDoc>thread_local for later attachment toZshRedirentries (viaheredoc_idx). - Here
DocInfo - Heredoc body+metadata attached to a parsed
ZshRedir. Carried through the AST and consumed by the compiler when emittingOp::HereDoc(idx)for the fusevm VM. - List
Flags - Redirect
- Redirect
- Simple
Command - Simple command with assignments, words, and redirects
- Sublist
Flags - ZshAssign
- An assignment
- ZshCase
- Case statement
- ZshFor
- For loop
- ZshFunc
Def - 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 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 Rust port stores the source-text body inline since the C-sideEprog↔parse_stringchain isn’t fully wired through this layer yet (build_dumpfalls back to source-text caching).
Enums§
- Case
Term - Case
Terminator - Case terminator
- Compound
Command - Compound command
- ForList
- ListOp
- List operator (for shell command lists)
- Redirect
Op - Redirect operator
- Shell
Command - Shell command - the old shell_ast compatible type
- Shell
Word - Shell word - can be simple literal or complex expansion
- Sublist
Op - VarModifier
- Variable modifier for parameter expansion
- ZshAssign
Value - ZshCommand
- A command
- ZshCond
- Conditional expression [[ … ]]
- ZshParam
Flag - 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.Stringwould 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 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.- PARSER_
GLOBAL_ ITERATIONS - PARSER_
RECURSION_ DEPTH
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 COND_SEP()macro fromSrc/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))fromSrc/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)fromSrc/parse.c:547. 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(char *nam, char *dump, char **names, int match, int map, int what)fromSrc/parse.c:3536. Compiles currently-loaded functions (-cfor functions,-afor aliases) into a.zwcdump. Same wordcode-emit dependency asbuild_dump. - build_
dump - Port of
build_dump(char *nam, char *dump, char **files, int ali, int map, int flags)fromSrc/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)fromSrc/parse.c:3833. Opens + validates a.zwcfile, 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 globalhdocslinked list and frees each node. zshrs stores pending heredocs on the lexer’sheredocsVec — truncating it has the same effect. - closedumps
- Port of
closedumps(void)fromSrc/parse.c:4008/4033. Walksdumpsfreeing every entry. Called on shell exit (exec.c:522). - condlex
- Port of
condlexfunction-pointer global fromSrc/parse.c. C flips this betweenzshlexandtestlexdepending on whether we’re inside[[ ]]vs/bin/testbuiltin. zshrs has no separatetestlexyet, so this just defers tozshlex. - copy_
ecstr - Port of
copy_ecstr(Eccstr s, char *p)fromSrc/parse.c:537. Walks the in-build string-eccstr tree and writes each entry top[s->aoffs..]. The Rust port mirrors via theECSTRS_REVERSEHashMap (eccstr-tree replacement) and writes into aVec<u8>slice. - cur_
add_ func - Port of
cur_add_func(char *nam, Shfunc shf, LinkList names, LinkList progs, int *hlen, int *tlen, int what)fromSrc/parse.c:3489. Adds a shfunc to the in-build dump progs+names lists. Stub:Eprogfor the function body isn’t yet wired throughshfunc.funcdefto be serializable here. - decrdumpcount
- Port of
decrdumpcount(FuncDump f)fromSrc/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)fromSrc/parse.c:4042. Registers every function in a.zwcfor autoload viashfunctab. Stub: returns 1 (error) until the dump-cache port lands. - dump_
find_ func - Port of
dump_find_func(Wordcode h, char *name)fromSrc/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)fromSrc/parse.c:2767. 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
- Direct port of
ecadd(wordcode c)atSrc/parse.c:397. Appendcto the wordcode buffer with grow-on-demand, return the new index. - ecadjusthere
- Direct port of
ecadjusthere(int p, int d)atSrc/parse.c:360. Walk the pending-heredocs list and bump eachpcbydif it’s at or after positionp. Called byecispace/ecdelwhen wordcodes shift. - eccopyredirs
- Port of
eccopyredirs(Estate s)fromSrc/parse.c:3003. 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
- Direct port of
ecdel(int p)atSrc/parse.c:413. Remove the wordcode at positionp, shift later entries left by one, decrement ecused, adjust pending heredoc pointers. - ecgetarr
- Port of
ecgetarr(Estate s, int num, int dup, int *tokflag)fromSrc/parse.c:2917. Readsnumstrings from wordcode ats->pcand OR-folds each entry’s token flag into*tokflag. - ecgetlist
- Port of
ecgetlist(Estate s, int num, int dup, int *tokflag)fromSrc/parse.c:2937. Same shape asecgetarrbut C returnsLinkList; zshrs usesVec<String>for both. - ecgetredirs
- Port of
ecgetredirs(Estate s)fromSrc/parse.c:2959. - ecgetstr
- Port of
ecgetstr(Estate s, int dup, int *tokflag)fromSrc/parse.c:2855.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 - P9b decoder (wordcode-pipeline variant): direct port of
ecgetstr(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
- Direct port of
ecispace(int p, int n)atSrc/parse.c:372. Insertnempty wordcode slots at positionp, shifting later entries right, growing the buffer as needed, adjusting heredoc pointers. - ecrawstr
- Port of
ecrawstr(Eprog p, Wordcode pc, int *tokflag)fromSrc/parse.c:2891. Likeecgetstrbut reads at the given pc without advancing — caller stepspcseparately. - ecstr
ecstr(s)helper —ecadd(ecstrcode(s)). Mirrors the C macro atSrc/parse.c:482used everywhere by the par_* emitters.- ecstrcode
- Direct port of
ecstrcode(char *s)atSrc/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)fromSrc/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 packedpre[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 wordFD_PRELEN). - fdhflags
- Port of
fdhflags(f)macro (Src/parse.c:3145) — low 2 bits of the header’sflagsfield (the kshload/zshload marker). - fdhtail
- Port of
fdhtail(f)macro (Src/parse.c:3146) — high 30 bits offlags, byte offset from the name start to its basename. - fdmagic
- Port of
fdmagic(f)macro (Src/parse.c:3127) — first prelude word, eitherFD_MAGICorFD_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 ofpre[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 ofpre[1]. - fdsetother
- Port of
fdsetother(f, o)macro (Src/parse.c:3134). - fdswap
- Port of
fdswap(Wordcode p, int n)fromSrc/parse.c:3318. Byte-swap each u32 inp[..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 theZSH_VERSIONC-string frompre[2..]. - firstfdhead_
offset - Port of
firstfdhead(f)macro (Src/parse.c:3142) — pointer to the firststruct fdheadpast the prelude. - freedump
- Port of
freedump(FuncDump f)fromSrc/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)fromSrc/parse.c:2823. 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(char *tst)fromSrc/parse.c:2643. 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(FuncDump f)fromSrc/parse.c:3970/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(void)fromSrc/parse.c:3069. 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 - 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)fromSrc/parse.c:3675. 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(char *nam, char *name, int err)fromSrc/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 whenerr != 0). - nextfdhead_
offset - Port of
nextfdhead(f)macro (Src/parse.c:3143) — advance to the next header by reading the currenthlenslot. - par_
arith_ wordcode - Port of the
case DINPAR:arm ofpar_cmdfromSrc/parse.c:1031-1034: - par_
case_ wordcode - Port of
par_case(int *cmplx)fromSrc/parse.c:1209-1409. - par_
cmd_ wordcode - Port of
par_cmd(int *cmplx, int zsh_construct)fromSrc/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)fromSrc/parse.c:2434. Parses one||-separated cond expression. EmitsWCB_COND(COND_AND, …)when an&&is found and recurses. - par_
cond_ 2 - Port of
par_cond_2(void)fromSrc/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)fromSrc/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)fromSrc/parse.c:2716. Emits wordcode for[ -OP A B C … ]n-ary cond (alternation). - par_
cond_ top - Port of
par_cond(void)fromSrc/parse.c:2409. 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(char *a, char *b, char *c)fromSrc/parse.c:2659. Emits wordcode for the binary forms[ A op B ]—=/==/!=/</>/=~/-X. - par_
cond_ wordcode - Port of
par_dinbrack(void)fromSrc/parse.c:1810. Wrapspar_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) — callspar_subsh_wordcode_impl(true). C uses the samepar_subshfunction withzsh_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)fromSrc/parse.c:1810. Body parser inside[[ ... ]]— callspar_condto 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)fromSrc/parse.c:683-720. Emits a minimal wordcode stream for the parsed program into the liveECBUFthread_local via P9b’secadd/ecstrcodeAPI and returns the start index of the emitted Eprog (matching C’sEprog parse_event(...)return). - par_
for_ wordcode - P9c stub: direct port of
par_for(int *complex)from Port ofpar_for(int *cmplx)fromSrc/parse.c:1087-1199. - par_
funcdef_ wordcode - Port of
par_funcdef(int *cmplx)fromSrc/parse.c:1672-1786. - par_
if_ wordcode - Port of
par_if(int *cmplx)fromSrc/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)fromSrc/parse.c:805-816. 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_list(int *cmplx)fromSrc/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)fromSrc/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 BARAMP2>&1synthetic redir. - par_
repeat_ wordcode - Port of
par_repeat(int *cmplx)fromSrc/parse.c:1565-1618. - par_
select_ wordcode selectshares 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:1054par_simple(cmplx, nr)). - par_
simple_ wordcode_ impl - Port of
par_simple(int *cmplx, int nr)fromSrc/parse.c:1836-2227. 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(int *cmplx)fromSrc/parse.c:869. Secondary-sublist arm: handles theCOPROC/Bangprefix in front of a pline. Returns the WC_SUBLIST flag word added. - par_
sublist_ wordcode - Port of
par_sublist(int *cmplx)fromSrc/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 — callspar_subsh_wordcode_impl(false). - par_
subsh_ wordcode_ impl 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(void)fromSrc/parse.c:1787.time PIPEemits WCB_TIMED(WC_TIMED_PIPE) + the sublist code; baretimewith no pipeline emits WCB_TIMED(WC_TIMED_EMPTY). - par_
until_ wordcode untilshares par_while body — tok==UNTIL flips the type.- par_
while_ wordcode - Port of
par_while(int *cmplx)fromSrc/parse.c:1521-1564. - par_
wordlist - Parse a wordlist for
for ... in WORDS;. Direct port of zsh/Src/parse.c:2362par_wordlist. Reads STRING tokens until the next SEPER / SEMI / NEWLIN. - parse
- Parse the complete input. Direct port of
parse_event/par_listfromSrc/parse.c:614-720. On syntax error, setserrflag |= ERRFLAG_ERROR(viazerr) and returns the partial program — callers checkerrflagto detect failure, matching C’sEprog parse_event(...)+if (errflag) {...}. - parse_
cond - Port of
parse_cond(void)fromSrc/parse.c:722. Only used bybin_test/bin_bracketfor/bin/test/[compat — thecondlexglobal must already point attestlexbefore entry. - parse_
context_ restore - Direct port of
parse_context_restore(const struct parse_stack *ps, int toplevel)atSrc/parse.c:326. 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 - Direct port of
parse_context_save(struct parse_stack *ps, int toplevel)atSrc/parse.c:295. Snapshots the lexer-side file-statics (which currently live onlexeruntil 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)fromSrc/parse.c:697. C-shape entry point: drivespar_listand finalizes viabld_eprog. ReturnsNoneon 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
fdheadrecord at the given u32-word offset in the dump buffer. Used by the header-walk loops inbin_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 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(int p, int type, int flags, int skip, int cmplx)fromSrc/parse.c:755. 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(char *path, char *name, char *file, int *ksh, int test_only)fromSrc/parse.c:3746. Tries to load a function from a.zwcin 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)fromSrc/parse.c:3795. Triessource <file>then falls back tosource <file>.zwc. Returns the resolved path on hit. Stub: returns None until the dump-cache port lands. - useeprog
- Port of
void useeprog(Eprog p)fromSrc/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 nextfreeeprog. - write_
dump - Port of
write_dump(int dfd, LinkList progs, int map, int hlen, int tlen)fromSrc/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)fromSrc/parse.c:3656. 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).