From 4ecd7fff4237df32f2409f7ee16db16d32cd57f6 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sat, 14 Apr 2007 04:27:15 -0500
Subject: [PATCH 01/24] split up some unix constants split up netbsd stat

---
 extra/unix/bsd/bsd.factor             | 11 +++++++---
 extra/unix/bsd/freebsd/freebsd.factor |  3 +++
 extra/unix/bsd/macosx/macosx.factor   |  3 +++
 extra/unix/bsd/netbsd/netbsd.factor   |  3 +++
 extra/unix/bsd/openbsd/openbsd.factor |  3 +++
 extra/unix/stat/netbsd/32/32.factor   | 26 ++++++++++++++++++++++++
 extra/unix/stat/netbsd/64/64.factor   | 27 +++++++++++++++++++++++++
 extra/unix/stat/netbsd/netbsd.factor  | 29 +++++----------------------
 extra/unix/types/netbsd/netbsd.factor |  5 ++---
 extra/unix/unix.factor                |  1 -
 10 files changed, 80 insertions(+), 31 deletions(-)
 create mode 100644 extra/unix/bsd/freebsd/freebsd.factor
 create mode 100644 extra/unix/bsd/macosx/macosx.factor
 create mode 100644 extra/unix/bsd/netbsd/netbsd.factor
 create mode 100644 extra/unix/bsd/openbsd/openbsd.factor
 create mode 100644 extra/unix/stat/netbsd/32/32.factor
 create mode 100644 extra/unix/stat/netbsd/64/64.factor

diff --git a/extra/unix/bsd/bsd.factor b/extra/unix/bsd/bsd.factor
index e652f1b9f9..cb7b347c20 100755
--- a/extra/unix/bsd/bsd.factor
+++ b/extra/unix/bsd/bsd.factor
@@ -1,7 +1,7 @@
 ! Copyright (C) 2005, 2006 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
+USING: alien.syntax combinators system vocabs.loader ;
 IN: unix
-USING: alien.syntax ;
 
 ! FreeBSD
 
@@ -15,8 +15,6 @@ USING: alien.syntax ;
 : O_TRUNC   HEX: 0400 ; inline
 : O_EXCL    HEX: 0800 ; inline
 
-: FD_SETSIZE 1024 ; inline
-
 : SOL_SOCKET HEX: ffff ; inline
 : SO_REUSEADDR HEX: 4 ; inline
 : SO_OOBINLINE HEX: 100 ; inline
@@ -83,3 +81,10 @@ C-STRUCT: sockaddr-un
 : SEEK_SET 0 ; inline
 : SEEK_CUR 1 ; inline
 : SEEK_END 2 ; inline
+
+os {
+    { "macosx"  [ "unix.bsd.macosx"  require ] }
+    { "freebsd" [ "unix.bsd.freebsd" require ] }
+    { "openbsd" [ "unix.bsd.openbsd" require ] }
+    { "netbsd"  [ "unix.bsd.netbsd"  require ] }
+} case
diff --git a/extra/unix/bsd/freebsd/freebsd.factor b/extra/unix/bsd/freebsd/freebsd.factor
new file mode 100644
index 0000000000..94bb708527
--- /dev/null
+++ b/extra/unix/bsd/freebsd/freebsd.factor
@@ -0,0 +1,3 @@
+IN: unix
+
+: FD_SETSIZE 1024 ;
diff --git a/extra/unix/bsd/macosx/macosx.factor b/extra/unix/bsd/macosx/macosx.factor
new file mode 100644
index 0000000000..3c0617ad17
--- /dev/null
+++ b/extra/unix/bsd/macosx/macosx.factor
@@ -0,0 +1,3 @@
+IN: unix
+
+: FD_SETSIZE 1024 ; inline
diff --git a/extra/unix/bsd/netbsd/netbsd.factor b/extra/unix/bsd/netbsd/netbsd.factor
new file mode 100644
index 0000000000..ac18749830
--- /dev/null
+++ b/extra/unix/bsd/netbsd/netbsd.factor
@@ -0,0 +1,3 @@
+IN: unix
+
+: FD_SETSIZE 256 ; inline
diff --git a/extra/unix/bsd/openbsd/openbsd.factor b/extra/unix/bsd/openbsd/openbsd.factor
new file mode 100644
index 0000000000..3c0617ad17
--- /dev/null
+++ b/extra/unix/bsd/openbsd/openbsd.factor
@@ -0,0 +1,3 @@
+IN: unix
+
+: FD_SETSIZE 1024 ; inline
diff --git a/extra/unix/stat/netbsd/32/32.factor b/extra/unix/stat/netbsd/32/32.factor
new file mode 100644
index 0000000000..bb2df6d6d3
--- /dev/null
+++ b/extra/unix/stat/netbsd/32/32.factor
@@ -0,0 +1,26 @@
+USING: kernel alien.syntax math ;
+IN: unix.stat
+
+! NetBSD 4.0
+
+C-STRUCT: stat
+    { "dev_t" "st_dev" }
+    { "mode_t" "st_mode" }
+    { "ino_t" "st_ino" }
+    { "nlink_t" "st_nlink" }
+    { "uid_t" "st_uid" }
+    { "gid_t" "st_gid" }
+    { "dev_t" "st_rdev" }
+    { "timespec" "st_atim" }
+    { "timespec" "st_mtim" }
+    { "timespec" "st_ctim" }
+    { "timespec" "st_birthtim" }
+    { "off_t" "st_size" }
+    { "blkcnt_t" "st_blocks" }
+    { "blksize_t" "st_blksize" }
+    { "uint32_t" "st_flags" }
+    { "uint32_t" "st_gen" }
+    { { "uint32_t" 2 } "st_qspare" } ;
+
+FUNCTION: int stat  ( char* pathname, stat* buf ) ;
+FUNCTION: int lstat ( char* pathname, stat* buf ) ;
diff --git a/extra/unix/stat/netbsd/64/64.factor b/extra/unix/stat/netbsd/64/64.factor
new file mode 100644
index 0000000000..f1f6f93dbd
--- /dev/null
+++ b/extra/unix/stat/netbsd/64/64.factor
@@ -0,0 +1,27 @@
+USING: kernel alien.syntax math ;
+IN: unix.stat
+
+! NetBSD 4.0
+
+C-STRUCT: stat
+    { "dev_t" "st_dev" }
+    { "ino_t" "st_ino" }
+    { "mode_t" "st_mode" }
+    { "nlink_t" "st_nlink" }
+    { "uid_t" "st_uid" }
+    { "gid_t" "st_gid" }
+    { "dev_t" "st_rdev" }
+    { "timespec" "st_atim" }
+    { "timespec" "st_mtim" }
+    { "timespec" "st_ctim" }
+    { "off_t" "st_size" }
+    { "blkcnt_t" "st_blocks" }
+    { "blksize_t" "st_blksize" }
+    { "uint32_t" "st_flags" }
+    { "uint32_t" "st_gen" }
+    { "uint32_t" "st_spare0" }
+    { "timespec" "st_birthtim" }
+    { "int" "__pad5" } ;
+
+FUNCTION: int stat  ( char* pathname, stat* buf ) ;
+FUNCTION: int lstat ( char* pathname, stat* buf ) ;
diff --git a/extra/unix/stat/netbsd/netbsd.factor b/extra/unix/stat/netbsd/netbsd.factor
index bb2df6d6d3..8057e5939b 100644
--- a/extra/unix/stat/netbsd/netbsd.factor
+++ b/extra/unix/stat/netbsd/netbsd.factor
@@ -1,26 +1,7 @@
-USING: kernel alien.syntax math ;
+USING: layouts combinators vocabs.loader ;
 IN: unix.stat
 
