Commits

Markus Mottl committed ea29f86

Merged sexplib 7.0.4 from OCaml Forge

Comments (0)

Files changed (14)

base/sexplib/Changelog

+2011-09-18:  Improved documentation.
+
+2011-09-15:  Fixes to improve package dependency resolution.
+
+2011-07-05:  Fixed a parser position bug.  Parser positions passed by the user
+             were not updated correctly.
+
+             Internal code beautification.
+
+2011-07-04:  Internal updates to sync with Jane Street.
+
+2011-01-30:  Fixed a code generation bug with toplevel entries.
+
+             Thanks to Yong Lu <lyongu@gmail.com> for the report!
+
+2010-12-27:  Added support for MoreLabels.Hashtbl and improved reporting of
+             error locations with preprocessor.
+
+2010-12-26:  Worked around a compiler bug that is expected to be fixed in
+             OCaml 3.12.1.  This workaround temporarily removes the interface
+             for module Conv (conv.mli), thus exposing the internals.
+             This should not cause any problems for end users as long as
+             they do not depend on the exported internal representations.
+             The interface will become constrained again as soon as the
+             fixed compiler is out.
+
+2010-12-22:  Major release.
+
+             Merged with Jane Street version.  This has caused an API-change
+             that requires "open Sexplib.Conv" at the top of files that use the
+             syntax extension.
+
+             Renamed functions:
+
+               * sexp_of_lazy -> sexp_of_lazy_t
+               * lazy_of_sexp -> lazy_t_of_sexp
+
+            Some standard library modules are now re-exported with predefined
+            S-expression converters in module Conv.
+
+2010-09-25:  Fixed inferred types of generated functions when dealing with arrow
+             types.
+
+2010-08-26:  Fixed a lexer bug when parsing comments.
+
 2010-05-21:  Added support for sexp_bool record field annotations.
 
 2010-05-18:  Improved performance of converting S-expressions to strings.

base/sexplib/README

-      
+    
                                         
                           README: library "Sexplib"
                           *************************
-             Copyright   (C)   2008  Jane Street Holding, LLC (1)
+             Copyright   (C)   2011  Jane Street Holding, LLC (1)
             =====================================================
                              Author: Markus Mottl 
                             ======================
-                             New York, 2008-09-30
+                             New York, 2010-03-31
                              ====================
   
 
 
   
   This library contains functionality for parsing and pretty-printing
-S-expressions. In addition to that it contains an extremely useful
-preprocessing module for Camlp4, which can be used to automatically generate
-code from type definitions for efficiently converting OCaml-values to
-S-expressions and vice versa. In combination with the parsing and
-pretty-printing functionality this frees users from having to write their own
-I/O-routines for datastructures they define. Possible errors during automatic
-conversions from S-expressions to OCaml-values are reported in a very
-human-readable way. Another module in the library allows you to extract and
-replace sub-expressions in S-expressions.
+S-expressions. In addition to that it contains a preprocessing module for
+Camlp4, which can be used to automatically generate code from type definitions
+for efficiently converting OCaml-values to S-expressions and vice versa. In
+combination with the parsing and pretty-printing functionality this frees
+users from having to write their own I/O-routines for datastructures they
+define. Possible errors during automatic conversions from S-expressions to
+OCaml-values are reported in human-readable ways with exact location
+information. Another module in this library allows you to extract and replace
+sub-expressions in S-expressions.
   
 
 3  How can you use it?
 signatures. Just add 'with sexp' to the type in a signature, and the
 appropriate function signatures will be generated.
   
-  See the file 'lib\_test/conv\_test.ml' for example usage. It also
-demonstrates how to extract and substitute sub-expressions.
+  Converters for standard types (int, list, Hashtbl.t, etc.) become visible to
+the macro-generated code by opening the standard module before their first use
+in a type definition. Users will therefore usually want to place the following
+at the top of their files:
+<<  open Sexplib.Std
+>>
+  
+  See the file 'lib_test/conv_test.ml' for example usage. It also demonstrates
+how to extract and substitute sub-expressions.
   
 
 3.1  Compiling and linking
 argument, at the top of the file to be preprocessed (see example
 'conv_test.ml'). It is supposed to set the module path to the given module
 file. This is necessary, because modules may get packed at a later stage, and
-error messages generated by Sexplib will refer to this location to easily find
-the associated type.
+error messages generated by Sexplib will refer to this location to help
+pinpointing the associated type.
   
   In the linking stage you will only have to link with 'sexplib'. E.g. when
 using OCamlMakefile just add it to the 'PACKS'-variable.
   
   The type 'sexp_option' is equivalent to ordinary options, but is treated
 specially by the code generator. The above would lead to the following
