compiler/
lib/
examples/
std/
arch/
rv64/
tests/
abi.sizes.rad
3.4 KiB
aggregate.return.rad
4.0 KiB
arith.assignment.rad
580 B
arith.basic.rad
176 B
arith.modulo.rad
96 B
arith.subword.rad
3.8 KiB
arith.sum.rad
177 B
arith.w64.rad
4.1 KiB
array.assign.rad
221 B
array.bounds.check.rad
321 B
array.index.assign.rad
367 B
array.index.rad
249 B
array.length.rad
262 B
array.math.rad
1.2 KiB
array.nested.assign.rad
319 B
array.nested.rad
325 B
array.record.elements.rad
1.7 KiB
array.repeat.edge.rad
548 B
array.repeat.rad
828 B
array.return.rad
330 B
array.slice.empty.rad
108 B
array.slice.gen.end.rad
126 B
array.slice.gen.index.rad
139 B
array.slice.gen.open.rad
125 B
array.slice.gen.start.end.rad
127 B
array.slice.gen.start.rad
126 B
array.slice.rad
759 B
as.precedence.rad
212 B
assert.basic.rad
387 B
assert.fail.rad
138 B
assert.false.rad
140 B
assert.true.rad
100 B
assign.mutable.rad
6.1 KiB
assign.rad
129 B
assign.shadow.mutable.rad
461 B
binop.bitwise.rad
1.2 KiB
binop.cmp.rad
426 B
bool.comparison.array.rad
688 B
bool.comparison.nested.gen.rad
1.0 KiB
bool.comparison.opt.rad
905 B
bool.comparison.record.gen.rad
1.0 KiB
bool.comparison.record.rad
1.1 KiB
bool.comparison.slice.gen.rad
157 B
bool.comparison.slice.rad
4.1 KiB
bool.comparison.slice.record.gen.rad
2.0 KiB
bool.comparison.slice.union.gen.rad
2.5 KiB
bool.comparison.union.ctor.rad
690 B
bool.comparison.union.gen.rad
1.2 KiB
bool.comparison.union.record.gen.rad
1.5 KiB
bool.comparison.union.simple.gen.rad
281 B
bool.operators.complex.rad
384 B
bool.operators.rad
831 B
bool.short.circuit.rad
2.3 KiB
bool.simple.rad
194 B
bool.values.rad
772 B
builtin.size.align.rad
1.3 KiB
builtin.sliceof.mut.rad
606 B
builtin.sliceof.rad
505 B
call.arg.clobber.rad
717 B
call.basic.rad
241 B
call.clobber.rad
462 B
cast.same.size.rad
1.0 KiB
casting.numbers.rad
1.5 KiB
char.literal.rad
165 B
compound.assign.field.rad
285 B
compound.assign.rad
1.1 KiB
cond.assign.rad
723 B
cond.expr.aggregate.rad
1.1 KiB
cond.expr.rad
1.8 KiB
cond.for.else.break.rad
326 B
cond.for.indexed.rad
238 B
cond.for.rad
165 B
cond.for.range.indexed.rad
526 B
cond.for.range.rad
171 B
cond.for.unsigned.range.rad
644 B
cond.forever.break.continue.rad
182 B
cond.forever.break.rad
232 B
cond.fused.rad
926 B
cond.if.case.rad
2.2 KiB
cond.if.else.min.rad
143 B
cond.if.else.rad
225 B
cond.if.elseif.rad
420 B
cond.if.noelse.rad
120 B
cond.if.rad
865 B
cond.match.fallthrough.rad
369 B
cond.match.guard.rad
1.4 KiB
cond.match.guard.regalloc.rad
1.3 KiB
cond.while.else.break.rad
282 B
cond.while.rad
119 B
const.array.copy.mutate.rad
386 B
const.array.rad
195 B
const.basic.rad
325 B
const.char.rad
159 B
const.fn.array.rad
664 B
const.record.array.rad
1.2 KiB
const.record.array.simple.rad
523 B
const.record.ctor.rad
170 B
const.record.fn.rad
353 B
const.record.rad
182 B
const.slice.param.rad
333 B
const.union.payload.ctor.rad
349 B
const.union.record.literal.rad
359 B
data.array.rad
767 B
data.bool.rad
216 B
data.i16.rad
261 B
data.i32.rad
281 B
data.i8.rad
248 B
data.record.rad
561 B
data.simple.rad
436 B
data.u16.rad
220 B
data.u32.rad
240 B
data.u8.rad
208 B
data.union.rad
886 B
debug.tag.rad
557 B
edge.cases.2.rad
337 B
edge.cases.3.rad
594 B
edge.cases.4.rad
1.2 KiB
edge.cases.5.rad
1.0 KiB
edge.cases.6.rad
2.6 KiB
edge.cases.7.addr.bug.rad
224 B
edge.cases.8.bug.rad
508 B
edge.cases.rad
223 B
error.basic.rad
159 B
error.catch.rad
1.6 KiB
error.division.zero.rad
164 B
error.modulo.zero.rad
162 B
error.multi.basic.rad
672 B
error.multi.catch.rad
772 B
error.multi.catch.typed.binding.rad
791 B
error.multi.catch.typed.catchall.rad
1.0 KiB
error.multi.catch.typed.rad
1.1 KiB
error.multi.propagate.multi.rad
953 B
error.multi.propagate.rad
825 B
error.multi.try.optional.rad
507 B
error.slice.bounds.rad
219 B
error.try.bang.success.rad
370 B
error.try.catch.binding.rad
2.0 KiB
error.try.optional.rad
1.8 KiB
error.try.rad
4.0 KiB
fn.block.scope.rad
508 B
fn.callback.nested.rad
1.2 KiB
fn.default.rad
131 B
fn.local.rad
140 B
fn.recursion.2.rad
239 B
fn.void.rad
150 B
for.else.continue.rad
1.1 KiB
frame.large.rad
567 B
if-let-mut.rad
1.1 KiB
iflet.shadow.leak.rad
317 B
integer.bitwise.basic.rad
693 B
integer.overflow.rad
1.8 KiB
large.blit.store.rad
2.1 KiB
let.guard.rad
1.9 KiB
literal.w64.rad
1.7 KiB
loc.addr.offset.bug.rad
410 B
loc.addr.opt.to.opt.rad
433 B
loc.addr.optional.assign.rad
408 B
loc.addr.record.assign.rad
443 B
loop.complex.flow.rad
1007 B
loop.sealblock.rad
911 B
match.array.rad
3.4 KiB
match.char.rad
1.6 KiB
match.multi.seal.rad
987 B
match.multi.survive.rad
1.6 KiB
match.mutref.push.rad
1.0 KiB
match.mutref.union.rad
662 B
match.nested.call.rad
1.7 KiB
match.nested.deep.rad
2.2 KiB
match.nested.deref.rad
3.7 KiB
match.nested.guard.rad
1.6 KiB
match.nested.iflet.guard.rad
1.6 KiB
match.nested.iflet.rad
1.4 KiB
match.nested.letelse.rad
813 B
match.nested.letelse.union.rad
1.3 KiB
match.nested.literal.rad
3.1 KiB
match.nested.multi.rad
2.4 KiB
match.nested.pattern.rad
5.2 KiB
match.nested.record.rad
2.0 KiB
match.nested.union.rad
2.3 KiB
match.nested.whilelet.rad
2.4 KiB
match.string.rad
1.8 KiB
match.value.copy.rad
2.0 KiB
match.void.then.or.rad
1.6 KiB
memzero.result.bug.rad
806 B
memzero.union.bug.rad
576 B
mutref.loop.bug.rad
1.8 KiB
opt.assignment.bug.rad
1.3 KiB
opt.bug.test.rad
1.4 KiB
opt.if.let.complex.rad
6.2 KiB
opt.if.let.guard.rad
809 B
opt.if.let.rad
956 B
opt.nil.check.rad
1.5 KiB
opt.record.eq.rad
842 B
opt.record.rad
655 B
opt.return.array.rad
289 B
opt.return.nested.rad
797 B
opt.return.record.rad
344 B
opt.slice.npo.rad
2.8 KiB
opt.type.rad
200 B
opt.while.let.complex.rad
404 B
panic.rad
111 B
placeholder.basic.rad
133 B
placeholder.comprehensive.rad
562 B
pointer.copy.edge.case.rad
1.3 KiB
pointer.slice.index.rad
269 B
pointer.slice.store.rad
881 B
prog.ackermann.rad
5.0 KiB
prog.bignum.rad
9.4 KiB
prog.binsearch.rad
2.4 KiB
prog.bubblesort.rad
2.0 KiB
prog.cordic.rad
6.9 KiB
prog.crc32.rad
2.7 KiB
prog.dijkstra.rad
7.7 KiB
prog.eval.rad
6.2 KiB
prog.hanoi.rad
3.8 KiB
prog.huffman.rad
9.3 KiB
prog.hybridsort.rad
3.0 KiB
prog.linkedlist.rad
5.8 KiB
prog.lzw.rad
6.7 KiB
prog.matmul.rad
2.9 KiB
prog.mersenne.rad
5.2 KiB
prog.nqueens.rad
3.4 KiB
prog.rbtree.rad
8.2 KiB
prog.regex.rad
10.2 KiB
prog.sha256.rad
7.0 KiB
prog.sieve.rad
2.8 KiB
prog.symtab.rad
10.1 KiB
prog.tokenizer.rad
13.8 KiB
prog.vm.rad
17.4 KiB
ptr.assign.rad
137 B
ptr.deref.rad
622 B
ptr.eq.rad
966 B
ptr.mutate.rad
244 B
ptr.opaque.rad
1.4 KiB
record.access.rad
285 B
record.alignment.rad
179 B
record.array.elements.rad
1.7 KiB
record.copy.rad
2.0 KiB
record.field.assign.rad
184 B
record.nested.calls.2.rad
612 B
record.nested.calls.3.rad
734 B
record.param.lit.rad
353 B
record.ptr.access.rad
227 B
record.ptr.mutate.rad
243 B
record.shorthand.rad
1.5 KiB
record.unlabeled.rad
407 B
ref.if.bug.rad
519 B
ref.immut.loop.bug.rad
670 B
ref.mut.ptr.rad
261 B
regalloc.callee.save.rad
1.5 KiB
regalloc.spill.reuse.rad
473 B
reserve.loop.rad
392 B
result.void.success.rad
716 B
slice.alloc.loop.rad
788 B
slice.append.rad
3.3 KiB
slice.cap.rad
941 B
slice.delete.rad
971 B
slice.of.rad
460 B
slice.subslice.rad
1.4 KiB
spill.blockarg.clobber.rad
3.5 KiB
spill.loop.rad
1.6 KiB
stack.local.corrupt.rad
320 B
static.array.mutate.rad
387 B
static.basic.rad
327 B
static.fn.array.rad
628 B
static.record.array.rad
503 B
static.slice.index.assign.rad
408 B
static.slice.offset.rad
668 B
string.basic.rad
149 B
string.escape.rad
349 B
string.index.rad
116 B
switch.blockargs.clobber.rad
1.3 KiB
trait.aggregate.ret.rad
1.5 KiB
trait.array.optional.rad
1.7 KiB
trait.basic.rad
565 B
trait.control.flow.rad
1.1 KiB
trait.fn.param.rad
1.6 KiB
trait.multiple.methods.rad
1.2 KiB
trait.multiple.traits.rad
1.2 KiB
trait.multiple.types.rad
1.3 KiB
trait.supertrait.rad
2.5 KiB
trait.throws.rad
1.0 KiB
trait.writer.rad
2.6 KiB
type.unify.rad
4.5 KiB
undefined.rad
417 B
union-tag.rad
911 B
union.bitfield.rad
1.2 KiB
union.discriminant.cast.rad
389 B
union.edge.case.2.rad
679 B
union.edge.case.3.rad
608 B
union.mixed.assign.rad
977 B
union.payload.mutref.rad
1.4 KiB
union.payload.rad
580 B
union.record.forward.rad
1.3 KiB
union.void.match.rad
403 B
union.void.rad
824 B
unsigned.compare.rad
1.9 KiB
var.align.rad
1013 B
var.infer.rad
549 B
decode.rad
14.6 KiB
emit.rad
24.4 KiB
encode.rad
19.9 KiB
isel.rad
41.1 KiB
printer.rad
13.0 KiB
tests.rad
15.7 KiB
rv64.rad
13.0 KiB
collections/
lang/
sys/
arch.rad
65 B
collections.rad
36 B
fmt.rad
3.8 KiB
intrinsics.rad
206 B
io.rad
1.2 KiB
lang.rad
222 B
mem.rad
2.2 KiB
sys.rad
167 B
testing.rad
2.4 KiB
tests.rad
11.6 KiB
vec.rad
3.1 KiB
std.rad
231 B
scripts/
seed/
test/
vim/
.gitignore
353 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
3.1 KiB
README
2.5 KiB
std.lib
987 B
std.lib.test
252 B
lib/std/arch/rv64/tests/prog.regex.rad
raw
| 1 | //! NFA-based regex matcher. |
| 2 | //! Implement a simple regular expression engine using Thompson's NFA |
| 3 | //! construction. Supports: literal characters, '.', '*', '+', '?', |
| 4 | //! and concatenation. |
| 5 | |
| 6 | const MAX_STATES: u32 = 128; |
| 7 | const MAX_TRANSITIONS: u32 = 256; |
| 8 | const NIL: u32 = 0xFFFFFFFF; |
| 9 | |
| 10 | const TRANS_CHAR: u32 = 0; |
| 11 | const TRANS_EPSILON: u32 = 1; |
| 12 | const TRANS_DOT: u32 = 2; |
| 13 | |
| 14 | record Trans { |
| 15 | kind: u32, |
| 16 | ch: u8, |
| 17 | to: u32, |
| 18 | } |
| 19 | |
| 20 | record Frag { |
| 21 | start: u32, |
| 22 | endState: u32, |
| 23 | } |
| 24 | |
| 25 | record NfaState { |
| 26 | trans: *mut [Trans], |
| 27 | transCount: u32, |
| 28 | stateFirst: *mut [u32], |
| 29 | transNext: *mut [u32], |
| 30 | stateCount: u32, |
| 31 | acceptState: u32, |
| 32 | current: *mut [u32], |
| 33 | nextSet: *mut [u32], |
| 34 | closure: *mut [u32], |
| 35 | fragStack: *mut [Frag], |
| 36 | fragTop: u32, |
| 37 | } |
| 38 | |
| 39 | fn newState(nfa: *mut NfaState) -> u32 { |
| 40 | let s: u32 = nfa.stateCount; |
| 41 | nfa.stateFirst[s] = NIL; |
| 42 | nfa.stateCount += 1; |
| 43 | return s; |
| 44 | } |
| 45 | |
| 46 | fn addTrans(nfa: *mut NfaState, from: u32, kind: u32, ch: u8, to: u32) { |
| 47 | let idx: u32 = nfa.transCount; |
| 48 | nfa.trans[idx] = Trans { kind, ch, to }; |
| 49 | nfa.transNext[idx] = nfa.stateFirst[from]; |
| 50 | nfa.stateFirst[from] = idx; |
| 51 | nfa.transCount += 1; |
| 52 | } |
| 53 | |
| 54 | fn pushFrag(nfa: *mut NfaState, f: Frag) { |
| 55 | nfa.fragStack[nfa.fragTop] = f; |
| 56 | nfa.fragTop += 1; |
| 57 | } |
| 58 | |
| 59 | fn popFrag(nfa: *mut NfaState) -> Frag { |
| 60 | nfa.fragTop -= 1; |
| 61 | return nfa.fragStack[nfa.fragTop]; |
| 62 | } |
| 63 | |
| 64 | fn setEmpty(s: *mut [u32]) { |
| 65 | s[0] = 0; |
| 66 | s[1] = 0; |
| 67 | s[2] = 0; |
| 68 | s[3] = 0; |
| 69 | } |
| 70 | |
| 71 | fn setAdd(s: *mut [u32], bit: u32) { |
| 72 | let word: u32 = bit / 32; |
| 73 | let pos: u32 = bit % 32; |
| 74 | s[word] |= (1 << pos); |
| 75 | } |
| 76 | |
| 77 | fn setHas(s: *[u32], bit: u32) -> bool { |
| 78 | let word: u32 = bit / 32; |
| 79 | let pos: u32 = bit % 32; |
| 80 | return (s[word] >> pos) & 1 == 1; |
| 81 | } |
| 82 | |
| 83 | fn setIsEmpty(s: *[u32]) -> bool { |
| 84 | return s[0] == 0 and s[1] == 0 and s[2] == 0 and s[3] == 0; |
| 85 | } |
| 86 | |
| 87 | fn setCopy(dst: *mut [u32], src: *[u32]) { |
| 88 | dst[0] = src[0]; |
| 89 | dst[1] = src[1]; |
| 90 | dst[2] = src[2]; |
| 91 | dst[3] = src[3]; |
| 92 | } |
| 93 | |
| 94 | fn epsilonClosure(nfa: *mut NfaState, states: *mut [u32]) { |
| 95 | setCopy(nfa.closure, states); |
| 96 | |
| 97 | let mut changed: bool = true; |
| 98 | while changed { |
| 99 | changed = false; |
| 100 | let mut s: u32 = 0; |
| 101 | while s < nfa.stateCount { |
| 102 | if setHas(nfa.closure, s) { |
| 103 | let mut t: u32 = nfa.stateFirst[s]; |
| 104 | while t != NIL { |
| 105 | if nfa.trans[t].kind == TRANS_EPSILON { |
| 106 | if not setHas(nfa.closure, nfa.trans[t].to) { |
| 107 | setAdd(nfa.closure, nfa.trans[t].to); |
| 108 | changed = true; |
| 109 | } |
| 110 | } |
| 111 | t = nfa.transNext[t]; |
| 112 | } |
| 113 | } |
| 114 | s += 1; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | setCopy(states, nfa.closure); |
| 119 | } |
| 120 | |
| 121 | fn resetNFA(nfa: *mut NfaState) { |
| 122 | nfa.stateCount = 0; |
| 123 | nfa.transCount = 0; |
| 124 | nfa.fragTop = 0; |
| 125 | let mut i: u32 = 0; |
| 126 | while i < MAX_STATES { |
| 127 | nfa.stateFirst[i] = NIL; |
| 128 | i += 1; |
| 129 | } |
| 130 | i = 0; |
| 131 | while i < MAX_TRANSITIONS { |
| 132 | nfa.transNext[i] = NIL; |
| 133 | i += 1; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | fn compile(nfa: *mut NfaState, pattern: *[u8]) -> u32 { |
| 138 | resetNFA(nfa); |
| 139 | |
| 140 | let mut i: u32 = 0; |
| 141 | while i < pattern.len { |
| 142 | let ch: u8 = pattern[i]; |
| 143 | |
| 144 | if i + 1 < pattern.len { |
| 145 | let nextCh: u8 = pattern[i + 1]; |
| 146 | |
| 147 | if nextCh == 42 { |
| 148 | let s: u32 = newState(nfa); |
| 149 | let e: u32 = newState(nfa); |
| 150 | let body: u32 = newState(nfa); |
| 151 | |
| 152 | if ch == 46 { |
| 153 | addTrans(nfa, body, TRANS_DOT, 0, body); |
| 154 | } else { |
| 155 | addTrans(nfa, body, TRANS_CHAR, ch, body); |
| 156 | } |
| 157 | addTrans(nfa, s, TRANS_EPSILON, 0, body); |
| 158 | addTrans(nfa, s, TRANS_EPSILON, 0, e); |
| 159 | addTrans(nfa, body, TRANS_EPSILON, 0, e); |
| 160 | |
| 161 | pushFrag(nfa, Frag { start: s, endState: e }); |
| 162 | i += 2; |
| 163 | continue; |
| 164 | } |
| 165 | if nextCh == 43 { |
| 166 | let s: u32 = newState(nfa); |
| 167 | let m: u32 = newState(nfa); |
| 168 | let e: u32 = newState(nfa); |
| 169 | |
| 170 | if ch == 46 { |
| 171 | addTrans(nfa, s, TRANS_DOT, 0, m); |
| 172 | addTrans(nfa, m, TRANS_DOT, 0, m); |
| 173 | } else { |
| 174 | addTrans(nfa, s, TRANS_CHAR, ch, m); |
| 175 | addTrans(nfa, m, TRANS_CHAR, ch, m); |
| 176 | } |
| 177 | addTrans(nfa, m, TRANS_EPSILON, 0, e); |
| 178 | |
| 179 | pushFrag(nfa, Frag { start: s, endState: e }); |
| 180 | i += 2; |
| 181 | continue; |
| 182 | } |
| 183 | if nextCh == 63 { |
| 184 | let s: u32 = newState(nfa); |
| 185 | let m: u32 = newState(nfa); |
| 186 | let e: u32 = newState(nfa); |
| 187 | |
| 188 | if ch == 46 { |
| 189 | addTrans(nfa, s, TRANS_DOT, 0, m); |
| 190 | } else { |
| 191 | addTrans(nfa, s, TRANS_CHAR, ch, m); |
| 192 | } |
| 193 | addTrans(nfa, s, TRANS_EPSILON, 0, e); |
| 194 | addTrans(nfa, m, TRANS_EPSILON, 0, e); |
| 195 | |
| 196 | pushFrag(nfa, Frag { start: s, endState: e }); |
| 197 | i += 2; |
| 198 | continue; |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | let s: u32 = newState(nfa); |
| 203 | let e: u32 = newState(nfa); |
| 204 | if ch == 46 { |
| 205 | addTrans(nfa, s, TRANS_DOT, 0, e); |
| 206 | } else { |
| 207 | addTrans(nfa, s, TRANS_CHAR, ch, e); |
| 208 | } |
| 209 | pushFrag(nfa, Frag { start: s, endState: e }); |
| 210 | i += 1; |
| 211 | } |
| 212 | |
| 213 | if nfa.fragTop == 0 { |
| 214 | let s: u32 = newState(nfa); |
| 215 | nfa.acceptState = s; |
| 216 | return s; |
| 217 | } |
| 218 | |
| 219 | let numFrags: u32 = nfa.fragTop; |
| 220 | let mut frags: [Frag; 64] = [Frag { start: 0, endState: 0 }; 64]; |
| 221 | let mut k: u32 = 0; |
| 222 | while k < numFrags { |
| 223 | frags[numFrags - 1 - k] = popFrag(nfa); |
| 224 | k += 1; |
| 225 | } |
| 226 | |
| 227 | let mut j: u32 = 0; |
| 228 | while j < numFrags - 1 { |
| 229 | addTrans(nfa, frags[j].endState, TRANS_EPSILON, 0, frags[j + 1].start); |
| 230 | j += 1; |
| 231 | } |
| 232 | |
| 233 | nfa.acceptState = frags[numFrags - 1].endState; |
| 234 | return frags[0].start; |
| 235 | } |
| 236 | |
| 237 | fn nfaMatches(nfa: *mut NfaState, start: u32, input: *[u8]) -> bool { |
| 238 | setEmpty(nfa.current); |
| 239 | setAdd(nfa.current, start); |
| 240 | epsilonClosure(nfa, nfa.current); |
| 241 | |
| 242 | let mut i: u32 = 0; |
| 243 | while i < input.len { |
| 244 | let ch: u8 = input[i]; |
| 245 | setEmpty(nfa.nextSet); |
| 246 | |
| 247 | let mut s: u32 = 0; |
| 248 | while s < nfa.stateCount { |
| 249 | if setHas(nfa.current, s) { |
| 250 | let mut t: u32 = nfa.stateFirst[s]; |
| 251 | while t != NIL { |
| 252 | if nfa.trans[t].kind == TRANS_CHAR and nfa.trans[t].ch == ch { |
| 253 | setAdd(nfa.nextSet, nfa.trans[t].to); |
| 254 | } else if nfa.trans[t].kind == TRANS_DOT { |
| 255 | setAdd(nfa.nextSet, nfa.trans[t].to); |
| 256 | } |
| 257 | t = nfa.transNext[t]; |
| 258 | } |
| 259 | } |
| 260 | s += 1; |
| 261 | } |
| 262 | |
| 263 | epsilonClosure(nfa, nfa.nextSet); |
| 264 | setCopy(nfa.current, nfa.nextSet); |
| 265 | |
| 266 | if setIsEmpty(nfa.current) { |
| 267 | return false; |
| 268 | } |
| 269 | i += 1; |
| 270 | } |
| 271 | |
| 272 | return setHas(nfa.current, nfa.acceptState); |
| 273 | } |
| 274 | |
| 275 | fn testLiteral(nfa: *mut NfaState) -> i32 { |
| 276 | let start: u32 = compile(nfa, "abc"); |
| 277 | |
| 278 | assert nfaMatches(nfa, start, "abc"); |
| 279 | if nfaMatches(nfa, start, "ab") { return 2; } |
| 280 | if nfaMatches(nfa, start, "abcd") { return 3; } |
| 281 | if nfaMatches(nfa, start, "abd") { return 4; } |
| 282 | |
| 283 | return 0; |
| 284 | } |
| 285 | |
| 286 | fn testStar(nfa: *mut NfaState) -> i32 { |
| 287 | let start: u32 = compile(nfa, "a*"); |
| 288 | |
| 289 | assert nfaMatches(nfa, start, ""); |
| 290 | assert nfaMatches(nfa, start, "a"); |
| 291 | assert nfaMatches(nfa, start, "aaa"); |
| 292 | if nfaMatches(nfa, start, "b") { return 4; } |
| 293 | |
| 294 | return 0; |
| 295 | } |
| 296 | |
| 297 | fn testPlus(nfa: *mut NfaState) -> i32 { |
| 298 | let start: u32 = compile(nfa, "a+"); |
| 299 | |
| 300 | if nfaMatches(nfa, start, "") { return 1; } |
| 301 | assert nfaMatches(nfa, start, "a"); |
| 302 | assert nfaMatches(nfa, start, "aaaaa"); |
| 303 | |
| 304 | return 0; |
| 305 | } |
| 306 | |
| 307 | fn testQuestion(nfa: *mut NfaState) -> i32 { |
| 308 | let start: u32 = compile(nfa, "a?"); |
| 309 | |
| 310 | assert nfaMatches(nfa, start, ""); |
| 311 | assert nfaMatches(nfa, start, "a"); |
| 312 | if nfaMatches(nfa, start, "aa") { return 3; } |
| 313 | |
| 314 | return 0; |
| 315 | } |
| 316 | |
| 317 | fn testDot(nfa: *mut NfaState) -> i32 { |
| 318 | let start: u32 = compile(nfa, ".."); |
| 319 | |
| 320 | assert nfaMatches(nfa, start, "ab"); |
| 321 | assert nfaMatches(nfa, start, "zz"); |
| 322 | if nfaMatches(nfa, start, "a") { return 3; } |
| 323 | if nfaMatches(nfa, start, "abc") { return 4; } |
| 324 | |
| 325 | return 0; |
| 326 | } |
| 327 | |
| 328 | fn testComplex(nfa: *mut NfaState) -> i32 { |
| 329 | let start: u32 = compile(nfa, "ab*c"); |
| 330 | |
| 331 | assert nfaMatches(nfa, start, "ac"); |
| 332 | assert nfaMatches(nfa, start, "abc"); |
| 333 | assert nfaMatches(nfa, start, "abbc"); |
| 334 | assert nfaMatches(nfa, start, "abbbc"); |
| 335 | if nfaMatches(nfa, start, "a") { return 5; } |
| 336 | if nfaMatches(nfa, start, "adc") { return 6; } |
| 337 | |
| 338 | return 0; |
| 339 | } |
| 340 | |
| 341 | fn testDotStar(nfa: *mut NfaState) -> i32 { |
| 342 | let start: u32 = compile(nfa, ".*"); |
| 343 | |
| 344 | assert nfaMatches(nfa, start, ""); |
| 345 | assert nfaMatches(nfa, start, "hello"); |
| 346 | assert nfaMatches(nfa, start, "x"); |
| 347 | |
| 348 | return 0; |
| 349 | } |
| 350 | |
| 351 | @default fn main() -> i32 { |
| 352 | let mut trans: [Trans; 256] = [Trans { kind: 0, ch: 0, to: 0 }; 256]; |
| 353 | let mut stateFirst: [u32; 128] = [0xFFFFFFFF; 128]; |
| 354 | let mut transNext: [u32; 256] = [0xFFFFFFFF; 256]; |
| 355 | let mut current: [u32; 4] = [0; 4]; |
| 356 | let mut nextSet: [u32; 4] = [0; 4]; |
| 357 | let mut closureBuf: [u32; 4] = [0; 4]; |
| 358 | let mut fragStack: [Frag; 64] = [Frag { start: 0, endState: 0 }; 64]; |
| 359 | |
| 360 | let mut nfa: NfaState = NfaState { |
| 361 | trans: &mut trans[..], |
| 362 | transCount: 0, |
| 363 | stateFirst: &mut stateFirst[..], |
| 364 | transNext: &mut transNext[..], |
| 365 | stateCount: 0, |
| 366 | acceptState: 0, |
| 367 | current: &mut current[..], |
| 368 | nextSet: &mut nextSet[..], |
| 369 | closure: &mut closureBuf[..], |
| 370 | fragStack: &mut fragStack[..], |
| 371 | fragTop: 0, |
| 372 | }; |
| 373 | |
| 374 | let r1: i32 = testLiteral(&mut nfa); |
| 375 | if r1 != 0 { return 10 + r1; } |
| 376 | |
| 377 | let r2: i32 = testStar(&mut nfa); |
| 378 | if r2 != 0 { return 20 + r2; } |
| 379 | |
| 380 | let r3: i32 = testPlus(&mut nfa); |
| 381 | if r3 != 0 { return 30 + r3; } |
| 382 | |
| 383 | let r4: i32 = testQuestion(&mut nfa); |
| 384 | if r4 != 0 { return 40 + r4; } |
| 385 | |
| 386 | let r5: i32 = testDot(&mut nfa); |
| 387 | if r5 != 0 { return 50 + r5; } |
| 388 | |
| 389 | let r6: i32 = testComplex(&mut nfa); |
| 390 | if r6 != 0 { return 60 + r6; } |
| 391 | |
| 392 | let r7: i32 = testDotStar(&mut nfa); |
| 393 | if r7 != 0 { return 70 + r7; } |
| 394 | |
| 395 | return 0; |
| 396 | } |