-! NetBSD 4.0
-
-C-STRUCT: stat
-    { "dev_t" "st_dev" }
-    { "mode_t" "st_mode" }
-    { "ino_t" "st_ino" }
-    { "nlink_t" "st_nlink" }
-    { "uid_t" "st_uid" }
-    { "gid_t" "st_gid" }
-    { "dev_t" "st_rdev" }
-    { "timespec" "st_atim" }
-    { "timespec" "st_mtim" }
-    { "timespec" "st_ctim" }
-    { "timespec" "st_birthtim" }
-    { "off_t" "st_size" }
-    { "blkcnt_t" "st_blocks" }
-    { "blksize_t" "st_blksize" }
-    { "uint32_t" "st_flags" }
-    { "uint32_t" "st_gen" }
-    { { "uint32_t" 2 } "st_qspare" } ;
-
-FUNCTION: int stat  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat ( char* pathname, stat* buf ) ;
+cell-bits {
+    { 32 [ "unix.stat.netbsd.32" require ] }
+    { 64 [ "unix.stat.netbsd.64" require ] }
+} case
diff --git a/extra/unix/types/netbsd/netbsd.factor b/extra/unix/types/netbsd/netbsd.factor
index 77636a6d6d..6d33547627 100755
--- a/extra/unix/types/netbsd/netbsd.factor
+++ b/extra/unix/types/netbsd/netbsd.factor
@@ -18,7 +18,7 @@ TYPEDEF: ulonglong      u_int64_t
 
 TYPEDEF: __uint32_t     __dev_t
 TYPEDEF: __uint32_t     dev_t
-TYPEDEF: __uint64_t     ino_t
+TYPEDEF: __uint32_t     ino_t
 TYPEDEF: __uint32_t     mode_t
 TYPEDEF: __uint32_t     nlink_t
 TYPEDEF: __uint32_t     uid_t
@@ -26,7 +26,6 @@ TYPEDEF: __uint32_t     gid_t
 TYPEDEF: __int64_t      off_t
 TYPEDEF: __int64_t      blkcnt_t
 TYPEDEF: __uint32_t     blksize_t
-TYPEDEF: __uint32_t     fflags_t
-TYPEDEF: int            ssize_t
+TYPEDEF: longlong       ssize_t
 TYPEDEF: int            pid_t
 TYPEDEF: int            time_t
diff --git a/extra/unix/unix.factor b/extra/unix/unix.factor
index 09d77fee11..d02e180cff 100755
--- a/extra/unix/unix.factor
+++ b/extra/unix/unix.factor
@@ -149,6 +149,5 @@ FUNCTION: ssize_t write ( int fd, void* buf, size_t nbytes ) ;
     { [ linux? ] [ "unix.linux" require ] }
     { [ bsd? ] [ "unix.bsd" require ] }
     { [ solaris? ] [ "unix.solaris" require ] }
-    { [ t ] [ ] }
 } cond
 

From b993a1c588c5bf091e353d84bd3295081f3e05f2 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sat, 14 Apr 2007 04:27:28 -0500
Subject: [PATCH 02/24] more constants

---
 build-support/grovel.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/build-support/grovel.c b/build-support/grovel.c
index 8422ec197c..1260b29c80 100644
--- a/build-support/grovel.c
+++ b/build-support/grovel.c
@@ -141,10 +141,12 @@ void unix_constants()
 	constant(EINTR);
 	constant(EAGAIN);
 	constant(EINPROGRESS);
-    constant(PROT_READ);
+    	constant(PROT_READ);
 	constant(PROT_WRITE);
 	constant(MAP_FILE);
 	constant(MAP_SHARED);
+	grovel(pid_t);
+
 }
 	
 int main() {
@@ -158,6 +160,10 @@ int main() {
 	openbsd_stat();
 	openbsd_types();
 #endif
+	grovel(blkcnt_t);
+        grovel(blksize_t);
+        //grovel(fflags_t);
+        grovel(ssize_t);
 
 #ifdef UNIX
 	unix_types();

From bc5f82255fbdeeb11f3b3cfef555856ec2dcb8cf Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Thu, 27 Mar 2008 17:24:05 +1300
Subject: [PATCH 03/24] peg refactorings

---
 extra/peg/peg.factor | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index 10c9ce907d..0ae2aba2ee 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -24,8 +24,13 @@ SYMBOL: packrat
 
 GENERIC: (compile) ( parser -- quot )
 
+: input-from ( input -- n )
+  #! Return the index from the original string that the
+  #! input slice is based on.
+  dup slice? [ slice-from ] [ drop 0 ] if ;
+
 :: run-packrat-parser ( input quot c -- result )
-  input slice? [ input slice-from ] [ 0 ] if
+  input input-from
   quot c [ drop H{ } clone ] cache 
   [
     drop input quot call  

From 4c50daed2213b9442954aec3a38abb51586fd05c Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Thu, 27 Mar 2008 17:45:59 +1300
Subject: [PATCH 04/24] Testcase for packrat behaviour

---
 extra/peg/peg-tests.factor | 20 ++++++++++++++++++++
 extra/peg/peg.factor       | 18 ++++++++++++++----
 2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor
index 89cc243863..bd4699f097 100644
--- a/extra/peg/peg-tests.factor
+++ b/extra/peg/peg-tests.factor
@@ -158,3 +158,23 @@ IN: peg.tests
   "a]" "[" token hide "a" token "]" token hide 3array seq parse 
 ] unit-test
 
+
+{ V{ "1" "-" "1" } V{ "1" "+" "1" } } [
+  [
+    [ "1" token , "-" token , "1" token , ] seq* ,
+    [ "1" token , "+" token , "1" token , ] seq* ,
+  ] choice* 
+  "1-1" over parse parse-result-ast swap
+  "1+1" swap parse parse-result-ast
+] unit-test
+
+{ V{ "1" "-" "1" } V{ "1" "+" "1" } } [
+  [ 
+    [
+      [ "1" token , "-" token , "1" token , ] seq* ,
+      [ "1" token , "+" token , "1" token , ] seq* ,
+    ] choice* 
+    "1-1" over parse parse-result-ast swap
+    "1+1" swap parse parse-result-ast
+  ] with-packrat
+] unit-test
\ No newline at end of file
diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index 0ae2aba2ee..bbd55ec6fa 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -29,12 +29,22 @@ GENERIC: (compile) ( parser -- quot )
   #! input slice is based on.
   dup slice? [ slice-from ] [ drop 0 ] if ;
 
+: input-cache ( quot cache -- cache )
+  #! From the packrat cache, obtain the cache for the parser quotation 
+  #! that maps the input string position to the parser result.
+  [ drop H{ } clone ] cache ;
+
+: cached-result ( n input-cache input quot -- result )
+  #! Get the cached result for input position n
+  #! from the input cache. If the item is not in the cache,
+  #! call 'quot' with 'input' on the stack to get the result
+  #! and store that in the cache and return it.
+  [ nip ] swap compose curry cache ; inline
+
 :: run-packrat-parser ( input quot c -- result )
   input input-from
-  quot c [ drop H{ } clone ] cache 
-  [
-    drop input quot call  
-  ] cache ; inline
+  quot c input-cache 
+  input quot cached-result ; inline
 
 : run-parser ( input quot -- result )
   #! If a packrat cache is available, use memoization for

From 4e29081e93aadb902ebbcc27d9c2049d73434adb Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Thu, 27 Mar 2008 18:07:30 +1300
Subject: [PATCH 05/24] Make left recursion in pegs a failed parse Eventually
 left recursion will work fine, but this is prevents an infinite loop for now.

---
 extra/peg/peg-tests.factor | 4 +++-
 extra/peg/peg.factor       | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor
index bd4699f097..bd8abb63e6 100644
--- a/extra/peg/peg-tests.factor
+++ b/extra/peg/peg-tests.factor
@@ -175,6 +175,8 @@ IN: peg.tests
       [ "1" token , "+" token , "1" token , ] seq* ,
     ] choice* 
     "1-1" over parse parse-result-ast swap
-    "1+1" swap parse parse-result-ast
   ] with-packrat
