ref: 5fe0859c8a8a801150efa772492db9b6f1baa631
parent: 0529dbb64b33733ef6caeb7403e708e49e8f1b36
author: Ori Bernstein <[email protected]>
date: Tue Oct 22 18:06:47 EDT 2013
Implement matching
--- a/compile.myr
+++ b/compile.myr
@@ -39,12 +39,15 @@
re = std.zalloc()
re.pat = pat
+ re.nmatch = 1 /* whole match */
match parse(re)
`None: -> `std.Failure (`Earlystop);;
`Fail f: -> `std.Failure f;;
`Some t:
dump(t, 0)
+ append(re, `Ilbra 0)
gen(re, t)
+ append(re, `Irbra 0)
append(re, `Imatch)
idump(re)
-> `std.Success re
@@ -54,6 +57,8 @@
}
const gen = {re, t
+ var m
+
match t#
`Alt (a, b): genalt(re, a, b);;
`Cat (a, b): gen(re, a); gen(re, b);;
@@ -72,8 +77,10 @@
/* meta */
`Cap a:
- std.put("WARNING: Capture not implemented\n")
+ m = re.nmatch++
+ append(re, `Ilbra m)
gen(re, a)
+ append(re, `Irbra m)
;;
;;
-> re.proglen
@@ -166,10 +173,14 @@
`Idot:
std.put("`Idot\n")
;;
- /*
- Control flow. All of these recursively call step() until
- exactly one byte is consumed from the string.
- */
+ /* capture groups */
+ `Ilbra m:
+ std.put("`Ilbra %z\n", m)
+ ;;
+ `Irbra m:
+ std.put("`Irbra %z\n", m)
+ ;;
+ /* control flow */
`Ifork (lip, rip):
std.put("`Ifork (%z,%z)\n", lip, rip)
;;
--- a/interp.myr
+++ b/interp.myr
@@ -14,6 +14,8 @@
re.strp = 0
re.matched = `std.None
mkthread(re, 0)
+ re.thr[0].mstart = std.slzalloc(re.nmatch)
+ re.thr[0].mend = std.slzalloc(re.nmatch)
while re.nthr > 0
for i = 0; i < re.nthr; i++
trace(re, "tid=%z, ip=%z, c=b\n", re.thr[i].uid, re.thr[i].ip, str[re.strp])
@@ -24,7 +26,11 @@
;;
;;
match re.matched
- `std.Some thr: -> re.strp == str.len;;
+ `std.Some thr:
+ for i = 0; i < re.nmatch; i++
+ std.put("match %i:[%z..%z]\n", i, thr.mstart[i], thr.mend[i])
+ ;;
+ -> re.strp == str.len;;
`std.None: -> false;;
;;
}
@@ -65,13 +71,25 @@
;;
;;
/*
- Control flow. All of these recursively call step() until
+ Non-consuming. All of these recursively call step() until
exactly one byte is consumed from the string.
*/
+ `Ilbra m:
+ trace(re, "\t%i:\tLbra %z\n", thr.ip, m)
+ thr.mstart[m] = re.strp
+ thr.ip++
+ step(re, tid)
+ ;;
+ `Irbra m:
+ trace(re, "\t%i:\tRbra %z\n", thr.ip, m)
+ thr.mend[m] = re.strp
+ thr.ip++
+ step(re, tid)
+ ;;
`Ifork (lip, rip):
trace(re, "\t%i:\tFork (%z, %z)\n", thr.ip, rip, lip)
jmp(re, tid, rip)
- spawn(re, lip)
+ fork(re, thr, lip)
;;
`Ijmp ip:
trace(re, "\t%i:\tJmp %z\n", thr.ip, ip)
@@ -109,8 +127,13 @@
-> tid
}
-const spawn = {re, ip
- step(re, mkthread(re, ip))
+const fork = {re, thr, ip
+ var tid
+
+ tid = mkthread(re, ip)
+ re.thr[tid].mstart = std.sldup(thr.mstart)
+ re.thr[tid].mend = std.sldup(thr.mend)
+ step(re, tid)
}
const kill = {re, tid, msg
--- a/types.myr
+++ b/types.myr
@@ -12,6 +12,8 @@
type regex = struct
debug : bool
pat : byte[:]
+ nmatch : std.size
+
/* VM state */
proglen : std.size
prog : reinst[:]
@@ -26,7 +28,6 @@
uid : std.size /* just for debugging */
ip : std.size /* the instruction pointer */
- mactive : std.size[:] /* stack of active matches */
mstart : std.size[:] /* match starts */
mend : std.size[:] /* match ends */
;;
@@ -38,7 +39,8 @@
`Idot
/* groups */
-
+ `Ilbra std.size
+ `Irbra std.size
/* control flow */
`Ifork [std.size, std.size]