code wiki / _hdl_build / nx_regex_gate.nx

nx_regex_gate.nx source

↩ module page · 77 lines · 5650 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_regex_gate.nx -- SOVEREIGN referee for the regex engine. Exercises literals, ., classes (ranges/neg/predef), 4// \d\w\s, anchors ^ $, quantifiers * + ? {n} {n,m} greedy+lazy, groups (capturing + (?:)), alternation, \b, 5// icase, plus capture-group offsets + a compile-DECLINE for unsupported lookahead. GREEN iff all pass. 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_rxfull.nx" 9 10func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 11" as *u8); return ok } 12func gsl(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 13 14// run pat/flags on subj. es>=0 = expected match-start (and ee=expected end); es=-1 = expect NO match; 15// es=-2 = expect compile DECLINE (re.ok==0). returns 1 pass / 0 fail. 16func rt(pat: *u8, flags: i64, subj: *u8, es: i64, ee: i64) -> i64 { 17 let re: *Regex = nx_regex_compile(pat, gsl(pat), flags) 18 if re.ok == 0 { if es == 0 - 2 { return 1 } return 0 } 19 if es == 0 - 2 { return 0 } 20 let saves: *i64 = sys_mmap(re.nsave * 8) as *i64 21 let ms: i64 = nx_regex_exec(re, subj, gsl(subj), 0, saves) 22 if es == 0 - 1 { if ms < 0 { return 1 } return 0 } 23 if ms != es { return 0 } 24 if saves[1] != ee { return 0 } 25 return 1 26} 27// check capture group g offsets == [lo,hi] 28func rg(pat: *u8, subj: *u8, g: i64, lo: i64, hi: i64) -> i64 { 29 let re: *Regex = nx_regex_compile(pat, gsl(pat), 0) 30 if re.ok == 0 { return 0 } 31 let saves: *i64 = sys_mmap(re.nsave * 8) as *i64 32 if nx_regex_exec(re, subj, gsl(subj), 0, saves) < 0 { return 0 } 33 if saves[2 * g] != lo { return 0 } 34 if saves[2 * g + 1] != hi { return 0 } 35 return 1 36} 37 38func main() -> i64 { 39 gw("regex SOVEREIGN gate (Cox-VM: literals/./classes/anchors/quantifiers/groups/alt/\\b/icase + captures)\n" as *u8) 40 var pass: i64 = 0 41 var ttl: i64 = 0 42 43 ttl=ttl+1; pass=pass+grow("R1 literal 'abc' in 'xabcy' @1-4\x00" as *u8, rt("abc" as *u8, 0, "xabcy" as *u8, 1, 4)) 44 ttl=ttl+1; pass=pass+grow("R2 'abc' NO match in 'xyz'\x00" as *u8, rt("abc" as *u8, 0, "xyz" as *u8, 0-1, 0)) 45 ttl=ttl+1; pass=pass+grow("R3 'a.c' matches 'axc'\x00" as *u8, rt("a.c" as *u8, 0, "axc" as *u8, 0, 3)) 46 ttl=ttl+1; pass=pass+grow("R4 'a.c' NO match 'ac' (. needs a char)\x00" as *u8, rt("a.c" as *u8, 0, "ac" as *u8, 0-1, 0)) 47 ttl=ttl+1; pass=pass+grow("R5 '[a-z]+' in ' hi5' @2-4\x00" as *u8, rt("[a-z]+" as *u8, 0, " hi5" as *u8, 2, 4)) 48 ttl=ttl+1; pass=pass+grow("R6 '\\d+' in 'ab123c' @2-5\x00" as *u8, rt("\\d+" as *u8, 0, "ab123c" as *u8, 2, 5)) 49 ttl=ttl+1; pass=pass+grow("R7 '^\\d+$' matches '456'\x00" as *u8, rt("^\\d+$" as *u8, 0, "456" as *u8, 0, 3)) 50 ttl=ttl+1; pass=pass+grow("R8 '^\\d+$' NO match '45a'\x00" as *u8, rt("^\\d+$" as *u8, 0, "45a" as *u8, 0-1, 0)) 51 ttl=ttl+1; pass=pass+grow("R9 'colou?r' matches 'color'\x00" as *u8, rt("colou?r" as *u8, 0, "color" as *u8, 0, 5)) 52 ttl=ttl+1; pass=pass+grow("R10 'colou?r' matches 'colour'\x00" as *u8, rt("colou?r" as *u8, 0, "colour" as *u8, 0, 6)) 53 ttl=ttl+1; pass=pass+grow("R11 'a*' greedy 'aaab' @0-3\x00" as *u8, rt("a*" as *u8, 0, "aaab" as *u8, 0, 3)) 54 ttl=ttl+1; pass=pass+grow("R12 'a*' empty match 'bbb' @0-0\x00" as *u8, rt("a*" as *u8, 0, "bbb" as *u8, 0, 0)) 55 ttl=ttl+1; pass=pass+grow("R13 '[^0-9]+' in 'abc12' @0-3\x00" as *u8, rt("[^0-9]+" as *u8, 0, "abc12" as *u8, 0, 3)) 56 ttl=ttl+1; pass=pass+grow("R14 '(?:ab)+' in 'ababx' @0-4\x00" as *u8, rt("(?:ab)+" as *u8, 0, "ababx" as *u8, 0, 4)) 57 ttl=ttl+1; pass=pass+grow("R15 '\\bword\\b' in 'a word x' @2-6\x00" as *u8, rt("\\bword\\b" as *u8, 0, "a word x" as *u8, 2, 6)) 58 ttl=ttl+1; pass=pass+grow("R16 '\\bword\\b' NO match 'swordfish'\x00" as *u8, rt("\\bword\\b" as *u8, 0, "swordfish" as *u8, 0-1, 0)) 59 ttl=ttl+1; pass=pass+grow("R17 'a{2,3}' greedy 'aaaa' @0-3\x00" as *u8, rt("a{2,3}" as *u8, 0, "aaaa" as *u8, 0, 3)) 60 ttl=ttl+1; pass=pass+grow("R18 'a{2,3}?' lazy 'aaaa' @0-2\x00" as *u8, rt("a{2,3}?" as *u8, 0, "aaaa" as *u8, 0, 2)) 61 ttl=ttl+1; pass=pass+grow("R19 'a{2}' exact 'aaa' @0-2\x00" as *u8, rt("a{2}" as *u8, 0, "aaa" as *u8, 0, 2)) 62 ttl=ttl+1; pass=pass+grow("R20 'cat|dog|bird' in 'my dog runs' @3-6\x00" as *u8, rt("cat|dog|bird" as *u8, 0, "my dog runs" as *u8, 3, 6)) 63 ttl=ttl+1; pass=pass+grow("R21 icase 'abc' in 'XABCY' @1-4\x00" as *u8, rt("abc" as *u8, RXF_I, "XABCY" as *u8, 1, 4)) 64 ttl=ttl+1; pass=pass+grow("R22 '\\w+' in ' he_llo x' @2-8\x00" as *u8, rt("\\w+" as *u8, 0, " he_llo x" as *u8, 2, 8)) 65 ttl=ttl+1; pass=pass+grow("R23 'a.*?b' lazy 'axbxb' @0-3\x00" as *u8, rt("a.*?b" as *u8, 0, "axbxb" as *u8, 0, 3)) 66 ttl=ttl+1; pass=pass+grow("R24 'a.*b' greedy 'axbxb' @0-5\x00" as *u8, rt("a.*b" as *u8, 0, "axbxb" as *u8, 0, 5)) 67 ttl=ttl+1; pass=pass+grow("R25 '(?=x)' lookahead DECLINES\x00" as *u8, rt("(?=x)" as *u8, 0, "x" as *u8, 0-2, 0)) 68 69 // capture groups 70 ttl=ttl+1; pass=pass+grow("G1 '(foo|bar)baz' on 'barbaz' g1=[0,3]\x00" as *u8, rg("(foo|bar)baz" as *u8, "barbaz" as *u8, 1, 0, 3)) 71 ttl=ttl+1; pass=pass+grow("G2 '(\\d+)-(\\d+)' on '12-345' g2=[3,6]\x00" as *u8, rg("(\\d+)-(\\d+)" as *u8, "12-345" as *u8, 2, 3, 6)) 72 ttl=ttl+1; pass=pass+grow("G3 '((a)(b))' on 'ab' g3=[1,2]\x00" as *u8, rg("((a)(b))" as *u8, "ab" as *u8, 3, 1, 2)) 73 74 gw("pass=" as *u8); gn(pass); gw("/" as *u8); gn(ttl); gw("\n" as *u8) 75 if pass == ttl { gw("verdict=GREEN (sovereign regex engine: full feature set + captures, step+depth bounded)\n" as *u8); sys_exit(0); return 0 } 76 gw("verdict=RED\n" as *u8); sys_exit(1); return 1 77}