+  [
+    "1+1" swap parse parse-result-ast
+  ] with-packrat 
 ] unit-test
\ No newline at end of file
diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index bbd55ec6fa..1361f9fdbd 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -34,12 +34,12 @@ GENERIC: (compile) ( parser -- quot )
   #! that maps the input string position to the parser result.
   [ drop H{ } clone ] cache ;
 
-: cached-result ( n input-cache input quot -- result )
+:: cached-result ( n input-cache input quot -- result )
   #! Get the cached result for input position n
   #! from the input cache. If the item is not in the cache,
   #! call 'quot' with 'input' on the stack to get the result
   #! and store that in the cache and return it.
-  [ nip ] swap compose curry cache ; inline
+  n input-cache [ drop input quot call ] cache ; inline
 
 :: run-packrat-parser ( input quot c -- result )
   input input-from

From f6b7f8197e5e1bf033157bdcd389aa216383a29e Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Thu, 27 Mar 2008 23:54:34 +1300
Subject: [PATCH 06/24] Add tests for left recusion in pegs

---
 extra/peg/ebnf/ebnf-tests.factor | 30 +++++++++++++++++++++++++++++-
 extra/peg/ebnf/ebnf.factor       |  4 ++--
 extra/peg/peg-tests.factor       | 18 +++++++++++++++++-
 extra/peg/peg.factor             |  6 +++++-
 4 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/extra/peg/ebnf/ebnf-tests.factor b/extra/peg/ebnf/ebnf-tests.factor
index c9b9f5d977..dea549eb37 100644
--- a/extra/peg/ebnf/ebnf-tests.factor
+++ b/extra/peg/ebnf/ebnf-tests.factor
@@ -142,4 +142,32 @@ IN: peg.ebnf.tests
 
 { f } [
   "Z" [EBNF foo=[^A-Z] EBNF] call  
-] unit-test
\ No newline at end of file
+] unit-test
+
+[ 
+  #! Test direct left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  #! Not using packrat, so recursion causes data stack overflow  
+  "1+1" [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call
+] must-fail
+
+{ V{ 49 } } [ 
+  #! Test direct left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  #! Using packrat, so first part of expr fails, causing 2nd choice to be used  
+  "1+1" [ [EBNF num=([0-9])+ expr=expr "+" num | num EBNF] call ] with-packrat parse-result-ast
+] unit-test
+
+[ 
+  #! Test indirect left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  #! Not using packrat, so recursion causes data stack overflow  
+  "1+1" [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call
+] must-fail
+
+{ V{ 49 } } [ 
+  #! Test indirect left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  #! Using packrat, so first part of expr fails, causing 2nd choice to be used  
+  "1+1" [ [EBNF num=([0-9])+ x=expr expr=x "+" num | num EBNF] call ] with-packrat parse-result-ast
+] unit-test
diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor
index 11e1e2ea64..be4beab3f1 100644
--- a/extra/peg/ebnf/ebnf.factor
+++ b/extra/peg/ebnf/ebnf.factor
@@ -266,7 +266,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   ] [ ] make delay sp ;
 
 : transform-ebnf ( string -- object )
-  'ebnf' parse parse-result-ast transform ;
+  'ebnf' [ parse ] packrat-parse parse-result-ast transform ;
 
 : check-parse-result ( result -- result )
   dup [
@@ -281,7 +281,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   ] if ;
 
 : ebnf>quot ( string -- hashtable quot )
-  'ebnf' parse check-parse-result 
+  'ebnf' [ parse ] with-packrat check-parse-result 
   parse-result-ast transform dup main swap at compile 1quotation ;
 
 : [EBNF "EBNF]" parse-multiline-string ebnf>quot nip parsed ; parsing
diff --git a/extra/peg/peg-tests.factor b/extra/peg/peg-tests.factor
index bd8abb63e6..cd95bd3b93 100644
--- a/extra/peg/peg-tests.factor
+++ b/extra/peg/peg-tests.factor
@@ -179,4 +179,20 @@ IN: peg.tests
   [
     "1+1" swap parse parse-result-ast
   ] with-packrat 
-] unit-test
\ No newline at end of file
+] unit-test
+
+: expr ( -- parser ) 
+  #! Test direct left recursion. Currently left recursion should cause a
+  #! failure of that parser.
+  [ expr ] delay "+" token "1" token 3seq "1" token 2choice ;
+
+[
+  #! Not using packrat, so recursion causes data stack overflow  
+  "1+1" expr parse parse-result-ast   
+] must-fail
+
+{ "1" } [
+  #! Using packrat, so expr fails, causing the 2nd choice to be used.  
+  "1+1" expr [ parse ] with-packrat parse-result-ast   
+] unit-test
+
diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index 1361f9fdbd..e5632d645c 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -39,7 +39,11 @@ GENERIC: (compile) ( parser -- quot )
   #! from the input cache. If the item is not in the cache,
   #! call 'quot' with 'input' on the stack to get the result
   #! and store that in the cache and return it.
-  n input-cache [ drop input quot call ] cache ; inline
+  n input-cache [ 
+    drop
+    f n input-cache set-at
+    input quot call 
+  ] cache ; inline
 
 :: run-packrat-parser ( input quot c -- result )
   input input-from

From fa8b311b277582adbcdf5fe9e6aca747b1cd5322 Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Fri, 28 Mar 2008 00:04:08 +1300
Subject: [PATCH 07/24] Add packrat-parse, etc

---
 extra/peg/ebnf/ebnf.factor |  4 ++--
 extra/peg/peg-docs.factor  | 30 ++++++++++++++++++++++++++----
 extra/peg/peg.factor       | 10 ++++++++--
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/extra/peg/ebnf/ebnf.factor b/extra/peg/ebnf/ebnf.factor
index be4beab3f1..ed0dea0410 100644
--- a/extra/peg/ebnf/ebnf.factor
+++ b/extra/peg/ebnf/ebnf.factor
@@ -266,7 +266,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   ] [ ] make delay sp ;
 
 : transform-ebnf ( string -- object )
-  'ebnf' [ parse ] packrat-parse parse-result-ast transform ;
+  'ebnf' packrat-parse parse-result-ast transform ;
 
 : check-parse-result ( result -- result )
   dup [
@@ -281,7 +281,7 @@ M: ebnf-non-terminal (transform) ( ast -- parser )
   ] if ;
 
 : ebnf>quot ( string -- hashtable quot )
