shithub: mc

Download patch

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]