ref: a7ba738bca21b54d6cf2bd5cdfe39b00f3d4b350
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
}