-  'ebnf' [ parse ] with-packrat check-parse-result 
+  'ebnf' packrat-parse check-parse-result 
   parse-result-ast transform dup main swap at compile 1quotation ;
 
 : [EBNF "EBNF]" parse-multiline-string ebnf>quot nip parsed ; parsing
diff --git a/extra/peg/peg-docs.factor b/extra/peg/peg-docs.factor
index 30e7f0e72f..c93d1af830 100644
--- a/extra/peg/peg-docs.factor
+++ b/extra/peg/peg-docs.factor
@@ -12,7 +12,7 @@ HELP: parse
 { $description 
     "Given the input string, parse it using the given parser. The result is a <parse-result> object if "
     "the parse was successful, otherwise it is f." } 
-{ $see-also compile with-packrat } ;
+{ $see-also compile with-packrat packrat-parse } ;
 
 HELP: with-packrat
 { $values 
@@ -23,8 +23,30 @@ HELP: with-packrat
     "Calls the quotation with a packrat cache in scope. Usually the quotation will "
     "call " { $link parse } " or call a word produced by " { $link compile } "."
     "The cache is used to avoid the possible exponential time performace that pegs "
-    "can have, instead giving linear time at the cost of increased memory usage."  } 
-{ $see-also compile parse } ;
+    "can have, instead giving linear time at the cost of increased memory usage. "
+    "Use of this packrat option also allows direct and indirect recursion to "
+    "be handled in the parser without entering an infinite loop."  } 
+{ $see-also compile parse packrat-parse packrat-call } ;
+
+HELP: packrat-parse
+{ $values 
+  { "input" "a string" } 
+  { "parser" "a parser" } 
+  { "result" "a parse-result or f" } 
+}
+{ $description 
+    "Compiles and calls the parser with a packrat cache in scope."  } 
+{ $see-also compile parse packrat-call with-packrat } ;
+
+HELP: packrat-call
+{ $values 
+  { "input" "a string" } 
+  { "quot" "a quotation with stack effect ( input -- result )" } 
+  { "result" "a parse-result or f" } 
+}
+{ $description 
+    "Calls the compiled parser with a packrat cache in scope."  } 
+{ $see-also compile packrat-call packrat-parse with-packrat } ;
 
 HELP: compile
 { $values 
@@ -36,7 +58,7 @@ HELP: compile
     "The mapping from parser to compiled word is kept in a cache. If you later change "
     "the definition of a parser you'll need to clear this cache with " 
     { $link reset-compiled-parsers } " before using " { $link compile } " on that parser again." } 
