diff -rN -U 2 ocaml-3.10.0/Description.plist fresh-ocaml-3.10.0/Description.plist
--- ocaml-3.10.0/Description.plist	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/Description.plist	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,15 @@
+  <?xml version="1.0" encoding="UTF-8"?>
+  <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+            "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+  <plist version="1.0">
+  <dict>
+          <key>IFPkgDescriptionDeleteWarning</key>
+          <string></string>
+          <key>IFPkgDescriptionDescription</key>
+          <string>The Objective Caml compiler and tools</string>
+          <key>IFPkgDescriptionTitle</key>
+          <string>Objective Caml</string>
+          <key>IFPkgDescriptionVersion</key>
+          <string></string>
+  </dict>
+  </plist>
diff -rN -U 2 ocaml-3.10.0/INSTALL fresh-ocaml-3.10.0/INSTALL
--- ocaml-3.10.0/INSTALL	2007-02-07 11:31:35.000000000 +0100
+++ fresh-ocaml-3.10.0/INSTALL	2007-05-30 23:03:00.000000000 +0200
@@ -1,4 +1,4 @@
-            Installing Objective Caml on a Unix machine
-            -------------------------------------------
+            Installing Fresh Objective Caml on a Unix machine
+            -------------------------------------------------
 
 PREREQUISITES
@@ -130,5 +130,5 @@
         make world
 
-This builds the Objective Caml bytecode compiler for the first time.
+This builds the Fresh Objective Caml bytecode compiler for the first time.
 This phase is fairly verbose; consider redirecting the output to a file:
 
@@ -137,5 +137,5 @@
 
 3- (Optional) To be sure everything works well, you can try to
-bootstrap the system --- that is, to recompile all Objective Caml
+bootstrap the system --- that is, to recompile all Fresh Objective Caml
 sources with the newly created compiler. From the top directory, do:
 
@@ -191,27 +191,27 @@
         ./build/fastworld.sh
 
-6- You can now install the Objective Caml system. This will create the
+6- You can now install the Fresh Objective Caml system. This will create the
 following commands (in the binary directory selected during
 autoconfiguration):
 
-        ocamlc           the batch bytecode compiler
-        ocamlopt         the batch native-code compiler (if supported)
-        ocamlrun         the runtime system for the bytecode compiler
-        ocamlyacc        the parser generator
-        ocamllex         the lexer generator
-        ocaml            the interactive, toplevel-based system
-        ocamlmktop       a tool to make toplevel systems that integrate
-                         user-defined C primitives and Caml code
-        ocamldebug       the source-level replay debugger
-        ocamldep         generator of "make" dependencies for Caml sources
-        ocamldoc         documentation generator
-        ocamlprof        execution count profiler
-        ocamlcp          the bytecode compiler in profiling mode
+        fresh-ocamlc           the batch bytecode compiler
+        fresh-ocamlopt         the batch native-code compiler (if supported)
+        fresh-ocamlrun         the runtime system for the bytecode compiler
+        fresh-ocamlyacc        the parser generator
+        fresh-ocamllex         the lexer generator
+        fresh-ocaml            the interactive, toplevel-based system
+        fresh-ocamlmktop       a tool to make toplevel systems that integrate
+                               user-defined C primitives and Caml code
+        fresh-ocamldebug       the source-level replay debugger
+        fresh-ocamldep         generator of "make" dependencies for Caml sources
+        fresh-ocamldoc         documentation generator
+        fresh-ocamlprof        execution count profiler
+        fresh-ocamlcp          the bytecode compiler in profiling mode
 
 and also, if you built them during step 5,
 
-        ocamlc.opt       the batch bytecode compiler compiled with ocamlopt
-        ocamlopt.opt     the batch native-code compiler compiled with ocamlopt
-        ocamllex.opt     the lexer generator compiled with ocamlopt
+        fresh-ocamlc.opt       the batch bytecode compiler compiled with ocamlopt
+        fresh-ocamlopt.opt     the batch native-code compiler compiled with ocamlopt
+        fresh-ocamllex.opt     the lexer generator compiled with ocamlopt
 
 From the top directory, become superuser and do:
diff -rN -U 2 ocaml-3.10.0/Info.plist fresh-ocaml-3.10.0/Info.plist
--- ocaml-3.10.0/Info.plist	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/Info.plist	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+        <key>CFBundleGetInfoString</key>
+        <string>Objective Caml </string>
+        <key>CFBundleIdentifier</key>
+        <string>fr.inria.ocaml</string>
+        <key>CFBundleName</key>
+        <string>Objective Caml</string>
+        <key>CFBundleShortVersionString</key>
+        <string></string>
+        <key>IFMajorVersion</key>
+        <integer></integer>
+        <key>IFMinorVersion</key>
+        <integer></integer>
+        <key>IFPkgFlagAllowBackRev</key>
+        <true/>
+        <key>IFPkgFlagAuthorizationAction</key>
+        <string>AdminAuthorization</string>
+        <key>IFPkgFlagDefaultLocation</key>
+        <string>/usr/local</string>
+        <key>IFPkgFlagInstallFat</key>
+        <false/>
+        <key>IFPkgFlagIsRequired</key>
+        <false/>
+        <key>IFPkgFlagRelocatable</key>
+        <false/>
+        <key>IFPkgFlagRestartAction</key>
+        <string>NoRestart</string>
+        <key>IFPkgFlagRootVolumeOnly</key>
+        <true/>
+        <key>IFPkgFlagUpdateInstalledLanguages</key>
+        <false/>
+        <key>IFPkgFormatVersion</key>
+        <real>0.10000000149011612</real>
+</dict>
+</plist>
diff -rN -U 2 ocaml-3.10.0/Makefile fresh-ocaml-3.10.0/Makefile
--- ocaml-3.10.0/Makefile	2007-04-16 18:01:59.000000000 +0200
+++ fresh-ocaml-3.10.0/Makefile	2007-05-30 22:42:01.000000000 +0200
@@ -18,15 +18,15 @@
 include stdlib/StdlibModules
 
-CAMLC=boot/ocamlrun boot/ocamlc -nostdlib -I boot
-CAMLOPT=boot/ocamlrun ./ocamlopt -nostdlib -I stdlib
+CAMLC=boot/fresh-ocamlrun boot/fresh-ocamlc -nostdlib -I boot
+CAMLOPT=boot/fresh-ocamlrun ./fresh-ocamlopt -nostdlib -I stdlib
 COMPFLAGS=-warn-error A $(INCLUDES)
 LINKFLAGS=
 
-CAMLYACC=boot/ocamlyacc
+CAMLYACC=boot/fresh-ocamlyacc
 YACCFLAGS=-v
-CAMLLEX=boot/ocamlrun boot/ocamllex
-CAMLDEP=boot/ocamlrun tools/ocamldep
+CAMLLEX=boot/fresh-ocamlrun boot/fresh-ocamllex
+CAMLDEP=boot/fresh-ocamlrun tools/fresh-ocamldep
 DEPFLAGS=$(INCLUDES)
-CAMLRUN=byterun/ocamlrun
+CAMLRUN=byterun/fresh-ocamlrun
 SHELL=/bin/sh
 MKDIR=mkdir -p
@@ -111,5 +111,5 @@
   bytecomp/dll.cmo bytecomp/meta.cmo bytecomp/symtable.cmo toplevel/expunge.cmo
 
-PERVASIVES=$(STDLIB_MODULES) outcometree topdirs toploop
+PERVASIVES=$(STDLIB_MODULES) outcometree topdirs toploop freshness
 
 # For users who don't read the INSTALL file
@@ -124,6 +124,6 @@
 
 # Recompile the system using the bootstrap compiler
-all: runtime ocamlc ocamllex ocamlyacc ocamltools library ocaml \
-  otherlibraries ocamlbuild.byte camlp4out $(DEBUGGER) ocamldoc
+all: runtime fresh-ocamlc fresh-ocamllex fresh-ocamlyacc ocamltools library fresh-ocaml \
+  otherlibraries ocamlbuild.byte $(DEBUGGER) 
 
 # The compilation of ocaml will fail if the runtime has changed.
@@ -146,5 +146,5 @@
 # Rebuild ocamlc and ocamllex (run on byterun/ocamlrun)
 	$(MAKE) partialclean
-	$(MAKE) ocamlc ocamllex ocamltools
+	$(MAKE) fresh-ocamlc fresh-ocamllex ocamltools
 # Rebuild the library (using byterun/ocamlrun ./ocamlc)
 	$(MAKE) library-cross
@@ -168,8 +168,8 @@
 coldstart:
 	cd byterun; $(MAKE) all
-	cp byterun/ocamlrun$(EXE) boot/ocamlrun$(EXE)
+	cp byterun/fresh-ocamlrun$(EXE) boot/fresh-ocamlrun$(EXE)
 	cd yacc; $(MAKE) all
-	cp yacc/ocamlyacc$(EXE) boot/ocamlyacc$(EXE)
-	cd stdlib; $(MAKE) COMPILER=../boot/ocamlc all
+	cp yacc/fresh-ocamlyacc$(EXE) boot/fresh-ocamlyacc$(EXE)
+	cd stdlib; $(MAKE) COMPILER=../boot/fresh-ocamlc all
 	cd stdlib; cp $(LIBFILES) ../boot
 	if test -f boot/libcamlrun.a; then :; else \
@@ -179,5 +179,5 @@
 
 # Build the core system: the minimum needed to make depend and bootstrap
-core : coldstart ocamlc ocamllex ocamlyacc ocamltools library
+core : coldstart fresh-ocamlc fresh-ocamllex fresh-ocamlyacc ocamltools library
 
 # Save the current bootstrap compiler
@@ -189,6 +189,6 @@
 	mkdir boot/Saved
 	mv boot/Saved.prev boot/Saved/Saved.prev
-	cp boot/ocamlrun$(EXE) boot/Saved
-	mv boot/ocamlc boot/ocamllex boot/ocamlyacc$(EXE) boot/ocamldep boot/Saved
+	cp boot/fresh-ocamlrun$(EXE) boot/Saved
+	mv boot/fresh-ocamlc boot/fresh-ocamllex boot/fresh-ocamlyacc$(EXE) boot/fresh-ocamldep boot/Saved
 	cd boot; cp $(LIBFILES) Saved
 
@@ -196,8 +196,8 @@
 # (Runs on the old runtime, produces code for the new runtime)
 promote-cross:
-	cp ocamlc boot/ocamlc
-	cp lex/ocamllex boot/ocamllex
-	cp yacc/ocamlyacc$(EXE) boot/ocamlyacc$(EXE)
-	cp tools/ocamldep boot/ocamldep
+	cp fresh-ocamlc boot/fresh-ocamlc
+	cp lex/fresh-ocamllex boot/fresh-ocamllex
+	cp yacc/fresh-ocamlyacc$(EXE) boot/fresh-ocamlyacc$(EXE)
+	cp tools/fresh-ocamldep boot/fresh-ocamldep
 	cd stdlib; cp $(LIBFILES) ../boot
 
@@ -205,5 +205,5 @@
 # (Runs on the new runtime, produces code for the new runtime)
 promote: promote-cross
-	cp byterun/ocamlrun$(EXE) boot/ocamlrun$(EXE)
+	cp byterun/fresh-ocamlrun$(EXE) boot/fresh-ocamlrun$(EXE)
 
 # Restore the saved bootstrap compiler if a problem arises
@@ -215,5 +215,5 @@
 # Check if fixpoint reached
 compare:
-	@if cmp boot/ocamlc ocamlc && cmp boot/ocamllex lex/ocamllex && cmp boot/ocamldep tools/ocamldep; \
+	@if cmp boot/fresh-ocamlc fresh-ocamlc && cmp boot/fresh-ocamllex lex/fresh-ocamllex && cmp boot/fresh-ocamldep tools/fresh-ocamldep; \
 	then echo "Fixpoint reached, bootstrap succeeded."; \
         else echo "Fixpoint not reached, try one more bootstrapping cycle."; \
@@ -225,11 +225,11 @@
 
 # Compile the native-code compiler
-opt-core:runtimeopt ocamlopt libraryopt
-opt: runtimeopt ocamlopt libraryopt otherlibrariesopt
+opt-core:runtimeopt fresh-ocamlopt libraryopt
+opt: runtimeopt fresh-ocamlopt libraryopt otherlibrariesopt
 
 # Native-code versions of the tools
-opt.opt: checkstack runtime core ocaml opt-core ocamlc.opt otherlibraries \
-	 ocamlbuild.byte camlp4out $(DEBUGGER) ocamldoc ocamlopt.opt otherlibrariesopt \
-	 ocamllex.opt ocamltoolsopt.opt ocamlbuild.native camlp4opt ocamldoc.opt
+opt.opt: checkstack runtime core fresh-ocaml opt-core fresh-ocamlc.opt otherlibraries \
+	 ocamlbuild.byte $(DEBUGGER) fresh-ocamlopt.opt otherlibrariesopt \
+	 fresh-ocamllex.opt ocamltoolsopt.opt ocamlbuild.native 
 
 # Installation
@@ -243,9 +243,9 @@
           dlltkanim.so
 	cd byterun; $(MAKE) install
-	cp ocamlc $(BINDIR)/ocamlc$(EXE)
-	cp ocaml $(BINDIR)/ocaml$(EXE)
+	cp fresh-ocamlc $(BINDIR)/fresh-ocamlc$(EXE)
+	cp fresh-ocaml $(BINDIR)/fresh-ocaml$(EXE)
 	cd stdlib; $(MAKE) install
-	cp lex/ocamllex $(BINDIR)/ocamllex$(EXE)
-	cp yacc/ocamlyacc$(EXE) $(BINDIR)/ocamlyacc$(EXE)
+	cp lex/fresh-ocamllex $(BINDIR)/fresh-ocamllex$(EXE)
+	cp yacc/fresh-ocamlyacc$(EXE) $(BINDIR)/fresh-ocamlyacc$(EXE)
 	cp toplevel/toplevellib.cma $(LIBDIR)/toplevellib.cma
 	cp expunge $(LIBDIR)/expunge$(EXE)
@@ -258,6 +258,6 @@
           (cd otherlibs/$$i; $(MAKE) install) || exit $$?; \
         done
-	cd ocamldoc; $(MAKE) install
-	if test -f ocamlopt; then $(MAKE) installopt; else :; fi
+#	cd ocamldoc; $(MAKE) install
+	if test -f fresh-ocamlopt; then $(MAKE) installopt; else :; fi
 	if test -f debugger/ocamldebug; then (cd debugger; $(MAKE) install); \
 	   else :; fi
@@ -268,14 +268,14 @@
 installopt:
 	cd asmrun; $(MAKE) install
-	cp ocamlopt $(BINDIR)/ocamlopt$(EXE)
+	cp fresh-ocamlopt $(BINDIR)/fresh-ocamlopt$(EXE)
 	cd stdlib; $(MAKE) installopt
 	cd ocamldoc; $(MAKE) installopt
 	for i in $(OTHERLIBRARIES); do (cd otherlibs/$$i; $(MAKE) installopt) || exit $$?; done
-	if test -f ocamlc.opt; \
-	  then cp ocamlc.opt $(BINDIR)/ocamlc.opt$(EXE); else :; fi
-	if test -f ocamlopt.opt; \
-	  then cp ocamlopt.opt $(BINDIR)/ocamlopt.opt$(EXE); else :; fi
-	if test -f lex/ocamllex.opt; \
-	  then cp lex/ocamllex.opt $(BINDIR)/ocamllex.opt$(EXE); else :; fi
+	if test -f fresh-ocamlc.opt; \
+	  then cp fresh-ocamlc.opt $(BINDIR)/fresh-ocamlc.opt$(EXE); else :; fi
+	if test -f fresh-ocamlopt.opt; \
+	  then cp fresh-ocamlopt.opt $(BINDIR)/fresh-ocamlopt.opt$(EXE); else :; fi
+	if test -f lex/fresh-ocamllex.opt; \
+	  then cp lex/fresh-ocamllex.opt $(BINDIR)/fresh-ocamllex.opt$(EXE); else :; fi
 
 clean:: partialclean
@@ -283,29 +283,29 @@
 # The compiler
 
-ocamlc: $(COMPOBJS)
-	$(CAMLC) $(LINKFLAGS) -o ocamlc $(COMPOBJS)
-	@sed -e 's|@compiler@|$$topdir/boot/ocamlrun $$topdir/ocamlc|' \
+fresh-ocamlc: $(COMPOBJS)
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamlc $(COMPOBJS)
+	@sed -e 's|@compiler@|$$topdir/boot/fresh-ocamlrun $$topdir/fresh-ocamlc|' \
 	  driver/ocamlcomp.sh.in > ocamlcomp.sh
 	@chmod +x ocamlcomp.sh
 
 partialclean::
-	rm -f ocamlc ocamlcomp.sh
+	rm -f fresh-ocamlc ocamlcomp.sh
 
 # The native-code compiler
 
-ocamlopt: $(OPTOBJS)
-	$(CAMLC) $(LINKFLAGS) -o ocamlopt $(OPTOBJS)
-	@sed -e 's|@compiler@|$$topdir/boot/ocamlrun $$topdir/ocamlopt|' \
+fresh-ocamlopt: $(OPTOBJS)
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamlopt $(OPTOBJS)
+	@sed -e 's|@compiler@|$$topdir/boot/fresh-ocamlrun $$topdir/fresh-ocamlopt|' \
 	  driver/ocamlcomp.sh.in > ocamlcompopt.sh
 	@chmod +x ocamlcompopt.sh
 
 partialclean::
-	rm -f ocamlopt ocamlcompopt.sh
+	rm -f fresh-ocamlopt ocamlcompopt.sh
 
 # The toplevel
 
-ocaml: $(TOPOBJS) expunge
-	$(CAMLC) $(LINKFLAGS) -linkall -o ocaml.tmp $(TOPOBJS)
-	- $(CAMLRUN) ./expunge ocaml.tmp ocaml $(PERVASIVES)
+fresh-ocaml: $(TOPOBJS) expunge
+	$(CAMLC) $(LINKFLAGS) -linkall -o fresh-ocaml.tmp $(TOPOBJS)
+	- $(CAMLRUN) ./expunge fresh-ocaml.tmp fresh-ocaml $(PERVASIVES)
 	rm -f ocaml.tmp
 
@@ -314,5 +314,5 @@
 
 partialclean::
-	rm -f ocaml toplevel/toplevellib.cma
+	rm -f fresh-ocaml toplevel/toplevellib.cma
 
 # The configuration file
@@ -381,10 +381,10 @@
 # The bytecode compiler compiled with the native-code compiler
 
-ocamlc.opt: $(COMPOBJS:.cmo=.cmx)
+fresh-ocamlc.opt: $(COMPOBJS:.cmo=.cmx)
 	cd asmrun; $(MAKE) meta.o dynlink.o
-	$(CAMLOPT) $(LINKFLAGS) -ccopt "$(BYTECCLINKOPTS)" -o ocamlc.opt \
+	$(CAMLOPT) $(LINKFLAGS) -ccopt "$(BYTECCLINKOPTS)" -o fresh-ocamlc.opt \
           $(COMPOBJS:.cmo=.cmx) \
           asmrun/meta.o asmrun/dynlink.o -cclib "$(BYTECCLIBS)"
-	@sed -e 's|@compiler@|$$topdir/ocamlc.opt|' \
+	@sed -e 's|@compiler@|$$topdir/fresh-ocamlc.opt|' \
 	  driver/ocamlcomp.sh.in > ocamlcomp.sh
 	@chmod +x ocamlcomp.sh
@@ -395,14 +395,14 @@
 # The native-code compiler compiled with itself
 
-ocamlopt.opt: $(OPTOBJS:.cmo=.cmx)
-	$(CAMLOPT) $(LINKFLAGS) -o ocamlopt.opt $(OPTOBJS:.cmo=.cmx)
-	@sed -e 's|@compiler@|$$topdir/ocamlopt.opt|' \
+fresh-ocamlopt.opt: $(OPTOBJS:.cmo=.cmx)
+	$(CAMLOPT) $(LINKFLAGS) -o fresh-ocamlopt.opt $(OPTOBJS:.cmo=.cmx)
+	@sed -e 's|@compiler@|$$topdir/fresh-ocamlopt.opt|' \
 	  driver/ocamlcomp.sh.in > ocamlcompopt.sh
 	@chmod +x ocamlcompopt.sh
 
 partialclean::
-	rm -f ocamlopt.opt
+	rm -f fresh-ocamlopt.opt
 
-$(OPTOBJS:.cmo=.cmx): ocamlopt
+$(OPTOBJS:.cmo=.cmx): fresh-ocamlopt
 
 # The numeric opcodes
@@ -491,5 +491,5 @@
 tools/cvt_emit: tools/cvt_emit.mll
 	cd tools; \
-	$(MAKE) CAMLC="../$(CAMLRUN) ../boot/ocamlc -I ../stdlib" cvt_emit
+	$(MAKE) CAMLC="../$(CAMLRUN) ../boot/fresh-ocamlc -I ../stdlib" cvt_emit
 
 # The "expunge" utility
@@ -528,8 +528,8 @@
 # The library
 
-library: ocamlc
+library: fresh-ocamlc
 	cd stdlib; $(MAKE) all
 library-cross:
-	cd stdlib; $(MAKE) RUNTIME=../byterun/ocamlrun all
+	cd stdlib; $(MAKE) RUNTIME=../byterun/fresh-ocamlrun all
 libraryopt:
 	cd stdlib; $(MAKE) allopt
@@ -541,7 +541,7 @@
 # The lexer and parser generators
 
-ocamllex: ocamlyacc ocamlc
+fresh-ocamllex: fresh-ocamlyacc fresh-ocamlc
 	cd lex; $(MAKE) all
-ocamllex.opt: ocamlopt
+fresh-ocamllex.opt: fresh-ocamlopt
 	cd lex; $(MAKE) allopt
 partialclean::
@@ -550,5 +550,5 @@
 	cd lex; $(MAKE) depend
 
-ocamlyacc:
+fresh-ocamlyacc:
 	cd yacc; $(MAKE) all
 clean::
@@ -557,7 +557,7 @@
 # Tools
 
-ocamltools: ocamlc ocamlyacc ocamllex
+ocamltools: fresh-ocamlc fresh-ocamlyacc fresh-ocamllex
 	cd tools; $(MAKE) all
-ocamltoolsopt.opt: ocamlc.opt ocamlyacc ocamllex
+ocamltoolsopt.opt: fresh-ocamlc.opt fresh-ocamlyacc fresh-ocamllex
 	cd tools; $(MAKE) opt.opt
 partialclean::
@@ -568,7 +568,7 @@
 # OCamldoc
 
-ocamldoc: ocamlc ocamlyacc ocamllex
+fresh-ocamldoc: fresh-ocamlc fresh-ocamlyacc fresh-ocamllex
 	cd ocamldoc && $(MAKE) all
-ocamldoc.opt: ocamlc.opt ocamlyacc ocamllex
+ocamldoc.opt: fresh-ocamlc.opt fresh-ocamlyacc fresh-ocamllex
 	cd ocamldoc && $(MAKE) opt.opt
 partialclean::
@@ -598,5 +598,5 @@
 # The replay debugger
 
-ocamldebugger: ocamlc ocamlyacc ocamllex
+ocamldebugger: fresh-ocamlc fresh-ocamlyacc fresh-ocamllex
 	cd debugger; $(MAKE) all
 partialclean::
@@ -614,7 +614,7 @@
 # Ocamlbuild
 
-ocamlbuild.byte: ocamlc otherlibraries ocamlbuild-partial-boot
+ocamlbuild.byte: fresh-ocamlc otherlibraries ocamlbuild-partial-boot
 	./build/ocamlbuild-byte-only.sh
-ocamlbuild.native: ocamlopt otherlibrariesopt ocamlbuild-partial-boot
+ocamlbuild.native: fresh-ocamlopt otherlibrariesopt ocamlbuild-partial-boot
 	./build/ocamlbuild-native-only.sh
 
diff -rN -U 2 ocaml-3.10.0/asmcomp/cmmgen.ml fresh-ocaml-3.10.0/asmcomp/cmmgen.ml
--- ocaml-3.10.0/asmcomp/cmmgen.ml	2007-02-22 13:13:00.000000000 +0100
+++ fresh-ocaml-3.10.0/asmcomp/cmmgen.ml	2007-05-18 16:50:55.000000000 +0200
@@ -631,4 +631,9 @@
   | Pbigarrayset(n, Pbigarray_unknown, layout) ->
       Pccall (default_prim ("caml_ba_set_" ^ string_of_int n))
+  | Pswapatoms -> Pccall (default_prim "fresh_swap_atoms")
+  | Pfreshen -> Pccall (default_prim "fresh_throughout")
+  | Pnewatom -> Pccall (default_prim "fresh_new_atom")
+  | Pfreshfor -> Pccall (default_prim "fresh_freshfor")
+  | Pcreateabst -> Pccall (default_prim "fresh_create_abstraction")
   | Pbigarrayref(n, kind, Pbigarray_unknown_layout) ->
       Pccall (default_prim ("caml_ba_get_" ^ string_of_int n))
diff -rN -U 2 ocaml-3.10.0/asmrun/Makefile fresh-ocaml-3.10.0/asmrun/Makefile
--- ocaml-3.10.0/asmrun/Makefile	2007-02-23 10:29:45.000000000 +0100
+++ fresh-ocaml-3.10.0/asmrun/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -27,5 +27,5 @@
   floats.o str.o array.o io.o extern.o intern.o hash.o sys.o parsing.o \
   gc_ctrl.o terminfo.o md5.o obj.o lexing.o printexc.o callback.o weak.o \
-  compact.o finalise.o custom.o unix.o backtrace.o
+  compact.o finalise.o custom.o unix.o backtrace.o freshness.o hashtable_cwc22.o hashtable_itr_cwc22.o
 
 ASMOBJS=$(ARCH).o
@@ -119,4 +119,10 @@
 obj.c: ../byterun/obj.c
 	ln -s ../byterun/obj.c obj.c
+freshness.c: ../byterun/freshness.c
+	ln -s ../byterun/freshness.c freshness.c
+hashtable_itr_cwc22.c: ../byterun/hashtable_itr_cwc22.c
+	ln -s ../byterun/hashtable_itr_cwc22.c hashtable_itr_cwc22.c
+hashtable_cwc22.c: ../byterun/hashtable_cwc22.c
+	ln -s ../byterun/hashtable_cwc22.c hashtable_cwc22.c
 lexing.c: ../byterun/lexing.c
 	ln -s ../byterun/lexing.c lexing.c
