ref: f507c7ee81391e004d492d1095ca4263d3ee1830
dir: /interp.myr/
use std use "types.use" pkg regex = const exec : (re : regex#, str : byte[:] -> bool) ;; const exec = {re, str var i re.str = str re.strp = 0 re.matched = `std.None mkthread(re, 0) std.put("tid %z, ip %z, strp %z\n", re.thr[0].uid, re.thr[0].ip, re.strp) while re.nthr > 0 for i = 0; i < re.nthr; i++ std.put("Switch to %i\n", i) std.put("tid %z, ip %z, strp %z\n", re.thr[i].uid, re.thr[i].ip, re.strp) step(re, i) ;; if re.nthr > 0 std.put("Step forward\n") re.strp++ ;; ;; match re.matched `std.Some thr: -> true;; `std.None: -> false;; ;; } const step = {re, tid var thr var str thr = re.thr[tid] str = re.str match re.prog[thr.ip] /* Char matching. Consume exactly one byte from the string. */ `Ibyte b: if !in(re, str) kill(re, tid, "end of string") elif b != str[re.strp] std.put("re.strp: %i\n", re.strp) std.put("\tb: %b (%c), str[re.strp]: %b (%c)\n", b, b castto(char), str[re.strp], str[re.strp] castto(char)) kill(re, tid, "not right char") else std.put("matched %b with %b\n", b, str[re.strp]) ;; ;; `Irange (start, end): if !in(re, str) || start > str[re.strp] || end < str[re.strp] kill(re, tid, "bad range") ;; ;; `Idot: if !in(re, str) kill(re, tid, "past end") ;; ;; /* Control flow. All of these recursively call step() until exactly one byte is consumed from the string. */ `Ifork (lip, rip): spawn(re, lip) jmp(re, tid, rip) ;; `Ijmp ip: jmp(re, tid, ip) ;; `Imatch: finish(re, tid) ;; ;; thr.ip++ } const jmp = {re, tid, ip std.put("jmp %z\n", ip) re.thr[tid].ip = ip step(re, tid) } var uid = 0 const mkthread = {re, ip var thr : rethread# var tid std.put("spawn %z\n", re.nthr) tid = re.nthr if re.nthr >= re.thr.len re.thr = std.slgrow(re.thr, std.max(1, re.nthr * 2)) ;; thr = std.alloc() thr.ip = ip thr.uid = uid++ re.thr[re.nthr] = thr re.nthr++ -> tid } const spawn = {re, ip step(re, mkthread(re, ip)) } const kill = {re, tid, msg /* free the dying thread, and shuffle the last thread into the it's place in the thread list */ std.put("kill %z: %s\n", tid, msg) std.free(re.thr[tid]) re.thr[tid] = re.thr[re.nthr - 1] re.nthr-- } const finish = {re, tid std.put("finish\n", tid) match re.matched `std.Some thr: std.free(thr);; `std.None: ;; ;; re.matched = `std.Some re.thr[tid] re.thr[tid] = re.thr[re.nthr - 1] re.nthr-- } const in = {re, str -> re.strp < str.len }