@sema-agent/core
Version:
Stateless, task-oriented AI agent core
36 lines (35 loc) • 3.16 kB
TypeScript
/**
* The ONE table of the words bash's grammar owns — and the builtins that move the working directory — with the part each plays for a reader.
*
* "Which word is syntax" is one fact about bash. Every reader that acts on it — the lexer's position walk, the program
* model, the read plan, the binding walk, the tightening reader, the read-only classifier, the rule model — asks it of
* THIS table through {@link shellWordsOf} instead of keeping a set of its own. A role is one question a reader asks of
* a word; a word a reader must know is a row here carrying that role. Adding a keyword is one row.
*
* The table holds every SET of words. A reader that tests the spelling of ONE word on its own (the conditional's `[[`
* and `]]`, the `in` of a loop header, the `for NAME in …; do …; done` shape the poll classifier matches) holds no set
* and compares it. A test reads the source tree for a second set of the table's words, and for a chain of comparisons
* that spells one.
*
* Measured with `compgen -k`: bash 3.2.57 and 5.3 list the same 21 words, and 5.3 adds `coproc`. The structural roles
* `control_prefix`, `group` and `block` partition exactly those 22 (3.2 reads `coproc` as a command name; the
* position walk reads it as syntax all the same — the side that judges more). `((` and `))` are no reserved words:
* they are the arithmetic command's tokens, kept for the one role that refuses every word which cannot name a program.
*
* The table also owns the four builtins that carry the shell's WORKING DIRECTORY — `cd`, `pushd`, `popd`, `dirs` — because
* "which word moves where a command stands" is the same kind of fact (they are no reserved words, so the structural
* roles above do not touch them): the working-directory thread reads where a move leads, the rule model asks whether a
* segment moved the cursor, and the program model's stack rows derive from the same roles. A move word is a row here;
* none of those readers spells the set. (Which programs the read-only classifier admits is another fact — the reference's
* read-only command set — and is not a role of this table.)
*
* Pure data and a pure projection: this module imports nothing.
*/
export declare const SHELL_WORD_ROLES: readonly ["control_prefix", "group", "block", "compound_open", "loop_list_head", "loop_iterates", "loop_condition", "loop_end", "definition", "background", "case_arms", "timer", "scope_open", "scope_close", "scope_switch", "stripped_prefix", "stripped_standalone", "opaque", "rule_reserved", "base_mover", "stack_mover", "stack_editor"];
export type ShellWordRole = (typeof SHELL_WORD_ROLES)[number];
/** Every word that plays `role`. The same set object on every call: a projection is a view, not a copy to edit. */
export declare function shellWordsOf(role: ShellWordRole): ReadonlySet<string>;
/** The roles one word plays, in {@link SHELL_WORD_ROLES} order; empty for a word the table does not own. */
export declare function shellWordRolesOf(word: string): readonly ShellWordRole[];
/** Every word the table owns, in row order. */
export declare function shellWordTable(): readonly string[];