diff -rN -U 2 ocaml-3.10.0/asmrun/hashtable_cwc22.h fresh-ocaml-3.10.0/asmrun/hashtable_cwc22.h
--- ocaml-3.10.0/asmrun/hashtable_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/asmrun/hashtable_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,188 @@
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, 0.75, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   maxloadfactor   maximum ratio entries / tablesize
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize, float maxloadfactor,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/asmrun/hashtable_itr_cwc22.h fresh-ocaml-3.10.0/asmrun/hashtable_itr_cwc22.h
--- ocaml-3.10.0/asmrun/hashtable_itr_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/asmrun/hashtable_itr_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,73 @@
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable_cwc22.h"
+#include "hashtable_private_cwc22.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/asmrun/hashtable_private_cwc22.h fresh-ocaml-3.10.0/asmrun/hashtable_private_cwc22.h
--- ocaml-3.10.0/asmrun/hashtable_private_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/asmrun/hashtable_private_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,52 @@
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable_cwc22.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+unsigned int
+hash(struct hashtable *h, void *k);
+
+unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue);
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
Binary files ocaml-3.10.0/boot/fresh-ocamlc and fresh-ocaml-3.10.0/boot/fresh-ocamlc differ
Binary files ocaml-3.10.0/boot/fresh-ocamldep and fresh-ocaml-3.10.0/boot/fresh-ocamldep differ
Binary files ocaml-3.10.0/boot/fresh-ocamllex and fresh-ocaml-3.10.0/boot/fresh-ocamllex differ
Binary files ocaml-3.10.0/boot/myocamlbuild.boot and fresh-ocaml-3.10.0/boot/myocamlbuild.boot differ
Binary files ocaml-3.10.0/boot/ocamlc and fresh-ocaml-3.10.0/boot/ocamlc differ
Binary files ocaml-3.10.0/boot/ocamldep and fresh-ocaml-3.10.0/boot/ocamldep differ
Binary files ocaml-3.10.0/boot/ocamllex and fresh-ocaml-3.10.0/boot/ocamllex differ
diff -rN -U 2 ocaml-3.10.0/build/boot-c-parts.sh fresh-ocaml-3.10.0/build/boot-c-parts.sh
--- ocaml-3.10.0/build/boot-c-parts.sh	2007-03-12 12:58:48.000000000 +0100
+++ fresh-ocaml-3.10.0/build/boot-c-parts.sh	2007-05-18 16:50:55.000000000 +0200
@@ -16,5 +16,5 @@
        _build/boot
 
-[ -f boot/ocamlrun ] || ln -sf ../byterun/ocamlrun boot
+[ -f boot/fresh-ocamlrun ] || ln -sf ../byterun/fresh-ocamlrun boot
 
 (cd byterun && make)
diff -rN -U 2 ocaml-3.10.0/build/boot.sh fresh-ocaml-3.10.0/build/boot.sh
--- ocaml-3.10.0/build/boot.sh	2007-05-14 15:59:36.000000000 +0200
+++ fresh-ocaml-3.10.0/build/boot.sh	2007-05-18 16:57:46.000000000 +0200
@@ -4,9 +4,9 @@
 set -ex
 TAGLINE='true: -use_stdlib'
-./boot/ocamlrun boot/myocamlbuild.boot \
+./boot/fresh-ocamlrun boot/myocamlbuild.boot \
   -tag-line "$TAG_LINE" \
   boot/stdlib.cma boot/std_exit.cmo
 
-boot/ocamlrun boot/myocamlbuild.boot \
+boot/fresh-ocamlrun boot/myocamlbuild.boot \
   -tag-line "$TAG_LINE" -log _boot_log1 \
   ocamlbuild/ocamlbuildlightlib.cma ocamlbuild/ocamlbuildlight.byte
@@ -14,10 +14,10 @@
 rm -f _build/myocamlbuild
 
-boot/ocamlrun boot/myocamlbuild.boot \
+boot/fresh-ocamlrun boot/myocamlbuild.boot \
   -just-plugin -install-lib-dir _build/ocamlbuild -byte-plugin
 
 cp _build/myocamlbuild boot/myocamlbuild
 
-./boot/ocamlrun boot/myocamlbuild \
+./boot/fresh-ocamlrun boot/myocamlbuild \
   -tag-line "$TAG_LINE" \
-  $@ -log _boot_log2 boot/camlheader ocamlc
+  $@ -log _boot_log2 boot/camlheader fresh-ocamlc
diff -rN -U 2 ocaml-3.10.0/build/myocamlbuild.sh fresh-ocaml-3.10.0/build/myocamlbuild.sh
--- ocaml-3.10.0/build/myocamlbuild.sh	2007-03-12 12:58:48.000000000 +0100
+++ fresh-ocaml-3.10.0/build/myocamlbuild.sh	2007-05-18 16:50:55.000000000 +0200
@@ -15,5 +15,5 @@
 rm -f ocamlbuild/myocamlbuild_config.ml ocamlbuild/myocamlbuild_config.mli
 rm -rf _build/myocamlbuild boot/myocamlbuild boot/myocamlbuild.native
-./boot/ocamlrun _build/ocamlbuild/ocamlbuildlight.byte -no-hygiene \
+./boot/fresh-ocamlrun _build/ocamlbuild/ocamlbuildlight.byte -no-hygiene \
   -tag debug -install-lib-dir _build/ocamlbuild -byte-plugin -just-plugin
 cp _build/myocamlbuild boot/myocamlbuild.boot
--- ocaml-3.10.0/build/partial-install.sh	2007-04-05 10:12:39.000000000 +0200
+++ fresh-ocaml-3.10.0/build/partial-install.sh	2007-05-30 22:07:32.000000000 +0200
@@ -92,5 +92,5 @@
 mkdir -p $BINDIR
 mkdir -p $LIBDIR
-mkdir -p $LIBDIR/camlp4
+# mkdir -p $LIBDIR/camlp4
 mkdir -p $LIBDIR/ocamlbuild
 mkdir -p $STUBLIBDIR
@@ -101,48 +101,9 @@
 cd _build
 
-echo "Installing camlp4..."
-installbin camlp4/camlp4prof.byte$EXE $BINDIR/camlp4prof$EXE
-installbin camlp4/mkcamlp4.byte$EXE $BINDIR/mkcamlp4$EXE
-installbin camlp4/camlp4.byte$EXE $BINDIR/camlp4$EXE
-installbin camlp4/camlp4boot.byte$EXE $BINDIR/camlp4boot$EXE
-installbin camlp4/camlp4o.byte$EXE $BINDIR/camlp4o$EXE
-installbin camlp4/camlp4of.byte$EXE $BINDIR/camlp4of$EXE
-installbin camlp4/camlp4oof.byte$EXE $BINDIR/camlp4oof$EXE
-installbin camlp4/camlp4orf.byte$EXE $BINDIR/camlp4orf$EXE
-installbin camlp4/camlp4r.byte$EXE $BINDIR/camlp4r$EXE
-installbin camlp4/camlp4rf.byte$EXE $BINDIR/camlp4rf$EXE
-installbin camlp4/camlp4o.native$EXE $BINDIR/camlp4o.opt$EXE
-installbin camlp4/camlp4of.native$EXE $BINDIR/camlp4of.opt$EXE
-installbin camlp4/camlp4oof.native$EXE $BINDIR/camlp4oof.opt$EXE
-installbin camlp4/camlp4orf.native$EXE $BINDIR/camlp4orf.opt$EXE
-installbin camlp4/camlp4r.native$EXE $BINDIR/camlp4r.opt$EXE
-installbin camlp4/camlp4rf.native$EXE $BINDIR/camlp4rf.opt$EXE
-
-cd camlp4
-CAMLP4DIR=$LIBDIR/camlp4
-for dir in Camlp4Parsers Camlp4Printers Camlp4Filters Camlp4Top; do
-  echo "Installing $dir..."
-  mkdir -p $CAMLP4DIR/$dir
-  installdir     \
-    $dir/*.cm*   \
-    $dir/*.$O    \
-    $CAMLP4DIR/$dir
-done
-installdir \
-  camlp4lib.cma camlp4lib.cmxa Camlp4.cmi \
-  camlp4fulllib.cma camlp4fulllib.cmxa \
-  camlp4o.cma camlp4of.cma camlp4oof.cma \
-  camlp4orf.cma camlp4r.cma camlp4rf.cma \
-  Camlp4Bin.cm[iox] Camlp4Bin.$O Camlp4Top.cm[io] \
-  Camlp4_config.cmi camlp4prof.cm[iox] camlp4prof.$O \
-  $CAMLP4DIR
-installlibdir camlp4lib.$A camlp4fulllib.$A $CAMLP4DIR
-cd ..
-
 echo "Installing ocamlbuild..."
 cd ocamlbuild
-installbin ocamlbuild.byte$EXE $BINDIR/ocamlbuild.byte$EXE
-installbin ocamlbuild.native$EXE $BINDIR/ocamlbuild.native$EXE
-installbestbin ocamlbuild.native$EXE ocamlbuild.byte$EXE $BINDIR/ocamlbuild$EXE
+installbin ocamlbuild.byte$EXE $BINDIR/fresh-ocamlbuild.byte$EXE
+installbin ocamlbuild.native$EXE $BINDIR/fresh-ocamlbuild.native$EXE
+installbestbin ocamlbuild.native$EXE ocamlbuild.byte$EXE $BINDIR/fresh-ocamlbuild$EXE
 
 installlibdir \
diff -rN -U 2 ocaml-3.10.0/build/targets.sh fresh-ocaml-3.10.0/build/targets.sh
--- ocaml-3.10.0/build/targets.sh	2007-03-12 12:58:48.000000000 +0100
+++ fresh-ocaml-3.10.0/build/targets.sh	2007-05-30 22:53:25.000000000 +0200
@@ -9,7 +9,7 @@
 STDLIB_BYTE="stdlib/libcamlrun.$A stdlib/stdlib.cma \
              stdlib/std_exit.cmo stdlib/camlheader stdlib/camlheader_ur"
-OCAMLLEX_BYTE=lex/ocamllex$EXE
-OCAMLC_BYTE=ocamlc$EXE
-OCAMLOPT_BYTE=ocamlopt$EXE
+OCAMLLEX_BYTE=lex/fresh-ocamllex$EXE
+OCAMLC_BYTE=fresh-ocamlc$EXE
+OCAMLOPT_BYTE=fresh-ocamlopt$EXE
 OCAMLBUILD_BYTE="ocamlbuild/ocamlbuildlib.cma \
                  ocamlbuild/ocamlbuildlightlib.cma \
@@ -17,7 +17,7 @@
                  ocamlbuild/ocamlbuildlight.byte$EXE"
 TOPLEVEL=ocaml$EXE
-TOOLS_BYTE="tools/ocamldep.byte$EXE tools/profiling.cmo \
-            tools/ocamlprof.byte$EXE tools/ocamlcp.byte$EXE \
-            tools/ocamlmktop.byte$EXE tools/ocamlmklib$EXE \
+TOOLS_BYTE="tools/fresh-ocamldep.byte$EXE tools/profiling.cmo \
+            tools/fresh-ocamlprof.byte$EXE tools/fresh-ocamlcp.byte$EXE \
+            tools/fresh-ocamlmktop.byte$EXE tools/fresh-ocamlmklib$EXE \
             tools/scrapelabels.byte tools/addlabels.byte \
             tools/dumpobj.byte$EXE"
@@ -25,5 +25,5 @@
   DEBUGGER=debugger/ocamldebug$EXE
 fi
-OCAMLDOC_BYTE="ocamldoc/ocamldoc$EXE ocamldoc/odoc_info.cma"
+OCAMLDOC_BYTE="ocamldoc/fresh-ocamldoc$EXE ocamldoc/odoc_info.cma"
 STDLIB_NATIVE="stdlib/stdlib.cmxa stdlib/std_exit.cmx asmrun/libasmrun.$A"
 case $PROFILING in
@@ -34,9 +34,9 @@
 *) echo "unexpected PROFILING value $PROFILING"; exit 1;;
 esac
-OCAMLC_NATIVE=ocamlc.opt$EXE
-OCAMLOPT_NATIVE=ocamlopt.opt$EXE
-OCAMLLEX_NATIVE=lex/ocamllex.opt$EXE
-TOOLS_NATIVE=tools/ocamldep.native$EXE
-OCAMLDOC_NATIVE="ocamldoc/ocamldoc.opt$EXE ocamldoc/odoc_info.cmxa ocamldoc/stdlib_man/Pervasives.3o"
+OCAMLC_NATIVE=fresh-ocamlc.opt$EXE
+OCAMLOPT_NATIVE=fresh-ocamlopt.opt$EXE
+OCAMLLEX_NATIVE=lex/fresh-ocamllex.opt$EXE
+TOOLS_NATIVE=tools/fresh-ocamldep.native$EXE
+OCAMLDOC_NATIVE="ocamldoc/fresh-ocamldoc.opt$EXE ocamldoc/odoc_info.cmxa ocamldoc/stdlib_man/Pervasives.3o"
 OCAMLBUILD_NATIVE="ocamlbuild/ocamlbuildlib.cmxa \
                    ocamlbuild/ocamlbuildlightlib.cmxa \
@@ -46,4 +46,4 @@
   OCAMLBUILD=./boot/myocamlbuild.native
 else
-  OCAMLBUILD="./boot/ocamlrun boot/myocamlbuild"
+  OCAMLBUILD="./boot/fresh-ocamlrun boot/myocamlbuild"
 fi
diff -rN -U 2 ocaml-3.10.0/bytecomp/bytegen.ml fresh-ocaml-3.10.0/bytecomp/bytegen.ml
--- ocaml-3.10.0/bytecomp/bytegen.ml	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/bytecomp/bytegen.ml	2007-05-18 16:50:55.000000000 +0200
@@ -354,4 +354,9 @@
   | Pcvtbint(Pint32, Pint64) -> Kccall("caml_int64_of_int32", 1)
   | Pcvtbint(Pint64, Pint32) -> Kccall("caml_int64_to_int32", 1)
+  | Pswapatoms -> Kccall("fresh_swap_atoms", 3)
+  | Pfreshen -> Kccall("fresh_throughout", 1)
+  | Pnewatom -> Kccall("fresh_new_atom", 1)
+  | Pfreshfor -> Kccall("fresh_freshfor", 2)
+  | Pcreateabst -> Kccall("fresh_create_abstraction", 2)
   | Pcvtbint(Pnativeint, Pint64) -> Kccall("caml_int64_of_nativeint", 1)
   | Pcvtbint(Pint64, Pnativeint) -> Kccall("caml_int64_to_nativeint", 1)
diff -rN -U 2 ocaml-3.10.0/bytecomp/lambda.ml fresh-ocaml-3.10.0/bytecomp/lambda.ml
--- ocaml-3.10.0/bytecomp/lambda.ml	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/bytecomp/lambda.ml	2007-05-18 16:50:55.000000000 +0200
@@ -83,4 +83,10 @@
   | Pbigarrayref of int * bigarray_kind * bigarray_layout
   | Pbigarrayset of int * bigarray_kind * bigarray_layout
+  (* Freshness operations *)
+  | Pswapatoms   (* arity 3 *)
+  | Pfreshen     (* arity 1 *)
+  | Pnewatom	 (* arity 1 *)
+  | Pfreshfor	 (* arity 2 *)
+  | Pcreateabst  (* arity 2 *)
 
 and comparison =
diff -rN -U 2 ocaml-3.10.0/bytecomp/lambda.mli fresh-ocaml-3.10.0/bytecomp/lambda.mli
--- ocaml-3.10.0/bytecomp/lambda.mli	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/bytecomp/lambda.mli	2007-05-18 16:50:55.000000000 +0200
@@ -83,4 +83,10 @@
   | Pbigarrayref of int * bigarray_kind * bigarray_layout
   | Pbigarrayset of int * bigarray_kind * bigarray_layout
+  (* Freshness operations *)
+  | Pswapatoms
+  | Pfreshen
+  | Pnewatom
+  | Pfreshfor
+  | Pcreateabst
 
 and comparison =
diff -rN -U 2 ocaml-3.10.0/bytecomp/matching.ml fresh-ocaml-3.10.0/bytecomp/matching.ml
--- ocaml-3.10.0/bytecomp/matching.ml	2005-09-07 18:07:48.000000000 +0200
+++ fresh-ocaml-3.10.0/bytecomp/matching.ml	2007-05-18 16:50:55.000000000 +0200
@@ -198,4 +198,8 @@
       | Tpat_tuple args -> p,args @ rem
       | _          -> p, omegas @ rem)
+  | Tpat_abst (o1, o2) ->
+      (fun q rem -> match q.pat_desc with
+        Tpat_abst (p1, p2) -> p, [p1; p2] @ rem
+      | _ -> p, [o1; o2] @ rem)
   | Tpat_record l -> (* Records are normalized *)
       (fun q rem -> match q.pat_desc with
@@ -618,4 +622,5 @@
 | Tpat_variant (_,Some p, _) -> extract_vars r p
 | Tpat_or (p,_,_) -> extract_vars r p
+| Tpat_abst (p1, p2) -> List.fold_left extract_vars r [p1; p2]
 | Tpat_constant _|Tpat_any|Tpat_variant (_,None,_) -> r
 
@@ -684,4 +689,8 @@
   | _ -> false
 
+and group_abst = function
+  | {pat_desc=Tpat_abst _} -> true
+  | _ -> false
+
 let get_group p = match p.pat_desc with
 | Tpat_any -> group_var
@@ -692,4 +701,5 @@
 | Tpat_array _ -> group_array
 | Tpat_variant (_,_,_) -> group_variant
+| Tpat_abst _ -> group_abst
 |  _ -> fatal_error "Matching.get_group"
 
@@ -1270,5 +1280,5 @@
 
 (*
-  Three ``no-test'' cases
+  Four ``no-test'' cases
   *)
 
@@ -1288,4 +1298,33 @@
   divide_line ctx_lshift make_var_matching get_args_var omega ctx pm
 
+(* Matching against an abstraction pattern *)
+let get_args_abst p rem =
+  match p with
+    {pat_desc = Tpat_any} -> omegas 2 @ rem
+  | {pat_desc = Tpat_abst (p1, p2)} -> p1::p2::rem
+  | _ -> assert false
+
+let matcher_abst p rem =
+  match p.pat_desc with
+    Tpat_or (_, _, _) -> raise OrPat
+  | Tpat_var _ -> get_args_abst omega rem
+  | _ -> get_args_abst p rem
+
+let make_abst_matching def = function
+    (arg, mut) :: argl ->
+      let arglist = (Lprim (Pfield 0, [arg]), Alias) ::
+                    (Lprim (Pfield 1, [arg]), Alias) :: argl in
+        {cases = [];
+         args = arglist;
+         default = make_default matcher_abst def}
+  | _ -> fatal_error "Matching.make_abst_matching"
+
+let divide_abst p ctxt pm =
+  divide_line
+    (filter_ctx p)
+    make_abst_matching
+    get_args_abst
+    p ctxt pm
+
 (* Matching against a tuple pattern *)
 
@@ -2341,4 +2380,7 @@
         (combine_variant row arg partial)
         ctx pm
+  | Tpat_abst (p1, p2) ->
+      compile_no_test
+        (divide_abst (normalize_pat pat)) ctx_combine repr partial ctx pm
   | _ -> assert false
   end
@@ -2357,4 +2399,17 @@
 
 
+(* Determine if a pattern contains an abstraction pattern. *)
+let rec pat_has_abstractions pat =
+  match pat.pat_desc with
+    Tpat_alias (p, _) -> pat_has_abstractions p
+  | Tpat_tuple ps -> List.exists pat_has_abstractions ps
+  | Tpat_construct (_, ps) -> List.exists pat_has_abstractions ps
+  | Tpat_variant (_, Some p, _) -> pat_has_abstractions p
+  | Tpat_record lps -> List.exists (fun (_, p) -> pat_has_abstractions p) lps
+  | Tpat_array ps -> List.exists pat_has_abstractions ps
+  | Tpat_or (p1, p2, _) -> (pat_has_abstractions p1) ||
+                           (pat_has_abstractions p2)
+  | Tpat_abst _ -> true
+  | _ -> false
 
 
@@ -2407,5 +2462,9 @@
       let pm =
         { cases = List.map (fun (pat, act) -> ([pat], act)) pat_act_list;
-          args = [arg, Strict] ;
+          args =
+           (* if List.exists (fun (pat, _) -> pat_has_abstractions pat)
+                           pat_act_list
+            then [Lprim (Pfreshen, [arg]), Strict]
+            else *) [arg, Strict];
           default = []} in
       let (lambda, total) = compile_match repr partial (start_ctx 1) pm in
diff -rN -U 2 ocaml-3.10.0/bytecomp/printlambda.ml fresh-ocaml-3.10.0/bytecomp/printlambda.ml
--- ocaml-3.10.0/bytecomp/printlambda.ml	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/bytecomp/printlambda.ml	2007-05-18 16:50:55.000000000 +0200
@@ -180,4 +180,9 @@
   | Pbigarrayref(n, kind, layout) -> print_bigarray "get" kind ppf layout
   | Pbigarrayset(n, kind, layout) -> print_bigarray "set" kind ppf layout
+  | Pswapatoms -> fprintf ppf "swap_atoms"
+  | Pfreshen -> fprintf ppf "freshen"
+  | Pnewatom -> fprintf ppf "newatom"
+  | Pfreshfor -> fprintf ppf "freshfor"
+  | Pcreateabst -> fprintf ppf "createabst"
 
 let rec lam ppf = function
diff -rN -U 2 ocaml-3.10.0/bytecomp/translcore.ml fresh-ocaml-3.10.0/bytecomp/translcore.ml
--- ocaml-3.10.0/bytecomp/translcore.ml	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/bytecomp/translcore.ml	2007-05-18 16:50:55.000000000 +0200
@@ -141,5 +141,5 @@
 ]
 
-let primitives_table = create_hashtable 57 [
+let primitives_table = create_hashtable 62 [
   "%identity", Pidentity;
   "%ignore", Pignore;
@@ -521,4 +521,129 @@
   | a::l -> let (l1,l2) = cut (n-1) l in (a::l1,l2)
 
+(* Generate lambda-code to create a new atom value. *)
+let new_atom () = Lprim (Pnewatom, [Lconst const_unit])
+
+(* Generate lambda-code to swap two atoms throughout a value. *)
+let swap_atoms a a' v = Lprim (Pswapatoms, [a; a'; v])
+
+(* Determine if a pattern contains an abstraction pattern. *)
+let rec pat_has_abstractions pat =
+  match pat.pat_desc with
+    Tpat_alias (p, _) -> pat_has_abstractions p
+  | Tpat_tuple ps -> List.exists pat_has_abstractions ps
+  | Tpat_construct (_, ps) -> List.exists pat_has_abstractions ps
+  | Tpat_variant (_, Some p, _) -> pat_has_abstractions p
+  | Tpat_record lps -> List.exists (fun (_, p) -> pat_has_abstractions p) lps
+  | Tpat_array ps -> List.exists pat_has_abstractions ps
+  | Tpat_or (p1, p2, _) -> (pat_has_abstractions p1) ||
+                           (pat_has_abstractions p2)
+  | Tpat_abst _ -> true
+  | _ -> false
+
+(* Rewrite a pattern to turn all instances of abstraction patterns therein
+   into pair patterns. *)
+let rec rewrite_abstractions pat =
+  match pat.pat_desc with
+    Tpat_alias (p, i) ->
+      {pat with pat_desc = Tpat_alias (rewrite_abstractions p, i)}
+  | Tpat_tuple ps ->
+      {pat with pat_desc = Tpat_tuple (List.map rewrite_abstractions ps)}
+  | Tpat_construct (cd, ps) ->
+      {pat with
+       pat_desc = Tpat_construct (cd, List.map rewrite_abstractions ps)}
+  | Tpat_variant (l, Some p, rd) ->
+      {pat with pat_desc = Tpat_variant (l, Some (rewrite_abstractions p), rd)}
+  | Tpat_record lps ->
+      {pat with
+       pat_desc = Tpat_record (List.map (fun (l, p) ->
+                                         (l, rewrite_abstractions p)) lps)}
+  | Tpat_array ps ->
+      {pat with pat_desc = Tpat_array (List.map rewrite_abstractions ps)}
+  | Tpat_or (p1, p2, path_opt) ->
+      {pat with
+       pat_desc = Tpat_or (rewrite_abstractions p1, rewrite_abstractions p2,
+                           path_opt)}
+  | Tpat_abst (p1, p2) ->
+      {pat with pat_desc = Tpat_tuple [p1; p2]}
+  | _ -> pat
+  
+let rec rewrite_abstractions_2 pat =
+  match pat.pat_desc with
+    Tpat_var _ -> { pat with pat_desc = Tpat_any }
+  | Tpat_alias (p, i) -> p
+  | Tpat_tuple ps ->
+      {pat with pat_desc = Tpat_tuple (List.map rewrite_abstractions_2 ps)}
+  | Tpat_construct (cd, ps) ->
+      {pat with
+       pat_desc = Tpat_construct (cd, List.map rewrite_abstractions_2 ps)}
+  | Tpat_variant (l, Some p, rd) ->
+      {pat with pat_desc =
+       Tpat_variant (l, Some (rewrite_abstractions_2 p), rd)}
+  | Tpat_record lps ->
+      {pat with
+       pat_desc = Tpat_record (List.map (fun (l, p) ->
+                                         (l, rewrite_abstractions_2 p)) lps)}
+  | Tpat_array ps ->
+      {pat with pat_desc = Tpat_array (List.map rewrite_abstractions_2 ps)}
+  | Tpat_or (p1, p2, path_opt) ->
+      {pat with
+       pat_desc = Tpat_or (rewrite_abstractions_2 p1, rewrite_abstractions p2,
+                           path_opt)}
+  | Tpat_abst (p1, p2) ->
+      {pat with pat_desc = Tpat_tuple [rewrite_abstractions_2 p1;
+                                       rewrite_abstractions_2 p2]}
+  | _ -> pat
+
+(* Insertion of "freshening" code for abstraction patterns. *)
+let rec insert_freshening loc pat e =
+  match pat.pat_desc with
+    Tpat_alias (p, i) ->
+      let p', e' = insert_freshening loc p e in
+        ({pat with pat_desc = Tpat_alias (p', i)}, e')
+  | Tpat_tuple ps ->
+      let ps', e' = insert_freshening_list loc ps e in
+        ({pat with pat_desc = Tpat_tuple ps'}, e')
+  | Tpat_construct (cd, ps) ->
+      let ps', e' = insert_freshening_list loc ps e in
+        ({pat with pat_desc = Tpat_construct (cd, ps')}, e')
+  | Tpat_variant (l, Some p, rd) ->
+      let p', e' = insert_freshening loc p e in
+        ({pat with pat_desc = Tpat_variant (l, Some p', rd)}, e')
+  | Tpat_record lps ->
+      let lps', e' = insert_freshening_record loc lps e in
+        ({pat with pat_desc = Tpat_record lps'}, e')
+  | Tpat_array ps ->
+      let ps', e' = insert_freshening_list loc ps e in
+        ({pat with pat_desc = Tpat_array (ps')}, e')
+  | Tpat_or (p1, p2, path_opt) ->
+      let p1', e1 = insert_freshening loc p1 e in
+      let p2', e2 = insert_freshening loc p2 e1 in
+        ({pat with pat_desc = Tpat_or (p1', p2', path_opt)}, e2)
+  | Tpat_abst (p1, p2) ->
+      (* rewrite <<p1>>p2 to turn all abstraction patterns into pair
+         patterns *)
+      let pat'' = rewrite_abstractions pat in
+      let pat_no_ids = rewrite_abstractions_2 pat in
+      (* the pattern <<p1>>p2 is replaced with an alias pattern *)
+      let x = Ident.create "alias" in
+      let pat' = {pat with pat_desc = Tpat_alias (pat_no_ids, x)} in
+      (* generate code to freshen x *)
+      let freshen = Lprim (Pfreshen, [Lvar x]) in
+      (* assemble new expression *)
+        (pat', Matching.for_function loc None freshen [(pat'', e)] Partial)
+  | _ -> (pat, e)
+
+and insert_freshening_list loc ps e =
+    List.fold_right (fun cur_p ->
+                     fun (ps_acc, e_acc) ->
+                       let p_new, e_new = insert_freshening loc cur_p e_acc in
+                         p_new :: ps_acc, e_new) ps ([], e)
+
+and insert_freshening_record loc lps e =
+    List.fold_right (fun (l, cur_p) ->
+                     fun (lps_acc, e_acc) ->
+                       let p_new, e_new = insert_freshening loc cur_p e_acc in
+                         (l, p_new) :: lps_acc, e_new) lps ([], e)
+
 (* Translation of expressions *)
 
@@ -598,12 +723,15 @@
   | Texp_match({exp_desc = Texp_tuple argl}, pat_expr_list, partial) ->
       Matching.for_multiple_match e.exp_loc
-        (transl_list argl) (transl_cases pat_expr_list) partial
+        (transl_list argl)
+        (transl_cases e.exp_loc pat_expr_list) partial
   | Texp_match(arg, pat_expr_list, partial) ->
       Matching.for_function e.exp_loc None
-        (transl_exp arg) (transl_cases pat_expr_list) partial
+        (transl_exp arg)
+        (transl_cases e.exp_loc pat_expr_list) partial
   | Texp_try(body, pat_expr_list) ->
       let id = name_pattern "exn" pat_expr_list in
       Ltrywith(transl_exp body, id,
-               Matching.for_trywith (Lvar id) (transl_cases pat_expr_list))
+               Matching.for_trywith (Lvar id)
+                                    (transl_cases e.exp_loc pat_expr_list))
   | Texp_tuple el ->
       let ll = transl_list el in
@@ -737,15 +865,27 @@
           cl_type = Tcty_signature cty;
           cl_env = e.exp_env }
+   | Texp_abst (e1, e2) ->
+       Lprim (Pcreateabst, transl_list [e1; e2])
+   | Texp_swap (e1, e2, body) ->
+       swap_atoms (transl_exp e1) (transl_exp e2) (transl_exp body)
+   | Texp_fresh ->
+       new_atom ()
+   | Texp_freshfor (e1, e2) ->
+       Lprim (Pfreshfor, transl_list [e1; e2])
+   | Texp_customswap (e1, e2) ->
+       Lprim (Pmakeblock (243, Immutable), transl_list [e1; e2])
 
 and transl_list expr_list =
   List.map transl_exp expr_list
 
-and transl_cases pat_expr_list =
+and transl_cases loc pat_expr_list =
   List.map
-    (fun (pat, expr) -> (pat, event_before expr (transl_exp expr)))
+    (fun (pat, expr) ->
+       insert_freshening loc pat (event_before expr (transl_exp expr)))
     pat_expr_list
 
-and transl_tupled_cases patl_expr_list =
-  List.map (fun (patl, expr) -> (patl, transl_exp expr)) patl_expr_list
+and transl_tupled_cases loc patl_expr_list =
+  List.map (fun (patl, expr) ->
+              insert_freshening_list loc patl (transl_exp expr)) patl_expr_list
 
 and transl_apply lam sargs =
@@ -805,6 +945,7 @@
       let ((_, params), body) =
         transl_function exp.exp_loc false repr partial' pl in
+      let pat', body' = insert_freshening loc pat body in
       ((Curried, param :: params),
-       Matching.for_function loc None (Lvar param) [pat, body] partial)
+       Matching.for_function loc None (Lvar param) [pat', body'] partial)
   | ({pat_desc = Tpat_tuple pl}, _) :: _ when untuplify_fn ->
       begin try
@@ -817,10 +958,10 @@
         ((Tupled, params),
          Matching.for_tupled_function loc params
-           (transl_tupled_cases pats_expr_list) partial)
+           (transl_tupled_cases loc pats_expr_list) partial)
       with Matching.Cannot_flatten ->
         let param = name_pattern "param" pat_expr_list in
         ((Curried, [param]),
          Matching.for_function loc repr (Lvar param)
-           (transl_cases pat_expr_list) partial)
+           (transl_cases loc pat_expr_list) partial)
       end
   | _ ->
@@ -828,5 +969,5 @@
       ((Curried, [param]),
        Matching.for_function loc repr (Lvar param)
-         (transl_cases pat_expr_list) partial)
+         (transl_cases loc pat_expr_list) partial)
 
 and transl_let rec_flag pat_expr_list body =
@@ -837,4 +978,12 @@
           body
       | (pat, expr) :: rem ->
+          if pat_has_abstractions pat then
+            (* rewrite abstraction patterns to pair patterns and
+               freshen the right-hand side of the let *)
+            let pat' = rewrite_abstractions pat in
+            let expr' = Lprim (Pfreshen, [transl_exp expr]) in
+              Matching.for_let pat.pat_loc expr' pat' (transl rem)
+          else
+            (* no abstraction patterns present *)
           Matching.for_let pat.pat_loc (transl_exp expr) pat (transl rem)
       in transl pat_expr_list
diff -rN -U 2 ocaml-3.10.0/byterun/Makefile fresh-ocaml-3.10.0/byterun/Makefile
--- ocaml-3.10.0/byterun/Makefile	2007-02-23 10:29:45.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -16,5 +16,5 @@
 include ../config/Makefile
 
-CC=$(BYTECC)
+CC=$(BYTECC) -g
 CFLAGS=-DCAML_NAME_SPACE -O $(BYTECCCOMPOPTS)
 DFLAGS=-DCAML_NAME_SPACE -g -DDEBUG $(BYTECCCOMPOPTS)
@@ -26,5 +26,5 @@
   hash.o sys.o meta.o parsing.o gc_ctrl.o terminfo.o md5.o obj.o \
   lexing.o callback.o debugger.o weak.o compact.o finalise.o custom.o \
-  dynlink.o unix.o
+  dynlink.o unix.o freshness.o hashtable_cwc22.o hashtable_itr_cwc22.o
 
 DOBJS=$(OBJS:.o=.d.o) instrtrace.d.o
@@ -33,21 +33,21 @@
   intern.c interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c \
   signals.c str.c sys.c terminfo.c callback.c weak.c finalise.c stacks.c \
-  dynlink.c
+  dynlink.c freshness.c hashtable_cwc22.c hashtable_itr_cwc22.c
 
 PUBLIC_INCLUDES=alloc.h callback.h config.h custom.h fail.h intext.h \
   memory.h misc.h mlvalues.h printexc.h signals.h compatibility.h
 
-all: ocamlrun$(EXE) ld.conf
+all: fresh-ocamlrun$(EXE) ld.conf
 
-ocamlrun$(EXE): libcamlrun.a prims.o
-	$(BYTECC) $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o ocamlrun$(EXE) \
+fresh-ocamlrun$(EXE): libcamlrun.a prims.o
+	$(BYTECC) $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o fresh-ocamlrun$(EXE) \
 	          prims.o libcamlrun.a $(BYTECCLIBS)
 
-ocamlrund$(EXE): libcamlrund.a prims.o
-	$(BYTECC) -g $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o ocamlrund$(EXE) \
+fresh-ocamlrund$(EXE): libcamlrund.a prims.o
+	$(BYTECC) -g $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) -o fresh-ocamlrund$(EXE) \
 	          prims.o libcamlrund.a $(BYTECCLIBS)
 
 install:
-	cp ocamlrun$(EXE) $(BINDIR)/ocamlrun$(EXE)
+	cp fresh-ocamlrun$(EXE) $(BINDIR)/fresh-ocamlrun$(EXE)
 	cp libcamlrun.a $(LIBDIR)/libcamlrun.a
 	cd $(LIBDIR); $(RANLIB) libcamlrun.a
@@ -71,5 +71,5 @@
 
 clean:
-	rm -f ocamlrun$(EXE) ocamlrund$(EXE) *.o lib*.a
+	rm -f fresh-ocamlrun$(EXE) fresh-ocamlrund$(EXE) *.o lib*.a
 	rm -f primitives prims.c opnames.h jumptbl.h ld.conf
 	rm -f version.h
diff -rN -U 2 ocaml-3.10.0/byterun/compare.c fresh-ocaml-3.10.0/byterun/compare.c
--- ocaml-3.10.0/byterun/compare.c	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/compare.c	2007-05-18 16:50:55.000000000 +0200
@@ -21,4 +21,5 @@
 #include "misc.h"
 #include "mlvalues.h"
+#include "freshness.h"
 
 /* Structural comparison on trees. */