-{ $see-also compile with-packrat reset-compiled-parsers } ;
+{ $see-also compile with-packrat reset-compiled-parsers packrat-call packrat-parse } ;
 
 HELP: reset-compiled-parsers
 { $description 
diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index e5632d645c..246dbc7962 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -67,11 +67,17 @@ GENERIC: (compile) ( parser -- quot )
   [ compiled-parser ] with-compilation-unit ;
 
 : parse ( state parser -- result )
-  compile execute ;
+  compile execute ; inline
 
 : with-packrat ( quot -- result )
   #! Run the quotation with a packrat cache active.
-  [ H{ } clone packrat ] dip with-variable ;
+  [ H{ } clone packrat ] dip with-variable ; inline
+
+: packrat-parse ( state parser -- result )
+  [ parse ] with-packrat ;
+
+: packrat-call ( state quot -- result )
+  with-packrat ; inline
 
 <PRIVATE
 

From 4c449296b207fba5ba4de2125e0e6beb5ef93292 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Thu, 27 Mar 2008 11:18:32 -0500
Subject: [PATCH 08/24] Fix NetBSD FFI

---
 core/cpu/x86/architecture/architecture.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/cpu/x86/architecture/architecture.factor b/core/cpu/x86/architecture/architecture.factor
index 49b05ea48f..f993639c05 100755
--- a/core/cpu/x86/architecture/architecture.factor
+++ b/core/cpu/x86/architecture/architecture.factor
@@ -156,7 +156,7 @@ M: x86-backend %unbox-small-struct ( size -- )
 
 M: x86-backend struct-small-enough? ( size -- ? )
     { 1 2 4 8 } member?
-    os { "linux" "solaris" } member? not and ;
+    os { "linux" "netbsd" "solaris" } member? not and ;
 
 M: x86-backend %return ( -- ) 0 %unwind ;
 

From aad587d6647607042bbbed72e59cbbb67d801c46 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Thu, 27 Mar 2008 11:48:51 -0500
Subject: [PATCH 09/24] Fix deploy test

---
 extra/tools/deploy/deploy-tests.factor | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/extra/tools/deploy/deploy-tests.factor b/extra/tools/deploy/deploy-tests.factor
index 8db34320de..5030763a3d 100755
--- a/extra/tools/deploy/deploy-tests.factor
+++ b/extra/tools/deploy/deploy-tests.factor
@@ -1,10 +1,11 @@
 IN: tools.deploy.tests
 USING: tools.test system io.files kernel tools.deploy.config
 tools.deploy.backend math sequences io.launcher arrays
-namespaces ;
+namespaces continuations ;
 
 : shake-and-bake ( vocab -- )
-    "." resource-path [
+    [ "test.image" temp-file delete-file ] ignore-errors
+    "resource:" [
         >r vm
         "test.image" temp-file
         r> dup deploy-config make-deploy-image

From 89c76987388ad917247caed9f618c2253dfeb5da Mon Sep 17 00:00:00 2001
From: Chris Double <chris@bethia.(none)>
Date: Fri, 28 Mar 2008 11:30:46 +1300
Subject: [PATCH 10/24] Fix MEMO problem with seq* and choice*

---
 extra/peg/peg.factor | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/extra/peg/peg.factor b/extra/peg/peg.factor
index 246dbc7962..709052b7dd 100755
--- a/extra/peg/peg.factor
+++ b/extra/peg/peg.factor
@@ -338,7 +338,7 @@ MEMO: 3seq ( parser1 parser2 parser3 -- parser )
 MEMO: 4seq ( parser1 parser2 parser3 parser4 -- parser )
   4array seq ;
 
-MEMO: seq* ( quot -- paser )
+: seq* ( quot -- paser )
   { } make seq ; inline 
 
 MEMO: choice ( seq -- parser )
@@ -353,7 +353,7 @@ MEMO: 3choice ( parser1 parser2 parser3 -- parser )
 MEMO: 4choice ( parser1 parser2 parser3 parser4 -- parser )
   4array choice ;
 
-MEMO: choice* ( quot -- paser )
+: choice* ( quot -- paser )
   { } make choice ; inline 
 
 MEMO: repeat0 ( parser -- parser )

From ea94662abd7abe4b19ccd6e0a7eaf17211792db2 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sat, 14 Apr 2007 05:49:09 -0500
Subject: [PATCH 11/24] NetBSD x86/64 fixes

---
 vm/{os-linux-x86-32.h => os-linux-x86.32.h} |  0
 vm/{os-linux-x86-64.h => os-linux-x86.64.h} |  0
 vm/os-netbsd-x86.32.h                       |  3 +++
 vm/os-netbsd-x86.64.h                       |  4 ++++
 vm/os-netbsd.h                              |  1 -
 vm/platform.h                               | 13 +++++++++++--
 6 files changed, 18 insertions(+), 3 deletions(-)
 rename vm/{os-linux-x86-32.h => os-linux-x86.32.h} (100%)
 rename vm/{os-linux-x86-64.h => os-linux-x86.64.h} (100%)
 create mode 100644 vm/os-netbsd-x86.32.h
 create mode 100644 vm/os-netbsd-x86.64.h

diff --git a/vm/os-linux-x86-32.h b/vm/os-linux-x86.32.h
similarity index 100%
rename from vm/os-linux-x86-32.h
rename to vm/os-linux-x86.32.h
diff --git a/vm/os-linux-x86-64.h b/vm/os-linux-x86.64.h
similarity index 100%
rename from vm/os-linux-x86-64.h
rename to vm/os-linux-x86.64.h
diff --git a/vm/os-netbsd-x86.32.h b/vm/os-netbsd-x86.32.h
new file mode 100644
index 0000000000..ca4a9f88f5
--- /dev/null
+++ b/vm/os-netbsd-x86.32.h
@@ -0,0 +1,3 @@
+#include <ucontext.h>
+
+#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
diff --git a/vm/os-netbsd-x86.64.h b/vm/os-netbsd-x86.64.h
new file mode 100644
index 0000000000..587dc85ec7
--- /dev/null
+++ b/vm/os-netbsd-x86.64.h
@@ -0,0 +1,4 @@
+#include <ucontext.h>
+
+#define ucontext_stack_pointer(uap) \
+	((void *)(((ucontext_t *)(uap))->uc_mcontext.__gregs[_REG_URSP]))
diff --git a/vm/os-netbsd.h b/vm/os-netbsd.h
index e282828577..b42c6b9d7e 100644
--- a/vm/os-netbsd.h
+++ b/vm/os-netbsd.h
@@ -1,6 +1,5 @@
 #include <ucontext.h>
 
-#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
 #define UAP_PROGRAM_COUNTER(uap)    _UC_MACHINE_PC((ucontext_t *)uap)
 
 #define UNKNOWN_TYPE_P(file) ((file)->d_type == DT_UNKNOWN)
diff --git a/vm/platform.h b/vm/platform.h
index cd2b6e0a0e..7678d483d6 100644
--- a/vm/platform.h
+++ b/vm/platform.h
@@ -67,20 +67,29 @@
 			#endif
 		#elif defined(__NetBSD__)
 			#define FACTOR_OS_STRING "netbsd"
+
+			#if defined(FACTOR_X86)
+				#include "os-netbsd-x86.32.h"
+			#elif defined(FACTOR_AMD64)
+				#include "os-netbsd-x86.64.h"
+			#else
+				#error "Unsupported NetBSD flavor"
+			#endif
+
 			#include "os-netbsd.h"
 		#elif defined(linux)
 			#define FACTOR_OS_STRING "linux"
 			#include "os-linux.h"
 
 			#if defined(FACTOR_X86)
-				#include "os-linux-x86-32.h"
+				#include "os-linux-x86.32.h"
 			#elif defined(FACTOR_PPC)
 				#include "os-unix-ucontext.h"
 				#include "os-linux-ppc.h"
 			#elif defined(FACTOR_ARM)
 				#include "os-linux-arm.h"
 			#elif defined(FACTOR_AMD64)
-				#include "os-linux-x86-64.h"
+				#include "os-linux-x86.64.h"
 			#else
 				#error "Unsupported Linux flavor"
 			#endif

From d7872708a0d36fcc70290d23b94659ca7efed5a1 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sat, 14 Apr 2007 06:13:34 -0500
Subject: [PATCH 12/24] Fix 64-bit stat

---
 extra/unix/stat/netbsd/64/64.factor | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/extra/unix/stat/netbsd/64/64.factor b/extra/unix/stat/netbsd/64/64.factor
index f1f6f93dbd..46ab43eeca 100644
--- a/extra/unix/stat/netbsd/64/64.factor
+++ b/extra/unix/stat/netbsd/64/64.factor
@@ -20,8 +20,10 @@ C-STRUCT: stat
     { "uint32_t" "st_flags" }
     { "uint32_t" "st_gen" }
     { "uint32_t" "st_spare0" }
-    { "timespec" "st_birthtim" }
-    { "int" "__pad5" } ;
+    { "timespec" "st_birthtim" } ;
 
-FUNCTION: int stat  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat ( char* pathname, stat* buf ) ;
+FUNCTION: int __stat13 ( char* pathname, stat* buf ) ;
+FUNCTION: int __lstat13 ( char* pathname, stat* buf ) ;
+
+: stat __stat13 ; inline
+: lstat __lstat13 ; inline

From 0a34198912cc6b4c7054c661d8861e0faa4cb4cc Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Sat, 14 Apr 2007 06:24:02 -0500
Subject: [PATCH 13/24] Working on kqueue

---
 extra/unix/kqueue/freebsd/freebsd.factor | 13 +++++++++++++
 extra/unix/kqueue/kqueue.factor          | 15 +++------------
 extra/unix/kqueue/macosx/macosx.factor   | 13 +++++++++++++
 extra/unix/kqueue/netbsd/netbsd.factor   | 14 ++++++++++++++
 extra/unix/kqueue/openbsd/openbsd.factor | 14 ++++++++++++++
 5 files changed, 57 insertions(+), 12 deletions(-)
 create mode 100644 extra/unix/kqueue/freebsd/freebsd.factor
 create mode 100644 extra/unix/kqueue/macosx/macosx.factor
 create mode 100644 extra/unix/kqueue/netbsd/netbsd.factor
 create mode 100644 extra/unix/kqueue/openbsd/openbsd.factor

diff --git a/extra/unix/kqueue/freebsd/freebsd.factor b/extra/unix/kqueue/freebsd/freebsd.factor
new file mode 100644
index 0000000000..4cc539daa3
--- /dev/null
+++ b/extra/unix/kqueue/freebsd/freebsd.factor
@@ -0,0 +1,13 @@
+USE: alien.syntax
+IN: unix.kqueue
+
+C-STRUCT: kevent
+    { "ulong"  "ident"  } ! identifier for this event
+    { "short"  "filter" } ! filter for event
+    { "ushort" "flags"  } ! action flags for kqueue
+    { "uint"   "fflags" } ! filter flag value
+    { "long"   "data"   } ! filter data value
+    { "void*"  "udata"  } ! opaque user data identifier
+;
+
+FUNCTION: int kevent ( int kq, kevent* changelist, int nchanges, kevent* eventlist, int nevents, timespec* timeout ) ;
diff --git a/extra/unix/kqueue/kqueue.factor b/extra/unix/kqueue/kqueue.factor
index 4e6504470d..8166052b01 100644
--- a/extra/unix/kqueue/kqueue.factor
+++ b/extra/unix/kqueue/kqueue.factor
@@ -1,21 +1,12 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien.syntax ;
+USING: alien.syntax system sequences vocabs.loader ;
 IN: unix.kqueue
 
+<< "unix.kqueue." os append require >>
+
 FUNCTION: int kqueue ( ) ;
 
-FUNCTION: int kevent ( int kq, kevent* changelist, int nchanges, kevent* eventlist, int nevents, timespec* timeout ) ;
-
-C-STRUCT: kevent
-    { "ulong"  "ident"  } ! identifier for this event
-    { "short"  "filter" } ! filter for event
-    { "ushort" "flags"  } ! action flags for kqueue
-    { "uint"   "fflags" } ! filter flag value
-    { "long"   "data"   } ! filter data value
-    { "void*"  "udata"  } ! opaque user data identifier
-;
-
 : EVFILT_READ     -1 ; inline
 : EVFILT_WRITE    -2 ; inline
 : EVFILT_AIO      -3 ; inline ! attached to aio requests
diff --git a/extra/unix/kqueue/macosx/macosx.factor b/extra/unix/kqueue/macosx/macosx.factor
new file mode 100644
index 0000000000..4cc539daa3
--- /dev/null
+++ b/extra/unix/kqueue/macosx/macosx.factor
@@ -0,0 +1,13 @@
+USE: alien.syntax
+IN: unix.kqueue
+
+C-STRUCT: kevent
+    { "ulong"  "ident"  } ! identifier for this event
+    { "short"  "filter" } ! filter for event
+    { "ushort" "flags"  } ! action flags for kqueue
+    { "uint"   "fflags" } ! filter flag value
+    { "long"   "data"   } ! filter data value
+    { "void*"  "udata"  } ! opaque user data identifier
+;
+
+FUNCTION: int kevent ( int kq, kevent* changelist, int nchanges, kevent* eventlist, int nevents, timespec* timeout ) ;
diff --git a/extra/unix/kqueue/netbsd/netbsd.factor b/extra/unix/kqueue/netbsd/netbsd.factor
new file mode 100644
index 0000000000..7e97f3bcff
--- /dev/null
+++ b/extra/unix/kqueue/netbsd/netbsd.factor
@@ -0,0 +1,14 @@
+USE: alien.syntax
+IN: unix.kqueue
+
+C-STRUCT: kevent
+    { "ulong"    "ident"  } ! identifier for this event
+    { "uint"     "filter" } ! filter for event
+    { "uint"     "flags"  } ! action flags for kqueue
+    { "uint"     "fflags" } ! filter flag value
+    { "longlong" "data"   } ! filter data value
+    { "void*"    "udata"  } ! opaque user data identifier
+;
+
+FUNCTION: int kevent ( int kq, kevent* changelist, size_t nchanges, kevent* eventlist, size_t nevents, timespec* timeout ) ;
+
diff --git a/extra/unix/kqueue/openbsd/openbsd.factor b/extra/unix/kqueue/openbsd/openbsd.factor
new file mode 100644
index 0000000000..7e97f3bcff
--- /dev/null
+++ b/extra/unix/kqueue/openbsd/openbsd.factor
@@ -0,0 +1,14 @@
+USE: alien.syntax
+IN: unix.kqueue
+
+C-STRUCT: kevent
+    { "ulong"    "ident"  } ! identifier for this event
+    { "uint"     "filter" } ! filter for event
+    { "uint"     "flags"  } ! action flags for kqueue
+    { "uint"     "fflags" } ! filter flag value
+    { "longlong" "data"   } ! filter data value
+    { "void*"    "udata"  } ! opaque user data identifier
+;
+
+FUNCTION: int kevent ( int kq, kevent* changelist, size_t nchanges, kevent* eventlist, size_t nevents, timespec* timeout ) ;
+

From b2a430629b2121fd764031d36f7a8b92001fb51d Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 26 Mar 2008 14:55:04 -0500
Subject: [PATCH 14/24] fix wordpad

---
 extra/editors/editors.factor         | 7 ++++---
 extra/editors/wordpad/wordpad.factor | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/extra/editors/editors.factor b/extra/editors/editors.factor
index 67e515ebc1..bfbfe1b6ca 100755
--- a/extra/editors/editors.factor
+++ b/extra/editors/editors.factor
@@ -1,8 +1,9 @@
-! Copyright (C) 2005, 2007 Slava Pestov.
+! Copyright (C) 2005, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: parser kernel namespaces sequences definitions io.files
 inspector continuations tuples tools.crossref tools.vocabs 
-io prettyprint source-files assocs vocabs vocabs.loader ;
+io prettyprint source-files assocs vocabs vocabs.loader
+io.backend splitting ;
 IN: editors
 
 TUPLE: no-edit-hook ;
@@ -25,7 +26,7 @@ SYMBOL: edit-hook
     require ;
 
 : edit-location ( file line -- )
-    >r current-directory get prepend-path r>
+    >r normalize-pathname "\\\\?\\" ?head drop r>
     edit-hook get [ call ] [ no-edit-hook edit-location ] if* ;
 
 : edit ( defspec -- )
diff --git a/extra/editors/wordpad/wordpad.factor b/extra/editors/wordpad/wordpad.factor
index d1f979e0f3..3f3dd6cab1 100755
--- a/extra/editors/wordpad/wordpad.factor
+++ b/extra/editors/wordpad/wordpad.factor
@@ -5,10 +5,10 @@ IN: editors.wordpad
 
 : wordpad-path ( -- path )
     \ wordpad-path get [
-        program-files "\\Windows NT\\Accessories\\wordpad.exe" append-path
+        program-files "Windows NT\\Accessories\\wordpad.exe" append-path
     ] unless* ;
 
 : wordpad ( file line -- )
-    drop wordpad-path swap 2array run-detached drop ;
+    drop wordpad-path swap 2array dup . run-detached drop ;
 
 [ wordpad ] edit-hook set-global

From 8939dd49718c6573e674fb5d7e1914f05ec8b137 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Wed, 26 Mar 2008 14:57:35 -0500
Subject: [PATCH 15/24] add path-separator

---
 core/io/files/files.factor | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/core/io/files/files.factor b/core/io/files/files.factor
index 60943be48c..48098e612d 100755
--- a/core/io/files/files.factor
+++ b/core/io/files/files.factor
@@ -45,6 +45,8 @@ HOOK: (file-appender) io-backend ( path -- stream )
 ! Pathnames
 : path-separator? ( ch -- ? ) windows? "/\\" "/" ? member? ;
 
+: path-separator ( -- string ) windows? "\\" "/" ? ;
+
 : right-trim-separators ( str -- newstr )
     [ path-separator? ] right-trim ;
 

From c300d4482a3038533b4324e4f941fbe830d0574b Mon Sep 17 00:00:00 2001
From: sheeple <sheeple@self.internal.stack-effects.com>
Date: Thu, 27 Mar 2008 11:14:40 -0500
Subject: [PATCH 16/24] rm staging files in temp/

---
 misc/factor.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/misc/factor.sh b/misc/factor.sh
index 1fe003994c..09531350f3 100755
--- a/misc/factor.sh
+++ b/misc/factor.sh
@@ -306,7 +306,7 @@ update_boot_images() {
     echo "Deleting old images..."
     rm checksums.txt* > /dev/null 2>&1
     rm $BOOT_IMAGE.* > /dev/null 2>&1
-    rm staging.*.image > /dev/null 2>&1
+    rm temp/staging.*.image > /dev/null 2>&1
     if [[ -f $BOOT_IMAGE ]] ; then
         get_url http://factorcode.org/images/latest/checksums.txt
         factorcode_md5=`cat checksums.txt|grep $BOOT_IMAGE|cut -f2 -d' '`;

From f0a900d11b7446dc7cbbb0d617c517818232ae3d Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@factorcode.org>
Date: Thu, 27 Mar 2008 17:12:39 -0500
Subject: [PATCH 17/24] Fix Windows bootstrap

---
 core/io/backend/backend.factor | 6 ++++--
 core/io/files/files.factor     | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/core/io/backend/backend.factor b/core/io/backend/backend.factor
index 151dbc7df7..6bcd448385 100755
--- a/core/io/backend/backend.factor
+++ b/core/io/backend/backend.factor
@@ -1,6 +1,7 @@
 ! Copyright (C) 2007, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: init kernel system namespaces io io.encodings io.encodings.utf8 ;
+USING: init kernel system namespaces io io.encodings
+io.encodings.utf8 init assocs ;
 IN: io.backend
 
 SYMBOL: io-backend
@@ -22,7 +23,8 @@ HOOK: normalize-pathname io-backend ( str -- newstr )
 M: object normalize-directory normalize-pathname ;
 
 : set-io-backend ( io-backend -- )
-    io-backend set-global init-io init-stdio ;
+    io-backend set-global init-io init-stdio
+    "io.files" init-hooks get at call ;
 
 [ init-io embedded? [ init-stdio ] unless ]
 "io.backend" add-init-hook
diff --git a/core/io/files/files.factor b/core/io/files/files.factor
index f6888bf78d..436bf8598d 100755
--- a/core/io/files/files.factor
+++ b/core/io/files/files.factor
@@ -170,7 +170,7 @@ SYMBOL: current-directory
 
 M: object cwd ( -- path ) "." ;
 
-[ cwd current-directory set-global ] "current-directory" add-init-hook
+[ cwd current-directory set-global ] "io.files" add-init-hook
 
 : with-directory ( path quot -- )
     current-directory swap with-variable ; inline

From 2ff18ddea8f0ae5653eeb979afc5bc13a93f25b6 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@factorcode.org>
Date: Thu, 27 Mar 2008 17:12:47 -0500
Subject: [PATCH 18/24] Fix editors.jedit

---
 extra/editors/jedit/jedit.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 mode change 100644 => 100755 extra/editors/jedit/jedit.factor

diff --git a/extra/editors/jedit/jedit.factor b/extra/editors/jedit/jedit.factor
old mode 100644
new mode 100755
index 7b6066df7c..92320addef
--- a/extra/editors/jedit/jedit.factor
+++ b/extra/editors/jedit/jedit.factor
@@ -8,7 +8,7 @@ io.encodings.utf8 ;
 IN: editors.jedit
 
 : jedit-server-info ( -- port auth )
-    home "/.jedit/server" append-path ascii [
+    home ".jedit/server" append-path ascii [
         readln drop
         readln string>number
         readln string>number

From 8c5e01703d21074d262cc94663b8efb4178053dc Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@oberon.internal.stack-effects.com>
Date: Thu, 27 Mar 2008 17:19:48 -0500
Subject: [PATCH 19/24] Fixing deployment

---
 extra/tools/deploy/macosx/macosx.factor | 17 +++++++++--------
 extra/tools/deploy/shaker/shaker.factor |  2 +-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/extra/tools/deploy/macosx/macosx.factor b/extra/tools/deploy/macosx/macosx.factor
index 9fe35647fe..6d9c8e9d8a 100755
--- a/extra/tools/deploy/macosx/macosx.factor
+++ b/extra/tools/deploy/macosx/macosx.factor
@@ -62,11 +62,12 @@ T{ macosx-deploy-implementation } deploy-implementation set-global
 
 M: macosx-deploy-implementation deploy* ( vocab -- )
     ".app deploy tool" assert.app
-    "." resource-path cd
-    dup deploy-config [
-        bundle-name dup exists? [ delete-tree ] [ drop ] if
-        [ bundle-name create-app-dir ] keep
-        [ bundle-name deploy.app-image ] keep
-        namespace make-deploy-image
-        bundle-name show-in-finder
-    ] bind ;
+    "resource:" [
+        dup deploy-config [
+            bundle-name dup exists? [ delete-tree ] [ drop ] if
+            [ bundle-name create-app-dir ] keep
+            [ bundle-name deploy.app-image ] keep
+            namespace make-deploy-image
+            bundle-name show-in-finder
+        ] bind
+    ] with-directory ;
diff --git a/extra/tools/deploy/shaker/shaker.factor b/extra/tools/deploy/shaker/shaker.factor
index cf23e42283..ee9c2b9fab 100755
--- a/extra/tools/deploy/shaker/shaker.factor
+++ b/extra/tools/deploy/shaker/shaker.factor
@@ -81,7 +81,7 @@ IN: tools.deploy.shaker
     [
         "class" ,
         "metaclass" ,
-        "slot-names" ,
+        "layout" ,
         deploy-ui? get [
             "gestures" ,
             "commands" ,

From f09547ece13321bcc61dd1fa733daf02909472b5 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@factorcode.org>
Date: Thu, 27 Mar 2008 17:47:04 -0500
Subject: [PATCH 20/24] Fix mirrors docs

---
 core/mirrors/mirrors-docs.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/mirrors/mirrors-docs.factor b/core/mirrors/mirrors-docs.factor
index 29ed153a2e..725a757e61 100755
--- a/core/mirrors/mirrors-docs.factor
+++ b/core/mirrors/mirrors-docs.factor
@@ -36,7 +36,7 @@ HELP: <mirror>
         "TUPLE: circle center radius ;"
         "C: <circle> circle"
         "{ 100 50 } 15 <circle> <mirror> >alist ."
-        "{ { \"center\" { 100 50 } } { \"radius\" 15 } }"
+        "{ { \"delegate\" f } { \"center\" { 100 50 } } { \"radius\" 15 } }"
     }
 } ;
 

From 7616eefbfcadc3c4ef551702788267372b4b2782 Mon Sep 17 00:00:00 2001
From: Slava Pestov <slava@factorcode.org>
Date: Thu, 27 Mar 2008 18:00:55 -0500
Subject: [PATCH 21/24] Fix editor integration

---
 extra/editors/editors.factor | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/extra/editors/editors.factor b/extra/editors/editors.factor
index 89aef4d819..67e515ebc1 100755
--- a/extra/editors/editors.factor
+++ b/extra/editors/editors.factor
@@ -25,11 +25,8 @@ SYMBOL: edit-hook
     require ;
 
 : edit-location ( file line -- )
-    edit-hook get [
-        call
-    ] [
-        no-edit-hook edit-location
-    ] if* ;
+    >r current-directory get prepend-path r>
+    edit-hook get [ call ] [ no-edit-hook edit-location ] if* ;
 
 : edit ( defspec -- )
     where [ first2 edit-location ] when* ;

From d8fc44662286db830264df286be0bb84e91151c0 Mon Sep 17 00:00:00 2001
From: erg <erg@ergb.local>
Date: Thu, 27 Mar 2008 18:13:55 -0500
Subject: [PATCH 22/24] add unit tests and fix lots of words for
 normalize-pathname

---
 core/io/files/files-tests.factor | 50 ++++++++++++++++++++++++++++++++
 extra/io/unix/files/files.factor | 18 +++++++-----
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/core/io/files/files-tests.factor b/core/io/files/files-tests.factor
index b732495541..b78f7667a6 100755
--- a/core/io/files/files-tests.factor
+++ b/core/io/files/files-tests.factor
@@ -7,6 +7,56 @@ io.encodings.utf8 ;
 [ ] [ "blahblah" temp-file make-directory ] unit-test
 [ t ] [ "blahblah" temp-file directory? ] unit-test
 
+[ t ] [
+    [ temp-directory "loldir" append-path delete-directory ] ignore-errors
+    temp-directory [
+        "loldir" make-directory
+    ] with-directory
+    temp-directory "loldir" append-path exists?
+] unit-test
+
+[ ] [
+    [ temp-directory "loldir" append-path delete-directory ] ignore-errors
+    temp-directory [
+        "loldir" make-directory
+        "loldir" delete-directory
+    ] with-directory
+] unit-test
+
+[ "file1 contents" ] [
+    [ temp-directory "loldir" append-path delete-directory ] ignore-errors
+    temp-directory [
+        "file1 contents" "file1" utf8 set-file-contents
+        "file1" "file2" copy-file
+        "file2" utf8 file-contents
+    ] with-directory
+    "file1" temp-file delete-file
+    "file2" temp-file delete-file
+] unit-test
+
+[ "file3 contents" ] [
+    temp-directory [
+        "file3 contents" "file3" utf8 set-file-contents
+        "file3" "file4" move-file
+        "file4" utf8 file-contents
+    ] with-directory
+    "file4" temp-file delete-file
+] unit-test
+
+[ ] [
+    temp-directory [
+        "file5" touch-file
+        "file5" delete-file
+    ] with-directory
+] unit-test
+
+[ ] [
+    temp-directory [
+        "file6" touch-file
+        "file6" link-info drop
+    ] with-directory
+] unit-test
+
 [ "passwd" ] [ "/etc/passwd" file-name ] unit-test
 [ "awk" ] [ "/usr/libexec/awk/" file-name ] unit-test
 [ "awk" ] [ "/usr/libexec/awk///" file-name ] unit-test
diff --git a/extra/io/unix/files/files.factor b/extra/io/unix/files/files.factor
index 2888231e20..ca5d7a7bf1 100755
--- a/extra/io/unix/files/files.factor
+++ b/extra/io/unix/files/files.factor
@@ -7,11 +7,11 @@ calendar io.encodings.binary ;
 
 IN: io.unix.files
 
-M: unix-io cwd
+M: unix-io cwd ( -- path )
     MAXPATHLEN [ <byte-array> ] [ ] bi getcwd
     [ (io-error) ] unless* ;
 
-M: unix-io cd
+M: unix-io cd ( path -- )
     chdir io-error ;
 
 : read-flags O_RDONLY ; inline
@@ -39,25 +39,26 @@ M: unix-io (file-writer) ( path -- stream )
 M: unix-io (file-appender) ( path -- stream )
     open-append <writer> ;
 
-: touch-mode
+: touch-mode ( -- n )
     { O_WRONLY O_APPEND O_CREAT O_EXCL } flags ; foldable
 
 M: unix-io touch-file ( path -- )
+    normalize-pathname
     touch-mode file-mode open
     dup 0 < [ err_no EEXIST = [ err_no io-error ] unless ] when
     close ;
 
 M: unix-io move-file ( from to -- )
-    rename io-error ;
+    [ normalize-pathname ] 2apply rename io-error ;
 
 M: unix-io delete-file ( path -- )
-    unlink io-error ;
+    normalize-pathname unlink io-error ;
 
 M: unix-io make-directory ( path -- )
-    OCT: 777 mkdir io-error ;
+    normalize-pathname OCT: 777 mkdir io-error ;
 
 M: unix-io delete-directory ( path -- )
-    rmdir io-error ;
+    normalize-pathname rmdir io-error ;
 
 : (copy-file) ( from to -- )
     dup parent-directory make-directories
@@ -68,8 +69,9 @@ M: unix-io delete-directory ( path -- )
     ] with-disposal ;
 
 M: unix-io copy-file ( from to -- )
+    [ normalize-pathname ] 2apply
     [ (copy-file) ]
-    [ swap file-info file-info-permissions chmod  io-error ]
+    [ swap file-info file-info-permissions chmod io-error ]
     2bi ;
 
 : stat>type ( stat -- type )

From 857a442e072704e54acbe9a1d112dac08c89a6a4 Mon Sep 17 00:00:00 2001
From: Doug Coleman <doug.coleman@gmail.com>
Date: Thu, 27 Mar 2008 13:10:51 -0500
Subject: [PATCH 23/24] fix struct sizes fix file-info

---
 extra/unix/stat/netbsd/32/32.factor   |  7 +++++--
 extra/unix/types/netbsd/32/32.factor  |  6 ++++++
 extra/unix/types/netbsd/64/64.factor  |  6 ++++++
 extra/unix/types/netbsd/netbsd.factor | 11 ++++++++---
 4 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100755 extra/unix/types/netbsd/32/32.factor
 create mode 100755 extra/unix/types/netbsd/64/64.factor

diff --git a/extra/unix/stat/netbsd/32/32.factor b/extra/unix/stat/netbsd/32/32.factor
index bb2df6d6d3..d4b39a90d1 100644
--- a/extra/unix/stat/netbsd/32/32.factor
+++ b/extra/unix/stat/netbsd/32/32.factor
@@ -22,5 +22,8 @@ C-STRUCT: stat
     { "uint32_t" "st_gen" }
     { { "uint32_t" 2 } "st_qspare" } ;
 
-FUNCTION: int stat  ( char* pathname, stat* buf ) ;
-FUNCTION: int lstat ( char* pathname, stat* buf ) ;
+FUNCTION: int __stat30  ( char* pathname, stat* buf ) ;
+FUNCTION: int __lstat30 ( char* pathname, stat* buf ) ;
+
+: stat __stat30 ;
+: lstat __lstat30 ;
diff --git a/extra/unix/types/netbsd/32/32.factor b/extra/unix/types/netbsd/32/32.factor
new file mode 100755
index 0000000000..892626c416
--- /dev/null
+++ b/extra/unix/types/netbsd/32/32.factor
@@ -0,0 +1,6 @@
+USING: alien.syntax ;
+IN: unix.types
+
+! NetBSD 4.0
+
+TYPEDEF: __uint64_t     ino_t
diff --git a/extra/unix/types/netbsd/64/64.factor b/extra/unix/types/netbsd/64/64.factor
new file mode 100755
index 0000000000..e475bd449b
--- /dev/null
+++ b/extra/unix/types/netbsd/64/64.factor
@@ -0,0 +1,6 @@
+USING: alien.syntax ;
+IN: unix.types
+
+! NetBSD 4.0
+
+TYPEDEF: __uint32_t     ino_t
diff --git a/extra/unix/types/netbsd/netbsd.factor b/extra/unix/types/netbsd/netbsd.factor
index 6d33547627..5b54928d95 100755
--- a/extra/unix/types/netbsd/netbsd.factor
+++ b/extra/unix/types/netbsd/netbsd.factor
@@ -1,4 +1,4 @@
-USING: alien.syntax ;
+USING: alien.syntax combinators layouts vocabs.loader ;
 IN: unix.types
 
 ! NetBSD 4.0
@@ -18,7 +18,6 @@ TYPEDEF: ulonglong      u_int64_t
 
 TYPEDEF: __uint32_t     __dev_t
 TYPEDEF: __uint32_t     dev_t
-TYPEDEF: __uint32_t     ino_t
 TYPEDEF: __uint32_t     mode_t
 TYPEDEF: __uint32_t     nlink_t
 TYPEDEF: __uint32_t     uid_t
@@ -26,6 +25,12 @@ TYPEDEF: __uint32_t     gid_t
 TYPEDEF: __int64_t      off_t
 TYPEDEF: __int64_t      blkcnt_t
 TYPEDEF: __uint32_t     blksize_t
-TYPEDEF: longlong       ssize_t
+TYPEDEF: long           ssize_t
 TYPEDEF: int            pid_t
 TYPEDEF: int            time_t
+
+cell-bits {
+    { 32 [ "unix.types.netbsd.32" require ] }
+    { 64 [ "unix.types.netbsd.64" require ] }
+} case
+

From 36f51b46f252ba639264f3c3fc40e7374f5459a0 Mon Sep 17 00:00:00 2001
From: erg <erg@ergb.local>
Date: Thu, 27 Mar 2008 19:06:24 -0500
Subject: [PATCH 24/24] fix ultraedit

---
 extra/editors/ultraedit/ultraedit.factor | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extra/editors/ultraedit/ultraedit.factor b/extra/editors/ultraedit/ultraedit.factor
index 1fef9f3350..d0bb789c1b 100755
--- a/extra/editors/ultraedit/ultraedit.factor
+++ b/extra/editors/ultraedit/ultraedit.factor
@@ -5,7 +5,7 @@ IN: editors.ultraedit
 : ultraedit-path ( -- path )
     \ ultraedit-path get-global [
         program-files
-        "\\IDM Computer Solutions\\UltraEdit-32\\uedit32.exe" append-path
+        "IDM Computer Solutions\\UltraEdit-32\\uedit32.exe" append-path
     ] unless* ;
 
 : ultraedit ( file line -- )