-equivalences of values and S-expressions: 
+equivalences of values and S-expressions:
 <<  {
       x = Some 1;
       y = Some 2;
 down such a value as an option, i.e. the 'some'-tag must be dropped if the
 field should be defined.
   
-  There is also a type qualifier 'sexp_list'. It behaves similar to
-'sexp_option', but assumes the empty list as default value.
+  The types 'sexp_list', 'sexp_array', and 'sexp_bool' can be used in ways
+similar to the type 'sexp_option'. They assume the empty list, empty array,
+and false value respectively as default values.
   
 
 4.7  Conversion of sum types
 that can escape functions in the OCaml standard library.
   
 
-5  Contact information
+5  I/O and type conversions
+*=*=*=*=*=*=*=*=*=*=*=*=*=*
+
+  
+  There are multiple ways of performing I/O with S-expressions. If exact error
+locations are required when type conversions fail, S-expressions need to be
+parsed with location annotations. In most cases users may want to use
+functions like e.g. 'load_sexp_conv' or 'load_sexp_conv_exn', which load
+S-expressions from files and convert them. Only when conversions fail, the
+file will be reparsed with annotations, which is slower, and type errors will
+be reported accurately with file, line number, column, and file position.
+  
+
+6  Contact information
 *=*=*=*=*=*=*=*=*=*=*=
 
   

base/sexplib/doc/Makefile

+NAME        := README
+HEVEAFLAGS  := -w 78 -fix -exec ~/bin/xxdate.exe custom.hva 
+
+all:	text pdf
+
+$(NAME).tex:
+	touch $@
+
+-include HeveaMakefile

base/sexplib/doc/README.tex

+\documentclass[a4paper]{article}
+
+\usepackage{hevea}
+
+%BEGIN LATEX
+\usepackage{natbib}
+%END LATEX
+
+\newcommand{\mail}{\mailto{opensource@janestreet.com}}
+\newcommand{\homeurl}{http://www.janestreet.com}
+\newcommand{\athome}[2]{\ahref{\homeurl/#1}{#2}}
+\newcommand{\www}{\athome{}{Markus Mottl}}
+
+\newcommand{\ocaml}{\ahref{http://www.ocaml.org}{OCaml}}
+
+\newcommand{\myhref}[1]{\ahref{#1}{#1}}
+\newcommand{\ocsrc}[2]{\athome{ocaml/#1}{#2}}
+\newcommand{\myocsrc}[1]{\athome{ocaml/#1}{#1}}
+
+\newcommand{\janeshort}
+  {\ahref{http://www.janestreet.com}{Jane Street Holding, LLC}}
+
+\newcommand{\trow}[2]{\quad #1 \quad&\quad #2 \quad\\}
+\newcommand{\trowl}[2]{\trow{#1}{#2}\hline}
+
+%BEGIN LATEX
+\newcommand{\theyear}{\number\year}
+%END LATEX
+
+\title{README: library ``Sexplib''}
+\author{
+  Copyright \quad (C) \quad \theyear \quad \janeshort \quad\\
+  Author: Markus Mottl
+}
+\date{New York, 2010-03-31}
+
+% DOCUMENT
+\begin{document}
+\maketitle
+\section{Directory contents}
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline
+\trowl{CHANGES}{History of code changes}
+\trowl{COPYRIGHT}{Notes on copyright}
+\trow{INSTALL}{Short notes on compiling and}
+\trowl{}{installing the library}
+\trowl{LICENSE}{``GNU LESSER GENERAL PUBLIC LICENSE''}
+\trowl{LICENSE.Tywith}{License of Tywith, from which Sexplib is derived}
+\trowl{Makefile}{Top Makefile}
+\trowl{OCamlMakefile}{Generic Makefile for OCaml-projects}
+\trowl{OMakefile}{Ignore this file}
+\trowl{README.txt}{This file}
+\trowl{lib/}{OCaml-library for S-expression conversions}
+\trowl{lib\_test/}{Test applications for the Sexplib-library}
+\end{tabular}
+\end{center}
+
+\section{What is ``Sexplib''?}
+
+This library contains functionality for parsing and pretty-printing
+S-expressions.  In addition to that it contains a preprocessing module for
+Camlp4, which can be used to automatically generate code from type definitions
+for efficiently converting OCaml-values to S-expressions and vice versa.
+In combination with the parsing and pretty-printing functionality this frees
+users from having to write their own I/O-routines for datastructures they
+define.  Possible errors during automatic conversions from S-expressions
+to OCaml-values are reported in human-readable ways with exact location
+information.  Another module in this library allows you to extract and
+replace sub-expressions in S-expressions.
+
+\section{How can you use it?}
+
+Make sure you have installed the \verb=type-conv= package on your system,
+too.  It should be obtainable at the same site as \verb=sexplib=.\\
+\\
+The API (.mli-files) in the \verb=sexplib= library directory is
+fully documented.  Module \verb=Sexp= contains all I/O-functions for
+S-expressions, module \verb=Conv= helper functions for converting
+OCaml-values of standard types to S-expressions.  Module \verb=Path=
+supports sub-expression extraction and substitution.\\
+\\
+Module \verb=pa_sexp_conv.ml= contains the extensions for the
+Camlp4-preprocessor.  It adds the new construct \verb=with sexp=
+(and \verb=with sexp_of= and \verb=with of_sexp=, which are implied by
+the first).  When using this construct right after a type definition,
+function definitions will be generated automatically, which perform
+S-expression conversions.\\
+\\
+E.g.\ given the following type definition:
+
+\begin{verbatim}
+  type t = A | B
+  with sexp
+\end{verbatim}
+
+The above will generate the functions \verb=sexp_of_t= and
+\verb=t_of_sexp=.  The preprocessor also supports automatic addition
+of conversion functions to signatures.  Just add \verb=with sexp= to
+the type in a signature, and the appropriate function signatures will
+be generated.\\
+\\
+Converters for standard types (int, list, Hashtbl.t, etc.) become visible to
+the macro-generated code by opening the standard module before their first
+use in a type definition.  Users will therefore usually want to place the
+following at the top of their files:
+
+\begin{verbatim}
+  open Sexplib.Std
+\end{verbatim}
+
+See the file \verb=lib_test/conv_test.ml= for example usage.  It also
+demonstrates how to extract and substitute sub-expressions.
+
+\subsection{Compiling and linking}
+
+To compile a file you will have to add a preprocessing flag to the
+compiler invocation, e.g. for foo.ml:
+
+\begin{verbatim}
+  ocamlc -pp "camlp4o -I {path to type-conv} \
+    -I {path to sexplib} pa_type_conv.cmo pa_sexp_conv.cmo" \
+    -I {path to sexplib} foo.ml
+\end{verbatim}
+
+If you are using OCamlMakefile, just put the following line at the
+top of the file, assuming you have installed both \verb=type-conv= and
+\verb=sexplib= with ocamlfind.  The comment must start at the beginning of
+the line, and you must not break lines (here broken for readability only):
+
+\begin{verbatim}
+  (*pp camlp4o -I `ocamlfind query type-conv` \
+    -I `ocamlfind query sexplib` \
+    pa_type_conv.cmo pa_sexp_conv.cmo *)
+\end{verbatim}
+
+Don't forget to place the macro \verb=TYPE_CONV_PATH=, which takes a
+string argument, at the top of the file to be preprocessed (see example
+\verb=conv_test.ml=).  It is supposed to set the module path to the given
+module file.  This is necessary, because modules may get packed at a later
+stage, and error messages generated by Sexplib will refer to this location
+to help pinpointing the associated type.\\
+\\
+In the linking stage you will only have to link with \verb=sexplib=.
+E.g.\ when using OCamlMakefile just add it to the \verb=PACKS=-variable.
+
+\section{Syntax Specification of S-expressions}
+
+\subsection{Lexical conventions of S-expression}
+
+Whitespace, which consists of space, newline, carriage return, horizontal
+tab and form feed, is ignored unless within an OCaml-string, where it
+is treated according to OCaml-conventions.  The semicolon introduces
+comments.  Comments are ignored, and range up to the next newline
+character.  The left parenthesis opens a new list, the right parenthesis
+closes it again.  Lists can be empty.  The double quote denotes the
+beginning and end of a string following the lexical conventions of OCaml
+(see OCaml-manual for details).  All characters other than double quotes,
+left- and right parentheses, and whitespace are considered part of a
+contiguous string.
+
+\subsection{Grammar of S-expressions}
+
+S-expressions are either strings (= atoms) or lists. The lists can
+recursively contain further S-expressions or be empty, and must be
+balanced, i.e.\ parentheses must match.
+
+\subsection{Examples}
+
+{\samepage
+\begin{verbatim}
+  this_is_an_atom_123'&^%!  ; this is a comment
+  "another atom in an OCaml-string \"string in a string\" \123"
+
+  ; empty list follows below
+  ()
+
+  ; a more complex example
+  (
+    (
+      list in a list  ; comment within a list
+      (list in a list in a list)
+      42 is the answer to all questions
+    )
+  )
+\end{verbatim}
+}
+
+\subsection{Conversion of basic OCaml-values}
+
+Basic OCaml-values like the unit-value, integers (in all representations),
+floats, strings, and booleans are represented in S-exp syntax in the
+same way as in OCaml.  Strings may also appear without quotes if this
+does not clash with the lexical conventions for S-expressions.
+
+\subsection{Conversion of OCaml-tuples}
+
+OCaml-tuples are simple lists of values in the same order as in the tuple.
+E.g.:
+
+\begin{verbatim}
+  (3.14, "foo", "bar bla", 27) <===> (3.14 foo "bar bla" 27)
+\end{verbatim}
+
+\subsection{Conversion of OCaml-records}
+
+OCaml-records are represented as lists of pairs in S-expression syntax.
+Each pair consists of the name of the record field (first element),
+and its value (second element).  E.g.:
+
+\begin{verbatim}
+  {
+    foo = 3;
+    bar = "some string";
+  }
+
+  <===>
+
+  (
+    (foo 3)
+    (bar "some string")
+  )
+\end{verbatim}
+
+Type specifications of records allow the use of a special type
+\verb=sexp_option= which indicates that a record field should be optional.
+E.g.:
+
+\begin{verbatim}
+  type t =
+    {
+      x : int option;
+      y : int sexp_option;
+    }
+\end{verbatim}
+
+The type \verb=sexp_option= is equivalent to ordinary options, but is
+treated specially by the code generator.  The above would lead to the
+following equivalences of values and S-expressions:
+
+\begin{verbatim}
+  {
+    x = Some 1;
+    y = Some 2;
+  }
+
+  <===>
+
+  (
+    (x (some 1))
+    (y 2)
+  )
+\end{verbatim}
+
+\noindent And:
+
+{\samepage
+\begin{verbatim}
+  {
+    x = None;
+    y = None;
+  }
+
+  <===>
+
+  (
+    (x none)
+  )
+\end{verbatim}
+}
+
+Note how \verb=sexp_option= allows you to leave away record fields
+that should default to \verb=None=.  It is also unnecessary (and
+actually wrong) now to write down such a value as an option, i.e.\
+the \verb=some=-tag must be dropped if the field should be defined.\\
+\\
+The types \verb=sexp_list=, \verb=sexp_array=, and \verb=sexp_bool= can be
+used in ways similar to the type \verb=sexp_option=.  They assume the empty
+list, empty array, and false value respectively as default values.
+
+\subsection{Conversion of sum types}
+
+Constant constructors in sum types are represented as strings.
+Constructors with arguments are represented as lists, the first element
+being the constructor name, the rest being its arguments.  Constructors
+may also be started in lowercase in S-expressions, but will always be
+converted to uppercase when converting from OCaml-values.\\
+\\
+{\samepage
+\noindent For example:
+
+\begin{verbatim}
+  type t = A | B of int * float * t with sexp
+
+  B (42, 3.14, B (-1, 2.72, A)) <===> (B 42 3.14 (B -1 2.72 A))
+\end{verbatim}
+
+\noindent The above example also demonstrates recursion in datastructures.
+}
+
+\subsection{Conversion of variant types}
+
+The conversion of polymorphic variants is almost the same as with
+sum types.  The notable difference is that variant constructors must
+always start with an either lower- or uppercase character, matching
+the way it was specified in the type definition.  This is because OCaml
+also distinguishes between upper- and lowercase variant constructors.
+Note that type specifications containing unions of variant types are
+also supported by the S-expression converter.
+
+\subsection{Conversion of OCaml-lists and arrays}
+
+OCaml-lists and arrays are straightforwardly represented as S-expression
+lists.
+
+\subsection{Conversion of option types}
+
+The option type is converted like ordinary polymorphic sum types, i.e.:
+
+\begin{verbatim}
+  None        <===>  none
+  Some value  <===>  (some value)
+\end{verbatim}
+
+There is a deprecated version of the syntax in which values of option
+type are represented as lists in S-expressions:
+
+\begin{verbatim}
+  None        <===>  ()
+  Some value  <===>  (value)
+\end{verbatim}
+
+Reading of the old-style S-expression syntax for option values is only
+supported if the reference \verb=Conv.read_old_option_format= is set to
+\verb=true= (currently the default, which may change soon).  A conversion
+exception is raised otherwise.  The old format will be written only if
+\verb=Conv.write_old_option_format= is true (also currently the default).
+Reading of the new format is always supported.
+
+\subsection{Conversion of polymorphic values}
+
+There is nothing special about polymorphic values as long as there are
+conversion functions for the type parameters.  E.g.:
+
+\begin{verbatim}
+  type 'a t = A | B of 'a with sexp
+  type foo = int t with sexp
+\end{verbatim}
+
+In the above case the conversion functions will behave as if \verb=foo=
+had been defined as a monomorphic version of \verb=t= with \verb='a=
+replaced by \verb=int= on the right hand side.\\
+\\
+If a datastructure is indeed polymorphic, and you want to convert it,
+you will have to supply the conversion functions for the type parameters
+at runtime.  E.g.\ in the above example, if you wanted to convert a value
+of type \verb='a t=, you would have to write something like this:
+
+\begin{verbatim}
+  sexp_of_t sexp_of_a v
+\end{verbatim}
+
+\noindent where \verb=sexp_of_a=, which may also be named differently in
+this particular case, is a function that converts values of type \verb='a=
+to an S-expression.  Types with more than one parameter require passing
+conversion functions for those parameters in the order of their appearance
+on the left hand side of the type definition.
+
+\subsection{Conversion of abstract datatypes}
+
+Of course, if you want to convert an abstract datatype to an S-expression,
+you will have to roll your own conversion function, which should produce
+values of type \verb=Sexp.t= directly.  If, however, you want to make
+use of your abstract type within definitions of other types, make sure
+that you call your conversion function appropriately: it should be in the
+same scope as the typename, and must be named \verb=sexp_of_{typename}=.
+
+\subsection{Conversion of hashtables}
+
+Hashtables, which are abstract values in OCaml, are represented as
+association lists, i.e.\ lists of key-value pairs, e.g.:
+
+\begin{verbatim}
+  ((foo 42) (bar 3))
+\end{verbatim}
+
+Reading in the above S-expression as hashtable mapping strings to
+integers (\verb=(string, int) Hashtbl.t=) will map \verb="foo"= to $42$
+and \verb="bar"= to $3$.\\
+\\
+Note that the order of elements in the list may matter, because
+duplicates are kept: bindings will be inserted into the hashtable in
+order of appearence.  Therefore, the last binding of a key will be the
+``visible'' one, the others are ``hidden''.  See the OCaml-documentation
+on hashtables for details.\\
+\\
+Note, too, that polymorphic equality may not hold between conversions.
+You will have to use a function implementing logical equality for that
+purpose.
+
+\subsection{Conversion of opaque values}
+
+Opaque values are ones for which we do not want to perform conversions.
+This may be, because we do not have S-expression converters for them,
+or because we do not want to apply them in a particular type context,
+e.g.\ if the resulting S-expression should be printed out but without
+superfluous information.  To prevent the preprocessor from generating
+calls to converters, simply apply the qualifier \verb=sexp_opaque=
+as if it were a type constructor, e.g.:
+
+\begin{verbatim}
+  type foo = int * stuff sexp_opaque with sexp
+\end{verbatim}
+
+Thus, there is no need to specify converters for type \verb=stuff=,
+and if there are any, they will not be used in this particular context.
+Needless to say, it is not possible to convert such an S-expression back
+to the original value.  Here is an example conversion:
+
+\begin{verbatim}
+  (42, some_stuff) ===>  (42, <opaque>)
+\end{verbatim}
+
+\subsection{Conversion of exceptions}
+
+S-expression converters for exceptions can be automatically registered
+using the \verb=with sexp= macro, e.g.:
+
+\begin{verbatim}
+  module M = struct
+    exception Foo of int with sexp
+  end
+\end{verbatim}
+
+Such exceptions will be translated in a similar way as sum types, but
+their constructor will be prefixed with the fully qualified module path
+(here: \verb=M.Foo=) so as to be able to discriminate between them
+without problems.\\
+
+The user can then easily convert an exception matching the above
+one to an S-expression using \verb=Sexplib.Conv.sexp_of_exn=.
+User-defined conversion functions can be registered, too, by calling
+\verb=Sexplib.Conv.add_exn_converter=.  This should make it very
+convenient for users to catch arbitrary exceptions escaping their program
+and pretty-printing them, including all arguments, as S-expressions.
+The library already contains mappings for all known exceptions that can
+escape functions in the OCaml standard library.
+
+\section{I/O and type conversions}
+
+There are multiple ways of performing I/O with S-expressions.  If exact
+error locations are required when type conversions fail, S-expressions need
+to be parsed with location annotations.  In most cases users may want to use
+functions like e.g.\ \verb=load_sexp_conv= or \verb=load_sexp_conv_exn=, which
+load S-expressions from files and convert them.  Only when conversions fail,
+the file will be reparsed with annotations, which is slower, and type errors
+will be reported accurately with file, line number, column, and file position.
+
+\section{Contact information}
+
+\noindent In the case of bugs, feature requests and similar, you can
+contact us here:\\
+
+\hspace{2ex}\mail\\
+
+\noindent Up-to-date information concerning this library should be
+available here:\\
+
+\hspace{2ex}\homeurl/ocaml\\
+
+Enjoy!!\\
+
+\end{document}

base/sexplib/doc/custom.hva

+% INPUT STYLE
+\input{article.hva}
+
+% FANCY SECTION HEADERS WITH NICE COLOURS
+\def\@color{194}
+\input{fancysection.hva}
+
+% FOREGROUND AND BACKGROUND COLOURS
+\renewcommand{\@bodyargs}{TEXT=black BGCOLOR=white}

base/sexplib/doc/hevea.sty

+% hevea  : hevea.sty
+% This is a very basic style file for latex document to be processed
+% with hevea. It contains definitions of LaTeX environment which are
+% processed in a special way by the translator. 
+%  Mostly :
+%     - latexonly, not processed by hevea, processed by latex.
+%     - htmlonly , the reverse.
+%     - rawhtml,  to include raw HTML in hevea output.
+%     - toimage, to send text to the image file.
+% The package also provides hevea logos, html related commands (ahref
+% etc.), void cutting and image commands.
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{hevea}[2002/01/11]
+\RequirePackage{comment}
+\newif\ifhevea\heveafalse
+\@ifundefined{ifimagen}{\newif\ifimagen\imagenfalse}
+\makeatletter%
+\newcommand{\heveasmup}[2]{%
+\raise #1\hbox{$\m@th$%
+  \csname S@\f@size\endcsname
+  \fontsize\sf@size 0%
+  \math@fontsfalse\selectfont
+#2%
+}}%
+\DeclareRobustCommand{\hevea}{H\kern-.15em\heveasmup{.2ex}{E}\kern-.15emV\kern-.15em\heveasmup{.2ex}{E}\kern-.15emA}%
+\DeclareRobustCommand{\hacha}{H\kern-.15em\heveasmup{.2ex}{A}\kern-.15emC\kern-.1em\heveasmup{.2ex}{H}\kern-.15emA}%
+\DeclareRobustCommand{\html}{\protect\heveasmup{0.ex}{HTML}}
+%%%%%%%%% Hyperlinks hevea style
+\newcommand{\ahref}[2]{{#2}}
+\newcommand{\ahrefloc}[2]{{#2}}
+\newcommand{\aname}[2]{{#2}}
+\newcommand{\ahrefurl}[1]{\texttt{#1}}
+\newcommand{\footahref}[2]{#2\footnote{\texttt{#1}}}
+\newcommand{\mailto}[1]{\texttt{#1}}
+\newcommand{\imgsrc}[2][]{}
+\newcommand{\home}[1]{\protect\raisebox{-.75ex}{\char126}#1}
+\AtBeginDocument
+{\@ifundefined{url}
+{%url package is not loaded
+\let\url\ahref\let\oneurl\ahrefurl\let\footurl\footahref}
+{}}
+%% Void cutting instructions
+\newcounter{cuttingdepth}
+\newcommand{\tocnumber}{}
+\newcommand{\notocnumber}{}
+\newcommand{\cuttingunit}{}
+\newcommand{\cutdef}[2][]{}
+\newcommand{\cuthere}[2]{}
+\newcommand{\cutend}{}
+\newcommand{\htmlhead}[1]{}
+\newcommand{\htmlfoot}[1]{}
+\newcommand{\htmlprefix}[1]{}
+\newenvironment{cutflow}[1]{}{}
+\newcommand{\cutname}[1]{}
+\newcommand{\toplinks}[3]{}
+%%%% Html only
+\excludecomment{rawhtml}
+\newcommand{\rawhtmlinput}[1]{}
+\excludecomment{htmlonly}
+%%%% Latex only
+\newenvironment{latexonly}{}{}
+\newenvironment{verblatex}{}{}
+%%%% Image file stuff
+\def\toimage{\endgroup}
+\def\endtoimage{\begingroup\def\@currenvir{toimage}}
+\def\verbimage{\endgroup}
+\def\endverbimage{\begingroup\def\@currenvir{verbimage}}
+\newcommand{\imageflush}[1][]{}
+%%% Bgcolor definition
+\newsavebox{\@bgcolorbin}
+\newenvironment{bgcolor}[2][]
+  {\newcommand{\@mycolor}{#2}\begin{lrbox}{\@bgcolorbin}\vbox\bgroup}
+  {\egroup\end{lrbox}%
+   \begin{flushleft}%
+   \colorbox{\@mycolor}{\usebox{\@bgcolorbin}}%
+   \end{flushleft}}
+%%% Postlude
+\makeatother

base/sexplib/lib/conv.ml

-(*  Utility Module for S-expression Conversions *)
+(* Utility Module for S-expression Conversions *)
 
 open Printf
 open Bigarray
 let sexp_of_num n = Atom (Num.string_of_num n)
 let sexp_of_ratio n = Atom (Ratio.string_of_ratio n)
 let sexp_of_ref sexp_of__a rf = sexp_of__a !rf
-let sexp_of_lazy sexp_of__a lv = sexp_of__a (Lazy.force lv)
+let sexp_of_lazy_t sexp_of__a lv = sexp_of__a (Lazy.force lv)
 
 let sexp_of_option sexp_of__a = function
   | Some x when !write_old_option_format -> List [sexp_of__a x]
   | List _ -> of_sexp_error "ratio_of_sexp: atom needed" sexp
 
 let ref_of_sexp a__of_sexp sexp = ref (a__of_sexp sexp)
-let lazy_of_sexp a__of_sexp sexp = lazy (a__of_sexp sexp)
+let lazy_t_of_sexp a__of_sexp sexp = Lazy.lazy_from_val (a__of_sexp sexp)
 
 let option_of_sexp a__of_sexp sexp =
   if !read_old_option_format then
   with e ->
     failwith (sprintf "of_string failed on %s with %s" s (exn_to_string e))
 
+(* Registering default exception printers *)
+
 let get_flc_error name (file, line, chr) =
-  (List [Atom name; Atom file; sexp_of_int line; sexp_of_int chr])
+  List [Atom name; Atom file; sexp_of_int line; sexp_of_int chr]
 
-(* Registering default exception printers *)
 let () =
   List.iter
     (fun (exc, handler) -> Exn_converter.add_auto ~finalise:false exc handler)
         | Parse_error pe ->
             let ppos =
               match pe.parse_state with
-              | `Sexp { parse_pos = parse_pos }
-              | `Annot { parse_pos = parse_pos } -> parse_pos
+              | `Sexp { parse_pos } | `Annot { parse_pos } -> parse_pos
             in
             List [
               Atom "Sexplib.Sexp.Parse_error";

base/sexplib/lib/conv.mli

 (** [sexp_of_ratio n] converts the value [n] of type [Ratio.ratio] to an
     S-expression. *)
 
-val sexp_of_ref : ('a -> 'b) -> 'a ref -> 'b
+val sexp_of_ref : ('a -> Sexp.t) -> 'a ref -> Sexp.t
 (** [sexp_of_ref conv r] converts the value [r] of type ['a ref] to
     an S-expression.  Uses [conv] to convert values of type ['a] to an
     S-expression. *)
 
-val sexp_of_lazy : ('a -> 'b) -> 'a lazy_t -> 'b
-(** [sexp_of_ref conv l] converts the value [l] of type ['a lazy_t] to
+val sexp_of_lazy_t : ('a -> Sexp.t) -> 'a lazy_t -> Sexp.t
+(** [sexp_of_lazy_t conv l] converts the value [l] of type ['a lazy_t] to
     an S-expression.  Uses [conv] to convert values of type ['a] to an
     S-expression. *)
 
     to convert the hashtable keys of type ['a], and [conv_value] to
     convert hashtable values of type ['b] to S-expressions. *)
 
-val bigstring_of_sexp : Sexp.t -> bigstring
-
 val sexp_of_bigstring : bigstring -> Sexp.t
 (** [sexp_of_bigstring bstr] converts a bigstring (character bigarray
     in C-layout) to an S-expression. *)
     S-expression.  This means the user need not provide converters,
     but the result cannot be interpreted. *)
 
-val sexp_of_fun : _ -> Sexp.t
+val sexp_of_fun : ('a -> 'b) -> Sexp.t
 (** [sexp_of_fun f] converts the value [f] of function type to a
     dummy S-expression.  Functions cannot be serialized as S-expressions,
     but at least a placeholder can be generated for pretty-printing. *)
     of type ['a ref] using conversion function [conv], which converts
     an S-expression to a value of type ['a]. *)
 
-val lazy_of_sexp : (Sexp.t -> 'a) -> Sexp.t -> 'a lazy_t
-(** [lazy_of_sexp conv sexp] converts S-expression [sexp] to a value
+val lazy_t_of_sexp : (Sexp.t -> 'a) -> Sexp.t -> 'a lazy_t
+(** [lazy_t_of_sexp conv sexp] converts S-expression [sexp] to a value
     of type ['a lazy_t] using conversion function [conv], which converts
     an S-expression to a value of type ['a]. *)
 
     key of type ['a], and function [conv_value], which converts an
     S-expression to hashtable value of type ['b]. *)
 
+val bigstring_of_sexp : Sexp.t -> bigstring
+(** [bigstring_of_sexp sexp] converts S-expression [sexp] to a
+    bigstring (character bigarray in C-layout). *)
+
 val float32_vec_of_sexp : Sexp.t -> float32_vec
 (** [float32_vec_of_sexp sexp] converts S-expression [sexp] to a
     one-dimensional bigarray of 32-bit floats in Fortran-layout. *)

base/sexplib/lib/lexer.mll

 
 rule main buf = parse
   | newline { found_newline lexbuf 1; main buf lexbuf }
-  | space+ { main buf lexbuf }
-  | ';' [^ '\n' '\r']* { main buf lexbuf }
+  | space+ | ';' [^ '\n' '\r']* { main buf lexbuf }
   | '(' { LPAREN }
   | ')' { RPAREN }
   | '"'

base/sexplib/lib/pre_sexp.ml

 
 (* Output of S-expressions to file *)
 
-(* The temporary functions in ocaml Filename module don't allow to
-   pass in the permission. Opening a file with a given permission is different
-   than opening it and chmoding it to that permission because the umask is
-   taken in account. Under unix there's no easy way to get the umask in a
-   threadsafe way.
-*)
+(* The temp file functions in the OCaml Filename module do not support
+   permissions.  But opening a file with given permissions is different
+   from opening it and chmoding it to these permissions, because the umask
+   is taken in account.  Under Unix there's no easy way to get the umask in
+   a thread-safe way. *)
 module Tmp_file = struct
   let prng = ref None
 
   let temp_file_name prefix suffix =
     let rand_state = match !prng with
-    | None ->
-      let ret = Random.State.make_self_init () in
-      prng := Some ret;
-      ret
-    | Some v -> v
+      | Some v -> v
+      | None ->
+          let ret = Random.State.make_self_init () in
+          prng := Some ret;
+          ret
     in
     let rnd = (Random.State.bits rand_state) land 0xFFFFFF in
     Printf.sprintf "%s%06x%s" prefix rnd suffix
 
-  let open_temp_file ?(perm=0o666) prefix suffix =
+  let open_temp_file ?(perm = 0o600) prefix suffix =
     let rec try_name counter =
       let name = temp_file_name prefix suffix in
       try
-        (name,
-         open_out_gen [Open_wronly;Open_creat;Open_excl;Open_text] perm name)
+        let oc =
+          open_out_gen [Open_wronly; Open_creat; Open_excl; Open_text] perm name
+        in
+        name, oc
       with Sys_error _ as e ->
         if counter >= 1000 then raise e else try_name (counter + 1)
-    in try_name 0
-
+    in
+    try_name 0
 end
 
 let save_of_output ?perm output_function file sexp =
     try
       output_function oc sexp;
       close_out oc;
-    with
-      e ->
-        close_out_noerr oc;
-        (try
-           Sys.remove tmp_name;
-         with _ -> ());
-        raise e
+    with e ->
+      close_out_noerr oc;
+      begin try Sys.remove tmp_name with _ -> () end;
+      raise e
   end;
   Sys.rename tmp_name file
 
     else if text_char < 0 then fail "text_char < 0"
     else if global_offset < 0 then fail "global_offset < 0"
     else if buf_pos < 0 then fail "buf_pos < 0"
-    else
-      {
-        text_line = text_line;
-        text_char = text_char;
-        global_offset = global_offset;
-        buf_pos = buf_pos;
-      }
+    else { text_line; text_char; global_offset; buf_pos }
 
-  let with_buf_pos t buf_pos = { t with buf_pos = buf_pos }
+  let with_buf_pos t buf_pos = { t with buf_pos }
 end
 
 type ('a, 't) parse_result =
 
 exception Parse_error of parse_error
 
-let bump_text_line { parse_pos = parse_pos } =
+let bump_text_line { parse_pos } =
   parse_pos.Parse_pos.text_line <- parse_pos.Parse_pos.text_line + 1;
   parse_pos.Parse_pos.text_char <- 0
 
-let bump_text_pos { parse_pos = parse_pos } =
+let bump_text_pos { parse_pos } =
   parse_pos.Parse_pos.text_char <- parse_pos.Parse_pos.text_char + 1
 
 let bump_pos_cont state str ~max_pos ~pos cont =
   parse_pos.Parse_pos.buf_pos <- buf_pos;
   parse_pos.Parse_pos.global_offset <- parse_pos.Parse_pos.global_offset + len
 
-let mk_parse_pos { parse_pos = parse_pos } buf_pos =
+let mk_parse_pos { parse_pos } buf_pos =
   set_parse_pos parse_pos buf_pos;
   parse_pos
 
 let raise_parse_error parse_state location buf_pos err_msg =
   begin
     match parse_state with
-    | `Sexp { parse_pos = parse_pos }
-    | `Annot { parse_pos = parse_pos } ->
+    | `Sexp { parse_pos } | `Annot { parse_pos } ->
         set_parse_pos parse_pos buf_pos;
         parse_pos.Parse_pos.text_char <- parse_pos.Parse_pos.text_char + 1;
   end;
-  let parse_error =
-    {
-      location = location;
-      err_msg = err_msg;
-      parse_state = parse_state;
-    }
-  in
+  let parse_error = { location; err_msg; parse_state } in
   raise (Parse_error parse_error)
 
 let raise_unexpected_char parse_state location buf_pos c =
     let max_pos = check_str_bounds "parse" ~pos ~len str in \
     let state = \
       { \
-        parse_pos = parse_pos; \
+        parse_pos; \
         pstack = INIT_PSTACK; \
         pbuf = Buffer.create 128; \
       } \
 
 let mk_annot_pos
       ({ Parse_pos.text_line = line; text_char = col } as parse_pos) pos =
-  let offset = get_glob_ofs parse_pos pos in
-  { Annot.line = line; col = col; offset = offset }
+  { Annot.line; col; offset = get_glob_ofs parse_pos pos }
 
 let mk_annot_pos1
       ({ Parse_pos.text_line = line; text_char = col } as parse_pos) pos =
-  let offset = get_glob_ofs parse_pos pos in
-  { Annot.line = line; col = col + 1; offset = offset }
+  { Annot.line; col = col + 1; offset = get_glob_ofs parse_pos pos }
 
-let add_annot_pos { parse_pos = parse_pos; pstack = pstack } pos =
-  pstack.Annot.positions <-
-    mk_annot_pos parse_pos pos :: pstack.Annot.positions
+let add_annot_pos { parse_pos; pstack } pos =
+  pstack.Annot.positions <- mk_annot_pos parse_pos pos :: pstack.Annot.positions
 
-let add_annot_pos1 { parse_pos = parse_pos; pstack = pstack } pos =
+let add_annot_pos1 { parse_pos; pstack } pos =
   pstack.Annot.positions <-
     mk_annot_pos1 parse_pos pos :: pstack.Annot.positions
 
-let get_annot_range { parse_pos = parse_pos; pstack = pstack } pos =
+let get_annot_range { parse_pos; pstack } pos =
   let start_pos =
     match pstack.Annot.positions with
     | [] -> assert false  (* impossible *)
       offset = get_glob_ofs parse_pos pos;
     }
   in
-  { Annot.start_pos = start_pos; end_pos = end_pos }
+  { Annot.start_pos; end_pos }
 
 let mk_annot_atom parse_state str pos =
   Annot.Atom (get_annot_range parse_state pos, Atom str)
   let parse_pos =
     match parse_pos with
     | None -> Parse_pos.create ~buf_pos:pos ()
-    | Some parse_pos -> Parse_pos.with_buf_pos parse_pos pos
+    | Some parse_pos -> parse_pos.Parse_pos.buf_pos <- pos; parse_pos
   in
   my_parse ?parse_pos:(Some parse_pos) ?len:(Some len) str
 
   let rec loop this_parse ~pos ~len ~is_incomplete =
     if len > 0 then
       match this_parse ~pos ~len buf with
-      | Done (sexp, ({ Parse_pos.buf_pos = buf_pos } as parse_pos)) ->
+      | Done (sexp, ({ Parse_pos.buf_pos } as parse_pos)) ->
           rev_sexps_ref := sexp :: !rev_sexps_ref;
           let n_parsed = buf_pos - pos in
           let this_parse = mk_this_parse ~parse_pos my_parse in
 
 let of_string_bigstring loc this_parse ws_buf get_len get_sub str =
   match this_parse str with
-  | Done (_, { Parse_pos.buf_pos = buf_pos }) when buf_pos <> get_len str ->
+  | Done (_, { Parse_pos.buf_pos }) when buf_pos <> get_len str ->
       let prefix_len = min (get_len str - buf_pos) 20 in
       let prefix = get_sub str buf_pos prefix_len in
       let msg =
       failwith (sprintf "Sexplib.Sexp.gen_load_sexp: end of file: %s" file)
     else
       match this_parse ~pos:0 ~len buf with
-      | Done (sexp, ({ Parse_pos.buf_pos = buf_pos } as parse_pos))
+      | Done (sexp, ({ Parse_pos.buf_pos } as parse_pos))
         when strict ->
           let rec strict_loop this_parse ~pos ~len =
             match this_parse ~pos ~len buf with
 
   let get_conv_exn ~file ~exc annot_sexp =
     let range = get_range annot_sexp in
-    let { start_pos = start_pos } = range in
-    let { line = sline; col = scol } = start_pos in
-    let loc = sprintf "%s:%d:%d" file sline scol in
+    let { start_pos = { line; col } } = range in
+    let loc = sprintf "%s:%d:%d" file line col in
     Of_sexp_error (Annot.Conv_exn (loc, exc), get_sexp annot_sexp)
 end
 
 let load_sexps_conv ?(buf = String.create 8192) file f =
   let rev_sexps = load_rev_sexps ~buf file in
   try List.rev_map (fun sexp -> `Result (f sexp)) rev_sexps
-  with Of_sexp_error (e, s) ->
-    let rev_annot_sexps = Annotated.load_rev_sexps ~buf file in
-    if 0 = List.length rev_annot_sexps then
-      (* File is now empty - perhaps it was a temporary file handle? *)
-      raise (Of_sexp_error (e, s))
-    else
-      List.rev_map (fun annot_sexp -> Annotated.conv f annot_sexp) rev_annot_sexps
+  with Of_sexp_error _ as e ->
+    match Annotated.load_rev_sexps ~buf file with
+    | [] ->
+        (* File is now empty - perhaps it was a temporary file handle? *)
+        raise e
+    | rev_annot_sexps ->
+        List.rev_map (fun annot_sexp -> Annotated.conv f annot_sexp)
+          rev_annot_sexps
 
 let load_sexps_conv_exn ?(buf = String.create 8192) file f =
   let rev_sexps = load_rev_sexps ~buf file in
   try List.rev_map f rev_sexps
-  with Of_sexp_error (e,s) ->
-    let rev_annot_sexps = Annotated.load_rev_sexps ~buf file in
-    if List.length rev_annot_sexps = 0 then
-      (* File is now empty - perhaps it was a temporary file handle? *)
-      raise (Of_sexp_error (e,s))
-    else
-      List.rev_map
-        (fun annot_sexp -> raise_conv_exn ~file (Annotated.conv f annot_sexp))
-        rev_annot_sexps
+  with Of_sexp_error _ as e ->
+    match Annotated.load_rev_sexps ~buf file with
+    | [] ->
+        (* File is now empty - perhaps it was a temporary file handle? *)
+        raise e
+    | rev_annot_sexps ->
+        List.rev_map
+          (fun annot_sexp -> raise_conv_exn ~file (Annotated.conv f annot_sexp))
+          rev_annot_sexps
 
 let gen_of_string_conv of_string annot_of_string str f =
   let sexp = of_string str in
   let sexp = of_string str in
   try f sexp
   with Of_sexp_error (exc, sub_sexp) ->
-    raise (
-      Of_string_conv_exn.E {
-        Of_string_conv_exn.exc = exc;
-        sexp = sexp;
-        sub_sexp = sub_sexp;
-      })
+    raise (Of_string_conv_exn.E { Of_string_conv_exn.exc; sexp; sub_sexp })
 
 let of_string_conv_exn str f = gen_of_string_conv_exn of_string str f
 let of_bigstring_conv_exn bstr f = gen_of_string_conv_exn of_bigstring bstr f

base/sexplib/lib/sexp_intf.ml

   val to_buffer : buf : Buffer.t -> t -> unit
   (** [to_buffer ~buf sexp] same as {!to_buffer_mach}. *)
 
-  val to_buffer_gen : 
+  val to_buffer_gen :
        buf : 'buffer
     -> add_char : ('buffer -> char -> unit)
     -> add_string : ('buffer -> string -> unit)
     -> t
     -> unit
+  (** [to_buffer_gen ~buf ~add_char ~add_string sexp] outputs the S-expression
+      [sexp] converted to a string to buffer [buf] using the output functions
+      [add_char] and [add_string]. *)
+
 
   (** {6 Utilities for automated type conversions} *)
 

base/sexplib/lib/std.ml

 module Hashtbl = struct
   include Hashtbl
+
   let sexp_of_t = Conv.sexp_of_hashtbl
   let t_of_sexp = Conv.hashtbl_of_sexp
 end
+
 module Big_int = struct
   include Big_int
+
   let sexp_of_big_int = Conv.sexp_of_big_int
   let big_int_of_sexp = Conv.big_int_of_sexp
 end
+
 module Nat = struct
   include Nat
+
   let sexp_of_nat = Conv.sexp_of_nat
   let nat_of_sexp = Conv.nat_of_sexp
 end
+
 module Num = struct
   include Num
+
   let sexp_of_num = Conv.sexp_of_num
   let num_of_sexp = Conv.num_of_sexp
 end
+
 module Ratio = struct
   include Ratio
+
   let sexp_of_ratio = Conv.sexp_of_ratio
   let ratio_of_sexp = Conv.ratio_of_sexp
 end
+
 module Lazy = struct
-  include Lazy 
+  include Lazy
 
-  let t_of_sexp = Conv.lazy_of_sexp
-  let sexp_of_t = Conv.sexp_of_lazy
+  let t_of_sexp = Conv.lazy_t_of_sexp
+  let sexp_of_t = Conv.sexp_of_lazy_t
 end
-let lazy_t_of_sexp  = Conv.lazy_of_sexp
-let sexp_of_lazy_t  = Conv.sexp_of_lazy
+
+let sexp_of_unit = Conv.sexp_of_unit
+let unit_of_sexp = Conv.unit_of_sexp
+
+let sexp_of_bool = Conv.sexp_of_bool
+let bool_of_sexp = Conv.bool_of_sexp
+
+let sexp_of_string = Conv.sexp_of_string
+let string_of_sexp = Conv.string_of_sexp
+
+let sexp_of_char = Conv.sexp_of_char
+let char_of_sexp = Conv.char_of_sexp
+
+let sexp_of_int = Conv.sexp_of_int
+let int_of_sexp = Conv.int_of_sexp
+
+let sexp_of_float = Conv.sexp_of_float
+let float_of_sexp = Conv.float_of_sexp
+
+let sexp_of_int32 = Conv.sexp_of_int32
+let int32_of_sexp = Conv.int32_of_sexp
+
+let sexp_of_int64 = Conv.sexp_of_int64
+let int64_of_sexp = Conv.int64_of_sexp
+
+let sexp_of_nativeint = Conv.sexp_of_nativeint
+let nativeint_of_sexp = Conv.nativeint_of_sexp
+
+let sexp_of_ref = Conv.sexp_of_ref
+let ref_of_sexp = Conv.ref_of_sexp
+
+let sexp_of_lazy_t = Conv.sexp_of_lazy_t
+let lazy_t_of_sexp = Conv.lazy_t_of_sexp
+
+let sexp_of_option = Conv.sexp_of_option
+let option_of_sexp = Conv.option_of_sexp
+
+let sexp_of_list = Conv.sexp_of_list
+let list_of_sexp = Conv.list_of_sexp
+
 let sexp_of_array = Conv.sexp_of_array
 let array_of_sexp = Conv.array_of_sexp
-let sexp_of_bool = Conv.sexp_of_bool
-let bool_of_sexp = Conv.bool_of_sexp
-let sexp_of_char = Conv.sexp_of_char
-let char_of_sexp = Conv.char_of_sexp
+
 let sexp_of_exn = Conv.sexp_of_exn
-let sexp_of_float = Conv.sexp_of_float
-let float_of_sexp = Conv.float_of_sexp
-let sexp_of_int = Conv.sexp_of_int
-let int_of_sexp = Conv.int_of_sexp
-let sexp_of_int32 = Conv.sexp_of_int32
-let int32_of_sexp = Conv.int32_of_sexp
-let sexp_of_int64 = Conv.sexp_of_int64
-let int64_of_sexp = Conv.int64_of_sexp
-let sexp_of_list = Conv.sexp_of_list
-let list_of_sexp = Conv.list_of_sexp
-let sexp_of_nativeint = Conv.sexp_of_nativeint
-let nativeint_of_sexp = Conv.nativeint_of_sexp
-let sexp_of_option = Conv.sexp_of_option
-let option_of_sexp = Conv.option_of_sexp
-let sexp_of_string = Conv.sexp_of_string
-let string_of_sexp = Conv.string_of_sexp
-let ref_of_sexp    = Conv.ref_of_sexp
-let sexp_of_ref    = Conv.sexp_of_ref
-let unit_of_sexp   = Conv.unit_of_sexp
-let sexp_of_unit   = Conv.sexp_of_unit

base/sexplib/oasis.sh

 OASISFormat:  0.2
 OCamlVersion: >= 3.12
 Name:         sexplib
-Version:      5.2.2
+Version:      7.0.4
 Synopsis:     automated S-expression conversion
 Authors:      Markus Mottl,
               Martin Sandin
 Plugins:      StdFiles (0.2),
               DevFiles (0.2),
               META (0.2)
-BuildTools:   ocamlbuild, ocamllex, ocamlyacc
+BuildTools:   ocamlbuild
 XStdFilesAUTHORS: false
 XStdFilesINSTALLFilename: INSTALL
 XStdFilesREADME: false
                       Pre_sexp,
                       Sexp_intf,
                       Sexp,
-                      Std,
                       Path,
                       Conv,
                       Conv_error,
-                      Exn_magic
+                      Exn_magic,
+                      Std
   BuildDepends:       unix,bigarray,num
 #  XMETAType:          library
   XMETARequires:      unix,bigarray,num
 
 Library pa_sexp_conv
   Path:               syntax
+  FindlibName:        syntax
+  FindlibParent:      sexplib
   Modules:            Pa_sexp_conv
-  FindlibParent:      sexplib
-  FindlibName:        syntax
-  BuildDepends:       camlp4.lib,
-                      camlp4.quotations,
-                      type-conv (>= 2.0.1)
+  BuildDepends:       camlp4.quotations,camlp4.extend,type-conv (>= 3.0.4)
   CompiledObject:     byte
   XMETAType:          syntax
   XMETARequires:      camlp4,type-conv,sexplib
   XMETADescription:   Syntax extension for Sexplib
 
-#Library sexplib_top
-#  Path:               top
-#  FindlibParent:      sexplib
-#  FindlibName:        top
+Library sexplib_top
+  Path:               top
+  FindlibName:        top
+  FindlibParent:      sexplib
+  Modules:            Install_printers
+  XMETARequires:      sexplib
+  XMETADescription:   Toplevel printers for S-expressions
 
 # TODO: figure out how to build tests without installing sexplib
 Flag tests
 $(tag_for_pack Sexplib $HERE/lib/*.ml{,l,y})
 
 <lib/pre_sexp.ml>: pp(cpp -undef -traditional -Werror -I$HERE/syntax)
-<lib_test/*.ml{,i}>: syntax_camlp4o
+<lib_test/*.ml{,i}>: syntax_camlp4o, pkg_type-conv.syntax
+<lib_test/conv_test.byte>: use_sexplib, pkg_unix, pkg_num, pkg_bigarray
 <syntax/pa_sexp_conv.ml>: syntax_camlp4o
 EOF
 
+make_myocamlbuild $HERE/myocamlbuild.ml <<EOF
+Ocamlbuild_plugin.dispatch
+  begin
+    function
+      | After_rules as e ->
+          flag ["ocamldep"; "ocaml"; "use_pa_sexp_conv"]
+            (S [A "-ppopt"; P "syntax/pa_sexp_conv.cma"]);
+          flag ["compile"; "ocaml"; "use_pa_sexp_conv"]
+            (S [A "-ppopt"; P "syntax/pa_sexp_conv.cma"]);
+          dispatch_default e
+      | e -> dispatch_default e
+  end
+;;
+EOF
+
 cd $HERE
 oasis setup
 enable_pack_in_setup_ml sexplib
 
 ./configure "$@"
-

base/sexplib/syntax/pa_sexp_conv.ml

 
 open Camlp4
 open PreCast
+
 module Gen = Pa_type_conv.Gen
 
 (* Utility functions *)
+
 let mk_rev_bindings loc fps =
   let coll (i, bindings, patts, vars) fp =
     let name = "v" ^ string_of_int i in
-    let var_expr = Gen.ide loc name in
+    let var_expr = <:expr@loc< $lid:name$ >> in
     let expr =
       match fp with
       | `Fun fun_expr -> <:expr@loc< $fun_expr$ $var_expr$ >>
       | `Match matchings -> <:expr@loc< match $var_expr$ with [ $matchings$ ] >>
     in
-    let patt = Gen.idp loc name in
+    let patt = <:patt@loc< $lid:name$ >> in
     let bindings = <:binding@loc< $patt$ = $expr$ and $bindings$ >> in
     i - 1, bindings, patt :: patts, var_expr :: vars
   in
 let unroll_fun_matches loc fp1 fp2 =
   match fp1, fp2 with
   | `Fun fun_expr1, `Fun fun_expr2 ->
-    <:expr@loc< $fun_expr1$ $fun_expr2$ >>
+      <:expr@loc< $fun_expr1$ $fun_expr2$ >>
   | `Fun fun_expr, `Match matching ->
-    <:expr@loc< $fun_expr$ (fun [ $matching$ ]) >>
+      <:expr@loc< $fun_expr$ (fun [ $matching$ ]) >>
   | _ -> assert false  (* impossible *)
 
 let rec sig_of_tds cnv = function
 
   let rec sig_of_td__loop acc = function
     | [] ->
-      let loc = Ast.loc_of_ctyp acc in
-      <:ctyp@loc< $acc$ -> Sexplib.Sexp.t >>
+        let loc = Ast.loc_of_ctyp acc in
+        <:ctyp@loc< $acc$ -> Sexplib.Sexp.t >>
     | tp :: tps ->
-      let tp = Gen.drop_variance_annotations tp in
-      let loc = Ast.loc_of_ctyp tp in
-      let sexp_of = sig_of_td__loop <:ctyp@loc< $acc$ $tp$ >> tps in
-      <:ctyp@loc< ( $tp$ -> Sexplib.Sexp.t ) -> $sexp_of$ >>
+        let tp = Gen.drop_variance_annotations tp in
+        let loc = Ast.loc_of_ctyp tp in
+        let sexp_of = sig_of_td__loop <:ctyp@loc< $acc$ $tp$ >> tps in
+        <:ctyp@loc< ( $tp$ -> Sexplib.Sexp.t ) -> $sexp_of$ >>
 
   let sig_of_td loc type_name tps _rhs _cl =
     let sexp_of = sig_of_td__loop <:ctyp@loc< $lid:type_name$ >> tps in
     <:sig_item@loc< value $lid: "sexp_of_" ^ type_name$ : $sexp_of$ >>
 
-  let mk_sig tds =
-    <:sig_item< $sig_of_tds sig_of_td tds$ >>
+  let mk_sig tds = <:sig_item< $sig_of_tds sig_of_td tds$ >>
 
   let () = Pa_type_conv.add_sig_generator "sexp_of" mk_sig
 
     | <:ctyp< $id:_$ >>
     | <:ctyp< >> -> `Maybe
     | <:ctyp< $tp1$ == $tp2$ >> ->
-      begin match is_polymorphic_variant tp1 with
-      | (`Surely_not | `Definitely) as res -> res
-      | `Maybe -> is_polymorphic_variant tp2 end
+        begin match is_polymorphic_variant tp1 with
+        | (`Surely_not | `Definitely) as res -> res
+        | `Maybe -> is_polymorphic_variant tp2 end
     | tp -> Gen.unknown_type tp "Sig_generate_of_sexp.is_polymorphic_variant"
 
   let rec sig_of_td__loop acc = function
     | [] ->
-      let loc = Ast.loc_of_ctyp acc in
-      <:ctyp@loc< Sexplib.Sexp.t -> $acc$ >>
+        let loc = Ast.loc_of_ctyp acc in
+        <:ctyp@loc< Sexplib.Sexp.t -> $acc$ >>
     | tp :: tps ->
-      let tp = Gen.drop_variance_annotations tp in
-      let loc = Ast.loc_of_ctyp tp in
-      let of_sexp = sig_of_td__loop <:ctyp@loc< $acc$ $tp$ >> tps in
-      <:ctyp@loc< ( Sexplib.Sexp.t -> $tp$ ) -> $of_sexp$ >>
+        let tp = Gen.drop_variance_annotations tp in
+        let loc = Ast.loc_of_ctyp tp in
+        let of_sexp = sig_of_td__loop <:ctyp@loc< $acc$ $tp$ >> tps in
+        <:ctyp@loc< ( Sexplib.Sexp.t -> $tp$ ) -> $of_sexp$ >>
 
   let sig_of_td with_poly loc type_name tps rhs _cl =
     let of_sexp = sig_of_td__loop <:ctyp@loc< $lid:type_name$ >> tps in
     in
     match with_poly, is_polymorphic_variant rhs with
     | true, `Surely_not ->
-      Gen.error rhs ~fn:"Sig_generate_of_sexp.sig_of_td"
-        ~msg:"sexp_poly annotation \
-          but type is surely not a polymorphic variant"
+        Gen.error rhs ~fn:"Sig_generate_of_sexp.sig_of_td"
+          ~msg:"sexp_poly annotation \
+            but type is surely not a polymorphic variant"
     | false, (`Surely_not | `Maybe) -> of_sexp_item
     | (true | false), `Definitely | true, `Maybe ->
         <:sig_item@loc<
 (* Generator for converters of OCaml-values to S-expressions *)
 module Generate_sexp_of = struct
   let mk_abst_call loc tn rev_path =
-    <:expr@loc< $id:Gen.ident_of_rev_path loc (("sexp_of_" ^ tn) :: rev_path)$ >>
+    <:expr@loc<
+      $id:Gen.ident_of_rev_path loc (("sexp_of_" ^ tn) :: rev_path)$
+    >>
 
   (* Conversion of type paths *)
   let sexp_of_path_fun loc id =
   (* Conversion of types *)
   let rec sexp_of_type = function
     | <:ctyp@loc< sexp_opaque $_$ >> ->
-      `Fun <:expr@loc< Sexplib.Conv.sexp_of_opaque >>
+        `Fun <:expr@loc< Sexplib.Conv.sexp_of_opaque >>
     | <:ctyp@loc< $tp1$ $tp2$ >> -> `Fun (sexp_of_appl_fun loc tp1 tp2)
     | <:ctyp< ( $tup:tp$ ) >> -> sexp_of_tuple tp
-    | <:ctyp@loc< '$parm$ >> -> `Fun (Gen.ide loc ("_of_" ^ parm))
+    | <:ctyp@loc< '$parm$ >> -> `Fun <:expr@loc< $lid:"_of_" ^ parm$ >>
     | <:ctyp@loc< $id:id$ >> -> `Fun (sexp_of_path_fun loc id)
-    | <:ctyp@loc< $_$ -> $_$ >> -> `Fun <:expr@loc< Sexplib.Conv.sexp_of_fun >>
+    | <:ctyp@loc< $_$ -> $_$ >> as arrow ->
+        `Fun <:expr@loc< fun (_f : $arrow$) ->
+          Sexplib.Conv.sexp_of_fun Pervasives.ignore >>
     | <:ctyp< [< $row_fields$ ] >> | <:ctyp< [> $row_fields$ ] >>
     | <:ctyp< [= $row_fields$ ] >> -> sexp_of_variant row_fields
     | <:ctyp< ! $parms$ . $poly_tp$ >> -> sexp_of_poly parms poly_tp
     let expr = <:expr@loc< let $bindings$ in $in_expr$ >> in
     `Match <:match_case@loc< ( $tup:Ast.paCom_of_list patts$ ) -> $expr$ >>
 
+
   (* Conversion of variant types *)
+
   and mk_cnv_expr tp =
     let loc = Ast.loc_of_ctyp tp in
     match sexp_of_type tp with
   and sexp_of_variant row_fields =
     let rec loop = function
       | <:ctyp@loc< $tp1$ | $tp2$ >> ->
-        <:match_case@loc< $loop tp1$ | $loop tp2$ >>
+          <:match_case@loc< $loop tp1$ | $loop tp2$ >>
       | <:ctyp@loc< `$cnstr$ >> ->
           <:match_case@loc< `$cnstr$ -> Sexplib.Sexp.Atom $str:cnstr$ >>
       | <:ctyp@loc< `$cnstr$ of sexp_list $tp$>> ->
     let loc = Ast.loc_of_ctyp tp in
     let bindings =
       let mk_binding parm =
-        <:binding@loc<
-          $Gen.idp loc ("_of_" ^ parm)$ = Sexplib.Conv.sexp_of_opaque
-        >>
+        <:binding@loc< $lid:"_of_" ^ parm$ = Sexplib.Conv.sexp_of_opaque >>
       in
       List.map ~f:mk_binding (Gen.ty_var_list_of_ctyp parms [])
     in
 
   let rec branch_sum = function
     | <:ctyp@loc< $tp1$ | $tp2$ >> ->
-       <:match_case@loc< $branch_sum tp1$ | $branch_sum tp2$ >>
+        <:match_case@loc< $branch_sum tp1$ | $branch_sum tp2$ >>
     | <:ctyp@loc< $uid:cnstr$ >> ->
         <:match_case@loc< $uid:cnstr$ -> Sexplib.Sexp.Atom $str:cnstr$ >>
     | <:ctyp@loc< $uid:cnstr$ of sexp_list $tp$>> ->
                    Sexplib.Conv.list_map $cnv_expr$ l]
         >>
     | <:ctyp@loc< $uid:cnstr$ of $tps$ >> ->
-        let fps = List.map ~f:(sexp_of_type) (Ast.list_of_ctyp tps []) in
+        let fps = List.map ~f:sexp_of_type (Ast.list_of_ctyp tps []) in
         let cnstr_expr = <:expr@loc< Sexplib.Sexp.Atom $str:cnstr$ >> in
         let bindings, patts, vars = mk_bindings loc fps in
         let patt =
 
   let sexp_of_sum alts = `Match (branch_sum alts)
 
+
   (* Conversion of record types *)
 
   let mk_rec_patt loc patt name =
     in
     let loc = Ast.loc_of_ctyp flds_ctyp in
     let init_expr = <:expr@loc< Sexplib.Sexp.List bnds >> in
-    let patt, expr = List.fold_left ~f:coll ~init:(<:patt@loc<>>, init_expr) flds in
+    let patt, expr =
+      List.fold_left ~f:coll ~init:(<:patt@loc<>>, init_expr) flds
+    in
     `Match
       <:match_case@loc<
         { $patt$ } ->
     let body =
       let rec loop tp =
         Gen.switch_tp_def tp
-          ~alias:(fun (_:Loc.t) tp -> sexp_of_type tp )
-          ~sum:(fun (_:Loc.t) tp -> sexp_of_sum tp)
-          ~record:(fun (_:Loc.t) tp -> sexp_of_record tp)
-          ~variants:(fun (_:Loc.t) tp -> sexp_of_variant tp)
-          ~mani:(fun (_:Loc.t) _tp1 tp2 -> loop tp2)
+          ~alias:(fun (_ : Loc.t) tp -> sexp_of_type tp)
+          ~sum:(fun (_ : Loc.t) tp -> sexp_of_sum tp)
+          ~record:(fun (_ : Loc.t) tp -> sexp_of_record tp)
+          ~variants:(fun (_ : Loc.t) tp -> sexp_of_variant tp)
+          ~mani:(fun (_ : Loc.t) _tp1 tp2 -> loop tp2)
           ~nil:sexp_of_nil
       in
       match loop rhs with
           <:expr@loc< fun [ v -> $fun_expr$ v ] >>
       | `Match matchings -> <:expr@loc< fun [ $matchings$ ] >>
     in
+    let mk_pat id = <:patt@loc< $lid:id$ >> in
     let patts =
       List.map tps
-        ~f:(fun ty -> Gen.idp loc ("_of_" ^ (Gen.get_tparam_id ty)))
+        ~f:(fun ty -> <:patt@loc< $lid:"_of_" ^ Gen.get_tparam_id ty$>>)
     in
-    let bnd = Gen.idp loc ("sexp_of_" ^ type_name) in
+    let bnd = mk_pat ("sexp_of_" ^ type_name) in
     <:binding@loc< $bnd$ = $Gen.abstract loc patts body$ >>
 
   let rec sexp_of_tds = function
     | _ -> assert false  (* impossible *)
 
   let sexp_of tds =
-    let binding, recursive,loc =
+    let binding, recursive, loc =
       match tds with
       | Ast.TyDcl (loc, type_name, tps, rhs, _cl) ->
           sexp_of_td loc type_name tps rhs,
   (* Generate code for matching malformed S-expressions *)
   let mk_variant_other_matches loc rev_els call =
     let coll_structs acc (loc, cnstr) =
-      <:match_case@loc< $str:cnstr$ -> Sexplib.Conv_error.$lid:call$ _loc _sexp >>
-        :: acc
+      <:match_case@loc<
+        $str:cnstr$ -> Sexplib.Conv_error.$lid:call$ _tp_loc _sexp
+      >> :: acc
     in
     let exc_no_variant_match =
-      <:match_case@loc< _ -> Sexplib.Conv_error.no_variant_match _loc _sexp >>
+      <:match_case@loc<
+        _ -> Sexplib.Conv_error.no_variant_match _tp_loc _sexp
+      >>
     in
     List.fold_left ~f:coll_structs ~init:[exc_no_variant_match] rev_els
 
           atoms,
           (loc, cnstr) :: structs,
           ainhs,
-          `S (loc,cnstr, tps) :: sinhs
+          `S (loc, cnstr, tps) :: sinhs
         )
     | <:ctyp< [< $row_fields$ ] >> | <:ctyp< [> $row_fields$ ] >>
     | <:ctyp< [= $row_fields$ ] >> ->
   (* Conversion of types *)
   let rec type_of_sexp = function
     | <:ctyp@loc< sexp_opaque $_$ >> ->
-      `Fun <:expr@loc< Sexplib.Conv.opaque_of_sexp >>
+        `Fun <:expr@loc< Sexplib.Conv.opaque_of_sexp >>
     | <:ctyp@loc< sexp_option >> ->
         `Fun <:expr@loc< fun a_of_sexp v -> Some (a_of_sexp v) >>
     | <:ctyp@loc< sexp_list >> ->
-        `Fun <:expr@loc< fun a_of_sexp v -> Sexplib.Conv.list_of_sexp a_of_sexp v >>
+        `Fun <:expr@loc< fun a_of_sexp v ->
+          Sexplib.Conv.list_of_sexp a_of_sexp v >>
     | <:ctyp@loc< sexp_array >> ->
         `Fun <:expr@loc< fun a_of_sexp v ->
           Sexplib.Conv.array_of_sexp a_of_sexp v >>
         let fp2 = type_of_sexp tp2 in
         `Fun (unroll_fun_matches loc fp1 fp2)
     | <:ctyp< ( $tup:tp$ ) >> -> tuple_of_sexp tp
-    | <:ctyp@loc< '$parm$ >> -> `Fun (Gen.ide loc ("_of_" ^ parm))
+    | <:ctyp@loc< '$parm$ >> -> `Fun <:expr@loc< $lid:"_of_" ^ parm$ >>
     | <:ctyp@loc< $id:id$ >> -> `Fun (path_of_sexp_fun loc id)
-    | <:ctyp@loc< $_$ -> $_$ >> -> `Fun <:expr@loc< Sexplib.Conv.fun_of_sexp >>
+    | <:ctyp@loc< $_$ -> $_$ >> as arrow ->
+        `Fun <:expr@loc< fun sexp ->
+          (Sexplib.Conv.fun_of_sexp sexp : $arrow$) >>
     | <:ctyp< [< $row_fields$ ] >> | <:ctyp< [> $row_fields$ ] >>
     | <:ctyp< [= $row_fields$ ] >> ->
         variant_of_sexp ?full_type:None row_fields
           Sexplib.Sexp.List $Gen.mk_patt_lst loc patts$ ->
             let $bindings$ in
             ( $tup:Ast.exCom_of_list vars$ )
-        | sexp -> Sexplib.Conv_error.tuple_of_size_n_expected _loc $int:n$ sexp
+        | sexp ->
+            Sexplib.Conv_error.tuple_of_size_n_expected _tp_loc $int:n$ sexp
       >>
 
   (* Generate internal call *)
     | <:ctyp@loc< sexp_list $tp$ >> ->
       let cnv =
         match type_of_sexp tp with
-        | `Fun fun_expr -> <:expr< $fun_expr$ >>
+        | `Fun fun_expr -> <:expr@loc< $fun_expr$ >>
         | `Match matchings ->
             <:expr@loc< fun el -> match el with [ $matchings$ ] >>
       in
     | _ ->
         let fps = List.map ~f:type_of_sexp (Ast.list_of_ctyp tps []) in
         let bindings, patts, vars = mk_bindings loc fps in
-        let good_arg_match_expr =
+        let good_arg_match =
           let vars_expr =
             match vars with
             | [var_expr] -> var_expr
           cnstr vars_expr
         in
         let handle_exc =
-          if is_variant then "ptag_incorrect_n_args" else "stag_incorrect_n_args"
+          if is_variant then "ptag_incorrect_n_args"
+          else "stag_incorrect_n_args"
         in
         <:expr@loc<
           match sexp_args with
-            [ $Gen.mk_patt_lst loc patts$ -> let $bindings$ in $good_arg_match_expr$
-            | _ -> Sexplib.Conv_error.$lid:handle_exc$ _loc _tag _sexp ]
+            [ $Gen.mk_patt_lst loc patts$ -> let $bindings$ in $good_arg_match$
+            | _ -> Sexplib.Conv_error.$lid:handle_exc$ _tp_loc _tag _sexp ]
         >>
 
   (* Generate code for matching structured variants *)
       | `S (loc, cnstr, tps) ->
           has_structs_ref := true;
           let expr = mk_cnstr_args_match ~is_variant:true cnstr tps in
-          let new_match = <:match_case@loc< ($str:cnstr$ as _tag) -> $expr$ >> in
+          let new_match =
+            <:match_case@loc< ($str:cnstr$ as _tag) -> $expr$ >>
+          in
           new_match :: other_matches, false
       | `I inh ->
           handle_variant_inh full_type match_last other_matches inh
           [Sexplib.Sexp.Atom atom :: $maybe_sexp_args_patt$] as _sexp ->
             $match_struct$
       | Sexplib.Sexp.List [Sexplib.Sexp.List _ :: _] as sexp ->
-          Sexplib.Conv_error.nested_list_invalid_poly_var _loc sexp
+          Sexplib.Conv_error.nested_list_invalid_poly_var _tp_loc sexp
       | Sexplib.Sexp.List [] as sexp ->
-          Sexplib.Conv_error.empty_list_invalid_poly_var _loc sexp
+          Sexplib.Conv_error.empty_list_invalid_poly_var _tp_loc sexp
     >>
 
   (* Generate matching code for variants *)
           fun sexp ->
             try match sexp with [ $top_match$ ]
             with
-            [ Sexplib.Conv_error.No_variant_match (_loc, sexp) ->
-                Sexplib.Conv_error.no_matching_variant_found _loc sexp
+            [ Sexplib.Conv_error.No_variant_match (_tp_loc, sexp) ->
+                Sexplib.Conv_error.no_matching_variant_found _tp_loc sexp
             ]
         >>
     else `Match top_match
     let bindings =
       let mk_binding parm =
         <:binding@loc<
-          $Gen.idp loc ("_of_" ^ parm)$ =
-            fun sexp -> Sexplib.Conv_error.record_poly_field_value _loc sexp
+          $lid:"_of_" ^ parm$ =
+            fun sexp -> Sexplib.Conv_error.record_poly_field_value _tp_loc sexp
         >>
       in
       List.map ~f:mk_binding (Gen.ty_var_list_of_ctyp parms [])
         <:match_case@loc<
           Sexplib.Sexp.List
             [Sexplib.Sexp.Atom ($str:lccnstr$ | $str:cnstr$) :: _] as sexp ->
-              Sexplib.Conv_error.stag_no_args _loc sexp
+              Sexplib.Conv_error.stag_no_args _tp_loc sexp
         >>
     | <:ctyp@loc< $uid:cnstr$ of $_$ >> ->
         let lccnstr = String.uncapitalize cnstr in
         <:match_case@loc<
           Sexplib.Sexp.Atom ($str:lccnstr$ | $str:cnstr$) as sexp ->
-            Sexplib.Conv_error.stag_takes_args _loc sexp
+            Sexplib.Conv_error.stag_takes_args _tp_loc sexp
         >>
     | <:ctyp@loc< $tp1$ | $tp2$ >> ->
         <:match_case@loc<
           $mk_good_sum_matches alts$
         | $mk_bad_sum_matches alts$
         | Sexplib.Sexp.List [Sexplib.Sexp.List _ :: _] as sexp ->
-            Sexplib.Conv_error.nested_list_invalid_sum _loc sexp
+            Sexplib.Conv_error.nested_list_invalid_sum _tp_loc sexp
         | Sexplib.Sexp.List [] as sexp ->
-            Sexplib.Conv_error.empty_list_invalid_sum _loc sexp
-        | sexp -> Sexplib.Conv_error.unexpected_stag _loc sexp
+            Sexplib.Conv_error.empty_list_invalid_sum _tp_loc sexp
+        | sexp -> Sexplib.Conv_error.unexpected_stag _tp_loc sexp
       >>
 
 
               | <:ctyp@loc< sexp_array $_$ >>
               | <:ctyp@loc< mutable sexp_array $_$ >> ->
                   bi_lst, <:patt@loc< $lid:nm ^ "_value"$ >> :: good_patts
-              | tp ->
-                let loc = Ast.loc_of_ctyp tp in
-                has_nonopt_fields := true;
-                (
-                  <:expr@loc< (Pervasives.(=) $fld$ None, $str:nm$) >> :: bi_lst,
-                  <:patt@loc< Some $lid:nm ^ "_value"$ >> :: good_patts
-                )
+              | _ ->
+                  let loc = Ast.loc_of_ctyp tp in
+                  has_nonopt_fields := true;
+                  (
+                    <:expr@loc<
+                      (Pervasives.(=) $fld$ None, $str:nm$) >> :: bi_lst,
+                    <:patt@loc< Some $lid:nm ^ "_value"$ >> :: good_patts
+                  )
             in
             (
               <:expr@loc< $fld$ >> :: res_tpls,
         let rec loop acc = function
           | <:ctyp< $tp1$; $tp2$ >> -> loop (loop acc tp2) tp1
           | <:ctyp@loc< $lid:nm$ : $_$ >> ->
-            <:expr@loc< $lid:nm ^ "_value"$ >> :: acc
+              <:expr@loc< $lid:nm ^ "_value"$ >> :: acc
           | _ -> assert false  (* impossible *)
         in
         match loop [] flds with
         | [match_good_expr] -> match_good_expr
         | match_good_exprs ->
-          <:expr@loc<
-            $tup:Ast.exCom_of_list match_good_exprs$
-          >>
+            <:expr@loc< $tup:Ast.exCom_of_list match_good_exprs$ >>
       else
         let rec loop = function
           | <:ctyp@loc< $tp1$; $tp2$ >> ->
-          <:rec_binding@loc< $loop tp1$; $loop tp2$ >>
+              <:rec_binding@loc< $loop tp1$; $loop tp2$ >>
           | <:ctyp@loc< $lid:nm$ : sexp_list $_$ >> ->
               <:rec_binding@loc<
                 $lid:nm$ =
         match $expr$ with
         [ $patt$ -> $match_good_expr$
         | _ ->
-            Sexplib.Conv_error.record_undefined_elements _loc sexp
+            Sexplib.Conv_error.record_undefined_elements _tp_loc sexp
               $Gen.mk_expr_lst loc bi_lst$
         ]
       >>
               match field_name with
               [ $mc_no_args_fields$ ];
               iter tail }
-        | [sexp :: _] -> Sexplib.Conv_error.record_only_pairs_expected _loc sexp
+        | [sexp :: _] ->
+            Sexplib.Conv_error.record_only_pairs_expected _tp_loc sexp
         | [] -> () ]
       in
       do {
         iter field_sexps;
         if Pervasives.(<>) duplicates.val [] then
           Sexplib.Conv_error.record_duplicate_fields
-            _loc duplicates.val sexp
+            _tp_loc duplicates.val sexp
         else if Pervasives.(<>) extra.val [] then
-          Sexplib.Conv_error.record_extra_fields _loc extra.val sexp
+          Sexplib.Conv_error.record_extra_fields _tp_loc extra.val sexp
         else $mk_handle_record_match_result has_poly flds$
       }
     >>
       <:match_case@loc<
           Sexplib.Sexp.List field_sexps as sexp -> $handle_fields$
         | Sexplib.Sexp.Atom _ as sexp ->
-            Sexplib.Conv_error.record_list_instead_atom _loc sexp
+            Sexplib.Conv_error.record_list_instead_atom _tp_loc sexp
       >>
 
 
   (* Empty type *)
   let nil_of_sexp loc =
-    `Fun <:expr@loc< fun sexp -> Sexplib.Conv_error.empty_type _loc sexp >>
+    `Fun <:expr@loc< fun sexp -> Sexplib.Conv_error.empty_type _tp_loc sexp >>
 
 
   (* Generate code from type definitions *)
     let body =
       let rec loop tp =
         Gen.switch_tp_def tp
-          ~alias:(fun (_:Loc.t) tp -> handle_alias tp)
-          ~sum:(fun (_:Loc.t) tp -> sum_of_sexp tp)
-          ~record:(fun (_:Loc.t) tp -> record_of_sexp tp)
-          ~variants:(fun (_:Loc.t) tp -> handle_variant tp)
-          ~mani:(fun (_:Loc.t) _tp1 tp2 -> loop tp2)
+          ~alias:(fun (_ : Loc.t) tp -> handle_alias tp)
+          ~sum:(fun (_ : Loc.t) tp -> sum_of_sexp tp)
+          ~record:(fun (_ : Loc.t) tp -> record_of_sexp tp)
+          ~variants:(fun (_ : Loc.t) tp -> handle_variant tp)
+          ~mani:(fun (_ : Loc.t) _tp1 tp2 -> loop tp2)
           ~nil:nil_of_sexp
       in
       match loop rhs with
       List.split (
         List.map ~f:(function tp ->
             let name = "_of_" ^ Gen.get_tparam_id tp in
-            Gen.idp loc name, Gen.ide loc name
+            <:patt@loc< $lid:name$ >>, <:expr@loc< $lid:name$ >>
           )
           tps)
     in
     let with_poly_call = !is_alias_ref && is_poly_call body in
     let internal_fun_body =
-      let full_type_name = sprintf "%s.%s" (Pa_type_conv.get_conv_path ()) type_name in
+      let full_type_name =
+        sprintf "%s.%s" (Pa_type_conv.get_conv_path ()) type_name
+      in
       if with_poly_call then
         Gen.abstract loc arg_patts
           <:expr@loc<
           >>
       else
         <:expr@loc<
-          let _loc = $str:full_type_name$ in
+          let _tp_loc = $str:full_type_name$ in
           $Gen.abstract loc arg_patts body$
         >>
     in
     let pre_external_fun_body =
       let internal_call =
-        let internal_expr = Gen.ide loc internal_name in
+        let internal_expr = <:expr@loc< $lid:internal_name$ >> in
         <:expr@loc< $Gen.apply loc internal_expr arg_exprs$ sexp >>
       in
       let no_variant_match_mc =
         <:match_case@loc<
-          Sexplib.Conv_error.No_variant_match (_loc, sexp) ->
-            Sexplib.Conv_error.no_matching_variant_found _loc sexp
+          Sexplib.Conv_error.No_variant_match (_tp_loc, sexp) ->
+            Sexplib.Conv_error.no_matching_variant_found _tp_loc sexp
         >>
       in
       if with_poly_call then
     let internal_binding =
       <:binding@loc< $lid:internal_name$ = $internal_fun_body$ >>
     in
-    let external_fun_patt = Gen.idp loc (type_name ^ "_of_sexp") in
+    let external_fun_patt = <:patt@loc< $lid:type_name ^ "_of_sexp"$ >> in
     let external_fun_body =
-      Gen.abstract loc arg_patts <:expr@loc< fun sexp -> $pre_external_fun_body$ >>
+      Gen.abstract loc arg_patts
+        <:expr@loc< fun sexp -> $pre_external_fun_body$ >>
     in
     let external_binding =
       <:binding@loc< $external_fun_patt$ = $external_fun_body$ >>
     in
     internal_binding, external_binding
 
-  let rec tds_of_sexp __loc_to_delete acc = function
+  let rec tds_of_sexp acc = function
     | Ast.TyDcl (loc, type_name, tps, rhs, _cl) ->
         td_of_sexp loc type_name tps rhs :: acc
-    | Ast.TyAnd (loc, tp1, tp2) ->
-      tds_of_sexp loc (tds_of_sexp loc acc tp2) tp1
+    | Ast.TyAnd (_, tp1, tp2) -> tds_of_sexp (tds_of_sexp acc tp2) tp1
     | _ -> assert false  (* impossible *)
 
   (* Generate code from type definitions *)
             value $external_binding$
           >>
     | Ast.TyAnd (loc, _, _) as tds ->
-        let two_bindings = tds_of_sexp loc [] tds in
+        let two_bindings = tds_of_sexp [] tds in
         let bindings =
-          List.map ~f:(fun (b1, b2) -> <:binding@loc< $b1$ and $b2$ >>) two_bindings
+          List.map ~f:(fun (b1, b2) -> <:binding@loc< $b1$ and $b2$ >>)
+            two_bindings
         in
         <:str_item@loc< value rec $list:bindings$ >>
     | _ -> assert false  (* impossible *)
 
   (* Add code generator to the set of known generators *)
   let () = Pa_type_conv.add_generator "of_sexp" of_sexp
- end
+end
 
 module Quotations = struct
-
   let of_sexp_quote loc _loc_name_opt cnt_str =
     Pa_type_conv.set_conv_path_if_not_set loc;
     let ctyp = Gram.parse_string Syntax.ctyp_quot loc cnt_str in
     let fp = Generate_of_sexp.type_of_sexp ctyp in
-    let body = match fp with
+    let body =
+      match fp with
       | `Fun fun_expr -> <:expr@loc< $fun_expr$ sexp >>
       | `Match matchings -> <:expr@loc< match sexp with [$matchings$]  >>
     in
-    let full_type_name = sprintf "%s line %i: %s"
-      (Pa_type_conv.get_conv_path ())
-      (Loc.start_line loc)
-      cnt_str
+    let full_type_name =
+      sprintf "%s line %i: %s"
+        (Pa_type_conv.get_conv_path ()) (Loc.start_line loc) cnt_str
     in
     <:expr@loc<
       fun [ sexp ->
-        let _loc = $str:full_type_name$ in
+        let _tp_loc = $str:full_type_name$ in
         $body$ ]
       >>
 
+  let () =
+    Syntax.Quotation.add "of_sexp" Syntax.Quotation.DynAst.expr_tag
+      of_sexp_quote
 
  let sexp_of_quote loc _loc_name_opt cnt_str =
    Pa_type_conv.set_conv_path_if_not_set loc;
   let () =
     Syntax.Quotation.add "sexp_of" Syntax.Quotation.DynAst.expr_tag
       sexp_of_quote
-
-  let () =