@@ -97,4 +98,20 @@
   tag_t t1, t2;
 
+  if (Is_block(v1) && Tag_val(v1) == Custom_swap_tag) {
+      return compare_val(Field(v1, 1), v2, total);
+  }
+  if (Is_block(v2) && Tag_val(v2) == Custom_swap_tag) {
+      return compare_val(v1, Field(v2, 1), total);
+  }
+  /*
+  if (Is_block(v1) && (Tag_val(v1) == Custom_swap_tag ||
+                       Tag_val(v1) == No_bind_tag)) {
+      return compare_val(Field(v1, 1), v2);
+  }
+  if (Is_block(v2) && (Tag_val(v2) == Custom_swap_tag ||
+                       Tag_val(v2) == No_bind_tag)) {
+      return compare_val(v1, Field(v2, 1));
+  }*/
+
   sp = compare_stack;
   while (1) {
@@ -135,4 +152,11 @@
     if (t1 != t2) return (intnat)t1 - (intnat)t2;
     switch(t1) {
+    case Atom_tag: {
+      long l1 = (long) Field(v1, 0);
+      long l2 = (long) Field(v2, 0);
+      if (l1 < l2) return -1;
+      if (l1 > l2) return 1;
+      break;
+    }
     case String_tag: {
       mlsize_t len1, len2, len;
@@ -210,4 +234,6 @@
       break;
     }
+    case Abst_tag:
+      return fresh_compare_abstractions(v1, v2);
     default: {
       mlsize_t sz1 = Wosize_val(v1);
@@ -268,6 +294,10 @@
 CAMLprim value caml_lessthan(value v1, value v2)
 {
-  intnat res = compare_val(v1, v2, 0);
-  if (compare_stack != compare_stack_init) compare_free_stack();
+  long res;
+  if ((Is_block(v1) && Tag_val(v1) == Atom_tag) ||
+      (Is_block(v2) && Tag_val(v2) == Atom_tag)) {
+    caml_invalid_argument("cannot perform less-than operation on atoms");
+  }
+  res = compare_val(v1, v2, 0);  if (compare_stack != compare_stack_init) compare_free_stack();
   return Val_int(res - 1 < -1);
 }
@@ -275,5 +305,10 @@
 CAMLprim value caml_lessequal(value v1, value v2)
 {
-  intnat res = compare_val(v1, v2, 0);
+  long res;
+  if ((Is_block(v1) && Tag_val(v1) == Atom_tag) ||
+      (Is_block(v2) && Tag_val(v2) == Atom_tag)) {
+    caml_invalid_argument("cannot perform less-than operation on atoms");
+  }
+  res = compare_val(v1, v2, 0);  if (compare_stack != compare_stack_init) compare_free_stack();
   if (compare_stack != compare_stack_init) compare_free_stack();
   return Val_int(res - 1 <= -1);
@@ -282,5 +317,10 @@
 CAMLprim value caml_greaterthan(value v1, value v2)
 {
-  intnat res = compare_val(v1, v2, 0);
+  long res;
+  if ((Is_block(v1) && Tag_val(v1) == Atom_tag) ||
+      (Is_block(v2) && Tag_val(v2) == Atom_tag)) {
+    caml_invalid_argument("cannot perform less-than operation on atoms");
+  }
+  res = compare_val(v1, v2, 0);  if (compare_stack != compare_stack_init) compare_free_stack();
   if (compare_stack != compare_stack_init) compare_free_stack();
   return Val_int(res > 0);
@@ -289,5 +329,10 @@
 CAMLprim value caml_greaterequal(value v1, value v2)
 {
-  intnat res = compare_val(v1, v2, 0);
+  long res;
+  if ((Is_block(v1) && Tag_val(v1) == Atom_tag) ||
+      (Is_block(v2) && Tag_val(v2) == Atom_tag)) {
+    caml_invalid_argument("cannot perform less-than operation on atoms");
+  }
+  res = compare_val(v1, v2, 0);  if (compare_stack != compare_stack_init) compare_free_stack();
   if (compare_stack != compare_stack_init) compare_free_stack();
   return Val_int(res >= 0);
diff -rN -U 2 ocaml-3.10.0/byterun/freshness.c fresh-ocaml-3.10.0/byterun/freshness.c
--- ocaml-3.10.0/byterun/freshness.c	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/freshness.c	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,1159 @@
+/*
+ *  byterun/freshness.c
+ *
+ *  Low-level support for freshness functionality.
+ *
+ *  (c) Copyright 2003-2005, Mark R. Shinwell.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  3. The names of the authors may not be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ *  NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "fail.h"
+#include "alloc.h"
+#include "memory.h"
+#include "custom.h"
+#include "mlvalues.h"
+#include "callback.h"
+#include "minor_gc.h"
+#include "major_gc.h"
+#include "hashtable_cwc22.h"
+#include "hashtable_itr_cwc22.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+
+/* Prototypes for external functions. */
+extern value compare(value, value);
+
+/***************************************************************************
+ * Functions local to this module.
+ **************************************************************************/
+
+static int atom_id = 0; /* FIXME needs to go to 64 bits */
+
+static inline unsigned int value_hasher(void* v)
+{
+    /* Hash function for things of type "value". */
+
+#ifdef ARCH_SIXTYFOUR
+    return ((unsigned int) v) % UINT_MAX;
+#else
+    return (unsigned int) v;
+#endif
+}
+
+static int value_equality(void* v1, void* v2)
+{
+    /* Hashtable equality function for things of type "value". */
+
+    return v1 == v2;
+}
+
+static void dump_rec(struct hashtable* ht, value v)
+{
+    CAMLparam1(v);
+        
+    if (Is_block(v) && Tag_val(v) < No_scan_tag && Tag_val(v) != Atom_tag) {
+        void* data = hashtable_search(ht, (void*) v);
+
+        printf("%p=", (void*) v);
+
+        if (data) {
+            /* seen this block already */
+            printf("<shared>");
+        }
+        else {
+            int x;
+
+            switch (Tag_val(v)) {
+                case 0: printf("tuple=["); break;
+                case Closure_tag: printf("closure=["); break;
+                case Double_array_tag: printf("<double array>"); break;
+                case Abstract_tag: printf("<abstract>"); break;
+                case Custom_tag: printf("<custom>"); break;
+                case String_tag: printf("<string>"); break;
+                case Abst_tag: printf("abst=["); break;
+                default: printf("tag %d=[", (int) Tag_val(v)); break;
+            }
+
+            fflush(stdout);
+           
+            for (x = (Tag_val(v) == Closure_tag ? 1 : 0);
+                 x < Wosize_val(v);
+                 x++) {
+                dump_rec(ht, Field(v, x));
+                if (x < Wosize_val(v) - 1) {
+                    printf(", ");
+                }
+            }
+            printf("]");
+        }
+    }
+    else if (Is_block(v) && Tag_val(v) == Atom_tag) {
+        printf("%p=atom#%d", (void*) v, Int_val(Field(v, 0)));
+    }
+    else {
+        if (!Is_block(v)) {
+            if (v == 0) {
+                printf("<null>");
+            }
+            else {
+                printf("<unboxed>");
+            }
+        }
+        else {
+            printf("<unstructured>");
+        }
+    }
+
+    fflush(stdout);
+
+    CAMLreturn0;
+}
+
+void dump(value v)
+{
+    CAMLparam1(v);
+
+    struct hashtable* ht =
+        create_hashtable(64, 0.75, value_hasher, value_equality);
+    
+    dump_rec(ht, v);
+
+    hashtable_destroy(ht, 0);
+
+    printf("\n");
+    fflush(stdout);
+
+    CAMLreturn0;
+}
+
+/* Allocate a new atom. */
+static value alloc_atom(void)
+{
+    CAMLparam0();
+    CAMLlocal1(atom);
+
+    /* an atom is a block with tag Atom_tag, whose first field
+     * is an "atom identifier".
+     */
+    atom = caml_alloc(1, Atom_tag);
+    Store_field(atom, 0, Val_int(atom_id++));
+
+    CAMLreturn(atom);
+}
+
+/* Allocate a number of fresh atoms and store them in a tuple. */
+static value alloc_atoms(int num)
+{
+    int i;
+
+    CAMLparam0();
+    CAMLlocal1(array);
+
+    assert(num > 0);
+    
+    array = caml_alloc_tuple(num);
+    for (i = 0; i < num; i++) {
+        Store_field(array, i, alloc_atom());
+    }
+
+    CAMLreturn(array);
+}
+
+/* Calculate the support of a value, given hashtables as described
+ * in calculate_support() below.
+ */
+static void calculate_support_rec(value v,
+                                  struct hashtable* ht_exclude,
+                                  struct hashtable* ht_visited,
+                                  struct hashtable* ht_support)
+{
+    CAMLparam1(v);
+
+    if (Is_block(v) && Tag_val(v) < No_scan_tag &&
+        Tag_val(v) != Object_tag &&
+        (Tag_val(v) == Atom_tag || !hashtable_search(ht_visited, (void*) v))) {
+        /* record having visited this value. */
+        hashtable_insert(ht_visited, (void*) v, (void*) 1);
+        
+        switch (Tag_val(v)) {
+            case Custom_swap_tag:
+                calculate_support_rec(Field(v, 0),
+                                      ht_exclude, ht_visited, ht_support);
+                break;
+                
+            case Atom_tag:
+            {
+                /* determine if this atom is to be excluded */
+                if (!hashtable_search(ht_exclude, (void*) v)) {
+                    /* the atom is not to be excluded, so see if it's
+                     * in the support set already...
+                     */
+                    if (!hashtable_search(ht_support, (void*) v)) {
+                        /* ...no it's not, so add it. */
+			hashtable_insert(ht_support, (void*) v,
+                                         (void*) Val_int(1));
+                    }
+                }
+                break;
+            }
+
+            case Abst_tag:
+            {
+                /* here we must calculate the support of the body v1 and
+                 * then subtract the support of the value v2 in binding
+                 * position: this is achieved by adding the support of v1
+                 * to ht_exclude and then calculating the support of v2.
+                 * We must take care with the ht_exclude hashtable, as we
+                 * might be dealing with something like (<<a>>a, a) and it
+                 * would be incorrect to have "a" remaining in ht_exclude
+                 * when treating the second component of the tuple.
+                 */
+
+                /* create a hashtable which will act as a copy of
+                 * ht_exclude, augmented with everything in the support of
+                 * the value in binding position
+                 */
+                struct hashtable* ht_exclude_new;
+                ht_exclude_new =
+                  create_hashtable(64, 0.75, value_hasher, value_equality);
+
+                /* calculate the support of the value
+                 * in binding position */
+                calculate_support_rec(Field(v, 0),
+                                      ht_exclude, ht_visited,
+                                      ht_exclude_new);
+
+                /* add everything in ht_exclude to ht_exclude_new */
+                if (hashtable_count((struct hashtable*) ht_exclude) > 0) {
+                    struct hashtable_itr* iter;
+                    iter = hashtable_iterator((struct hashtable*) ht_exclude);
+                    assert(iter);
+
+                    do {
+                        void* key;
+                        void* data;
+                        
+                        key = hashtable_iterator_key(iter);
+                        data = hashtable_iterator_value(iter);
+
+                        hashtable_insert(ht_exclude_new, key, data);
+                    } while (hashtable_iterator_advance(iter));
+                    free(iter);
+                }
+
+                /* calculate the support of the body */
+                calculate_support_rec(Field(v, 1),
+                                      ht_exclude_new, ht_visited,
+                                      ht_support);
+              
+                /* delete the new hashtable */
+                hashtable_destroy(ht_exclude_new, 0);
+
+                break;
+            }
+	    
+            default: /* tuple-like things and closures */
+            {
+                int i;
+                /* take the union of the supports of each field, being
+                 * careful to skip over the code pointer for closures */
+                for (i = (Tag_val(v) == Closure_tag ? 1 : 0);
+                     i < Wosize_val(v); i++) {
+                    calculate_support_rec(Field(v, i), ht_exclude,
+                                          ht_visited, ht_support);
+                }
+                
+                break;
+            }
+        }
+    }
+
+    CAMLreturn0;
+}
+
+/* Calculate the support of a value, returning the support as a tuple.
+ *
+ * Val_unit is returned if the support is empty.
+ * Wosize_val on a tuple result will give the cardinality of the support.
+ */
+static value calculate_support(value v)
+{
+    CAMLparam1(v);
+    CAMLlocal1(supp);
+
+    /* three hashtables are used for efficiency:
+     * - one which holds atoms which should not be added to the
+     *   support as we go along (used for treating abstraction values);
+     * - one which holds pointers to blocks which we've visited already
+     *   (each block only needs to be visited once);
+     * - one which acts as a set for collecting the support.
+     */
+    struct hashtable* ht_exclude;
+    struct hashtable* ht_visited;
+    struct hashtable* ht_support;
+
+    int cardinality;
+
+    /* return right away if we can: unboxed values have empty support;
+     * objects and non-scannable blocks are not inspected */
+    if (!Is_block(v) ||
+        (Tag_val(v) >= No_scan_tag || Tag_val(v) == Object_tag)) {
+        CAMLreturn(Val_unit);
+    }
+
+    /* create hashtables */
+    ht_exclude = create_hashtable(64, 0.75, value_hasher, value_equality);
+    ht_visited = create_hashtable(64, 0.75, value_hasher, value_equality);
+    ht_support = create_hashtable(64, 0.75, value_hasher, value_equality);
+
+    /* calculate the support */
+    calculate_support_rec(v, ht_exclude, ht_visited, ht_support);
+    cardinality = hashtable_count(ht_support);
+
+    /* allocate a tuple for the result and fill it, if the support
+     * is non-empty */
+    if (cardinality == 0) {
+        supp = Val_unit;
+    }
+    else {
+        /* transfer the contents of ht_support into the result tuple */
+        struct hashtable_itr* iter;
+        int pos;
+	value* supp_tmp = (value*) malloc(sizeof(value) * cardinality);
+	CAMLxparamN(supp_tmp, cardinality);
+
+        iter = hashtable_iterator((struct hashtable*) ht_support);
+        assert(iter);
+
+	pos = 0;
+
+        do {
+	    supp_tmp[pos++] = (value) hashtable_iterator_key(iter);
+        } while (hashtable_iterator_advance(iter));
+	assert(pos == cardinality);
+	free(iter);
+
+        supp = caml_alloc_tuple(cardinality);
+	for (pos = 0; pos < cardinality; pos++) {
+            Store_field(supp, pos, supp_tmp[pos]);
+	}
+
+        free(supp_tmp);
+    }
+    
+    /* delete the hashtables */
+    hashtable_destroy(ht_exclude, 0);
+    hashtable_destroy(ht_visited, 0);
+    hashtable_destroy(ht_support, 0);
+
+    CAMLreturn(supp);
+}
+
+#if 0
+static int calculate_cardinality_of_support(value v)
+{
+    CAMLparam1(v);
+    CAMLlocal1(supp);
+
+    /* three hashtables are used for efficiency:
+     * - one which holds atoms which should not be added to the
+     *   support as we go along (used for treating abstraction values);
+     * - one which holds pointers to blocks which we've visited already
+     *   (each block only needs to be visited once);
+     * - one which acts as a set for collecting the support.
+     */
+    struct hashtable* ht_exclude;
+    struct hashtable* ht_visited;
+    struct hashtable* ht_support;
+
+    int cardinality;
+
+    /* return right away if we can: unboxed values have empty support;
+     * objects and non-scannable blocks are not inspected */
+    if (!Is_block(v) ||
+        (Tag_val(v) >= No_scan_tag || Tag_val(v) == Object_tag)) {
+        CAMLreturn(0);
+    }
+
+    /* create hashtables */
+    ht_exclude = create_hashtable(64, 0.75, value_hasher, value_equality);
+    ht_visited = create_hashtable(64, 0.75, value_hasher, value_equality);
+    ht_support = create_hashtable(64, 0.75, value_hasher, value_equality);
+
+    /* calculate the support */
+    calculate_support_rec(v, ht_exclude, ht_visited, ht_support);
+    cardinality = hashtable_count(ht_support);
+    
+    /* delete the hashtables */
+    hashtable_destroy(ht_exclude, 0);
+    hashtable_destroy(ht_visited, 0);
+    hashtable_destroy(ht_support, 0);
+
+    CAMLreturn(cardinality);
+}
+#endif
+
+/* Worker function for contains_abstractions(), below. */
+static int contains_abstractions_rec(struct hashtable* ht, value v)
+{
+    CAMLparam1(v);
+    int ret = 0;
+        
+    if (Is_block(v) && Tag_val(v) < No_scan_tag && Tag_val(v) != Object_tag) {
+        void* data = hashtable_search(ht, (void*) v);
+
+        /* data is NULL if we haven't seen the block already;
+         *         (void*) 1 if we have seen the block already and it doesn't
+         *                   contain abstractions;
+         *         (void*) 2 if we have seen the block already and it does
+         *                   contain abstractions.
+         */
+
+        if (data) {
+            /* seen this block already */
+            ret = ((int) data) - 1;
+        }
+        else {
+            /* see if we have an abstraction block */
+            if (Tag_val(v) == Abst_tag) {
+                /* yes we do */
+                ret = 1;
+            }
+            else {
+                /* here we either have a closure, or another
+                 * structured block which isn't one of the special cases.
+                 */
+
+                int x;
+
+                /* add the current block to the hashtable.  Just in case
+                 * the value is recursive, we first assume that we _do_
+                 * contain abstractions to be on the safe side.
+                 */
+                hashtable_insert(ht, (void*) v, (void*) 2);
+
+                for (x = (Tag_val(v) == Closure_tag ? 1 : 0);
+                     x < Wosize_val(v) && !ret;
+                     x++) {
+                    ret = contains_abstractions_rec(ht, Field(v, x));
+                }
+                
+                /* replace our entry in the hashtable now we know the result */
+                hashtable_remove(ht, (void*) v);
+                /* insert is done below */
+            }
+            
+            hashtable_insert(ht, (void*) v, (void*) (ret + 1));
+        }
+    }
+
+    CAMLreturn(ret);
+}
+
+/* Approximate whether a value contains any abstraction blocks. */
+static int contains_abstractions(value v)
+{
+    CAMLparam1(v);
+
+    int ret;
+    struct hashtable* ht =
+        create_hashtable(64, 0.75, value_hasher, value_equality);
+  
+    /*
+    printf("contains_abstractions:\n");
+    dump(v);
+    printf("-end-\n");
+    */
+    ret = contains_abstractions_rec(ht, v);
+
+    hashtable_destroy(ht, 0);
+
+    CAMLreturn(ret);
+}
+
+/* Worker function for valid_in_binding_pos(), below. */
+static int valid_in_binding_pos_rec(struct hashtable* ht, value v)
+{
+    CAMLparam1(v);
+    int ret = 0;
+
+    if (!Is_block(v) || Tag_val(v) >= No_scan_tag) {
+	/* do nothing */
+    }
+    else if (Tag_val(v) == Object_tag ||
+	     Tag_val(v) == Closure_tag) {
+	/* not allowed! */
+	ret = 1;
+    }
+    else if (Tag_val(v) != Atom_tag /* atoms are OK */) {
+        void* data = hashtable_search(ht, (void*) v);
+
+        /* data is NULL if we haven't seen the block already;
+         *         (void*) 1 if we have seen the block already and it doesn't
+         *                   contain anything illegal in binding position;
+         *         (void*) 2 if we have seen the block already and it does
+         *                   contain something illegal in binding position.
+         */
+
+        if (data) {
+            /* seen this block already */
+            ret = ((int) data) - 1;
+        }
+        else {
+	    int x;
+
+	    hashtable_insert(ht, (void*) v, (void*) 1);
+
+	    for (x = 0; x < Wosize_val(v) && !ret; x++) {
+		ret = valid_in_binding_pos_rec(ht, Field(v, x));
+	    }
+		    
+	    /* replace our entry in the hashtable now we know the result */
+	    hashtable_remove(ht, (void*) v);
+            hashtable_insert(ht, (void*) v, (void*) (ret + 1));
+        }
+    }
+
+    CAMLreturn(ret);
+}
+
+/* Determine whether a value is acceptable in binding position.
+ * Returns 0 if the value is OK, 1 if not.
+ */
+static int valid_in_binding_pos(value v)
+{
+    CAMLparam1(v);
+
+    int ret;
+    struct hashtable* ht =
+        create_hashtable(64, 0.75, value_hasher, value_equality);
+   
+    ret = valid_in_binding_pos_rec(ht, v);
+
+    hashtable_destroy(ht, 0);
+
+    CAMLreturn(ret);
+}
+
+static value tuple_to_list(value v)
+{
+    /* Turn (x0, ..., xn) into [x0; ...; xn]. */
+
+    CAMLparam1(v);
+    CAMLlocal1(ret);
+    CAMLlocal1(cur);
+    CAMLlocal1(prev);
+    int i = 0;
+    
+    assert(Is_block(v) && Tag_val(v) == 0 && Wosize_val(v) >= 1);
+
+    prev = (value) 0;
+    ret = (value) 0;
+
+    do {
+        cur = caml_alloc_tuple(2);
+        Store_field(cur, 0, Field(v, i));
+        Store_field(cur, 1, Val_int(0));
+
+        if (!ret) {
+            ret = cur;
+        }
+
+        if (prev) {
+            Store_field(prev, 1, cur);
+        }
+
+        prev = cur;
+    } while (++i < Wosize_val(v));
+
+    CAMLreturn(ret);
+}
+
+typedef value (*alloc_fn)(int size, int tag);
+
+typedef enum {
+    entry_ALLOCATE,
+    entry_SHARED
+} dynarray_entry_type;
+
+typedef struct {
+    dynarray_entry_type type;
+    union {
+        struct {
+            alloc_fn fn;
+            int size;
+            int tag;
+        } allocate;
+        struct {
+            int index;
+        } shared;
+    } data;
+} dynarray_entry;
+
+typedef struct {
+    dynarray_entry* data;
+    int allocated;
+    int used;
+} dynarray;
+
+static dynarray dynarray_alloc(void)
+{
+    dynarray da;
+    da.allocated = 16;
+    da.used = 0;
+    da.data = (dynarray_entry*) malloc(da.allocated * sizeof(dynarray_entry));
+    return da;
+}
+
+static void dynarray_free(dynarray da)
+{
+    free((void*) da.data);
+}
+
+static void dynarray_check_size(dynarray* da)
+{
+    if (da->used == da->allocated) {
+        da->allocated *= 2;
+        da->data = (dynarray_entry*)
+          realloc((void*) da->data, da->allocated * sizeof(dynarray_entry));
+    }
+}
+
+static int dynarray_add_allocation(dynarray* da,
+                                   alloc_fn fn, int size, int tag)
+{
+    dynarray_check_size(da);
+    
+    da->data[da->used].type = entry_ALLOCATE;
+    da->data[da->used].data.allocate.fn = fn;
+    da->data[da->used].data.allocate.size = size;
+    da->data[da->used].data.allocate.tag = tag;
+    da->used++;
+
+    return da->used - 1;
+}
+
+static void dynarray_add_shared(dynarray* da, int index)
+{
+    assert(index < da->used);
+    
+    dynarray_check_size(da);
+
+    da->data[da->used].type = entry_SHARED;
+    da->data[da->used].data.shared.index = index;
+    da->used++;
+}
+
+static value dynarray_to_blocks(dynarray* da)
+{
+    CAMLparam0();
+    CAMLlocal1(v);
+
+    v = Val_unit;
+
+    if (da->used > 0) {
+        int i;
+        v = caml_alloc_tuple(da->used);
+        for (i = 0; i < da->used; i++) {
+            if (da->data[i].type == entry_ALLOCATE) {
+                Store_field(v, i,
+                            (*(da->data[i].data.allocate.fn))
+                            (da->data[i].data.allocate.size,
+                             da->data[i].data.allocate.tag));
+            }
+            else {
+                assert(i > 0);
+                assert(da->data[i].data.shared.index < i);
+
+                Store_field(v, i, Field(v, da->data[i].data.shared.index));
+            }
+        }
+    }
+
+    CAMLreturn(v);
+}
+
+static int dynarray_is_block_shared(dynarray* da, int index)
+{
+    /* Returns non-zero if the block at "index" is shared. */
+
+    assert(da);
+    assert(index >= 0 && index < da->used);
+
+    return (da->data[index].type == entry_SHARED);
+}
+
+static value alloc_fn_gen(int size, int tag)
+{
+    return caml_alloc(size, tag);
+}
+
+/*static value alloc_fn_atom(int unused1, int unused2)
+{
+    return alloc_atom();
+}*/
+
+static void deep_copy_collect_sizes(dynarray* da, struct hashtable* ht,
+			            value v, int under_nobind)
+{
+    /* No allocation on the ML heap may happen within this function, or
+     * "ht" will potentially be invalidated.
+     */
+
+    /* The hashtable maps from values which we have seen and will need to
+     * be copied, to integers specifying the *1-based* index in the array
+     * "da" corresponding to that value.  We have to use a 1-based index
+     * to distinguish the "not found" return value from hashtable_search.
+     */
+
+    if (Is_block(v) && (Tag_val(v) < No_scan_tag &&
+			Tag_val(v) != Object_tag &&
+			Tag_val(v) != Atom_tag &&
+			Tag_val(v) != No_swap_tag)) {
+        void* data = hashtable_search(ht, (void*) v);
+
+	if (data) {
+	    /* seen this value already: mark it as a shared block in
+             * the array */
+            dynarray_add_shared(da, ((int) data) - 1);
+  	    return;
+        }
+	else {
+            if (Tag_val(v) == Custom_swap_tag) {
+                hashtable_insert(ht, (void*) v,
+                  (void*) (1 + dynarray_add_allocation(da, alloc_fn_gen,
+                                                       2, Custom_swap_tag)));
+            }
+            else if (under_nobind || (Tag_val(v) != No_bind_tag)) {
+                int x;
+    
+                hashtable_insert(ht, (void*) v,
+                  (void*) (1 + dynarray_add_allocation(da, alloc_fn_gen,
+                                 Wosize_val(v), Tag_val(v))));
+                for (x = (Tag_val(v) == Closure_tag ? 1 : 0);
+                     x < Wosize_val(v);
+                     x++) {
+                    deep_copy_collect_sizes(da, ht, Field(v, x), under_nobind);
+                }
+            }
+	}
+    }
+}
+
+static value deep_copy(value blocks, int* next_block,
+                       dynarray* da, value v,
+                       value atoms_1, value atoms_2,
+                       int freshening_abstractions, int under_nobind)
+{
+    CAMLparam4(blocks, v, atoms_1, atoms_2);
+    CAMLlocal1(ret);
+
+    assert(Is_block(atoms_1) && Tag_val(atoms_1) == 0);
+    assert(Is_block(atoms_2) && Tag_val(atoms_2) == 0);
+    assert(Wosize_val(atoms_1) == Wosize_val(atoms_2));
+
+    ret = v;
+
+    if (Is_block(v) && (Tag_val(v) < No_scan_tag &&
+                        Tag_val(v) != Object_tag &&
+                        Tag_val(v) != Atom_tag &&
+			Tag_val(v) != No_swap_tag &&
+			(under_nobind || (Tag_val(v) != No_bind_tag)))) {
+        CAMLlocal1(data);
+
+        assert(Is_block(blocks));
+        assert(Wosize_val(blocks) == da->used);
+        assert(blocks != Val_unit);
+        assert(*next_block < da->used);
+
+        ret = Field(blocks, *next_block);
+        *next_block = *next_block + 1;
+
+        if (!dynarray_is_block_shared(da, *next_block - 1)) {
+            if (Tag_val(v) == Custom_swap_tag) {
+                CAMLlocal1(atoms_1_list);
+                CAMLlocal1(atoms_2_list);
+                CAMLlocal1(tuple);
+                
+                /* call user's function to do the swapping */
+                atoms_1_list = tuple_to_list(atoms_1);
+                atoms_2_list = tuple_to_list(atoms_2);
+                tuple = caml_alloc_tuple(3);
+                Store_field(tuple, 0, atoms_1_list);
+                Store_field(tuple, 1, atoms_2_list);
+                Store_field(tuple, 2, Field(v, 0));
+                Store_field(ret, 0, caml_callback(Field(v, 1),  tuple));
+                Store_field(ret, 1, Field(v, 1));
+            }
+            else if (Tag_val(v) == Abst_tag && freshening_abstractions) {
+                /* determine the support of the value in binding position */
+                CAMLlocal3(new_atoms_1, new_atoms_2, supp);
+                /*int supp_card;*/
+            
+                supp = calculate_support(Field(v, 0));
+
+                if (supp == Val_unit) {
+                    /* value in binding position has empty support */
+                    new_atoms_1 = atoms_1;
+                    new_atoms_2 = atoms_2;
+                }
+                else {
+                    /* value in binding position has non-empty support */
+                    int supp_card = Wosize_val(supp);
+                    int i;
+                    assert(supp_card > 0);
+            
+                    /* allocate as many fresh atoms as the cardinality
+                     * of "supp", enlarging "atoms_1" and "atoms_2" along
+                     * the way.  "atoms_1" receives atoms from "supp",
+                     * whilst "atoms_2" receives new atoms.
+                     */
+                    new_atoms_1 = caml_alloc_tuple(Wosize_val(atoms_1) + supp_card);
+                    new_atoms_2 = caml_alloc_tuple(Wosize_val(atoms_2) + supp_card);
+                    
+                    /* copy across stuff from atoms_1 and atoms_2 */
+                    for (i = 0; i < Wosize_val(atoms_1); i++) {
+                        Store_field(new_atoms_1, i, Field(atoms_1, i));
+                        Store_field(new_atoms_2, i, Field(atoms_2, i));
+                    }
+    
+                    /* fill the remainder of new_atoms_1 with "supp" and
+                     * the remainder of new_atoms_2 with fresh atoms
+                     */
+                    for (i = 0; i < supp_card; i++) {
+                        Store_field(new_atoms_1, i + Wosize_val(atoms_1),
+                                    Field(supp, i));
+                        Store_field(new_atoms_2, i + Wosize_val(atoms_2),
+                                    alloc_atom());
+                    }
+                }
+    
+                /* allocate space for the copy and propagate the
+                 * new permutations.  We still need to do this even if
+                 * the bound value has no support, as it may still contain
+                 * abstraction values which require freshening.
+                 */
+                Store_field(ret, 0,
+                            deep_copy(blocks, next_block, da, Field(v, 0),
+                                      new_atoms_1, new_atoms_2,
+                                      freshening_abstractions, under_nobind));
+                Store_field(ret, 1,
+                            deep_copy(blocks, next_block, da, Field(v, 1),
+                                      new_atoms_1, new_atoms_2,
+                                      freshening_abstractions, under_nobind));
+            }
+            else {
+                int x;
+    
+                /* copy code pointer for closures */
+                if (Tag_val(v) == Closure_tag) {
+                    /*Store_field(ret, 0, Field(v, 0));*/
+		    Code_val(ret) = Code_val(v);
+                }
+    
+                /* copy the rest */
+                for (x = (Tag_val(v) == Closure_tag ? 1 : 0);
+                     x < Wosize_val(v);
+                     x++) {
+                    Store_field(ret, x,
+                      deep_copy(blocks, next_block, da, Field(v, x),
+                                atoms_1, atoms_2, freshening_abstractions,
+				under_nobind));
+                }
+            }
+        }
+    }
+    else if (Is_block(v) && Tag_val(v) == Atom_tag) {
+        /* Apply any swap which might apply to this atom. */
+        int x;
+        ret = v;
+        for (x = 0; x < Wosize_val(atoms_1); x++) {
+            if (Field(ret, 0) == Field(Field(atoms_1, x), 0)) {
+                ret = Field(atoms_2, x);
+            }
+            else if (Field(ret, 0) == Field(Field(atoms_2, x), 0)) {
+                ret = Field(atoms_1, x);
+            }
+        }
+    }
+
+    CAMLreturn(ret);
+}
+
+/* Given two equally-sized tuples of atoms, swap the Nth element
+ * of the first tuple and the Nth element of the second tuple
+ * throughout the value v, copying the value along the way.
+ * At most one swap must apply to any particular atom in v.
+ */
+static value swap_atoms(value atoms_1, value atoms_2, value v,
+                        int freshening_abstractions, int under_nobind)
+{
+    CAMLparam3(atoms_1, atoms_2, v);
+    CAMLlocal2(ret, blocks);
+    dynarray da;
+    struct hashtable* ht;
+    int next_block = 0;
+
+    if (!Is_block(v)) {
+	CAMLreturn(v);
+    }
+
+    /* This needs to be done in multiple stages to avoid the necessity
+     * of having hashtables keyed on "value"s which are stable under GC.
+     */
+
+    /* Stage 1: collect sizes of blocks needed for a copy of "v"
+     * (no ML allocation is allowed in this stage as we require a hashtable
+     *  to detect cyclic structures)
+     */
+    da = dynarray_alloc();
+    ht = create_hashtable(64, 0.75, value_hasher, value_equality);
+    deep_copy_collect_sizes(&da, ht, v, under_nobind);
+    hashtable_destroy(ht, 0);
+    
+    /* Stage 2: allocate blocks */
+    blocks = dynarray_to_blocks(&da);
+
+    /* Stage 3: perform the copy */
+    ret = deep_copy(blocks, &next_block, &da, v, atoms_1, atoms_2,
+                    freshening_abstractions, under_nobind);
+    dynarray_free(da);
+
+    CAMLreturn(ret);
+}
+
+/***************************************************************************
+ * Exported functions which aren't primitives.
+ **************************************************************************/
+
+/* Test two abstraction values for equality.
+ * Returns 0 if equal and -1 if unequal.
+ */
+long fresh_compare_abstractions(value v1, value v2)
+{
+    int v1_support_size;
+    int v2_support_size;
+    long result = -1; /* "not equal" */
+    
+    CAMLparam2(v1, v2);
+    CAMLlocal3(v1_support, v2_support, new_atoms);
+
+    assert(Is_block(v1) && Tag_val(v1) == Abst_tag);
+    assert(Is_block(v2) && Tag_val(v2) == Abst_tag);
+
+    /* calculate the support of the values in binding position
+     * in v1 and v2...
+     */
+    v1_support = calculate_support(Field(v1, 0));
+    v2_support = calculate_support(Field(v2, 0));
+
+    /* ...determine the size of these supports... */
+    v1_support_size = (v1_support == Val_unit) ? 0 : Wosize_val(v1_support);
+    v2_support_size = (v2_support == Val_unit) ? 0 : Wosize_val(v2_support);
+
+    /* ...and if the sizes differ then the abstractions cannot be equal. */
+    if (v1_support_size == v2_support_size) {
+        CAMLlocal2(v1_new, v2_new);
+
+        if (v1_support_size > 0) {
+            /* allocate sufficiently many fresh atoms */
+            new_atoms = alloc_atoms(v1_support_size);
+
+            /* freshen throughout v1 and v2 with the same set
+             * of new atoms.
+             */
+            v1_new = swap_atoms(v1_support, new_atoms, v1, 0, 0);
+            v2_new = swap_atoms(v2_support, new_atoms, v2, 0, 0);
+        }
+        else {
+            v1_new = v1;
+            v2_new = v2;
+        }
+    
+        /* now compare v1 and v2, as if they were tuple blocks
+         * rather than abstraction blocks.
+         */
+        if (caml_compare(Field(v1_new, 0), Field(v2_new, 0)) == Val_int(0) &&
+            caml_compare(Field(v1_new, 1), Field(v2_new, 1)) == Val_int(0)) {
+            result = 0;
+        }
+    }
+    
+    CAMLreturn(result);
+}
+
+/***************************************************************************
+ * Exported primitives.
+ **************************************************************************/
+
+/* Inspect a value to see if it might contain any abstractions.
+ * If it definitely does not, return the value unchanged.
+ * Otherwise, copy the value (preserving sharing to a reasonable
+ * extent) and freshen up any atoms in binding position in abstractions therein,
+ * as required for the pattern-matching hack.
+ */
+CAMLprim value fresh_throughout(value v)
+{
+    CAMLparam1(v);
+    CAMLlocal1(ret);
+
+    /*dump(v);printf("--\n");fflush(stdout);*/
+
+    ret = v;
+
+    if (contains_abstractions(v)) {
+        /* initialise dummy swap (requirement for swap_atoms()) */
+        /* FIXME should adjust deep_copy_rec() so this isn't needed */
+        CAMLlocal2(atoms_1, atoms_2);
+        atoms_1 = caml_alloc_tuple(1);
+        atoms_2 = caml_alloc_tuple(1);
+        Store_field(atoms_1, 0, alloc_atom());
+        Store_field(atoms_2, 0, alloc_atom());
+
+        /* perform the freshening */
+        ret = swap_atoms(atoms_1, atoms_2, v, 1, 0);
+    }
+
+    CAMLreturn(ret);
+}
+
+/* Test if "n" occurs in the support of "v": return Val_false if
+ * so and Val_true otherwise. */
+CAMLprim value fresh_freshfor(value n, value v)
+{
+    CAMLparam1(v);
+    CAMLlocal2(ret, supp);
+    int supp_size;
+    int i;
+
+    assert(Is_block(n) && Tag_val(n) == Atom_tag);
+
+    ret = Val_true;
+
+    if (valid_in_binding_pos(v)) {
+        caml_invalid_argument("invalid value for fresh-for test");
+    }
+   
+    supp = calculate_support(v);
+    supp_size = (supp == Val_unit ? 0 : Wosize_val(supp));
+
+    for (i = 0; ret == Val_true && i < supp_size; i++) {
+        if (Field(n, 0) == Field(Field(supp, i), 0)) {
+            ret = Val_false;
+        }
+    }
+
+    CAMLreturn(ret);
+}
+
+/* Allocate a new atom. */
+CAMLprim value fresh_new_atom(void)
+{
+    CAMLparam0();
+    CAMLreturn(alloc_atom());
+}
+
+/* Swap two atoms throughout a value. */
+CAMLprim value fresh_swap_atoms(value atom1, value atom2, value v)
+{
+    CAMLparam3(atom1, atom2, v);
+    CAMLlocal2(blk1, blk2);
+    CAMLlocal1(ret);
+
+    blk1 = caml_alloc_tuple(1);
+    blk2 = caml_alloc_tuple(1);
+    Store_field(blk1, 0, atom1);
+    Store_field(blk2, 0, atom2);
+    
+    ret = swap_atoms(blk1, blk2, v, 0, 1);
+
+    CAMLreturn(ret);
+}
+
+/* Swap multiple atoms pairwise throughout a value. */
+CAMLprim value fresh_swap_multiple_atoms(value atoms1, value atoms2, value v)
+{
+    int i;
+    int total;
+    CAMLparam3(atoms1, atoms2, v);
+    CAMLlocal4(blk1, blk2, atoms1_copy, atoms2_copy);
+    CAMLlocal1(ret);
+
+    assert(Is_block(atoms1) && Is_block(atoms2));
+
+    total = 0;
+    atoms1_copy = atoms1;
+    atoms2_copy = atoms2;
+
+    while (Is_block(atoms1)) {
+        assert(Is_block(atoms2));
+
+        total++;
+
+        atoms1 = Field(atoms1, 1);
+        atoms2 = Field(atoms2, 1);
+    }
+
+    assert(total > 0);
+
+    atoms1 = atoms1_copy;
+    atoms2 = atoms2_copy;
+
+    blk1 = caml_alloc_tuple(total);
+    blk2 = caml_alloc_tuple(total);
+    for (i = 0; i < total; i++) {
+        assert(Is_block(atoms1));
+        assert(Is_block(atoms2));
+
+        Store_field(blk1, i, Field(atoms1, 0));
+        Store_field(blk2, i, Field(atoms2, 0));
+        atoms1 = Field(atoms1, 1);
+        atoms2 = Field(atoms2, 1);
+    }
+    
+    ret = swap_atoms(blk1, blk2, v, 0, 1);
+
+    CAMLreturn(ret);
+}
+
+/* Create an abstraction value <<v1>>v2. */
+CAMLprim value fresh_create_abstraction(value v1, value v2)
+{
+    CAMLparam2(v1, v2);
+    CAMLlocal1(v);
+
+    if (valid_in_binding_pos(v1)) {
+        caml_invalid_argument("Invalid value in binding position");
+    }
+
+    v = caml_alloc(2, Abst_tag);
+    Store_field(v, 0, v1);
+    Store_field(v, 1, v2);
+
+    CAMLreturn(v);
+}
+
diff -rN -U 2 ocaml-3.10.0/byterun/freshness.h fresh-ocaml-3.10.0/byterun/freshness.h
--- ocaml-3.10.0/byterun/freshness.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/freshness.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,43 @@
+/*
+ *  byterun/freshness.h
+ *
+ *  Low-level support for freshness functionality.
+ *
+ *  (c) Copyright 2003-2004, Mark R. Shinwell.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  3. The names of the authors may not be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ *  NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mlvalues.h"
+
+/* Primitives */
+extern value fresh_freshfor(value, value);
+extern value fresh_new_atom(void);
+extern value fresh_swap_atoms(value, value, value);
+extern value fresh_throughout(value);
+extern value fresh_create_abstraction(value, value);
+
+/* Other functions */
+extern long fresh_compare_abstractions(value, value);
+extern value fresh_swap_multiple_atoms(value atoms1, value atoms2, value v);
+
diff -rN -U 2 ocaml-3.10.0/byterun/hash.c fresh-ocaml-3.10.0/byterun/hash.c
--- ocaml-3.10.0/byterun/hash.c	2005-09-22 16:21:50.000000000 +0200
+++ fresh-ocaml-3.10.0/byterun/hash.c	2007-05-18 16:50:55.000000000 +0200
@@ -116,4 +116,8 @@
       Combine(Oid_val(obj));
       break;
+    case Atom_tag: {
+      Combine(Field(obj, 0));
+      break;
+    }
     case Custom_tag:
       /* If no hashing function provided, do nothing */
diff -rN -U 2 ocaml-3.10.0/byterun/hashtable_cwc22.c fresh-ocaml-3.10.0/byterun/hashtable_cwc22.c
--- ocaml-3.10.0/byterun/hashtable_cwc22.c	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/hashtable_cwc22.c	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,254 @@
+#include "hashtable_cwc22.h"
+#include "hashtable_private_cwc22.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize, float maxloadfactor,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int i, size = 1u;
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 31)) return NULL;
+    /* Enforce size as power of 2 */
+    while (size < minsize) size <<= 1;
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    for (i=0;i<size;i++) { h->table[i] = NULL; }
+    h->tablelength  = size;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ((float)size * maxloadfactor);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned inline int
+hash(struct hashtable *h, void *k)
+{
+#if 0
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+#endif
+    return h->hashfn(k);
+
+    /*
+    unsigned int i = h->hashfn(k);
+    return (i >> 3) * 2654435761u;
+    */
+}
+/*****************************************************************************/
+unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    /* Only works if tablelength == 2^N */
+    return (hashvalue & (tablelength - 1u));
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (0 == (newsize = (h->tablelength << 1))) return 0;
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) return 0;
+        h->table = newtable;
+        for (i = h->tablelength; i < newsize; i++) {
+            newtable[i] = NULL;
+        }
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit <<= 1;
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+
+    unsigned int index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        if (h->eqfn(k, e->k))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+          /*  free(e->k);*/
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; /*free(f->k);*/ free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; /* free(f->k); */ free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/byterun/hashtable_cwc22.h fresh-ocaml-3.10.0/byterun/hashtable_cwc22.h
--- ocaml-3.10.0/byterun/hashtable_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/hashtable_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,188 @@
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, 0.75, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   maxloadfactor   maximum ratio entries / tablesize
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize, float maxloadfactor,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/byterun/hashtable_itr_cwc22.c fresh-ocaml-3.10.0/byterun/hashtable_itr_cwc22.c
--- ocaml-3.10.0/byterun/hashtable_itr_cwc22.c	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/hashtable_itr_cwc22.c	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,119 @@
+#include "hashtable_cwc22.h"
+#include "hashtable_private_cwc22.h"
+#include "hashtable_itr_cwc22.h"
+#include <stdlib.h> /* defines NULL */
+
+/*struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    unsigned int index;
+};
+*/
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* key - return the key of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/byterun/hashtable_itr_cwc22.h fresh-ocaml-3.10.0/byterun/hashtable_itr_cwc22.h
--- ocaml-3.10.0/byterun/hashtable_itr_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/hashtable_itr_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,73 @@
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable_cwc22.h"
+#include "hashtable_private_cwc22.h" /* needed to enable inlining */
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/byterun/hashtable_private_cwc22.h fresh-ocaml-3.10.0/byterun/hashtable_private_cwc22.h
--- ocaml-3.10.0/byterun/hashtable_private_cwc22.h	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/hashtable_private_cwc22.h	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,52 @@
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable_cwc22.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+unsigned int
+hash(struct hashtable *h, void *k);
+
+unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue);
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
diff -rN -U 2 ocaml-3.10.0/byterun/mlvalues.h fresh-ocaml-3.10.0/byterun/mlvalues.h
--- ocaml-3.10.0/byterun/mlvalues.h	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/byterun/mlvalues.h	2007-05-18 16:50:55.000000000 +0200
@@ -199,4 +199,17 @@
 #define Lazy_tag 246
 
+/* Tag for semantic atoms. */
+#define Atom_tag 245
+
+/* Tag for abstraction values. */
+#define Abst_tag 244
+
+/* Tag for "custom swap" values. */
+#define Custom_swap_tag 243
+
+/* Tags for "no bind" and "no swap" values. */
+#define No_bind_tag 242
+#define No_swap_tag 241
+
 /* Another special case: variants */
 CAMLextern value caml_hash_variant(char * tag);
diff -rN -U 2 ocaml-3.10.0/byterun/roots.c fresh-ocaml-3.10.0/byterun/roots.c
--- ocaml-3.10.0/byterun/roots.c	2005-09-22 16:21:50.000000000 +0200
+++ fresh-ocaml-3.10.0/byterun/roots.c	2007-05-18 16:50:55.000000000 +0200
@@ -83,4 +83,5 @@
   /* Global C roots */
   for (gr = caml_global_roots.forward[0]; gr != NULL; gr = gr->forward[0]) {
+    value old_v = *(gr->root);
     f(*(gr->root), gr->root);
   }
diff -rN -U 2 ocaml-3.10.0/configure fresh-ocaml-3.10.0/configure
--- ocaml-3.10.0/configure	2007-05-03 14:49:56.000000000 +0200
+++ fresh-ocaml-3.10.0/configure	2007-05-18 16:50:55.000000000 +0200
@@ -1494,5 +1494,5 @@
 echo "** Configuration summary **"
 echo
-echo "Directories where Objective Caml will be installed:"
+echo "Directories where Fresh Objective Caml will be installed:"
 echo "        binaries.................. $bindir"
 echo "        standard library.......... $libdir"
@@ -1563,4 +1563,4 @@
 
 echo
-echo "** Objective Caml configuration completed successfully **"
+echo "** Fresh Objective Caml configuration completed successfully **"
 echo
diff -rN -U 2 ocaml-3.10.0/debugger/Makefile fresh-ocaml-3.10.0/debugger/Makefile
--- ocaml-3.10.0/debugger/Makefile	2006-12-09 14:49:10.000000000 +0100
+++ fresh-ocaml-3.10.0/debugger/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -18,8 +18,8 @@
 COMPFLAGS=-warn-error A $(INCLUDES)
 LINKFLAGS=-linkall -I ../otherlibs/unix
-CAMLYACC=../boot/ocamlyacc
+CAMLYACC=../boot/fresh-ocamlyacc
 YACCFLAGS=
-CAMLLEX=../boot/ocamlrun ../boot/ocamllex
-CAMLDEP=../boot/ocamlrun ../tools/ocamldep
+CAMLLEX=../boot/fresh-ocamlrun ../boot/fresh-ocamllex
+CAMLDEP=../boot/fresh-ocamlrun ../tools/fresh-ocamldep
 DEPFLAGS=$(INCLUDES)
 
@@ -78,14 +78,14 @@
 	main.cmo
 
-all: ocamldebug$(EXE)
+all: fresh-ocamldebug$(EXE)
 
-ocamldebug$(EXE): $(OBJS) $(OTHEROBJS)
-	$(CAMLC) $(LINKFLAGS) -o ocamldebug$(EXE) -linkall $(OTHEROBJS) $(OBJS)
+fresh-ocamldebug$(EXE): $(OBJS) $(OTHEROBJS)
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamldebug$(EXE) -linkall $(OTHEROBJS) $(OBJS)
 
 install:
-	cp ocamldebug$(EXE) $(BINDIR)/ocamldebug$(EXE)
+	cp fresh-ocamldebug$(EXE) $(BINDIR)/fresh-ocamldebug$(EXE)
 
 clean::
-	rm -f ocamldebug$(EXE)
+	rm -f fresh-ocamldebug$(EXE)
 	rm -f *.cmo *.cmi
 
diff -rN -U 2 ocaml-3.10.0/driver/main.ml fresh-ocaml-3.10.0/driver/main.ml
--- ocaml-3.10.0/driver/main.ml	2005-05-09 15:39:17.000000000 +0200
+++ fresh-ocaml-3.10.0/driver/main.ml	2007-05-18 16:50:55.000000000 +0200
@@ -62,5 +62,5 @@
 
 let print_version_and_library () =
-  print_string "The Objective Caml compiler, version ";
+  print_string "The Fresh Objective Caml compiler, version ";
   print_string Config.version; print_newline();
   print_string "Standard library directory: ";
@@ -74,5 +74,5 @@
   print_string Config.standard_library; print_newline(); exit 0
 
-let usage = "Usage: ocamlc <options> <files>\nOptions are:"
+let usage = "Usage: fresh-ocamlc <options> <files>\nOptions are:"
 
 (* Error messages to standard error formatter *)
diff -rN -U 2 ocaml-3.10.0/driver/optmain.ml fresh-ocaml-3.10.0/driver/optmain.ml
--- ocaml-3.10.0/driver/optmain.ml	2007-01-29 13:11:15.000000000 +0100
+++ fresh-ocaml-3.10.0/driver/optmain.ml	2007-05-18 16:50:55.000000000 +0200
@@ -60,5 +60,5 @@
 
 let print_version_and_library () =
-  print_string "The Objective Caml native-code compiler, version ";
+  print_string "The Fresh Objective Caml native-code compiler, version ";
   print_string Config.version; print_newline();
   print_string "Standard library directory: ";
@@ -83,5 +83,5 @@
   | None -> Config.default_executable_name
 
-let usage = "Usage: ocamlopt <options> <files>\nOptions are:"
+let usage = "Usage: fresh-ocamlopt <options> <files>\nOptions are:"
 
 let show_config () =
@@ -114,5 +114,5 @@
        "-for-pack", Arg.String (fun s -> for_package := Some s),
              "<ident>  Generate code that can later be `packed' with\n\
-         \     ocamlopt -pack -o <ident>.cmx";
+              fresh-ocamlopt -pack -o <ident>.cmx";
        "-g", Arg.Set debug, " Record debugging information for exception backtrace";
        "-i", Arg.Unit (fun () -> print_types := true; compile_only := true),
diff -rN -U 2 ocaml-3.10.0/emacs/README fresh-ocaml-3.10.0/emacs/README
--- ocaml-3.10.0/emacs/README	2002-08-05 04:05:42.000000000 +0200
+++ fresh-ocaml-3.10.0/emacs/README	2007-05-18 16:50:55.000000000 +0200
@@ -1,3 +1,3 @@
-        O'Caml emacs mode, snapshot of $Date: 2002/08/05 02:05:42 $
+        O'Caml emacs mode, snapshot of $Date: 2004/06/09 10:38:03 $
 
 The files in this archive define a caml-mode for emacs, for editing
diff -rN -U 2 ocaml-3.10.0/lex/Makefile fresh-ocaml-3.10.0/lex/Makefile
--- ocaml-3.10.0/lex/Makefile	2004-11-29 15:49:24.000000000 +0100
+++ fresh-ocaml-3.10.0/lex/Makefile	2007-05-30 23:23:06.000000000 +0200
@@ -11,29 +11,29 @@
 #########################################################################
 
-# $Id: Makefile,v 1.19 2004/11/29 14:49:24 doligez Exp $
+# $Id: Makefile,v 1.19 2006/01/23 14:49:24 uli Exp $
 
 # The lexer generator
-CAMLC=../boot/ocamlrun ../boot/ocamlc -nostdlib -I ../boot
-CAMLOPT=../boot/ocamlrun ../ocamlopt -nostdlib -I ../stdlib
+CAMLC=../boot/fresh-ocamlrun ../boot/fresh-ocamlc -nostdlib -I ../boot
+CAMLOPT=../boot/fresh-ocamlrun ../fresh-ocamlopt -nostdlib -I ../stdlib
 COMPFLAGS=-warn-error A
-CAMLYACC=../boot/ocamlyacc
+CAMLYACC=../boot/fresh-ocamlyacc
 YACCFLAGS=-v
-CAMLLEX=../boot/ocamlrun ../boot/ocamllex
-CAMLDEP=../boot/ocamlrun ../tools/ocamldep
+CAMLLEX=../boot/fresh-ocamlrun ../boot/fresh-ocamllex
+CAMLDEP=../boot/fresh-ocamlrun ../tools/fresh-ocamldep
 
 
 OBJS=cset.cmo syntax.cmo parser.cmo lexer.cmo table.cmo lexgen.cmo compact.cmo common.cmo output.cmo outputbis.cmo main.cmo
 
-all: ocamllex
-allopt: ocamllex.opt
+all: fresh-ocamllex
+allopt: fresh-ocamllex.opt
 
-ocamllex: $(OBJS)
-	$(CAMLC) $(LINKFLAGS) -o ocamllex $(OBJS)
+fresh-ocamllex: $(OBJS)
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamllex $(OBJS)
 
-ocamllex.opt: $(OBJS:.cmo=.cmx)
-	$(CAMLOPT) -o ocamllex.opt $(OBJS:.cmo=.cmx)
+fresh-ocamllex.opt: $(OBJS:.cmo=.cmx)
+	$(CAMLOPT) -o fresh-ocamllex.opt $(OBJS:.cmo=.cmx)
 
 clean::
-	rm -f ocamllex ocamllex.opt
+	rm -f fresh-ocamllex
 	rm -f *.cmo *.cmi *.cmx *.o *~
 
@@ -60,10 +60,10 @@
 	$(CAMLC) -c $(COMPFLAGS) $<
 
-.mli.cmi:
-	$(CAMLC) -c $(COMPFLAGS) $<
-
 .ml.cmx:
 	$(CAMLOPT) -c $(COMPFLAGS) $<
 
+.mli.cmi:
+	$(CAMLC) -c $(COMPFLAGS) $<
+
 depend: beforedepend
 	$(CAMLDEP) *.mli *.ml > .depend
diff -rN -U 2 ocaml-3.10.0/myocamlbuild.ml fresh-ocaml-3.10.0/myocamlbuild.ml
--- ocaml-3.10.0/myocamlbuild.ml	2007-03-29 16:31:04.000000000 +0200
+++ fresh-ocaml-3.10.0/myocamlbuild.ml	2007-05-30 22:57:36.000000000 +0200
@@ -81,5 +81,5 @@
           if dirname = Pathname.current_dir_name then Sh(add_exe_if_exists basename)
           else Sh(add_exe_if_exists (dirname ^ "\\" ^ basename)) in
-        if String.contains_string basename 0 "ocamlrun" = None then
+        if String.contains_string basename 0 "fresh-ocamlrun" = None then
           List.rev (p :: acc) @ specs
         else
@@ -92,6 +92,6 @@
   convert_command_for_windows_shell (solver ())
 
-let ocamlrun = A"boot/ocamlrun"
-let full_ocamlrun = P((Sys.getcwd ()) / "boot/ocamlrun")
+let ocamlrun = A"boot/fresh-ocamlrun"
+let full_ocamlrun = P((Sys.getcwd ()) / "boot/fresh-ocamlrun")
 
 let boot_ocamlc = S[ocamlrun; A"boot/ocamlc"; A"-I"; A"boot"; A"-nostdlib"]
@@ -128,7 +128,7 @@
 
 let ocamlopt_solver () =
-  S[if Pathname.exists "ocamlopt.opt" && Pathname.exists ("stdlib/stdlib.cmxa")
-    then A"./ocamlopt.opt"
-    else S[ocamlrun; A"./ocamlopt"];
+  S[if Pathname.exists "fresh-ocamlopt.opt" && Pathname.exists ("stdlib/stdlib.cmxa")
+    then A"./fresh-ocamlopt.opt"
+    else S[ocamlrun; A"./fresh-ocamlopt"];
     A"-nostdlib"];;
 
@@ -596,5 +596,5 @@
   begin fun _ _ ->
     if C.sharpbangscripts then
-      Cmd(Sh("echo '#!"^C.bindir^"/ocamlrun' > stdlib/camlheader && \
+      Cmd(Sh("echo '#!"^C.bindir^"/fresh-ocamlrun' > stdlib/camlheader && \
               echo '#!' | tr -d '\\012' > stdlib/camlheader_ur"))
     else if windows then
@@ -607,5 +607,5 @@
       Cmd(S[Sh C.bytecc; Sh C.bytecccompopts; Sh C.bytecclinkopts;
             A"-I"; A"../stdlib";
-            A("-DRUNTIME_NAME='\""^C.bindir^"/ocamlrun\"'");
+            A("-DRUNTIME_NAME='\""^C.bindir^"/fresh-ocamlrun\"'");
             A"stdlib/header.c"; A"-o"; Px tmpheader; Sh"&&";
             A"strip"; P tmpheader; Sh"&&";
@@ -632,5 +632,5 @@
       | Outcome.Bad exn -> raise exn
     end resluts in
-    mkdll dll (P("tmp"-.-C.a)) (S[atomize objs; P("byterun/ocamlrun"-.-C.a)])
+    mkdll dll (P("tmp"-.-C.a)) (S[atomize objs; P("byterun/fresh-ocamlrun"-.-C.a)])
           (T(tags_of_pathname dll++"dll"++"link"++"c"))
   end;;
diff -rN -U 2 ocaml-3.10.0/ocamlbuild/options.ml fresh-ocaml-3.10.0/ocamlbuild/options.ml
--- ocaml-3.10.0/ocamlbuild/options.ml	2007-04-12 15:19:02.000000000 +0200
+++ fresh-ocaml-3.10.0/ocamlbuild/options.ml	2007-05-18 16:54:47.000000000 +0200
@@ -62,14 +62,14 @@
 let () =
   mk_virtual_solvers
-    ["ocamlc"; "ocamlopt"; "ocamldep"; "ocamldoc";
-    "ocamlyacc"; "menhir"; "ocamllex"; "ocamlmklib"; "ocamlmktop"]
-let ocamlc = ref (V"OCAMLC")
-let ocamlopt = ref (V"OCAMLOPT")
-let ocamldep = ref (V"OCAMLDEP")
-let ocamldoc = ref (V"OCAMLDOC")
-let ocamlyacc = ref N
+    ["fresh-ocamlc"; "fresh-ocamlopt"; "fresh-ocamldep"; "fresh-ocamldoc";
+    "fresh-ocamlyacc"; "menhir"; "fresh-ocamllex"; "fresh-ocamlmklib"; "fresh-ocamlmktop"]
+let ocamlc = ref (V"FRESH-OCAMLC")
+let ocamlopt = ref (V"FRESH-OCAMLOPT")
+let ocamldep = ref (V"FRESH-OCAMLDEP")
+let ocamldoc = ref (V"FRESH-OCAMLDOC")
+let ocamlyacc = ref (V"FRESH-OCAMLYACC")
-let ocamllex = ref (V"OCAMLLEX")
-let ocamlmklib = ref (V"OCAMLMKLIB")
-let ocamlmktop = ref (V"OCAMLMKTOP")
+let ocamllex = ref (V"FRESH-OCAMLLEX")
+let ocamlmklib = ref (V"FRESH-OCAMLMKLIB")
+let ocamlmktop = ref (V"FRESH-OCAMLMKTOP")
 let ocamlrun = ref N
 let program_to_execute = ref false
diff -rN -U 2 ocaml-3.10.0/ocamldoc/Makefile fresh-ocaml-3.10.0/ocamldoc/Makefile
--- ocaml-3.10.0/ocamldoc/Makefile	2006-09-20 13:14:36.000000000 +0200
+++ fresh-ocaml-3.10.0/ocamldoc/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -16,10 +16,10 @@
 # Various commands and dir
 ##########################
-CAMLRUN=../boot/ocamlrun
+CAMLRUN=../boot/fresh-ocamlrun
 OCAMLC   = ../ocamlcomp.sh
 OCAMLOPT = ../ocamlcompopt.sh
-OCAMLDEP = $(CAMLRUN) ../tools/ocamldep
-OCAMLLEX = $(CAMLRUN) ../boot/ocamllex
-OCAMLYACC= ../boot/ocamlyacc
+OCAMLDEP = $(CAMLRUN) ../tools/fresh-ocamldep
+OCAMLLEX = $(CAMLRUN) ../boot/fresh-ocamllex
+OCAMLYACC= ../boot/fresh-ocamlyacc
 OCAMLLIB = $(LIBDIR)
 OCAMLBIN = $(BINDIR)
diff -rN -U 2 ocaml-3.10.0/ocamldoc/odoc_misc.ml fresh-ocaml-3.10.0/ocamldoc/odoc_misc.ml
--- ocaml-3.10.0/ocamldoc/odoc_misc.ml	2006-07-06 09:19:06.000000000 +0200
+++ fresh-ocaml-3.10.0/ocamldoc/odoc_misc.ml	2007-05-18 16:50:55.000000000 +0200
@@ -479,4 +479,5 @@
     | Types.Tobject _
     | Types.Tfield _
+    | Types.Tabst _
     | Types.Tnil
     | Types.Tvariant _ -> t
diff -rN -U 2 ocaml-3.10.0/ocamldoc/odoc_str.ml fresh-ocaml-3.10.0/ocamldoc/odoc_str.ml
--- ocaml-3.10.0/ocamldoc/odoc_str.ml	2005-03-24 18:20:53.000000000 +0100
+++ fresh-ocaml-3.10.0/ocamldoc/odoc_str.ml	2007-05-18 16:50:55.000000000 +0200
@@ -31,5 +31,5 @@
   | Types.Tlink t2 | Types.Tsubst t2 -> is_arrow_type t2
   | Types.Ttuple _
-  | Types.Tconstr _
+  | Types.Tconstr _ | Types.Tabst _
   | Types.Tvar | Types.Tunivar | Types.Tobject _ | Types.Tpoly _
   | Types.Tfield _ | Types.Tnil | Types.Tvariant _ -> false
@@ -45,4 +45,5 @@
         false
     | Types.Tvar | Types.Tunivar | Types.Tobject _ | Types.Tpoly _
+    | Types.Tabst _
     | Types.Tfield _ | Types.Tnil | Types.Tvariant _ -> false
   in
diff -rN -U 2 ocaml-3.10.0/ocamldoc/odoc_value.ml fresh-ocaml-3.10.0/ocamldoc/odoc_value.ml
--- ocaml-3.10.0/ocamldoc/odoc_value.ml	2004-07-13 14:25:12.000000000 +0200
+++ fresh-ocaml-3.10.0/ocamldoc/odoc_value.ml	2007-05-18 16:50:55.000000000 +0200
@@ -84,4 +84,5 @@
     | Types.Tnil
     | Types.Tunivar
+    | Types.Tabst _
     | Types.Tvariant _ ->
         []
diff -rN -U 2 ocaml-3.10.0/ocamldoc/runocamldoc fresh-ocaml-3.10.0/ocamldoc/runocamldoc
--- ocaml-3.10.0/ocamldoc/runocamldoc	2002-07-23 16:11:53.000000000 +0200
+++ fresh-ocaml-3.10.0/ocamldoc/runocamldoc	2007-05-18 16:50:55.000000000 +0200
@@ -4,5 +4,5 @@
 case "$1" in
   true) shift
-        exec ../boot/ocamlrun  -I ../otherlibs/unix -I ../otherlibs/str \
+        exec ../boot/fresh-ocamlrun  -I ../otherlibs/unix -I ../otherlibs/str \
              ./ocamldoc "$@"
         ;;
diff -rN -U 2 ocaml-3.10.0/otherlibs/bigarray/Makefile fresh-ocaml-3.10.0/otherlibs/bigarray/Makefile
--- ocaml-3.10.0/otherlibs/bigarray/Makefile	2007-02-07 11:31:36.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/bigarray/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -20,5 +20,5 @@
 CAMLC=../../ocamlcomp.sh -I ../unix
 CAMLOPT=../../ocamlcompopt.sh -I ../unix
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A -g
 
diff -rN -U 2 ocaml-3.10.0/otherlibs/dbm/Makefile fresh-ocaml-3.10.0/otherlibs/dbm/Makefile
--- ocaml-3.10.0/otherlibs/dbm/Makefile	2004-11-29 15:53:32.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/dbm/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -22,5 +22,5 @@
 CAMLC=../../ocamlcomp.sh
 CAMLOPT=../../ocamlcompopt.sh
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A
 
diff -rN -U 2 ocaml-3.10.0/otherlibs/dynlink/Makefile fresh-ocaml-3.10.0/otherlibs/dynlink/Makefile
--- ocaml-3.10.0/otherlibs/dynlink/Makefile	2006-09-19 14:41:33.000000000 +0200
+++ fresh-ocaml-3.10.0/otherlibs/dynlink/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -18,5 +18,5 @@
 include ../../config/Makefile
 
-CAMLC=../../boot/ocamlrun ../../ocamlc
+CAMLC=../../boot/fresh-ocamlrun ../../fresh-ocamlc
 INCLUDES=-I ../../utils -I ../../typing -I ../../bytecomp
 COMPFLAGS=-warn-error A -I ../../stdlib $(INCLUDES)
diff -rN -U 2 ocaml-3.10.0/otherlibs/graph/Makefile fresh-ocaml-3.10.0/otherlibs/graph/Makefile
--- ocaml-3.10.0/otherlibs/graph/Makefile	2007-01-29 13:11:16.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/graph/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -22,5 +22,5 @@
 CAMLC=../../ocamlcomp.sh
 CAMLOPT=../../ocamlcompopt.sh
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A -g
 
diff -rN -U 2 ocaml-3.10.0/otherlibs/labltk/browser/searchid.ml fresh-ocaml-3.10.0/otherlibs/labltk/browser/searchid.ml
--- ocaml-3.10.0/otherlibs/labltk/browser/searchid.ml	2005-01-28 17:13:11.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/labltk/browser/searchid.ml	2007-05-18 16:50:55.000000000 +0200
@@ -422,4 +422,5 @@
       bound_variables pat1 @ bound_variables pat2
   | Ppat_constraint (pat,_) -> bound_variables pat
+  | Ppat_abst (p1, p2) -> bound_variables p1 @ bound_variables p2
 
 let search_structure str ~name ~kind ~prefix =
diff -rN -U 2 ocaml-3.10.0/otherlibs/labltk/browser/searchpos.ml fresh-ocaml-3.10.0/otherlibs/labltk/browser/searchpos.ml
--- ocaml-3.10.0/otherlibs/labltk/browser/searchpos.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/otherlibs/labltk/browser/searchpos.ml	2007-05-18 16:50:55.000000000 +0200
@@ -131,4 +131,6 @@
   | Ptyp_alias (t, _)
   | Ptyp_poly (_, t) -> search_pos_type ~pos ~env t
+  | Ptyp_abst (t1, t2) -> search_pos_type t1 ~pos ~env;
+                          search_pos_type t2 ~pos ~env
   end
 
@@ -812,4 +814,14 @@
   | Texp_lazy exp ->
       search_pos_expr exp ~pos
+  | Texp_abst (exp1, exp2) -> search_pos_expr exp1 ~pos;
+                              search_pos_expr exp2 ~pos
+  | Texp_swap (exp1, exp2, exp3) -> search_pos_expr exp1 ~pos;
+                                    search_pos_expr exp2 ~pos;
+                                   search_pos_expr exp3 ~pos
+  | Texp_fresh -> ()
+  | Texp_freshfor (exp1, exp2) -> search_pos_expr exp1 ~pos;
+                                  search_pos_expr exp2 ~pos
+  | Texp_customswap (exp1, exp2) -> search_pos_expr exp1 ~pos;
+                                    search_pos_expr exp2 ~pos
   | Texp_object (cls, _, _) ->
       	search_pos_class_structure ~pos cls
@@ -842,4 +854,6 @@
   | Tpat_or (_, _, Some _) ->
       ()
+  | Tpat_abst (p1, p2) -> search_pos_pat p1 ~pos ~env;
+                          search_pos_pat p2 ~pos ~env
   end;
   add_found_str (`Exp(`Pat, pat.pat_type)) ~env ~loc:pat.pat_loc
diff -rN -U 2 ocaml-3.10.0/otherlibs/labltk/support/Makefile.common fresh-ocaml-3.10.0/otherlibs/labltk/support/Makefile.common
--- ocaml-3.10.0/otherlibs/labltk/support/Makefile.common	2007-01-29 13:11:16.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/labltk/support/Makefile.common	2007-05-18 16:50:55.000000000 +0200
@@ -13,15 +13,15 @@
 ## Tools from the Objective Caml distribution
 
-CAMLRUN=$(TOPDIR)/boot/ocamlrun
+CAMLRUN=$(TOPDIR)/boot/fresh-ocamlrun
 CAMLC=$(TOPDIR)/ocamlcomp.sh
 CAMLOPT=$(TOPDIR)/ocamlcompopt.sh
 CAMLCOMP=$(CAMLC) -c -warn-error A
-CAMLYACC=$(TOPDIR)/boot/ocamlyacc -v
-CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/ocamllex
+CAMLYACC=$(TOPDIR)/boot/fresh-ocamlyacc -v
+CAMLLEX=$(CAMLRUN) $(TOPDIR)/boot/fresh-ocamllex
 CAMLLIBR=$(CAMLC) -a
-CAMLDEP=$(CAMLRUN) $(TOPDIR)/tools/ocamldep
+CAMLDEP=$(CAMLRUN) $(TOPDIR)/tools/fresh-ocamldep
 COMPFLAGS=-g
 LINKFLAGS=
 CAMLOPTLIBR=$(CAMLOPT) -a
-MKLIB=$(CAMLRUN) $(TOPDIR)/tools/ocamlmklib
-CAMLRUNGEN=../../boot/ocamlrun
+MKLIB=$(CAMLRUN) $(TOPDIR)/tools/fresh-ocamlmklib
+CAMLRUNGEN=../../boot/fresh-ocamlrun
diff -rN -U 2 ocaml-3.10.0/otherlibs/num/Makefile fresh-ocaml-3.10.0/otherlibs/num/Makefile
--- ocaml-3.10.0/otherlibs/num/Makefile	2007-01-29 13:11:16.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/num/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -24,5 +24,5 @@
 CAMLC=../../ocamlcomp.sh
 CAMLOPT=../../ocamlcompopt.sh
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A -g
 
@@ -47,5 +47,5 @@
 	$(MKLIB) -o nums $(COBJS)
 
-$(CAMLOBJS:.cmo=.cmx): ../../ocamlopt
+$(CAMLOBJS:.cmo=.cmx): ../../fresh-ocamlopt
 
 install:
diff -rN -U 2 ocaml-3.10.0/otherlibs/str/Makefile fresh-ocaml-3.10.0/otherlibs/str/Makefile
--- ocaml-3.10.0/otherlibs/str/Makefile	2007-01-29 13:11:16.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/str/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -25,5 +25,5 @@
 COMPFLAGS=-warn-error A -g
 COBJS=strstubs.o
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 
 all: libstr.a str.cmi str.cma
@@ -40,5 +40,5 @@
 	$(MKLIB) -ocamlopt '$(CAMLOPT)' -o str str.cmx
 
-str.cmx: ../../ocamlopt
+str.cmx: ../../fresh-ocamlopt
 
 partialclean:
diff -rN -U 2 ocaml-3.10.0/otherlibs/systhreads/Makefile fresh-ocaml-3.10.0/otherlibs/systhreads/Makefile
--- ocaml-3.10.0/otherlibs/systhreads/Makefile	2007-03-06 17:02:09.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/systhreads/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -18,5 +18,5 @@
 CAMLC=../../ocamlcomp.sh -I ../unix
 CAMLOPT=../../ocamlcompopt.sh -I ../unix
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A -g
 
@@ -58,5 +58,5 @@
           -cclib -lthreadsnat -cclib -lunix $(PTHREAD_LINK)
 
-$(THREAD_OBJS:.cmo=.cmx): ../../ocamlopt
+$(THREAD_OBJS:.cmo=.cmx): ../../fresh-ocamlopt
 
 thread.ml: thread_posix.ml
diff -rN -U 2 ocaml-3.10.0/otherlibs/threads/Makefile fresh-ocaml-3.10.0/otherlibs/threads/Makefile
--- ocaml-3.10.0/otherlibs/threads/Makefile	2007-02-16 10:54:55.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/threads/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -19,5 +19,5 @@
 CFLAGS=-I../../byterun -O $(BYTECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -g
 CAMLC=../../ocamlcomp.sh -I ../unix
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A
 
diff -rN -U 2 ocaml-3.10.0/otherlibs/unix/Makefile fresh-ocaml-3.10.0/otherlibs/unix/Makefile
--- ocaml-3.10.0/otherlibs/unix/Makefile	2007-02-07 16:49:11.000000000 +0100
+++ fresh-ocaml-3.10.0/otherlibs/unix/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -23,5 +23,5 @@
 CAMLC=../../ocamlcomp.sh
 CAMLOPT=../../ocamlcompopt.sh
-MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+MKLIB=../../boot/fresh-ocamlrun ../../tools/fresh-ocamlmklib
 COMPFLAGS=-warn-error A -g
 
@@ -58,5 +58,5 @@
 	$(MKLIB) -o unix -ocamlopt '$(CAMLOPT)' -linkall $(MLOBJS:.cmo=.cmx)
 
-unix.cmx: ../../ocamlopt
+unix.cmx: ../../fresh-ocamlopt
 
 partialclean:
diff -rN -U 2 ocaml-3.10.0/parsing/lexer.mll fresh-ocaml-3.10.0/parsing/lexer.mll
--- ocaml-3.10.0/parsing/lexer.mll	2005-04-11 18:44:26.000000000 +0200
+++ fresh-ocaml-3.10.0/parsing/lexer.mll	2007-05-18 16:50:55.000000000 +0200
@@ -42,4 +42,5 @@
     "class", CLASS;
     "constraint", CONSTRAINT;
+    "custom_swap", CUSTOMSWAP;
     "do", DO;
     "done", DONE;
@@ -51,4 +52,6 @@
     "false", FALSE;
     "for", FOR;
+    "fresh", FRESH;
+    "freshfor", FRESHFOR;
     "fun", FUN;
     "function", FUNCTION;
@@ -75,4 +78,5 @@
     "sig", SIG;
     "struct", STRUCT;
+    "swap", SWAP;
     "then", THEN;
     "to", TO;
@@ -371,4 +375,8 @@
   | "}"  { RBRACE }
   | ">}" { GREATERRBRACE }
+  | "<<" { LESSLESS }
+  | ">>" { GREATERGREATER }
+  | "<|" { LESSBAR }
+  | "|>" { BARGREATER }
 
   | "!=" { INFIXOP0 "!=" }
diff -rN -U 2 ocaml-3.10.0/parsing/parser.mly fresh-ocaml-3.10.0/parsing/parser.mly
--- ocaml-3.10.0/parsing/parser.mly	2006-12-15 05:50:30.000000000 +0100
+++ fresh-ocaml-3.10.0/parsing/parser.mly	2007-05-18 16:50:55.000000000 +0200
@@ -196,4 +196,5 @@
 %token BAR
 %token BARBAR
+%token BARGREATER
 %token BARRBRACKET
 %token BEGIN
@@ -206,4 +207,5 @@
 %token COMMA
 %token CONSTRAINT
+%token CUSTOMSWAP
 %token DO
 %token DONE
@@ -220,8 +222,11 @@
 %token <string> FLOAT
 %token FOR
+%token FRESH
+%token FRESHFOR
 %token FUN
 %token FUNCTION
 %token FUNCTOR
 %token GREATER
+%token GREATERGREATER
 %token GREATERRBRACE
 %token GREATERRBRACKET
@@ -248,4 +253,6 @@
 %token LBRACKETGREATER
 %token LESS
+%token LESSBAR
+%token LESSLESS
 %token LESSMINUS
 %token LET
@@ -284,4 +291,5 @@
 %token <string> STRING
 %token STRUCT
+%token SWAP
 %token THEN
 %token TILDE
@@ -814,4 +822,6 @@
   | LET MODULE UIDENT module_binding IN seq_expr
       { mkexp(Pexp_letmodule($3, $4, $6)) }
+  | CUSTOMSWAP expr IN simple_expr %prec below_SHARP
+      { mkexp(Pexp_customswap($2, $4)) }
   | FUNCTION opt_bar match_cases
       { mkexp(Pexp_function("", None, List.rev $3)) }
@@ -898,4 +908,19 @@
   | LAZY simple_expr %prec below_SHARP
       { mkexp (Pexp_lazy ($2)) }
+  | LESSLESS expr GREATERGREATER simple_expr %prec below_SHARP
+      { mkexp(Pexp_abst($2, $4)) }
+  | LESSBAR expr BARGREATER simple_expr %prec below_SHARP
+      { mkexp(Pexp_abst($2, $4)) }
+  | FRESH
+      { mkexp(Pexp_fresh) }
+  | SWAP simple_expr AND simple_expr IN expr
+      { mkexp(Pexp_swap ($2, $4, $6)) }
+  | simple_expr FRESHFOR expr %prec below_SHARP
+      { mkexp(Pexp_freshfor ($1, $3)) }
+  | BACKQUOTE BACKQUOTE val_ident DOT expr
+      { mkexp(Pexp_let (Nonrecursive,
+                        [({ppat_desc = Ppat_var $3;
+                           ppat_loc = rhs_loc 1}, mkexp(Pexp_fresh))],
+                        mkexp(Pexp_abst(mkexp(Pexp_ident (Lident $3)), $5)))) }
   | OBJECT class_structure END
       { mkexp (Pexp_object($2)) }
@@ -1118,4 +1143,8 @@
   | LPAREN pattern COLON core_type error
       { unclosed "(" 1 ")" 5 }
+  | LESSLESS pattern GREATERGREATER simple_pattern
+      { mkpat(Ppat_abst ($2, $4)) }
+  | LESSBAR pattern BARGREATER simple_pattern
+      { mkpat(Ppat_abst ($2, $4)) }
 ;
 
@@ -1288,4 +1317,12 @@
 ;
 simple_core_type2:
+    LESSLESS core_type GREATERGREATER simple_core_type %prec below_SHARP
+      { mktyp(Ptyp_abst ($2, $4)) }
+  | LESSBAR core_type BARGREATER simple_core_type %prec below_SHARP
+      { mktyp(Ptyp_abst ($2, $4)) }
+  | simple_core_type3 %prec below_SHARP
+      { $1 }
+;
+simple_core_type3:
     QUOTE ident
       { mktyp(Ptyp_var $2) }
@@ -1294,5 +1331,5 @@
   | type_longident
       { mktyp(Ptyp_constr($1, [])) }
-  | simple_core_type2 type_longident
+  | simple_core_type3 type_longident
       { mktyp(Ptyp_constr($2, [$1])) }
   | LPAREN core_type_comma_list RPAREN type_longident
@@ -1304,5 +1341,5 @@
   | SHARP class_longident opt_present
       { mktyp(Ptyp_class($2, [], $3)) }
-  | simple_core_type2 SHARP class_longident opt_present
+  | simple_core_type3 SHARP class_longident opt_present
       { mktyp(Ptyp_class($3, [$1], $4)) }
   | LPAREN core_type_comma_list RPAREN SHARP class_longident opt_present
diff -rN -U 2 ocaml-3.10.0/parsing/parsetree.mli fresh-ocaml-3.10.0/parsing/parsetree.mli
--- ocaml-3.10.0/parsing/parsetree.mli	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/parsing/parsetree.mli	2007-05-18 16:50:55.000000000 +0200
@@ -34,4 +34,5 @@
   | Ptyp_variant of row_field list * bool * label list option
   | Ptyp_poly of string list * core_type
+  | Ptyp_abst of core_type * core_type
 
 and core_field_type =
@@ -76,4 +77,5 @@
   | Ppat_constraint of pattern * core_type
   | Ppat_type of Longident.t
+  | Ppat_abst of pattern * pattern
 
 type expression =
@@ -112,4 +114,9 @@
   | Pexp_poly of expression * core_type option
   | Pexp_object of class_structure
+  | Pexp_abst of expression * expression
+  | Pexp_swap of expression * expression * expression
+  | Pexp_fresh
+  | Pexp_freshfor of expression * expression
+  | Pexp_customswap of expression * expression
 
 (* Value descriptions *)
diff -rN -U 2 ocaml-3.10.0/parsing/printast.ml fresh-ocaml-3.10.0/parsing/printast.ml
--- ocaml-3.10.0/parsing/printast.ml	2007-04-25 21:59:29.000000000 +0200
+++ fresh-ocaml-3.10.0/parsing/printast.ml	2007-05-18 16:50:55.000000000 +0200
@@ -147,4 +147,8 @@
         (fun ppf -> List.iter (fun x -> fprintf ppf " '%s" x)) sl;
       core_type i ppf ct;
+  | Ptyp_abst (t1, t2) ->
+      line i ppf "Ptyp_abst\n";
+      core_type i ppf t1;
+      core_type i ppf t2;
 
 and core_field_type i ppf x =
@@ -194,4 +198,8 @@
       line i ppf "PPat_type";
       longident i ppf li
+  | Ppat_abst (p1, p2) ->
+      line i ppf "Ppat_abst\n";
+      pattern i ppf p1;
+      pattern i ppf p2
 
 and expression i ppf x =
@@ -303,4 +311,23 @@
       line i ppf "Pexp_object";
       class_structure i ppf s
+  | Pexp_abst (e1, e2) ->
+      line i ppf "Pexp_abst\n";
+      expression i ppf e1;
+      expression i ppf e2;
+  | Pexp_swap (e1, e2, e3) ->
+      line i ppf "Pexp_swap\n";
+      expression i ppf e1;
+      expression i ppf e2;
+      expression i ppf e3;
+  | Pexp_fresh ->
+      line i ppf "Pexp_fresh\n";
+  | Pexp_freshfor (e1, e2) ->
+      line i ppf "Pexp_freshfor\n";
+      expression i ppf e1;
+      expression i ppf e2
+  | Pexp_customswap (e1, e2) ->
+      line i ppf "Pexp_customswap\n";
+      expression i ppf e1;
+      expression i ppf e2
 
 and value_description i ppf x =
diff -rN -U 2 ocaml-3.10.0/resources/ReadMe.txt fresh-ocaml-3.10.0/resources/ReadMe.txt
--- ocaml-3.10.0/resources/ReadMe.txt	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/resources/ReadMe.txt	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,9 @@
+This package installs Objective Caml version .
+You need Mac OS X 10.4.x (Tiger), with X11 and the
+XCode tools (v2.4) installed.
+
+Files will be installed in the following directories:
+
+/usr/local/bin - command-line executables
+/usr/local/lib/ocaml - library and support files
+/usr/local/man - manual pages
diff -rN -U 2 ocaml-3.10.0/stdlib/.depend fresh-ocaml-3.10.0/stdlib/.depend
--- ocaml-3.10.0/stdlib/.depend	2007-03-02 23:47:05.000000000 +0100
+++ fresh-ocaml-3.10.0/stdlib/.depend	2007-05-18 16:50:55.000000000 +0200
@@ -11,8 +11,8 @@
 arg.cmo: sys.cmi string.cmi printf.cmi list.cmi buffer.cmi array.cmi arg.cmi 
 arg.cmx: sys.cmx string.cmx printf.cmx list.cmx buffer.cmx array.cmx arg.cmi 
-array.cmo: array.cmi 
-array.cmx: array.cmi 
 arrayLabels.cmo: array.cmi arrayLabels.cmi 
 arrayLabels.cmx: array.cmx arrayLabels.cmi 
+array.cmo: array.cmi 
+array.cmx: array.cmi 
 buffer.cmo: sys.cmi string.cmi buffer.cmi 
 buffer.cmx: sys.cmx string.cmx buffer.cmi 
@@ -37,4 +37,6 @@
 format.cmo: string.cmi printf.cmi obj.cmi list.cmi buffer.cmi format.cmi 
 format.cmx: string.cmx printf.cmx obj.cmx list.cmx buffer.cmx format.cmi 
+freshness.cmo: list.cmi freshness.cmi 
+freshness.cmx: list.cmx freshness.cmi 
 gc.cmo: sys.cmi printf.cmi gc.cmi 
 gc.cmx: sys.cmx printf.cmx gc.cmi 
@@ -51,8 +53,8 @@
 lexing.cmo: sys.cmi string.cmi array.cmi lexing.cmi 
 lexing.cmx: sys.cmx string.cmx array.cmx lexing.cmi 
-list.cmo: list.cmi 
-list.cmx: list.cmi 
 listLabels.cmo: list.cmi listLabels.cmi 
 listLabels.cmx: list.cmx listLabels.cmi 
+list.cmo: list.cmi 
+list.cmx: list.cmi 
 map.cmo: map.cmi 
 map.cmx: map.cmi 
@@ -97,8 +99,8 @@
 stream.cmo: string.cmi obj.cmi list.cmi stream.cmi 
 stream.cmx: string.cmx obj.cmx list.cmx stream.cmi 
-string.cmo: pervasives.cmi list.cmi char.cmi string.cmi 
-string.cmx: pervasives.cmx list.cmx char.cmx string.cmi 
 stringLabels.cmo: string.cmi stringLabels.cmi 
 stringLabels.cmx: string.cmx stringLabels.cmi 
+string.cmo: pervasives.cmi list.cmi char.cmi string.cmi 
+string.cmx: pervasives.cmx list.cmx char.cmx string.cmi 
 sys.cmo: sys.cmi 
 sys.cmx: sys.cmi 
diff -rN -U 2 ocaml-3.10.0/stdlib/Makefile fresh-ocaml-3.10.0/stdlib/Makefile
--- ocaml-3.10.0/stdlib/Makefile	2007-02-09 14:24:20.000000000 +0100
+++ fresh-ocaml-3.10.0/stdlib/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -16,12 +16,12 @@
 include ../config/Makefile
 
-RUNTIME=../boot/ocamlrun
-COMPILER=../ocamlc
+RUNTIME=../boot/fresh-ocamlrun
+COMPILER=../fresh-ocamlc
 CAMLC=$(RUNTIME) $(COMPILER)
 COMPFLAGS=-g -warn-error A -nostdlib
-OPTCOMPILER=../ocamlopt
+OPTCOMPILER=../fresh-ocamlopt
 CAMLOPT=$(RUNTIME) $(OPTCOMPILER)
 OPTCOMPFLAGS=-warn-error A -nostdlib -g
-CAMLDEP=../boot/ocamlrun ../tools/ocamldep
+CAMLDEP=../boot/fresh-ocamlrun ../tools/fresh-ocamldep
 
 OBJS=pervasives.cmo $(OTHERS)
@@ -37,5 +37,6 @@
   genlex.cmo weak.cmo \
   lazy.cmo filename.cmo complex.cmo \
-  arrayLabels.cmo listLabels.cmo stringLabels.cmo moreLabels.cmo stdLabels.cmo
+  arrayLabels.cmo listLabels.cmo stringLabels.cmo moreLabels.cmo stdLabels.cmo \
+  freshness.cmo
 
 all: stdlib.cma std_exit.cmo camlheader camlheader_ur
@@ -80,9 +81,9 @@
 camlheader camlheader_ur: header.c ../config/Makefile
 	if $(SHARPBANGSCRIPTS); then \
-          echo '#!$(BINDIR)/ocamlrun' > camlheader && \
+          echo '#!$(BINDIR)/fresh-ocamlrun' > camlheader && \
           echo '#!' | tr -d '\012' > camlheader_ur; \
         else \
 	  $(BYTECC) $(BYTECCCOMPOPTS) $(BYTECCLINKOPTS) \
-                    -DRUNTIME_NAME='"$(BINDIR)/ocamlrun"' \
+                    -DRUNTIME_NAME='"$(BINDIR)/fresh-ocamlrun"' \
                     header.c -o tmpheader$(EXE) && \
           strip tmpheader$(EXE) && \
diff -rN -U 2 ocaml-3.10.0/stdlib/StdlibModules fresh-ocaml-3.10.0/stdlib/StdlibModules
--- ocaml-3.10.0/stdlib/StdlibModules	2004-08-12 14:57:00.000000000 +0200
+++ fresh-ocaml-3.10.0/stdlib/StdlibModules	2007-05-18 16:50:55.000000000 +0200
@@ -16,4 +16,5 @@
   filename \
   format \
+  freshness \
   gc \
   genlex \
diff -rN -U 2 ocaml-3.10.0/stdlib/freshness.ml fresh-ocaml-3.10.0/stdlib/freshness.ml
--- ocaml-3.10.0/stdlib/freshness.ml	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/stdlib/freshness.ml	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,41 @@
+(*
+ *  byterun/freshness.ml
+ *
+ *  Standard library support for freshness functionality.
+ *
+ *  (c) Copyright 2004, Mark R. Shinwell.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  3. The names of the authors may not be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ *  NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *)
+
+external fresh_swap_multiple_atoms : 'a name list -> 'a name list -> 'b -> 'b =
+  "fresh_swap_multiple_atoms"
+
+let swap_multiple_atoms atoms1 atoms2 v =
+  if List.length atoms1 <> List.length atoms2 then
+    raise (Invalid_argument
+           "Freshness.swap_multiple_atoms: lists are of differing length")
+  else if List.length atoms1 = 0 then v
+  else
+    fresh_swap_multiple_atoms atoms1 atoms2 v
+
diff -rN -U 2 ocaml-3.10.0/stdlib/freshness.mli fresh-ocaml-3.10.0/stdlib/freshness.mli
--- ocaml-3.10.0/stdlib/freshness.mli	1970-01-01 01:00:00.000000000 +0100
+++ fresh-ocaml-3.10.0/stdlib/freshness.mli	2007-05-18 16:50:55.000000000 +0200
@@ -0,0 +1,32 @@
+(*
+ *  byterun/freshness.mli
+ *
+ *  Standard library support for freshness functionality.
+ *
+ *  (c) Copyright 2004, Mark R. Shinwell.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  3. The names of the authors may not be used to endorse or promote products
+ *  derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ *  NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *)
+
+val swap_multiple_atoms : 'a name list -> 'a name list -> 'b -> 'b
+
diff -rN -U 2 ocaml-3.10.0/stdlib/obj.ml fresh-ocaml-3.10.0/stdlib/obj.ml
--- ocaml-3.10.0/stdlib/obj.ml	2004-01-01 17:42:40.000000000 +0100
+++ fresh-ocaml-3.10.0/stdlib/obj.ml	2007-05-18 16:50:55.000000000 +0200
@@ -37,4 +37,9 @@
   (Marshal.from_string str pos, pos + Marshal.total_size str pos)
 
+let no_swap_tag = 241
+let no_bind_tag = 242
+let custom_swap_tag = 243
+let abst_tag = 244
+let atom_tag = 245
 let lazy_tag = 246
 let closure_tag = 247
diff -rN -U 2 ocaml-3.10.0/stdlib/obj.mli fresh-ocaml-3.10.0/stdlib/obj.mli
--- ocaml-3.10.0/stdlib/obj.mli	2005-10-25 20:34:07.000000000 +0200
+++ fresh-ocaml-3.10.0/stdlib/obj.mli	2007-05-18 16:50:55.000000000 +0200
@@ -35,4 +35,9 @@
 external dup : t -> t = "caml_obj_dup"
 
+val no_swap_tag : int
+val no_bind_tag : int
+val custom_swap_tag : int
+val atom_tag : int
+val abst_tag : int
 val lazy_tag : int
 val closure_tag : int
diff -rN -U 2 ocaml-3.10.0/stdlib/sort.ml fresh-ocaml-3.10.0/stdlib/sort.ml
--- ocaml-3.10.0/stdlib/sort.ml	2005-10-25 20:34:07.000000000 +0200
+++ fresh-ocaml-3.10.0/stdlib/sort.ml	2007-05-18 16:50:55.000000000 +0200
@@ -44,5 +44,5 @@
   mergeall(initlist l)
 
-let swap arr i j =
+let exchange arr i j =
   let tmp = unsafe_get arr i in
   unsafe_set arr i (unsafe_get arr j);
@@ -61,8 +61,8 @@
          avoids extra comparisons on i and j in the two tight "while"
          loops below. *)
-      if cmp (unsafe_get arr mid) (unsafe_get arr lo) then swap arr mid lo;
+      if cmp (unsafe_get arr mid) (unsafe_get arr lo) then exchange arr mid lo;
       if cmp (unsafe_get arr hi) (unsafe_get arr mid) then begin
-        swap arr mid hi;
-        if cmp (unsafe_get arr mid) (unsafe_get arr lo) then swap arr mid lo
+        exchange arr mid hi;
+        if cmp (unsafe_get arr mid) (unsafe_get arr lo) then exchange arr mid lo
       end;
       let pivot = unsafe_get arr mid in
@@ -74,5 +74,5 @@
         while not (cmp pivot (unsafe_get arr !i)) do incr i done;
         while not (cmp (unsafe_get arr !j) pivot) do decr j done;
-        if !i < !j then swap arr !i !j;
+        if !i < !j then exchange arr !i !j;
         incr i; decr j
       done;
diff -rN -U 2 ocaml-3.10.0/tools/Makefile fresh-ocaml-3.10.0/tools/Makefile
--- ocaml-3.10.0/tools/Makefile	2007-02-07 11:31:36.000000000 +0100
+++ fresh-ocaml-3.10.0/tools/Makefile	2007-05-30 22:46:26.000000000 +0200
@@ -15,8 +15,8 @@
 include ../config/Makefile
 
-CAMLRUN=../boot/ocamlrun
-CAMLC=$(CAMLRUN) ../boot/ocamlc -nostdlib -I ../boot
-CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib
-CAMLLEX=$(CAMLRUN) ../boot/ocamllex
+CAMLRUN=../boot/fresh-ocamlrun
+CAMLC=$(CAMLRUN) ../boot/fresh-ocamlc -nostdlib -I ../boot
+CAMLOPT=$(CAMLRUN) ../fresh-ocamlopt -nostdlib -I ../stdlib
+CAMLLEX=$(CAMLRUN) ../boot/fresh-ocamllex
 INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \
          -I ../driver
@@ -24,8 +24,8 @@
 LINKFLAGS=$(INCLUDES)
 
-all: ocamldep ocamlprof ocamlcp ocamlmktop ocamlmklib scrapelabels addlabels \
+all: fresh-ocamldep fresh-ocamlprof fresh-ocamlcp fresh-ocamlmktop fresh-ocamlmklib scrapelabels addlabels \
      dumpobj
 
-opt.opt: ocamldep.opt
+opt.opt: fresh-ocamldep.opt
 
 # The dependency generator
@@ -36,9 +36,9 @@
   syntaxerr.cmo parser.cmo lexer.cmo parse.cmo
 
-ocamldep: depend.cmi $(CAMLDEP_OBJ)
-	$(CAMLC) $(LINKFLAGS) -o ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ)
+fresh-ocamldep: depend.cmi $(CAMLDEP_OBJ)
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamldep $(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ)
 
-ocamldep.opt: depend.cmi $(CAMLDEP_OBJ:.cmo=.cmx)
-	$(CAMLOPT) $(LINKFLAGS) -o ocamldep.opt $(CAMLDEP_IMPORTS:.cmo=.cmx) \
+fresh-ocamldep.opt: depend.cmi $(CAMLDEP_OBJ:.cmo=.cmx)
+	$(CAMLOPT) $(LINKFLAGS) -o fresh-ocamldep.opt $(CAMLDEP_IMPORTS:.cmo=.cmx) \
 	           $(CAMLDEP_OBJ:.cmo=.cmx)
 
@@ -46,11 +46,11 @@
 # bootstrap and we need to remake the dependencies
 clean::
-	if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi
-	rm -f ocamldep.opt
+	if test -f fresh-ocamldep; then mv -f fresh-ocamldep ocamldep.bak; else :; fi
+	rm -f fresh-ocamldep.opt
 
 install::
-	cp ocamldep $(BINDIR)/ocamldep$(EXE)
-	if test -f ocamldep.opt; \
-	  then cp ocamldep.opt $(BINDIR)/ocamldep.opt$(EXE); else :; fi
+	cp fresh-ocamldep $(BINDIR)/fresh-ocamldep$(EXE)
+	if test -f fresh-ocamldep.opt; \
+	  then cp fresh-ocamldep.opt $(BINDIR)/fresh-ocamldep.opt$(EXE); else :; fi
 
 # The profiler
@@ -61,34 +61,34 @@
   syntaxerr.cmo parser.cmo lexer.cmo parse.cmo
 
-ocamlprof: $(CSLPROF) profiling.cmo
-	$(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF)
+fresh-ocamlprof: $(CSLPROF) profiling.cmo
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF)
 
-ocamlcp: ocamlcp.cmo
-	$(CAMLC) $(LINKFLAGS) -o ocamlcp main_args.cmo ocamlcp.cmo
+fresh-ocamlcp: ocamlcp.cmo
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamlcp main_args.cmo ocamlcp.cmo
 
 install::
-	cp ocamlprof $(BINDIR)/ocamlprof$(EXE)
-	cp ocamlcp $(BINDIR)/ocamlcp$(EXE)
+	cp fresh-ocamlprof $(BINDIR)/fresh-ocamlprof$(EXE)
+	cp fresh-ocamlcp $(BINDIR)/fresh-ocamlcp$(EXE)
 	cp profiling.cmi profiling.cmo $(LIBDIR)
 
 clean::
-	rm -f ocamlprof ocamlcp
+	rm -f fresh-ocamlprof fresh-ocamlcp
 
 # To make custom toplevels
 
-ocamlmktop: ocamlmktop.tpl ../config/Makefile
-	sed -e 's|%%BINDIR%%|$(BINDIR)|' ocamlmktop.tpl > ocamlmktop
-	chmod +x ocamlmktop
+fresh-ocamlmktop: ocamlmktop.tpl ../config/Makefile
+	sed -e 's|%%BINDIR%%|$(BINDIR)|' ocamlmktop.tpl > fresh-ocamlmktop
+	chmod +x fresh-ocamlmktop
 
 install::
-	cp ocamlmktop $(BINDIR)/ocamlmktop
+	cp fresh-ocamlmktop $(BINDIR)/fresh-ocamlmktop
 
 clean::
-	rm -f ocamlmktop
+	rm -f fresh-ocamlmktop
 
 # To help building mixed-mode libraries (Caml + C)
 
-ocamlmklib: myocamlbuild_config.cmo ocamlmklib.cmo
-	$(CAMLC) $(LINKFLAGS) -o ocamlmklib myocamlbuild_config.cmo ocamlmklib.cmo
+fresh-ocamlmklib: myocamlbuild_config.cmo ocamlmklib.cmo
+	$(CAMLC) $(LINKFLAGS) -o fresh-ocamlmklib myocamlbuild_config.cmo ocamlmklib.cmo
 
 ocamlmklib.cmo: myocamlbuild_config.cmi
@@ -98,8 +98,8 @@
 
 install::
-	cp ocamlmklib $(BINDIR)/ocamlmklib
+	cp fresh-ocamlmklib $(BINDIR)/fresh-ocamlmklib
 
 clean::
-	rm -f ocamlmklib
+	rm -f fresh-ocamlmklib
 
 ocamlmklib.ml: ocamlmklib.mlp ../config/Makefile
@@ -261,5 +261,5 @@
 
 depend: beforedepend
-	$(CAMLRUN) ./ocamldep $(INCLUDES) *.mli *.ml > .depend
+	$(CAMLRUN) ./fresh-ocamldep $(INCLUDES) *.mli *.ml > .depend
 
 include .depend
diff -rN -U 2 ocaml-3.10.0/tools/addlabels.ml fresh-ocaml-3.10.0/tools/addlabels.ml
--- ocaml-3.10.0/tools/addlabels.ml	2006-05-29 05:55:36.000000000 +0200
+++ fresh-ocaml-3.10.0/tools/addlabels.ml	2007-05-18 16:50:55.000000000 +0200
@@ -66,4 +66,5 @@
   | Ppat_type _ ->
       []
+  | Ppat_abst (p1, p2) -> pattern_vars p1 @ pattern_vars p2
 
 let pattern_name pat =
@@ -276,6 +277,10 @@
   | Pexp_override lst ->
       List.iter lst ~f:(fun (_,e) -> add_labels_rec e)
+  | Pexp_abst (e1, e2) ->
+      add_labels_rec e1; add_labels_rec e2
+  | Pexp_swap (e1, e2, e3) ->
+      add_labels_rec e1; add_labels_rec e2; add_labels_rec e3
   | Pexp_ident _ | Pexp_constant _ | Pexp_construct _ | Pexp_variant _
-  | Pexp_new _ | Pexp_assertfalse | Pexp_object _ ->
+  | Pexp_new _ | Pexp_assertfalse | Pexp_object _ | Pexp_fresh | Pexp_freshfor _ ->
       ()
 
diff -rN -U 2 ocaml-3.10.0/tools/depend.ml fresh-ocaml-3.10.0/tools/depend.ml
--- ocaml-3.10.0/tools/depend.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/tools/depend.ml	2007-05-18 16:50:55.000000000 +0200
@@ -53,4 +53,5 @@
         fl
   | Ptyp_poly(_, t) -> add_type bv t
+  | Ptyp_abst(t1, t2) -> add_type bv t1; add_type bv t2
 
 and add_field_type bv ft =
@@ -113,4 +114,5 @@
   | Ppat_variant(_, op) -> add_opt add_pattern bv op
   | Ppat_type (li) -> add bv li
+  | Ppat_abst (p1, p2) -> add_pattern bv p1; add_pattern bv p2
 
 let rec add_expr bv exp =
@@ -155,4 +157,10 @@
   | Pexp_lazy (e) -> add_expr bv e
   | Pexp_poly (e, t) -> add_expr bv e; add_opt add_type bv t
+  | Pexp_abst (e1, e2) -> add_expr bv e1; add_expr bv e2
+  | Pexp_swap (e1, e2, body) ->
+      add_expr bv e1; add_expr bv e2; add_expr bv body
+  | Pexp_fresh -> ()
+  | Pexp_freshfor (e1, e2) -> add_expr bv e1; add_expr bv e2
+  | Pexp_customswap (e1, e2) -> add_expr bv e1; add_expr bv e2
   | Pexp_object (pat, fieldl) ->
       add_pattern bv pat; List.iter (add_class_field bv) fieldl
diff -rN -U 2 ocaml-3.10.0/tools/ocamlcp.ml fresh-ocaml-3.10.0/tools/ocamlcp.ml
--- ocaml-3.10.0/tools/ocamlcp.ml	2006-11-28 16:59:35.000000000 +0100
+++ fresh-ocaml-3.10.0/tools/ocamlcp.ml	2007-05-18 16:50:55.000000000 +0200
@@ -36,8 +36,8 @@
 ;;
 
-let usage = "Usage: ocamlcp <options> <files>\noptions are:"
+let usage = "Usage: fresh-ocamlcp <options> <files>\noptions are:"
 
 let incompatible o =
-  fprintf stderr "ocamlcp: profiling is incompatible with the %s option\n" o;
+  fprintf stderr "fresh-ocamlcp: profiling is incompatible with the %s option\n" o;
   exit 2
 
@@ -108,13 +108,13 @@
 Arg.parse optlist process_file usage;
 if !with_impl && !with_intf then begin
-  fprintf stderr "ocamlcp cannot deal with both \"-impl\" and \"-intf\"\n";
+  fprintf stderr "fresh-ocamlcp cannot deal with both \"-impl\" and \"-intf\"\n";
   fprintf stderr "please compile interfaces and implementations separately\n";
   exit 2;
 end else if !with_impl && !with_mli then begin
-  fprintf stderr "ocamlcp cannot deal with both \"-impl\" and .mli files\n";
+  fprintf stderr "fresh-ocamlcp cannot deal with both \"-impl\" and .mli files\n";
   fprintf stderr "please compile interfaces and implementations separately\n";
   exit 2;
 end else if !with_intf && !with_ml then begin
-  fprintf stderr "ocamlcp cannot deal with both \"-intf\" and .ml files\n";
+  fprintf stderr "fresh-ocamlcp cannot deal with both \"-intf\" and .ml files\n";
   fprintf stderr "please compile interfaces and implementations separately\n";
   exit 2;
diff -rN -U 2 ocaml-3.10.0/tools/ocamlprof.ml fresh-ocaml-3.10.0/tools/ocamlprof.ml
--- ocaml-3.10.0/tools/ocamlprof.ml	2007-02-09 14:31:15.000000000 +0100
+++ fresh-ocaml-3.10.0/tools/ocamlprof.ml	2007-05-18 16:50:55.000000000 +0200
@@ -286,4 +286,23 @@
       List.iter (rewrite_class_field iflag) fieldl
 
+  | Pexp_abst (sexp1, sexp2) ->
+      rewrite_exp iflag sexp1;
+      rewrite_exp iflag sexp2
+
+  | Pexp_swap (sexp1, sexp2, sexp_body) ->
+      rewrite_exp iflag sexp1;
+      rewrite_exp iflag sexp2;
+      rewrite_exp iflag sexp_body
+
+  | Pexp_fresh -> ()
+
+  | Pexp_freshfor (sexp1, sexp2) ->
+      rewrite_exp iflag sexp1;
+      rewrite_exp iflag sexp2
+
+  | Pexp_customswap (sexp1, sexp2) ->
+      rewrite_exp iflag sexp1;
+      rewrite_exp iflag sexp2
+
 and rewrite_ifbody iflag ghost sifbody =
   if !instr_if && not ghost then
diff -rN -U 2 ocaml-3.10.0/toplevel/genprintval.ml fresh-ocaml-3.10.0/toplevel/genprintval.ml
--- ocaml-3.10.0/toplevel/genprintval.ml	2005-06-13 06:55:53.000000000 +0200
+++ fresh-ocaml-3.10.0/toplevel/genprintval.ml	2007-05-18 16:50:55.000000000 +0200
@@ -22,4 +22,6 @@
 open Outcometree
 
+external fresh_throughout : 'a -> 'a = "fresh_throughout"
+
 module type OBJ =
   sig
@@ -172,5 +174,21 @@
 
       let printer_steps = ref max_steps in
+      let atom_map = ref [] in
+      let atom_count = ref 0 in
 
+      let add_or_lookup_atom atm =
+        let rec search l =
+          match l with
+            [] ->
+              let tag = string_of_int !atom_count in
+                incr atom_count;
+                atom_map := (atm, tag) :: !atom_map;
+                tag
+          | ((atm', tag') :: rest) ->
+              if atm = atm' then tag'
+              else search rest
+        in
+          search !atom_map
+      in
       let rec tree_of_val depth obj ty =
         decr printer_steps;
@@ -238,5 +256,11 @@
                 match decl with
                 | {type_kind = Type_abstract; type_manifest = None} ->
-                    Oval_stuff "<abstr>"
+                    if path = Predef.path_name then
+                      let _ = assert (O.tag obj = Obj.atom_tag) in
+                      let (atm_blk : int) = O.obj (O.field obj 0) in
+                      let atm = add_or_lookup_atom atm_blk in
+                        Oval_stuff ("name_" ^ atm)
+                    else
+                      Oval_stuff ("<abstract type>")
                 | {type_kind = Type_abstract; type_manifest = Some body} ->
                     tree_of_val depth obj
@@ -246,5 +270,12 @@
                     let tag =
                       if O.is_block obj
-                      then Cstr_block(O.tag obj)
+                      then (
+                        if O.tag obj = Obj.no_bind_tag ||
+			   O.tag obj = Obj.no_swap_tag ||
+                           O.tag obj = Obj.custom_swap_tag then
+                          Cstr_block 0
+                        else
+                          Cstr_block(O.tag obj)
+                      )
                       else Cstr_constant(O.obj obj) in
                     let (constr_name, constr_args) =
@@ -282,5 +313,5 @@
               with
                 Not_found ->                (* raised by Env.find_type *)
-                  Oval_stuff "<abstr>"
+                  Oval_stuff "<abstract type>"
               | Datarepr.Constr_not_found -> (* raised by find_constr_by_tag *)
                   Oval_stuff "<unknown constructor>"
@@ -321,4 +352,8 @@
           | Tunivar ->
               Oval_stuff "<poly>"
+          | Tabst (ty1, ty2) ->
+              let obj' = fresh_throughout (O.obj obj) in
+                Oval_abst (tree_of_val (depth - 1) (O.field obj' 0) ty1,
+                           tree_of_val (depth - 1) (O.field obj' 1) ty2)
         end
 
diff -rN -U 2 ocaml-3.10.0/toplevel/toploop.ml fresh-ocaml-3.10.0/toplevel/toploop.ml
--- ocaml-3.10.0/toplevel/toploop.ml	2006-01-04 17:55:50.000000000 +0100
+++ fresh-ocaml-3.10.0/toplevel/toploop.ml	2007-05-18 16:50:55.000000000 +0200
@@ -399,5 +399,5 @@
 
 let loop ppf =
-  fprintf ppf "        Objective Caml version %s@.@." Config.version;
+  fprintf ppf "        Fresh Objective Caml release %s@.@." Config.version;
   initialize_toplevel_env ();
   let lb = Lexing.from_function refill_lexbuf in
diff -rN -U 2 ocaml-3.10.0/toplevel/topmain.ml fresh-ocaml-3.10.0/toplevel/topmain.ml
--- ocaml-3.10.0/toplevel/topmain.ml	2005-01-28 18:52:58.000000000 +0100
+++ fresh-ocaml-3.10.0/toplevel/topmain.ml	2007-05-18 16:50:55.000000000 +0200
@@ -15,5 +15,5 @@
 open Clflags
 
-let usage = "Usage: ocaml <options> <object-files> [script-file]\noptions are:"
+let usage = "Usage: fresh-ocaml <options> <object-files> [script-file]\noptions are:"
 
 let preload_objects = ref []
diff -rN -U 2 ocaml-3.10.0/typing/btype.ml fresh-ocaml-3.10.0/typing/btype.ml
--- ocaml-3.10.0/typing/btype.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/btype.ml	2007-05-18 16:50:55.000000000 +0200
@@ -197,4 +197,5 @@
   | Tunivar             -> ()
   | Tpoly (ty, tyl)     -> f ty; List.iter f tyl
+  | Tabst (ty1, ty2)    -> f ty1; f ty2
 
 let rec iter_abbrev f = function
@@ -263,4 +264,5 @@
       let tyl = List.map (fun x -> norm_univar (f x)) tyl in
       Tpoly (f ty, tyl)
+  | Tabst (ty1, ty2)    -> Tabst (f ty1, f ty2)
 
 
diff -rN -U 2 ocaml-3.10.0/typing/ctype.ml fresh-ocaml-3.10.0/typing/ctype.ml
--- ocaml-3.10.0/typing/ctype.ml	2007-03-05 02:24:10.000000000 +0100
+++ fresh-ocaml-3.10.0/typing/ctype.ml	2007-05-18 16:50:55.000000000 +0200
@@ -1569,4 +1569,7 @@
     | (Ttuple tl1, Ttuple tl2) ->
         unify_list env tl1 tl2
+    | (Tabst (t1, t2), Tabst (t1', t2')) ->
+        unify env t1 t1';
+        unify env t2 t2'
     | (Tconstr (p1, tl1, _), Tconstr (p2, tl2, _)) when Path.same p1 p2 ->
         unify_list env tl1 tl2
@@ -1961,5 +1964,4 @@
   let t2 = repr t2 in
   if t1 == t2 then () else
-
   try
     match (t1.desc, t2.desc) with
@@ -2010,5 +2012,8 @@
               enter_poly env univar_pairs t1 tl1 t2 tl2
                 (moregen inst_nongen type_pairs env)
-          | (_, _) ->
+          | (Tabst (t1, t1'), Tabst (t2, t2')) ->
+              moregen inst_nongen type_pairs env t1 t2;
+              moregen inst_nongen type_pairs env t1' t2'
+          | (_, _) -> 
               raise (Unify [])
         end
@@ -2262,4 +2267,7 @@
           | (Tunivar, Tunivar) ->
               unify_univar t1' t2' !univar_pairs
+          | (Tabst (t1, t2), Tabst (t1', t2')) ->
+              eqtype rename type_pairs subst env t1 t1';
+              eqtype rename type_pairs subst env t2 t2'
           | (_, _) ->
               raise (Unify [])
@@ -2853,4 +2861,10 @@
   | Tunivar ->
       (t, Unchanged)
+  | Tabst (t1, t2) ->
+      let (t1', c1) = build_subtype env visited loops posi level t1 in
+      let (t2', c2) = build_subtype env visited loops posi level t2 in
+      let c = max c1 c2 in
+      if c > Unchanged then (newty (Tabst (t1', t2')), c)
+                       else (t, Unchanged)
 
 let enlarge_type env ty =
diff -rN -U 2 ocaml-3.10.0/typing/datarepr.ml fresh-ocaml-3.10.0/typing/datarepr.ml
--- ocaml-3.10.0/typing/datarepr.ml	2003-07-02 11:14:32.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/datarepr.ml	2007-05-18 16:50:55.000000000 +0200
@@ -39,5 +39,9 @@
             cstr_args = ty_args;
             cstr_arity = List.length ty_args;
-            cstr_tag = tag;
+            cstr_tag =
+              if name = "Nobind" then Cstr_block Obj.no_bind_tag
+              else if name = "Noswap" then Cstr_block Obj.no_swap_tag
+              else if name = "Custom_swap" then Cstr_block Obj.custom_swap_tag
+              else tag;
             cstr_consts = !num_consts;
             cstr_nonconsts = !num_nonconsts;
diff -rN -U 2 ocaml-3.10.0/typing/oprint.ml fresh-ocaml-3.10.0/typing/oprint.ml
--- ocaml-3.10.0/typing/oprint.ml	2007-04-26 16:34:50.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/oprint.ml	2007-05-18 16:50:55.000000000 +0200
@@ -110,4 +110,6 @@
     | Oval_tuple tree_list ->
         fprintf ppf "@[<1>(%a)@]" (print_tree_list print_tree_1 ",") tree_list
+    | Oval_abst (t1, t2) ->
+        fprintf ppf "<<%a>>%a" print_simple_tree t1 print_simple_tree t2
     | tree -> fprintf ppf "@[<1>(%a)@]" (cautious print_tree_1) tree
   and print_fields first ppf =
@@ -173,5 +175,10 @@
   function
     Otyp_tuple tyl ->
-      fprintf ppf "@[<0>%a@]" (print_typlist print_simple_out_type " *") tyl
+      fprintf ppf "@[<0>%a@]" (print_typlist print_out_type_3 " *") tyl
+  | ty -> print_out_type_3 ppf ty
+and print_out_type_3 ppf =
+  function
+    Otyp_abst (ty1, ty2) ->
+      fprintf ppf "<<%a>>%a" print_out_type ty1 print_simple_out_type ty2
   | ty -> print_simple_out_type ppf ty
 and print_simple_out_type ppf =
@@ -205,7 +212,9 @@
         print_fields row_fields
         print_present tags
-  | Otyp_alias _ | Otyp_poly _ | Otyp_arrow _ | Otyp_tuple _ as ty ->
+  | Otyp_alias _ | Otyp_poly _ | Otyp_arrow _
+  | Otyp_tuple _ | Otyp_abst _ as ty ->
       fprintf ppf "@[<1>(%a)@]" print_out_type ty
   | Otyp_abstract | Otyp_sum _ | Otyp_record _ | Otyp_manifest (_, _) -> ()
+  | Otyp_bindable p -> fprintf ppf "%a" print_ident p
 and print_fields rest ppf =
   function
diff -rN -U 2 ocaml-3.10.0/typing/outcometree.mli fresh-ocaml-3.10.0/typing/outcometree.mli
--- ocaml-3.10.0/typing/outcometree.mli	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/outcometree.mli	2007-05-18 16:50:55.000000000 +0200
@@ -44,4 +44,5 @@
   | Oval_tuple of out_value list
   | Oval_variant of string * out_value option
+  | Oval_abst of out_value * out_value
 
 type out_type =
@@ -61,4 +62,7 @@
       bool * out_variant * bool * (string list) option
   | Otyp_poly of string list * out_type
+  | Otyp_abst of out_type * out_type
+  | Otyp_bindable of out_ident
+
 and out_variant =
   | Ovar_fields of (string * bool * out_type list) list
diff -rN -U 2 ocaml-3.10.0/typing/parmatch.ml fresh-ocaml-3.10.0/typing/parmatch.ml
--- ocaml-3.10.0/typing/parmatch.ml	2006-09-21 16:54:54.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/parmatch.ml	2007-05-18 16:50:55.000000000 +0200
@@ -98,4 +98,6 @@
       List.length ps = List.length qs &&
       compats ps qs
+  | Tpat_abst (p1, p2), Tpat_abst (p1', p2') ->
+      compat p1 p1' && compat p2 p2'
   | _,_  ->
       assert false
@@ -209,4 +211,6 @@
   | Tpat_or (v,w,_)    ->
       fprintf ppf "@[(%a|@,%a)@]" pretty_or v pretty_or w
+  | Tpat_abst (v, w) ->
+      fprintf ppf "<<%a>>%a" pretty_val v pretty_val w
 
 and pretty_car ppf v = match v.pat_desc with
@@ -271,4 +275,5 @@
   | Tpat_tuple _, Tpat_tuple _ -> true
   | Tpat_record _ , Tpat_record _ -> true
+  | Tpat_abst _, Tpat_abst _ -> true
   | Tpat_array p1s, Tpat_array p2s -> List.length p1s = List.length p2s
   | _, (Tpat_any | Tpat_var(_)) -> true
@@ -328,4 +333,5 @@
 | Tpat_variant(lab, Some arg, _) -> [arg]
 | Tpat_tuple(args)  -> args
+| Tpat_abst(a1, a2) -> [a1; a2]
 | Tpat_record(args) ->  extract_fields (record_arg p1) args
 | Tpat_array(args) -> args
@@ -335,4 +341,5 @@
     | Tpat_variant(_, Some _, _) -> [omega]
     | Tpat_tuple(args) -> omega_list args
+    | Tpat_abst(a1, a2) -> [omega; omega]
     | Tpat_record(args) ->  omega_list args
     | Tpat_array(args) ->  omega_list args
@@ -363,4 +370,6 @@
         q.pat_type q.pat_env
   | Tpat_or _ -> fatal_error "Parmatch.normalize_pat"
+  | Tpat_abst (p1, p2) ->
+      make_pat (Tpat_abst (omega, omega)) q.pat_type q.pat_env
 
 
@@ -380,4 +389,5 @@
         acc_pat acc pss
   | (({pat_desc = Tpat_tuple _} as p)::_)::_ -> normalize_pat p
+  | (({pat_desc = Tpat_abst _} as p)::_)::_ -> normalize_pat p
   | (({pat_desc = Tpat_record largs} as p)::_)::pss ->
       let new_omegas =
@@ -418,4 +428,10 @@
     let args,rest = read_args omegas r in
     make_pat (Tpat_tuple args) q.pat_type q.pat_env::rest
+| {pat_desc = Tpat_abst _} ->
+    begin match r with
+      a1::a2::rest ->
+        make_pat (Tpat_abst (a1, a2)) q.pat_type q.pat_env :: rest
+    | _ -> assert false
+    end
 | {pat_desc = Tpat_record omegas} ->
     let args,rest = read_args omegas r in
@@ -626,4 +642,5 @@
 | ({pat_desc = Tpat_record(_)},_) :: _ -> true
 | ({pat_desc = Tpat_array(_)},_) :: _ -> false
+| ({pat_desc = Tpat_abst(_)},_) :: _ -> true
 | _ -> fatal_error "Parmatch.full_match"
 
@@ -863,4 +880,5 @@
   | Tpat_construct (_,ps) | Tpat_tuple ps | Tpat_array ps -> has_instances ps
   | Tpat_record lps -> has_instances (List.map snd lps)
+  | Tpat_abst (p1, p2) -> has_instance p1 && has_instance p2
       
 and has_instances = function
@@ -1295,4 +1313,6 @@
   | Tpat_variant(_,_,_), Tpat_variant(_,_,_) -> false
   | Tpat_tuple(ps), Tpat_tuple(qs) -> le_pats ps qs
+  | Tpat_abst(p1, p2), Tpat_abst(q1, q2) ->
+      le_pat p1 q1 && le_pat p2 q2
   | Tpat_record l1, Tpat_record l2 ->
       let ps,qs = records_args l1 l2 in
@@ -1350,4 +1370,6 @@
         let rs = lubs ps qs in
         make_pat (Tpat_array rs) p.pat_type p.pat_env
+| Tpat_abst (p1, p2), Tpat_abst (q1, q2) ->
+    make_pat (Tpat_abst (lub p1 q1, lub p2 q2)) p.pat_type p.pat_env
 | _,_  ->
     raise Empty
@@ -1566,4 +1588,6 @@
 | Tpat_or (p1,p2,_) ->
     collect_paths_from_pat (collect_paths_from_pat r p1) p2
+| Tpat_abst (p1,p2) ->
+    collect_paths_from_pat (collect_paths_from_pat r p1) p2
       
 
diff -rN -U 2 ocaml-3.10.0/typing/predef.ml fresh-ocaml-3.10.0/typing/predef.ml
--- ocaml-3.10.0/typing/predef.ml	2006-10-24 22:54:58.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/predef.ml	2007-05-18 16:50:55.000000000 +0200
@@ -35,4 +35,8 @@
 and ident_int64 = Ident.create "int64"
 and ident_lazy_t = Ident.create "lazy_t"
+and ident_name = Ident.create "name"
+and ident_no_bind = Ident.create "nobind"
+and ident_no_swap = Ident.create "noswap"
+and ident_custom_swap = Ident.create "custom_swap"
 
 let path_int = Pident ident_int
@@ -51,4 +55,8 @@
 and path_int64 = Pident ident_int64
 and path_lazy_t = Pident ident_lazy_t
+and path_name = Pident ident_name
+and path_no_bind = Pident ident_no_bind
+and path_no_swap = Pident ident_no_swap
+and path_custom_swap = Pident ident_custom_swap
 
 let type_int = newgenty (Tconstr(path_int, [], ref Mnil))
@@ -66,4 +74,8 @@
 and type_int64 = newgenty (Tconstr(path_int64, [], ref Mnil))
 and type_lazy_t t = newgenty (Tconstr(path_lazy_t, [t], ref Mnil))
+and type_name t = newgenty (Tconstr(path_name, [t], ref Mnil))
+and type_no_bind t = newgenty (Tconstr(path_no_bind, [t], ref Mnil))
+and type_no_swap t = newgenty (Tconstr(path_no_swap, [t], ref Mnil))
+and type_custom_swap t = newgenty (Tconstr(path_custom_swap, [t], ref Mnil))
 
 let ident_match_failure = Ident.create_predef_exn "Match_failure"
@@ -152,4 +164,41 @@
      type_manifest = None;
      type_variance = [true, false, false]}
+  and decl_name =
+    let tvar = newgenvar() in
+    {type_params = [tvar];
+     type_arity = 1;
+     type_kind = Type_abstract;
+     type_manifest = None;
+     type_variance = [true, false, false]}
+  and decl_no_bind =
+    let tvar = newgenvar() in
+    {type_params = [tvar]; 
+     type_arity = 1;
+     type_kind = Type_variant(["Nobind",[tvar]], Public);
+     type_manifest = None;
+     type_variance = [true, false, false]}
+  and decl_no_swap =
+    let tvar = newgenvar() in
+    {type_params = [tvar]; 
+     type_arity = 1;
+     type_kind = Type_variant(["Noswap",[tvar]], Public);
+     type_manifest = None;
+     type_variance = [true, false, false]}
+  and decl_custom_swap =
+    let tvar1 = newgenvar () in
+    let tvar2 = newgenvar () in
+    let tvar2_name = newgenty (Tconstr (path_name, [tvar2], ref Mnil)) in
+    let tvar2_list = newgenty (Tconstr (path_list, [tvar2_name], ref Mnil)) in
+    let ty = newgenty (Tarrow ("",
+                               newgenty (Ttuple [tvar2_list;
+                                                 tvar2_list;
+                                                 tvar1]),
+                               tvar1, Cok)) in
+    {type_params = [tvar1; tvar2];
+     type_arity = 0;
+     type_kind = Type_variant(["Custom_swap",[tvar1; ty]], Public);
+     type_manifest = None;
+     type_variance = [true, false, false;
+                      true, false, false]}
   in
 
@@ -173,4 +222,8 @@
   add_type ident_nativeint decl_abstr (
   add_type ident_lazy_t decl_lazy_t (
+  add_type ident_no_bind decl_no_bind (
+  add_type ident_no_swap decl_no_swap (
+  add_type ident_custom_swap decl_custom_swap (
+  add_type ident_name decl_name (
   add_type ident_option decl_option (
   add_type ident_format6 decl_format6 (
@@ -184,5 +237,5 @@
   add_type ident_char decl_abstr (
   add_type ident_int decl_abstr (
-    empty_env)))))))))))))))))))))))))))
+    empty_env)))))))))))))))))))))))))))))))
 
 let builtin_values =
