code wiki / (root) / nx_js_lex.nx

nx_js_lex.nx

buildroot/runtime/nx_js_lex.nx

33002 B653 linesdepth 3pulls 3 transitivereach 144 importersview sourcekind tooltopic js
docsdependenciesstructsconstsfunctions

about

nx_js_lex.nx -- R-JS-LEX (WB-JS-001 rung 0): the ECMAScript TOKENIZER, the hardware-up floor of the sovereign JS engine (browser-engine-exceed roadmap ยง2). Founds R-JS-PARSE above it (no-floating law: the lexer is built+gated before any parser rides it). Shape = STATE_MACHINE/STRUCT_WALK over source bytes -- an EXISTING emitter shape, so team-authorable now (NOT blocked on X-AUT-006c). Scans ECMAScript source into a flat token stream (3 i64 slots per token: kind, start-offset, byte-length). Covers the lexical core real JS uses: - whitespace + line-terminators (skipped; ASI is a PARSER concern, rung 1) - // line comments and /* block */ comments (skipped) - identifiers + keywords ($ and _ legal; keyword set classified) - numeric literals: decimal int/float, exponent, 0x/0o/0b prefixes - string literals ' and " with backslash-escape handling (\" \' \\ \n ...) - punctuators incl. multi-char operators (=== !== >>>= => ?. ?? ** etc.) - unterminated string -> ERROR token (honest, never silently swallowed) HONEST RUNG-0 SCOPE (named OPEN, NOT faked): template literals (`...${}`) and regex-literal disambiguation need PARSER context (is `/` a divide or a regex?), so they are R-JS-LEX-0b, built once the parser can feed back context. BigInt `n` suffix + full Unicode IdentifierStart are also 0b. Rung 0 tokenizes ASCII JS. GATE (main): 7 KATs assert the exact token stream (kind + lexeme) on real JS snippets + TAMPER (unterminated string must be ERROR, never a fabricated STRING). Self-validating; exit 0 iff all pass; appends knowledge/status/js_engine.log. license_tier: ORIGINAL (tutor-bootstrap scaffold; team re-authors from the R-JS-LEX data spec via author=organ -- (B)-debt, mirror the h2 capstone note.)

dependencies 2 imports · 1 importers

nx_syscalls.nx nx_itoa_lib.nx nx_js_lex.nx nx_js_parse.nx

imports: nx_syscalls.nxnx_itoa_lib.nx

imported by: nx_js_parse.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap jl_puts sys_write js_lex js_skip_trivia js_is_space js_lex_one js_is_idstart js_is_alpha js_scan_ident js_is_idpart js_is_idstart ↻ js_is_digit js_is_keyword js_lexeme_eq js_emit js_num_starts js_is_digit ↻ js_scan_number js_scan_while_hex js_is_hex js_is_digit ↻ js_scan_while_digit js_is_digit ↻ js_scan_exp js_scan_while_digit ↻ js_lex_string js_scan_string js_emit ↻ js_lex_template js_emit ↻ js_regex_context js_lexeme_eq ↻ js_lex_regex js_emit ↻ js_punct_len js_is_digit ↻ jl_strlen js_expect

structs

none

consts

31const JS_TOK_EOF: i64 = 0
32const JS_TOK_IDENT: i64 = 1
33const JS_TOK_KEYWORD: i64 = 2
34const JS_TOK_NUMBER: i64 = 3
35const JS_TOK_STRING: i64 = 4
36const JS_TOK_PUNCT: i64 = 5
37const JS_TOK_ERROR: i64 = 8
38const JS_TOK_TEMPLATE: i64 = 9 // template literal: whole span incl both backticks; interior re-lexed at eval
39const JS_TOK_REGEX: i64 = 10 // regex literal /pattern/flags: whole span; pattern+flags extracted at eval

functions

42func js_is_digit(c: i64) -> i64 { if c >= 48 { if c <= 57 { return 1 } } return 0 }
43func js_is_alpha(c: i64) -> i64
called by 1: js_is_idstart
62func js_is_idstart(c: i64) -> i64
called by 2: js_is_idpartjs_lex_one calls 1: js_is_alpha
69func js_is_idpart(c: i64) -> i64
74func js_is_hex(c: i64) -> i64
called by 1: js_scan_while_hex calls 1: js_is_digit
80func js_is_space(c: i64) -> i64
called by 1: js_skip_trivia
91func js_lexeme_eq(src: *u8, start: i64, len: i64, lit: *u8) -> i64
103func js_is_keyword(src: *u8, start: i64, len: i64) -> i64
called by 1: js_lex_one calls 1: js_lexeme_eq
146func js_scan_ident(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_lex_one calls 1: js_is_idpart
155func js_scan_while_digit(src: *u8, srclen: i64, pos: i64) -> i64
164func js_scan_while_hex(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_scan_number calls 1: js_is_hex
173func js_scan_exp(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_scan_number calls 1: js_scan_while_digit
183func js_scan_number(src: *u8, srclen: i64, pos: i64) -> i64
208func js_scan_string(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_lex_string
229func js_punct_len(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_lex_one calls 1: js_is_digit
307func js_skip_trivia(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_lex calls 1: js_is_space
341func js_emit(toks: *i64, ntok_box: *i64, kind: i64, start: i64, len: i64) -> i64
350func js_num_starts(src: *u8, srclen: i64, pos: i64) -> i64
called by 1: js_lex_one calls 1: js_is_digit
357func js_lex_string(src: *u8, srclen: i64, pos: i64, toks: *i64, ntok_box: *i64) -> i64
called by 1: js_lex_one calls 2: js_scan_stringjs_emit
369func js_lex_template(src: *u8, srclen: i64, pos: i64, toks: *i64, ntok_box: *i64) -> i64
called by 1: js_lex_one calls 1: js_emit
406func js_regex_context(toks: *i64, ntok: i64, src: *u8) -> i64
called by 1: js_lex_one calls 1: js_lexeme_eq
434func js_lex_regex(src: *u8, srclen: i64, pos: i64, toks: *i64, ntok_box: *i64) -> i64
called by 1: js_lex_one calls 1: js_emit
457func js_lex_one(src: *u8, srclen: i64, pos: i64, toks: *i64, ntok_box: *i64) -> i64
482func js_lex(src: *u8, srclen: i64, toks: *i64, maxtoks: i64, ntok_box: *i64) -> i64
496func jl_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
called by 1: main calls 1: sys_write
501func jl_putn(v: i64) -> i64 { nxi_out(v); return 0 }
called by 1: main calls 1: nxi_out
502func jl_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
called by 1: main
504func js_expect(toks: *i64, ntok: i64, idx: i64, kind: i64, src: *u8, lit: *u8) -> i64
called by 1: main calls 1: js_lexeme_eq
510func main() -> i64
653func jl_fdn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }