ML-Yacc & SML/NJ Libraries in Poly/ML
The SML/NJ Library includes many features that the Standard ML Basis library does not, including: maps, sets, random numbers, atoms, parser combinators, pretty printing, regular expressions, and HTML generation. The manual pages do not do the library justice; a careful study of the source can be rewarding.
ML-Yacc is required to build the SML/NJ library.
Step-by-step instructions
The SML/NJ Library can be used in Poly/ML, on i386 and PPC, with little effort, using either the MLton or SML/NJ distributions. In the latter case, patches must be applied, and both mlyacc and mllex are required.
Building from an MLton installation
- Download and install MLton.
- Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
- Edit the root path in both scripts to point at the sml subdirectory of the MLton installation.
- Inside Poly/ML type:
use "poly_mlyacc.sml"; use "poly_smlnj-lib.sml";
Building from an SML/NJ installation
- Make copies of the ml-yacc and smlnj-lib subdirectories of the SML/NJ installation.
- Apply some minor patches, taken
from MLton, by typing
patch -p0 < poly_smlnj-lib.patch
- Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
- Edit the root path in both scripts to point at the directory containing the copied subdirectories.
- Inside Poly/ML type:
use "poly_mlyacc.sml"; use "poly_smlnj-lib.sml";
Building from the SML/NJ distribution with mllex and mlyacc
- Download and extract the ml-yacc source and the smlnj-lib source,
- Build the lexer and grammar files
mllex smlnj-lib/HTML/html-lex mlyacc smlnj-lib/HTML/html-grm
- Apply some minor patches, taken
from MLton, by typing
patch -p0 < poly_smlnj-lib.patch
- Download the poly_mlyacc.sml and poly_smlnj-lib.sml scripts.
- Edit the root path in both scripts to point at the directory containing the patched subdirectories.
- Inside Poly/ML type:
use "poly_mlyacc.sml"; use "poly_smlnj-lib.sml";
The patches
Four files (Util/hash-string.sml, Util/array-qsort.sml, Util/real-order-stats.sml, and Util/univariate-stats.sml) use SML/NJ's Unsafe structure, which does not exist in Poly/ML.
Three files (Util/redblack-set-fn.sml, Util/redblack-map-fn, and Util/graph-scc-fn.sml) use a non-standard where qualification over structures.
Two files (HTML/html-elements-fn.sml and HTML/html-attrs-fn.sml) use non-standard Or-patterns.
All issues are easily patched, after extracting the distribution:
patch -p0 < poly_smlnj-lib.patch
The where type and Or-pattern patches were taken from the MLton distribution of the SML/NJ Library, but the Unsafe patches are also needed under Poly/ML unless the additional declaration is made:
structure Unsafe = struct structure CharVector = CharVector structure Array = Array end;
Importing files
The basis is enriched by declaring library components in order of their dependencies, that is, the file containing a signature, structure, or functor must be loaded (with use) before any other file that relies upon the declaration. Unfortunately, each SML implementation handles this issue differently.
The *.mlb files used by MLton list the library *.sml files in the required order. They are easily transformed into a list of strings, using grep and sed, for example
cat sml/smlnj-lib/Util/smlnj-lib.mlb | sed 's/ *(\*.*\*) *//' \ | egrep '\.(sml|sig)$' \ | sed 's/^ *\(.*\)/"\1",/'
The poly_mlyacc.sml and poly_smlnj-lib.sml files described above are built from MLton's *.mlb files by running the shell scripts makemlyacc and makesmlnj-lib respectively.
Six files are intentionally missing from the smlnj-lib/Util/smlnj-lib.mlb file:
array2-sig.sml, array2.sml | The SML Basis Library already includes an Array2 structure. |
bit-vector.sml | Requires BitArray.Vector, which is not exported. |
iterate-sig.sml, iterate.sml | TODO suggests that this module will be revised. |
time-limit.sml | Relies on SMLofNJ.cont.callcc. |
The SML/NJ Library requires a Word31 structure that is not provided by Poly/ML. Since Poly/ML's default Word structure has 31 bits (Word.wordSize = 31), at least on i386 and PPC, a simple declaration can help:
structure Word31 = Word;
On other platforms, five files should be excluded from the list: random-sig.sml, random.sml, real-order-stats.sml, univariate-stats.sml, rand-sig.sml and rand.sml.
The library also requires an Int32 structure, but Poly/ML does not support fixed precision integers. Again, a simple declaration can help:
structure Int32 = Int;
Otherwise, the rand.sml file should be excluded.
The modifications and list described above, as well as details from the next section are incorporated available in the poly_smlnj-lib.sml file.