diff -rN -U 2 ocaml-3.10.0/typing/predef.mli fresh-ocaml-3.10.0/typing/predef.mli
--- ocaml-3.10.0/typing/predef.mli	2006-10-24 22:54:58.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/predef.mli	2007-05-18 16:50:55.000000000 +0200
@@ -31,4 +31,8 @@
 val type_int64: type_expr
 val type_lazy_t: type_expr -> type_expr
+val type_name: type_expr -> type_expr
+val type_no_bind: type_expr -> type_expr
+val type_no_swap: type_expr -> type_expr
+val type_custom_swap: type_expr -> type_expr
 
 val path_int: Path.t
@@ -47,4 +51,8 @@
 val path_int64: Path.t
 val path_lazy_t: Path.t
+val path_name: Path.t
+val path_no_bind: Path.t
+val path_no_swap: Path.t
+val path_custom_swap: Path.t
 
 val path_match_failure: Path.t
diff -rN -U 2 ocaml-3.10.0/typing/printtyp.ml fresh-ocaml-3.10.0/typing/printtyp.ml
--- ocaml-3.10.0/typing/printtyp.ml	2007-02-16 12:18:54.000000000 +0100
+++ fresh-ocaml-3.10.0/typing/printtyp.ml	2007-05-18 16:50:55.000000000 +0200
@@ -117,4 +117,6 @@
   | Ttuple tl ->
       fprintf ppf "@[<1>Ttuple@,%a@]" raw_type_list tl
+  | Tabst (t1, t2) ->
+      fprintf ppf "Tabst(%a,%a)" raw_type t1 raw_type t2
   | Tconstr (p, tl, abbrev) ->
       fprintf ppf "@[<hov1>Tconstr(@,%a,@,%a,@,%a)@]" path p
@@ -277,4 +279,6 @@
         mark_loops_rec visited ty
     | Tunivar -> ()
+    | Tabst (ty1, ty2) ->
+        mark_loops_rec visited ty1; mark_loops_rec visited ty2
 
 let mark_loops ty =
@@ -384,4 +388,6 @@
     | Tunivar ->
         Otyp_var (false, name_of_type ty)
+    | Tabst (ty1, ty2) ->
+        Otyp_abst (tree_of_typexp sch ty1, tree_of_typexp sch ty2)
   in
   if List.memq px !delayed then delayed := List.filter ((!=) px) !delayed;
diff -rN -U 2 ocaml-3.10.0/typing/typecore.ml fresh-ocaml-3.10.0/typing/typecore.ml
--- ocaml-3.10.0/typing/typecore.ml	2007-05-02 04:10:54.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/typecore.ml	2007-05-18 16:50:55.000000000 +0200
@@ -61,4 +61,5 @@
   | Incoherent_label_order
   | Less_general of string * (type_expr * type_expr) list
+  | Not_a_bindable_type of Longident.t
 
 exception Error of Location.t * error
@@ -287,4 +288,6 @@
       ty1
   | Tpat_any | Tpat_var _ | Tpat_constant _ | Tpat_array _ -> p.pat_type
+  | Tpat_abst (p1, p2) ->
+      newty (Tabst (build_as_type env p1, build_as_type env p2))
 
 let build_or_pat env loc lid =
@@ -511,4 +514,11 @@
   | Ppat_type lid ->
       build_or_pat env sp.ppat_loc lid
+  | Ppat_abst (sp1, sp2) ->
+      let p1 = type_pat env sp1 in
+      let p2 = type_pat env sp2 in
+      { pat_desc = Tpat_abst (p1, p2);
+        pat_loc = sp.ppat_loc;
+        pat_type = newty (Tabst (p1.pat_type, p2.pat_type));
+        pat_env = env }
 
 let get_ref r =
@@ -620,4 +630,5 @@
   (* Note: nonexpansive only means no _observable_ side effects *)
   | Texp_lazy e -> is_nonexpansive e
+  | Texp_abst (e1, e2) -> is_nonexpansive e1 && is_nonexpansive e2
   | Texp_object ({cl_field=fields}, {cty_vars=vars}, _) ->
       let count = ref 0 in
