code wiki / _hdl_build / nx_justify_gate.nx

nx_justify_gate.nx source

↩ module page · 151 lines · 8525 B

1// nx_justify_gate.nx -- VERDICT gate for flexbox justify-content (main-axis distribution). 3 items x 100px 2// in an 800px flex container => 500px FREE to distribute. Asserts exact item x positions for center / 3// flex-end / space-between vs the flex-start CONTROL (proves justify actually moves items, not a no-op). 4// LIAR-KILL: a wrong expectation is rejected. 100% sovereign nx_cc->nxasm. license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_css_tokenize.nx" 7import "nx_css_parse.nx" 8import "nx_css_apply.nx" 9import "nx_css_color_decode.nx" 10import "nx_css_dimension_to_px.nx" 11import "nx_css_selector_match.nx" 12import "nx_html_tokenizer.nx" 13import "nx_dom_query.nx" 14import "nx_layout_box.nx" 15import "nx_layout_default_display.nx" 16import "nx_layout_from_dom.nx" 17import "nx_layout_block.nx" 18import "nx_render_html.nx" 19 20func g_w(s: *u8) -> i64 { var k: i64=0; while s[k]!=(0 as u8){k=k+1} sys_write(1,s,k); return 0 } 21func pn(v0: i64) -> i64 { var v: i64=v0; if v<0 { let m: *u8=sys_mmap(8); m[0]=45 as u8; sys_write(1,m,1); v=0-v } let b: *u8=sys_mmap(24); var k: i64=0; if v==0 {b[0]=48;k=1} while v>0 {b[k]=(48+(v%10)) as u8; v=v/10; k=k+1} let o: *u8=sys_mmap(24); var j: i64=0; while j<k {o[j]=b[k-1-j];j=j+1} sys_write(1,o,k); return 0 } 22 23func run_layout(html: *u8, css: *u8, vw: i64, tree_out: **LayoutTree, boxel_out: **CssElement, buf_out: **u8) -> i64 { 24 var hlen: i64 = 0 25 while html[hlen]!=(0 as u8) { hlen=hlen+1 } 26 var clen: i64 = 0 27 while css[clen]!=(0 as u8) { clen=clen+1 } 28 let total: i64 = hlen + clen 29 let buf: *u8 = sys_mmap(total + 16) 30 var i: i64 = 0 31 while i < hlen { buf[i]=html[i]; i=i+1 } 32 var j: i64 = 0 33 while j < clen { buf[hlen+j]=css[j]; j=j+1 } 34 let boxes: *LayoutBox = (sys_mmap(NX_LAYOUT_BOX_BYTES*1024+16)) as *LayoutBox 35 let tree: *LayoutTree = (sys_mmap(64)) as *LayoutTree 36 nx_layout_tree_init(tree, boxes, 1024) 37 let stk: *LayoutFromDomStack = (sys_mmap(NX_LAYOUT_FROM_DOM_STACK_BYTES+8)) as *LayoutFromDomStack 38 let sidx: *i64 = (sys_mmap(8*64)) as *i64 39 nx_layout_from_dom_stack_init(stk, sidx, 64) 40 nx_layout_from_dom(buf, hlen, tree, stk) 41 let ext: *CssElement = (sys_mmap(NX_CSS_ELEMENT_BYTES*1024 as nx_size)) as *CssElement 42 let n_ext: i64 = rh_extract(buf, hlen, ext, 1024) 43 let boxel: *CssElement = (sys_mmap((NX_CSS_ELEMENT_BYTES*(tree.count+1)) as nx_size)) as *CssElement 44 var k: i64 = 0 45 i = 0 46 while i < tree.count { 47 let bb: *LayoutBox = ((tree.boxes as i64)+i*NX_LAYOUT_BOX_BYTES) as *LayoutBox 48 let e: *CssElement = ((boxel as i64)+i*NX_CSS_ELEMENT_BYTES) as *CssElement 49 e.src = buf 50 var mapped: i64 = 0 51 if rh_is_elem(bb.kind)==1 { if bb.parent_idx != (0-1) { if k < n_ext { 52 let s: *CssElement = ((ext as i64)+k*NX_CSS_ELEMENT_BYTES) as *CssElement 53 e.tag_off=s.tag_off; e.tag_len=s.tag_len; e.id_off=s.id_off; e.id_len=s.id_len; e.class_off=s.class_off; e.class_len=s.class_len 54 k=k+1; mapped=1 55 } } } 56 if mapped==0 { e.tag_off=0; e.tag_len=0; e.id_off=0; e.id_len=0; e.class_off=0; e.class_len=0 } 57 i=i+1 58 } 59 let cur: *CssCursor = (sys_mmap(NX_CSS_CURSOR_BYTES) as nx_size) as *CssCursor 60 nx_css_cursor_init(cur, buf, total); cur.pos = hlen 61 let tok: *CssToken = (sys_mmap(NX_CSS_TOKEN_BYTES) as nx_size) as *CssToken 62 let rules: *CssRule = (sys_mmap(NX_CSS_RULE_BYTES*512 as nx_size)) as *CssRule 63 let decls: *CssDeclaration = (sys_mmap(NX_CSS_DECLARATION_BYTES*512 as nx_size)) as *CssDeclaration 64 let st: *CssParseState = (sys_mmap(128) as nx_size) as *CssParseState 65 nx_css_parse_state_init(st, cur, tok, rules, 512, decls, 512) 66 nx_css_parse(st) 67 let computed: *CssComputedDecl = (sys_mmap(NX_CSS_COMPUTED_DECL_BYTES*4096 as nx_size)) as *CssComputedDecl 68 let cb: *i64 = (sys_mmap(8)) as *i64 69 rh_cascade(buf, rules, st.rule_count, decls, st.decl_count, boxel, tree.count, tree, computed, 4096, cb) 70 let ncomp: i64 = cb[0] 71 let pbuf: *u8 = sys_mmap(256) 72 let ltable: *LayoutPropTable = (sys_mmap(NX_LAYOUT_PROP_TABLE_BYTES)) as *LayoutPropTable 73 nx_layout_prop_table_init(ltable, pbuf) 74 let resolve: *CssResolveCtx = (sys_mmap(NX_CSS_RESOLVE_CTX_BYTES)) as *CssResolveCtx 75 resolve.root_font_size_px = 16; resolve.parent_font_size_px = 16; resolve.parent_dimension_px = vw 76 let lctx: *LayoutCtx = (sys_mmap(NX_LAYOUT_CTX_BYTES)) as *LayoutCtx 77 nx_layout_ctx_init(lctx, tree, computed, ncomp, buf, vw, resolve) 78 nx_layout_block_layout(lctx, ltable, 0) 79 tree_out[0] = tree; boxel_out[0] = boxel; buf_out[0] = buf 80 return 0 81} 82// find the nth (0-based) box whose mapped tag == `tag` 83func find_tag(tree: *LayoutTree, boxel: *CssElement, buf: *u8, tag: *u8, nth: i64) -> i64 { 84 var tl: i64 = 0 85 while tag[tl]!=(0 as u8) { tl=tl+1 } 86 var seen: i64 = 0 87 var i: i64 = 0 88 while i < tree.count { 89 let e: *CssElement = ((boxel as i64)+i*NX_CSS_ELEMENT_BYTES) as *CssElement 90 if e.tag_len == tl { 91 var ok: i64 = 1; var j: i64 = 0 92 while j < tl { if (buf[e.tag_off+j]&0xff) != (tag[j]&0xff) { ok=0; j=tl } else { j=j+1 } } 93 if ok==1 { if seen==nth { return i } seen=seen+1 } 94 } 95 i = i + 1 96 } 97 return 0 - 1 98} 99func box_x(tree: *LayoutTree, i: i64) -> i64 { let b: *LayoutBox = ((tree.boxes as i64)+i*NX_LAYOUT_BOX_BYTES) as *LayoutBox; return b.x } 100func chkx(tree: *LayoutTree, boxel: *CssElement, buf: *u8, item: i64, want: i64, label: *u8, pass: *i64) -> i64 { 101 let bi: i64 = find_tag(tree, boxel, buf, "div\x00" as *u8, item) // div0=#c container, div1..3 = items 102 let got: i64 = box_x(tree, bi) 103 g_w(" " as *u8); g_w(label); g_w(": " as *u8) 104 if got==want { g_w("OK (x=" as *u8); pn(got); g_w(")\n" as *u8); pass[0]=pass[0]+1 } 105 else { g_w("FAIL got x=" as *u8); pn(got); g_w(" want " as *u8); pn(want); g_w("\n" as *u8) } 106 return 0 107} 108 109func main() -> i64 { 110 let pass: *i64 = sys_mmap(8) as *i64; pass[0]=0 111 g_w("=== JUSTIFY-CONTENT GATE (flex main-axis distribution, sovereign) ===\n" as *u8) 112 let html: *u8 = "<div id=\"c\"><div class=\"i\">A</div><div class=\"i\">B</div><div class=\"i\">C</div></div>\x00" as *u8 113 let tp: **LayoutTree = sys_mmap(8) as **LayoutTree 114 let bp: **CssElement = sys_mmap(8) as **CssElement 115 let up: **u8 = sys_mmap(8) as **u8 116 117 // CONTROL flex-start: items packed at 0,100,200 (proves the others actually move them) 118 run_layout(html, "#c{display:flex}.i{width:100px;height:20px}\x00" as *u8, 800, tp, bp, up) 119 g_w("flex-start control (items 0,100,200)\n" as *u8) 120 chkx(tp[0], bp[0], up[0], 1, 0, "item A x=0\x00" as *u8, pass) 121 chkx(tp[0], bp[0], up[0], 3, 200, "item C x=200\x00" as *u8, pass) 122 123 // center: free=500 -> start 250 -> items 250,350,450 124 run_layout(html, "#c{display:flex;justify-content:center}.i{width:100px;height:20px}\x00" as *u8, 800, tp, bp, up) 125 g_w("justify-content:center (items 250,350,450)\n" as *u8) 126 chkx(tp[0], bp[0], up[0], 1, 250, "item A x=250\x00" as *u8, pass) 127 chkx(tp[0], bp[0], up[0], 3, 450, "item C x=450\x00" as *u8, pass) 128 129 // flex-end: start 500 -> items 500,600,700 130 run_layout(html, "#c{display:flex;justify-content:flex-end}.i{width:100px;height:20px}\x00" as *u8, 800, tp, bp, up) 131 g_w("justify-content:flex-end (items 500,600,700)\n" as *u8) 132 chkx(tp[0], bp[0], up[0], 1, 500, "item A x=500\x00" as *u8, pass) 133 chkx(tp[0], bp[0], up[0], 3, 700, "item C x=700\x00" as *u8, pass) 134 135 // space-between: spacing=250 -> items 0,350,700 136 run_layout(html, "#c{display:flex;justify-content:space-between}.i{width:100px;height:20px}\x00" as *u8, 800, tp, bp, up) 137 g_w("justify-content:space-between (items 0,350,700)\n" as *u8) 138 chkx(tp[0], bp[0], up[0], 1, 0, "item A x=0\x00" as *u8, pass) 139 chkx(tp[0], bp[0], up[0], 2, 350, "item B x=350\x00" as *u8, pass) 140 chkx(tp[0], bp[0], up[0], 3, 700, "item C x=700\x00" as *u8, pass) 141 142 // LIAR-KILL: in the space-between layout, item A is NOT at 250 (a wrong claim must be rejected) 143 let bi: i64 = find_tag(tp[0], bp[0], up[0], "div\x00" as *u8, 1) 144 g_w("LIAR-KILL (wrong position rejected)\n" as *u8) 145 g_w(" item A x != 250: " as *u8) 146 if box_x(tp[0], bi) != 250 { g_w("OK\n" as *u8); pass[0]=pass[0]+1 } else { g_w("FAIL\n" as *u8) } 147 148 g_w("JUSTIFY rows=10 pass=" as *u8); pn(pass[0]) 149 if pass[0]==10 { g_w(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 150 g_w(" verdict=RED\n" as *u8); sys_exit(1); return 1 151}