nx_css_parse.nx
buildroot/runtime/nx_css_parse.nx
about
nx_css_parse.nx -- CSS parser for the Nishi browser. Phase 2 (CSS
subset) of docs/NISHI_BROWSER_ROADMAP.md, second primitive after
nx_css_tokenize.nx.
Consumes the CssToken stream produced by nx_css_next_token and
emits a CssRule AST suitable for cascade + apply by nx_css_apply
(next primitive, queued).
Subset:
- one simple selector per rule (TAG / CLASS / ID)
- one or more declarations per rule, separated by ';'
- each declaration's value is ONE of:
NUMBER + UNIT (e.g., "16px" -- emitted as NUMBER then IDENT
by the tokenizer; parser pairs them)
HEXCOLOR (e.g., "#ff0000")
IDENT (e.g., "red" or "sans-serif")
STRING (e.g., "Arial")
- rules are separated by whitespace (no comma-separated selector
lists in Phase 2 -- one selector per rule, repeated for groups)
What it does NOT handle yet (named Phase 2b improvements):
- selector lists with commas (group as multiple rules)
- compound selectors (h1.foo#bar) (one type/class/id per rule)
- descendant chains (header h1) (single simple selector only)
- multi-token values (margin: 8px 16px;)
- !important
- shorthand expansion (border, font, margin)
- @-rules (silently skipped to next rule)
Subset is sufficient to drive nx_css_apply on andelinwest.com-class
hand-written CSS. Per cardinal feedback-honest-perf-verdict: gap
list is EXACT.
genealogy_id: w3c_css_syntax_module_level_3_parser_section +
substrate_browser_phase_2_second_primitive
lineage_id: nishi_browser_css_parse_v1
nx_safety_envelope:
intended_use: "CSS parser -- browser front-end style apply"
sil_target: SIL1
dependencies 2 imports · 26 importers
diagram shows first 10 each side; +0 more imports, +16 more importers in the complete lists below.
imports: nx_syscalls.nxnx_css_tokenize.nx
imported by: nx_align_gate.nxnx_css_apply.nxnx_css_apply_test.nxnx_css_boxmap_test.nxnx_css_cascade_test.nxnx_css_parse_test.nxnx_css_selector_match.nxnx_css_selector_match_test.nxnx_flexgrow_gate.nxnx_flexgrow_probe.nxnx_float_gate.nxnx_float_test.nxnx_grid_gate.nxnx_grid_test.nxnx_grid_track_gate.nxnx_justify_gate.nxnx_layout_block.nxnx_layout_block_horizontal_test.nxnx_layout_block_test.nxnx_layout_debug.nxnx_negmargin_gate.nxnx_real_page_gate.nxnx_render_html.nxnx_render_wiki_styled_window.nxnx_table_cell_gate.nxnx_wiki_boxdump.nx
structs
| 72 | struct CssDeclaration |
| 86 | struct CssRule |
| 101 | struct CssParseState |
consts
| 50 | const NX_MAGIC_8192: i64 = 8192 |
| 51 | const NX_MAGIC_65536: i64 = 65536 |
| 54 | const NX_CSS_SEL_UNKNOWN: i64 = 0 |
| 55 | const NX_CSS_SEL_TAG: i64 = 1 // body, div, h1 |
| 56 | const NX_CSS_SEL_CLASS: i64 = 2 // .head, .menu-item |
| 57 | const NX_CSS_SEL_ID: i64 = 3 // #main |
| 58 | const NX_CSS_SEL_N: i64 = 4 |
| 62 | const NX_CSS_VAL_UNKNOWN: i64 = 0 |
| 63 | const NX_CSS_VAL_NUMBER: i64 = 1 // bare number, no unit |
| 64 | const NX_CSS_VAL_DIMENSION: i64 = 2 // number + unit ident (16px, 1.5em) |
| 65 | const NX_CSS_VAL_HEXCOLOR: i64 = 3 // #ff0000 / #fff |
| 66 | const NX_CSS_VAL_IDENT: i64 = 4 // red, sans-serif, auto |
| 67 | const NX_CSS_VAL_STRING: i64 = 5 // "Arial" |
| 68 | const NX_CSS_VAL_N: i64 = 6 |
| 82 | const NX_CSS_DECLARATION_BYTES: i64 = 56 |
| 96 | const NX_CSS_RULE_BYTES: i64 = 56 |
| 113 | const NX_CSS_PARSE_STATE_BYTES: i64 = 72 |
functions
| 119 | func _css_advance_skip_ws(st: *CssParseState) -> i64 |
| 140 | func _css_advance_one(st: *CssParseState) -> i64 called by 3: _css_parse_selector_css_consume_value_rest_css_parse_declaration calls 1: nx_css_next_token |
| 156 | func _css_parse_selector(st: *CssParseState) -> i64 |
| 199 | func _css_consume_value_rest(st: *CssParseState, d: *CssDeclaration) -> i64 |
| 232 | func _css_parse_declaration(st: *CssParseState) -> i64 |
| 348 | func nx_css_parse_state_init(st: *CssParseState, |
| 371 | func nx_css_parse(st: *CssParseState) -> i64 called by 20: run_layoutbr_layoutbr_layoutmainmainmain+14 calls 3: _css_advance_skip_ws_css_parse_selector_css_parse_declaration |