@@ -835,4 +846,7 @@
       end;
       if sty2 = None then ty1 else ty2
+  | Pexp_abst (e1, e2) ->
+	      newty (Tabst (type_approx env e1, type_approx env e2))
+  | Pexp_swap (_, _, e) -> type_approx env e
   | _ -> newvar ()
 
@@ -1461,4 +1475,50 @@
   | Pexp_poly _ ->
       assert false
+  | Pexp_abst (sexp1, sexp2) ->
+      let exp1 = type_exp env sexp1 in
+      let exp2 = type_exp env sexp2 in
+      { exp_desc = Texp_abst (exp1, exp2);
+        exp_loc = sexp.pexp_loc;
+        exp_type = newty (Tabst (exp1.exp_type, exp2.exp_type));
+        exp_env = env }
+  | Pexp_swap (sexp1, sexp2, sexp_body) ->
+      let exp1 =
+          type_expect env sexp1 (instance (Predef.type_name (newvar ()))) in
+      let exp2 = type_expect env sexp2 exp1.exp_type in
+      let exp_body = type_exp env sexp_body in
+      { exp_desc = Texp_swap (exp1, exp2, exp_body);
+        exp_loc = sexp.pexp_loc;
+        exp_type = exp_body.exp_type;
+        exp_env = env }
+  | Pexp_fresh ->
+      { exp_desc = Texp_fresh;
+        exp_loc = sexp.pexp_loc;
+        exp_type = instance (Predef.type_name (newvar ()));
+        exp_env = env }
+  | Pexp_freshfor (sexp1, sexp2) ->
+      let exp1 =
+        type_expect env sexp1 (instance (Predef.type_name (newvar ()))) in
+      let exp2 = type_exp env sexp2 in
+      { exp_desc = Texp_freshfor (exp1, exp2);
+        exp_loc = sexp.pexp_loc;
+        exp_type = instance Predef.type_bool;
+        exp_env = env }
+  | Pexp_customswap (sexp1, sexp2) ->
+      (* 'a name *)
+      let alpha_name_ty = instance (Predef.type_name (newvar ())) in
+      (* 'a name list *)
+      let list_ty = instance (Predef.type_list alpha_name_ty) in
+      (* 'b *)
+      let value_ty = newvar () in
+      (* 'a name list * 'a name list * 'b *)
+      let swap_fn_arg_ty = newty (Ttuple [list_ty; list_ty; value_ty]) in
+      (* 'a name list * 'a name list * 'b -> 'b *)
+      let closure_ty = newty (Tarrow ("", swap_fn_arg_ty, value_ty, Cok)) in
+      let exp1 = type_expect env sexp1 closure_ty in
+      let exp2 = type_expect env sexp2 value_ty in
+      { exp_desc = Texp_customswap (exp1, exp2);
+        exp_loc = sexp.pexp_loc;
+	exp_type = value_ty;
+	exp_env = env }
 
 and type_argument env sarg ty_expected' =
@@ -2173,2 +2233,5 @@
         (fun ppf -> fprintf ppf "This %s has type" kind)
         (fun ppf -> fprintf ppf "which is less general than")
+  | Not_a_bindable_type lid ->
+      fprintf ppf "The type %a@ is not a type of bindable names" longident lid
+
diff -rN -U 2 ocaml-3.10.0/typing/typecore.mli fresh-ocaml-3.10.0/typing/typecore.mli
--- ocaml-3.10.0/typing/typecore.mli	2007-02-27 04:46:19.000000000 +0100
+++ fresh-ocaml-3.10.0/typing/typecore.mli	2007-05-18 16:50:55.000000000 +0200
@@ -99,4 +99,5 @@
   | Incoherent_label_order
   | Less_general of string * (type_expr * type_expr) list
+  | Not_a_bindable_type of Longident.t
 
 exception Error of Location.t * error
diff -rN -U 2 ocaml-3.10.0/typing/typedecl.ml fresh-ocaml-3.10.0/typing/typedecl.ml
--- ocaml-3.10.0/typing/typedecl.ml	2007-03-12 14:14:26.000000000 +0100
+++ fresh-ocaml-3.10.0/typing/typedecl.ml	2007-05-18 16:50:55.000000000 +0200
@@ -441,4 +441,7 @@
       | Tpoly (ty, _) ->
           compute_same ty
+      | Tabst (ty1, ty2) ->
+          compute_same ty1;
+          compute_same ty2
       | Tvar | Tnil | Tlink _ | Tunivar -> ()
     end
diff -rN -U 2 ocaml-3.10.0/typing/typedtree.ml fresh-ocaml-3.10.0/typing/typedtree.ml
--- ocaml-3.10.0/typing/typedtree.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/typedtree.ml	2007-05-18 16:50:55.000000000 +0200
@@ -38,4 +38,5 @@
   | Tpat_array of pattern list
   | Tpat_or of pattern * pattern * Path.t option
+  | Tpat_abst of pattern * pattern
 
 type partial = Partial | Total
@@ -78,4 +79,9 @@
   | Texp_assertfalse
   | Texp_lazy of expression
+  | Texp_abst of expression * expression
+  | Texp_swap of expression * expression * expression
+  | Texp_fresh
+  | Texp_freshfor of expression * expression
+  | Texp_customswap of expression * expression
   | Texp_object of class_structure * class_signature * string list
 
@@ -166,4 +172,5 @@
   | Tpat_var _
   | Tpat_constant _ -> ()
+  | Tpat_abst (p1, p2) -> f p1; f p2
 
 let map_pattern_desc f d =
@@ -187,4 +194,5 @@
   | Tpat_any
   | Tpat_variant (_,None,_) -> d
+  | Tpat_abst (p1, p2) -> Tpat_abst (f p1, f p2)
 
 (* List the identifiers bound by a pattern or a let *)
diff -rN -U 2 ocaml-3.10.0/typing/typedtree.mli fresh-ocaml-3.10.0/typing/typedtree.mli
--- ocaml-3.10.0/typing/typedtree.mli	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/typedtree.mli	2007-05-18 16:50:55.000000000 +0200
@@ -37,4 +37,5 @@
   | Tpat_array of pattern list
   | Tpat_or of pattern * pattern * Path.t option
+  | Tpat_abst of pattern * pattern
 
 type partial = Partial | Total
@@ -77,4 +78,9 @@
   | Texp_assertfalse
   | Texp_lazy of expression
+  | Texp_abst of expression * expression
+  | Texp_swap of expression * expression * expression
+  | Texp_fresh
+  | Texp_freshfor of expression * expression
+  | Texp_customswap of expression * expression
   | Texp_object of class_structure * class_signature * string list
 
diff -rN -U 2 ocaml-3.10.0/typing/types.ml fresh-ocaml-3.10.0/typing/types.ml
--- ocaml-3.10.0/typing/types.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/types.ml	2007-05-18 16:50:55.000000000 +0200
@@ -38,4 +38,5 @@
   | Tunivar
   | Tpoly of type_expr * type_expr list
+  | Tabst of type_expr * type_expr
 
 and row_desc =
diff -rN -U 2 ocaml-3.10.0/typing/types.mli fresh-ocaml-3.10.0/typing/types.mli
--- ocaml-3.10.0/typing/types.mli	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/types.mli	2007-05-18 16:50:55.000000000 +0200
@@ -37,4 +37,5 @@
   | Tunivar
   | Tpoly of type_expr * type_expr list
+  | Tabst of type_expr * type_expr
 
 and row_desc =
diff -rN -U 2 ocaml-3.10.0/typing/typetexp.ml fresh-ocaml-3.10.0/typing/typetexp.ml
--- ocaml-3.10.0/typing/typetexp.ml	2007-03-12 14:40:59.000000000 +0100
+++ fresh-ocaml-3.10.0/typing/typetexp.ml	2007-05-18 16:50:55.000000000 +0200
@@ -26,4 +26,5 @@
   | Unbound_type_constructor of Longident.t
   | Unbound_type_constructor_2 of Path.t
+  | Unbound_bindable_type of Longident.t
   | Type_arity_mismatch of Longident.t * int * int
   | Bound_type_variable of string
@@ -381,4 +382,7 @@
       unify_var env (newvar()) ty';
       ty'
+   | Ptyp_abst (t, t') ->
+       newty (Tabst (transl_type env policy t,
+                     transl_type env policy t'))
 
 and transl_fields env policy =
@@ -555,2 +559,5 @@
          if v.desc = Tunivar then "it is aliased to another variable"
          else "it is not a variable")
+  | Unbound_bindable_type lid ->
+      fprintf ppf "Unbound type of bindable names `%a'" longident lid
+
diff -rN -U 2 ocaml-3.10.0/typing/typetexp.mli fresh-ocaml-3.10.0/typing/typetexp.mli
--- ocaml-3.10.0/typing/typetexp.mli	2003-05-19 11:21:17.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/typetexp.mli	2007-05-18 16:50:55.000000000 +0200
@@ -41,4 +41,5 @@
   | Unbound_type_constructor of Longident.t
   | Unbound_type_constructor_2 of Path.t
+  | Unbound_bindable_type of Longident.t
   | Type_arity_mismatch of Longident.t * int * int
   | Bound_type_variable of string
diff -rN -U 2 ocaml-3.10.0/typing/unused_var.ml fresh-ocaml-3.10.0/typing/unused_var.ml
--- ocaml-3.10.0/typing/unused_var.ml	2006-04-05 04:28:13.000000000 +0200
+++ fresh-ocaml-3.10.0/typing/unused_var.ml	2007-05-18 16:50:55.000000000 +0200
@@ -75,4 +75,6 @@
   | Ppat_or (p1, _p2) -> get_vars acc p1
   | Ppat_constraint (pp, _) -> get_vars acc pp
+  | Ppat_abst (p1, p2) -> 
+		get_vars (get_vars acc p1) p2
   | Ppat_type _ -> acc
 
@@ -173,4 +175,19 @@
   | Pexp_poly (e, _) -> expression ppf tbl e;
   | Pexp_object cs -> class_structure ppf tbl cs;
+  | Pexp_abst (e1, e2) ->
+      expression ppf tbl e1;
+      expression ppf tbl e2;
+  | Pexp_swap (e1, e2, e3) ->
+	      expression ppf tbl e1;
+	      expression ppf tbl e2;
+	      expression ppf tbl e3;
+  | Pexp_fresh -> ()
+  | Pexp_freshfor (e1, e2) ->
+      expression ppf tbl e1;
+      expression ppf tbl e2;
+  | Pexp_customswap (e1, e2) ->
+      expression ppf tbl e1;
+      expression ppf tbl e2;
+
 
 and expression_option ppf tbl eo =
diff -rN -U 2 ocaml-3.10.0/utils/config.mlp fresh-ocaml-3.10.0/utils/config.mlp
--- ocaml-3.10.0/utils/config.mlp	2007-02-07 15:49:42.000000000 +0100
+++ fresh-ocaml-3.10.0/utils/config.mlp	2007-05-18 16:50:55.000000000 +0200
@@ -53,5 +53,5 @@
 let interface_suffix = ref ".mli"
 
-let max_tag = 245
+let max_tag = 240
 (* This is normally the same as in obj.ml, but we have to define it
    separately because it can differ when we're in the middle of a
diff -rN -U 2 ocaml-3.10.0/yacc/Makefile fresh-ocaml-3.10.0/yacc/Makefile
--- ocaml-3.10.0/yacc/Makefile	2007-02-07 15:49:42.000000000 +0100
+++ fresh-ocaml-3.10.0/yacc/Makefile	2007-05-18 16:50:55.000000000 +0200
@@ -23,8 +23,8 @@
   skeleton.o symtab.o verbose.o warshall.o
 
-all: ocamlyacc$(EXE)
+all: fresh-ocamlyacc$(EXE)
 
-ocamlyacc$(EXE): $(OBJS)
-	$(CC) $(CFLAGS) $(CCLINKFLAGS) -o ocamlyacc $(OBJS)
+fresh-ocamlyacc$(EXE): $(OBJS)
+	$(CC) $(CFLAGS) $(CCLINKFLAGS) -o fresh-ocamlyacc $(OBJS)
 
 version.h : ../VERSION
@@ -32,5 +32,5 @@
 
 clean:
-	rm -f *.o ocamlyacc$(EXE) *~ version.h
+	rm -f *.o fresh-ocamlyacc$(EXE) *~ version.h
 
 depend:

diff -rN -U 2 ocaml-3.10.0/ocamlbuild/start.sh fresh-ocaml-3.10.0/ocamlbuild/start.sh
--- ocaml-3.10.0/ocamlbuild/start.sh	2007-03-04 17:13:53.000000000 +0100
+++ fresh-ocaml-3.10.0/ocamlbuild/start.sh	2007-05-18 17:56:12.000000000 +0200
@@ -7,84 +7,84 @@
 cd _start
 echo "let bindir = ref \"<start>\";; let libdir = bindir;;" > ocamlbuild_where.ml
-ocamlc -c std_signatures.mli
-ocamlc -c signatures.mli
-ocamlc -c tags.mli
-ocamlc -c ocamlbuild_where.mli
-ocamlc -c my_unix.mli
-ocamlc -c my_std.mli
-ocamlc -c display.mli
-ocamlc -c shell.mli
-ocamlc -c log.mli
-ocamlc -c bool.mli
-ocamlc -c glob_ast.mli
-ocamlc -c glob_lexer.mli
-ocamlc -c glob.mli
-ocamlc -c lexers.mli
-ocamlc -c slurp.mli
-ocamlc -c pathname.mli
-ocamlc -c discard_printf.mli
-ocamlc -c command.mli
-ocamlc -c resource.mli
-ocamlc -c rule.mli
-ocamlc -c hygiene.mli
-ocamlc -c options.mli
-ocamlc -c tools.mli
-ocamlc -c main.mli
-ocamlc -c ocaml_utils.mli
-ocamlc -c ocaml_tools.mli
-ocamlc -c ocaml_compiler.mli
-ocamlc -c ocaml_dependencies.mli
-ocamlc -c hooks.mli
-ocamlc -c ocamldep.mli
-ocamlc -c ocaml_specific.mli
-ocamlc -c configuration.mli
-ocamlc -c flags.mli
-ocamlc -c ocaml_arch.mli
-ocamlc -c solver.mli
-ocamlc -c report.mli
-ocamlc -c ocamlbuild_where.ml
-ocamlc -c fda.mli
-ocamlc -c fda.ml
-ocamlc -c tools.ml
-ocamlc -c plugin.mli
-ocamlc -c plugin.ml
-ocamlc -c ocaml_dependencies.ml
-ocamlc -c main.ml
-ocamlc -c ocaml_specific.ml
-ocamlc -c display.ml
-ocamlc -c command.ml
-ocamlc -c -rectypes discard_printf.ml
-ocamlc -c my_std.ml
-ocamlc -c shell.ml
-ocamlc -c my_unix.ml
-ocamlc -c log.ml
-ocamlc -c pathname.ml
-ocamlc -c options.ml
-ocamlc -c slurp.ml
-ocamlc -c ocaml_utils.ml
-ocamlc -c ocaml_tools.ml
-ocamlc -c ocaml_compiler.ml
-ocamlc -c ocamldep.ml
-ocamlc -c hooks.ml
-ocamllex lexers.mll
-ocamlc -c lexers.ml
-ocamllex glob_lexer.mll
-ocamlc -c glob_lexer.ml
-ocamlc -c bool.ml
-ocamlc -c glob_ast.ml
-ocamlc -c glob.ml
-ocamlc -c tags.ml
-ocamlc -c configuration.ml
-ocamlc -c flags.ml
-ocamlc -c hygiene.ml
-ocamlc -c ocaml_arch.ml
-ocamlc -c resource.ml
-ocamlc -c rule.ml
-ocamlc -c report.ml
-ocamlc -c solver.ml
-ocamlc -c ocamlbuildlight.mli
-ocamlc -pack discard_printf.cmo my_std.cmo bool.cmo glob_ast.cmo glob_lexer.cmo glob.cmo lexers.cmo my_unix.cmo tags.cmo display.cmo log.cmo shell.cmo slurp.cmo ocamlbuild_where.cmo command.cmo options.cmo pathname.cmo resource.cmo rule.cmo flags.cmo solver.cmo report.cmo ocaml_arch.cmo hygiene.cmo configuration.cmo tools.cmo fda.cmo plugin.cmo ocaml_utils.cmo ocamldep.cmo ocaml_dependencies.cmo ocaml_compiler.cmo ocaml_tools.cmo hooks.cmo ocaml_specific.cmo main.cmo -o ocamlbuild_pack.cmo
-ocamlc -c ocamlbuildlight.ml
-ocamlc ocamlbuild_pack.cmo ocamlbuildlight.cmo -o ../ocamlbuild.byte.start
+fresh-ocamlc -c std_signatures.mli
+fresh-ocamlc -c signatures.mli
+fresh-ocamlc -c tags.mli
+fresh-ocamlc -c ocamlbuild_where.mli
+fresh-ocamlc -c my_unix.mli
+fresh-ocamlc -c my_std.mli
+fresh-ocamlc -c display.mli
+fresh-ocamlc -c shell.mli
+fresh-ocamlc -c log.mli
+fresh-ocamlc -c bool.mli
+fresh-ocamlc -c glob_ast.mli
+fresh-ocamlc -c glob_lexer.mli
+fresh-ocamlc -c glob.mli
+fresh-ocamlc -c lexers.mli
+fresh-ocamlc -c slurp.mli
+fresh-ocamlc -c pathname.mli
+fresh-ocamlc -c discard_printf.mli
+fresh-ocamlc -c command.mli
+fresh-ocamlc -c resource.mli
+fresh-ocamlc -c rule.mli
+fresh-ocamlc -c hygiene.mli
+fresh-ocamlc -c options.mli
+fresh-ocamlc -c tools.mli
+fresh-ocamlc -c main.mli
+fresh-ocamlc -c ocaml_utils.mli
+fresh-ocamlc -c ocaml_tools.mli
+fresh-ocamlc -c ocaml_compiler.mli
+fresh-ocamlc -c ocaml_dependencies.mli
+fresh-ocamlc -c hooks.mli
+fresh-ocamlc -c ocamldep.mli
+fresh-ocamlc -c ocaml_specific.mli
+fresh-ocamlc -c configuration.mli
+fresh-ocamlc -c flags.mli
+fresh-ocamlc -c ocaml_arch.mli
+fresh-ocamlc -c solver.mli
+fresh-ocamlc -c report.mli
+fresh-ocamlc -c ocamlbuild_where.ml
+fresh-ocamlc -c fda.mli
+fresh-ocamlc -c fda.ml
+fresh-ocamlc -c tools.ml
+fresh-ocamlc -c plugin.mli
+fresh-ocamlc -c plugin.ml
+fresh-ocamlc -c ocaml_dependencies.ml
+fresh-ocamlc -c main.ml
+fresh-ocamlc -c ocaml_specific.ml
+fresh-ocamlc -c display.ml
+fresh-ocamlc -c command.ml
+fresh-ocamlc -c -rectypes discard_printf.ml
+fresh-ocamlc -c my_std.ml
+fresh-ocamlc -c shell.ml
+fresh-ocamlc -c my_unix.ml
+fresh-ocamlc -c log.ml
+fresh-ocamlc -c pathname.ml
+fresh-ocamlc -c options.ml
+fresh-ocamlc -c slurp.ml
+fresh-ocamlc -c ocaml_utils.ml
+fresh-ocamlc -c ocaml_tools.ml
+fresh-ocamlc -c ocaml_compiler.ml
+fresh-ocamlc -c ocamldep.ml
+fresh-ocamlc -c hooks.ml
+fresh-ocamllex lexers.mll
+fresh-ocamlc -c lexers.ml
+fresh-ocamllex glob_lexer.mll
+fresh-ocamlc -c glob_lexer.ml
+fresh-ocamlc -c bool.ml
+fresh-ocamlc -c glob_ast.ml
+fresh-ocamlc -c glob.ml
+fresh-ocamlc -c tags.ml
+fresh-ocamlc -c configuration.ml
+fresh-ocamlc -c flags.ml
+fresh-ocamlc -c hygiene.ml
+fresh-ocamlc -c ocaml_arch.ml
+fresh-ocamlc -c resource.ml
+fresh-ocamlc -c rule.ml
+fresh-ocamlc -c report.ml
+fresh-ocamlc -c solver.ml
+fresh-ocamlc -c ocamlbuildlight.mli
+fresh-ocamlc -pack discard_printf.cmo my_std.cmo bool.cmo glob_ast.cmo glob_lexer.cmo glob.cmo lexers.cmo my_unix.cmo tags.cmo display.cmo log.cmo shell.cmo slurp.cmo ocamlbuild_where.cmo command.cmo options.cmo pathname.cmo resource.cmo rule.cmo flags.cmo solver.cmo report.cmo ocaml_arch.cmo hygiene.cmo configuration.cmo tools.cmo fda.cmo plugin.cmo ocaml_utils.cmo ocamldep.cmo ocaml_dependencies.cmo ocaml_compiler.cmo ocaml_tools.cmo hooks.cmo ocaml_specific.cmo main.cmo -o ocamlbuild_pack.cmo
+fresh-ocamlc -c ocamlbuildlight.ml
+fresh-ocamlc ocamlbuild_pack.cmo ocamlbuildlight.cmo -o ../ocamlbuild.byte.start
 cd ..
 rm -rf _start
