shithub: mc

Download patch

ref: 8c0eb9f56edefcc15a206f8e165056803f9f5b99
author: Ori Bernstein <[email protected]>
date: Mon Oct 21 21:10:26 EDT 2013

Initial commit

--- /dev/null
+++ b/Makefile
@@ -1,0 +1,9 @@
+MYRLIB=regex
+MYRSRC= \
+	compile.myr \
+	interp.myr \
+	types.myr \
+
+include config.mk
+include mk/myr.mk
+
--- /dev/null
+++ b/compile.myr
@@ -1,0 +1,22 @@
+use std
+
+use "types.use"
+
+pkg regex =
+	const compile	: (re : byte[:] -> regex#)
+;;
+
+const compile = {re
+	var re
+	re = std.zalloc()
+	re.prog = std.slalloc(4)
+	/* compiled regex for a* */
+	re.prog[0] = `Byte ('a' castto(byte))
+	re.prog[1] = `Byte ('a' castto(byte))
+	re.prog[2] = `Split (0, 3)
+	re.prog[3] = `Match
+
+	-> re
+}
+
+
--- /dev/null
+++ b/configure
@@ -1,0 +1,52 @@
+#!/bin/sh
+
+prefix="/usr/local"
+
+for i in `seq 300`; do
+    echo "Lots of output to emulate automake... ok"
+    echo "Testing for things you'll never use... fail"
+    echo "Satisfying the fortran77 lobby... ok"
+    echo "Burning CPU time checking for the bloody obvious... ok"
+done
+echo "Automake emulated successfully"
+
+INST_ROOT='/usr/local'
+
+for arg in $*; do
+    shift 1
+    case $arg in
+        "--prefix" | "-p")
+            prefix=shift $*
+            ;;
+        --prefix=*)
+            prefix=`echo $arg | sed 's/^--prefix=//g'`
+            ;;
+        "--help" | "-h")
+            echo "Usage:"
+            echo "      --prefix | -p: The prefix to install to"
+            break;
+            ;;
+        *) echo "Unrecognized argument $arg";;
+    esac
+done
+
+OS=`uname`
+
+echo export INST_ROOT=$prefix > config.mk
+case $OS in
+    *Linux*)
+        echo 'export SYS=linux' >> config.mk
+        ;;
+    *Darwin*)
+        echo 'export SYS=osx' >> config.mk
+        ;;
+    *)
+        echo 'Unknown architecture.'
+        ;;
+esac
+
+cat << EOF
+    Building with:
+        prefix=$prefix
+EOF
+
--- /dev/null
+++ b/interp.myr
@@ -1,0 +1,122 @@
+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
+	spawn(re, 0)
+	while re.nthr > 0
+		for i = 0; i < re.nthr; 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
+			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 */
+	`Byte b:
+		if !in(re, str) || b != str[re.strp]
+			kill(re, tid, "not char")
+		else
+			std.put("matched %b with %b\n", b, str[re.strp])
+		;;
+		;;
+	`Range (start, end):
+		if !in(re, str) || start > str[re.strp] || end < str[re.strp]
+			kill(re, tid, "bad range")
+		;;
+		;;
+	`Dot:
+		if !in(re, str)
+			kill(re, tid, "past end")
+		;;
+		;;
+	/* Control flow */
+	`Split	(lip, rip):
+		spawn(re, lip)
+		jmp(re, tid, rip)
+		;;
+	`Jmp ip:
+		jmp(re, tid, ip)
+		;;
+	`Match:
+		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 spawn = {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++
+
+	step(re, tid)
+}
+
+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
+}
--- /dev/null
+++ b/mk/myr.mk
@@ -1,0 +1,42 @@
+ifneq ($(MYRLIB),)
+    _LIBNAME=lib$(MYRLIB).a
+endif
+
+all: $(_LIBNAME) $(MYRBIN)
+
+$(_LIBNAME): $(MYRSRC) $(ASMSRC)
+	myrbuild -l $(MYRLIB) $^
+
+$(MYRBIN): $(MYRSRC) $(ASMSRC)
+	myrbuild -b $(MYRBIN) $^
+
+OBJ=$(MYRSRC:.myr=.o) $(ASMSRC:.s=.o)
+JUNKASM=$(MYRSRC:.myr=.s)
+USE=$(MYRSRC:.myr=.use) $(MYRLIB)
+.PHONY: clean
+clean:
+	rm -f $(OBJ)
+	rm -f $(USE)
+	rm -f $(JUNKASM)
+	rm -f lib$(MYRLIB).a
+
+install: install-bin install-lib
+
+install-bin: $(MYRBIN)
+	@if [ ! -z "$(MYRBIN)" ]; then \
+	    echo install $(MYRBIN) $(INST_ROOT)/bin; \
+	    mkdir -p $(INST_ROOT)/bin; \
+	    install $(MYRBIN) $(INST_ROOT)/bin; \
+	fi
+
+install-lib: $(_LIBNAME)
+	@if [ ! -z "$(_LIBNAME)" ]; then \
+		echo install -m 644 $(_LIBNAME) $(INST_ROOT)/lib/myr; \
+		echo install -m 644 $(MYRLIB) $(INST_ROOT)/lib/myr; \
+		mkdir -p $(INST_ROOT)/lib/myr; \
+		install -m 644 $(_LIBNAME) $(INST_ROOT)/lib/myr; \
+		install -m 644 $(MYRLIB) $(INST_ROOT)/lib/myr; \
+	fi
+
+config.mk:
+	./configure
--- /dev/null
+++ b/types.myr
@@ -1,0 +1,29 @@
+use std
+
+pkg regex =
+	type regex = struct
+		prog	: reinst[:]
+		nthr	: std.size
+		thr	: rethread#[:]
+		str	: byte[:]
+		strp	: std.size
+		matched	: std.option(rethread#)
+	;;
+
+	type rethread = struct
+		uid	: std.size
+		ip	: std.size
+	;;
+
+	type reinst = union
+		/* direct consumers */
+		`Byte	byte
+		`Range	[byte, byte]
+		`Dot
+
+		`Match	/* found the end of the expr */
+
+		`Split	[std.size, std.size]
+		`Jmp	std.size
+	;;
+;;