769 |
Here, the file {\tt bar-client.sml} gets included if {\tt |
Here, the file {\tt bar-client.sml} gets included if {\tt |
770 |
SMLNJ\_VERSION} is greater than 110 and {\tt new-foo.sml} exports a |
SMLNJ\_VERSION} is greater than 110 and {\tt new-foo.sml} exports a |
771 |
structure {\tt Bar} {\em or} if {\tt SMLNJ\_VERSION <= 110} and {\tt |
structure {\tt Bar} {\em or} if {\tt SMLNJ\_VERSION <= 110} and {\tt |
772 |
old-foo.sml} exports structure {\tt Bar}. Otherwise {\tt |
old-foo.sml} exports structure {\tt Bar}. \\ Otherwise {\tt |
773 |
no-bar-so-far.sml} gets included instead. In addition, the export of |
no-bar-so-far.sml} gets included instead. In addition, the export of |
774 |
structure {\tt Bar} is guarded by its own existence. (Structure {\tt |
structure {\tt Bar} is guarded by its own existence. (Structure {\tt |
775 |
Bar} could also be defined by {\tt no-bar-so-far.sml} in which case it |
Bar} could also be defined by {\tt no-bar-so-far.sml} in which case it |
896 |
built-in}, {\tt print-hook}, {\tt use-hook}, {\tt exn-info-hook}, {\tt |
built-in}, {\tt print-hook}, {\tt use-hook}, {\tt exn-info-hook}, {\tt |
897 |
core}, {\tt init-utils}. |
core}, {\tt init-utils}. |
898 |
|
|
899 |
|
\section{Files} |
900 |
|
|
901 |
|
CM uses three kinds of files to store derived information during and |
902 |
|
between sessions: |
903 |
|
|
904 |
|
\begin{enumerate} |
905 |
|
\item {\it Skeleton files} are used to store a highly abbreviated |
906 |
|
version of each ML source file's abstract syntax tree---just barely |
907 |
|
sufficient to drive CM's dependency analysis. Skeleton files are much |
908 |
|
smaller and easier to read than actual ML source code. Therefore, the |
909 |
|
existence of valid skeleton files makes CM a lot faster because |
910 |
|
usually most parsing operations can be avoided that way. |
911 |
|
\item {\it Binfiles} are the SML/NJ equivalent of object files. They |
912 |
|
contain executable code and a symbol table for the associated ML |
913 |
|
source file. |
914 |
|
\item {\it Library files} (sometimes called: {\em stablefiles}) |
915 |
|
dependency graph, executable code, and symbol tables for an entire CM |
916 |
|
library including all of its components (groups). |
917 |
|
\end{enumerate} |
918 |
|
|
919 |
|
Normally, all these files are stored in a subdirectory of directory |
920 |
|
{\tt CM} which itself is a subdirectory of the directory where the |
921 |
|
original ML source file or---in the case of library files---the |
922 |
|
original CM description file is located. |
923 |
|
|
924 |
|
Skeleton files are machine- and operating system-independent. |
925 |
|
Therefore, they are always placed into the same directory {\tt |
926 |
|
CM/SKEL}. Parsing (for the purpose of dependency analysis) will be |
927 |
|
done only once even if the same file system is accessible from |
928 |
|
machines of different type. |
929 |
|
|
930 |
|
Binfiles and library files contain executable code and other |
931 |
|
information that is potentially system- and architecture-dependent. |
932 |
|
Therefore, they are stored under {\tt CM/}{\it arch}{\tt -}{\it os} |
933 |
|
where {\it arch} is a string indicating the type of the current |
934 |
|
CPU architecture and {\it os} a string denoting the current operating |
935 |
|
system type. |
936 |
|
|
937 |
|
Library files are a bit of an exception in the sense that they do not |
938 |
|
require any source files or any other derived files of the same |
939 |
|
library to exist. As a consequence, the location of such a library |
940 |
|
file is best described as being relative to ``the location of the |
941 |
|
original CM description file if that description file still existed''. |
942 |
|
(Of course, nothing precludes the CM description file from actually |
943 |
|
existing, but in the presence of a corresponding library file CM will |
944 |
|
not take any notice.) |
945 |
|
|
946 |
|
\subsection{Time stamps} |
947 |
|
|
948 |
|
For skeleton files and binfiles, CM uses file system time stamps to |
949 |
|
determine whether a file has become outdated. The rule is that in |
950 |
|
order to be considered ``up-to-date'' the time stamp on skeleton file |
951 |
|
and binfile has to be exactly the same as the one on the ML source |
952 |
|
file. This guarantees that all changes to a source will be |
953 |
|
noticed\footnote{except for the pathological case where two different |
954 |
|
versions of the same source file have exactly the same time stamp}. |
955 |
|
|
956 |
|
CM also uses time stamps to decide whether tools such as ML-Yacc or |
957 |
|
ML-Lex need to be run (see Section~\ref{sec:tools}). However, the |
958 |
|
difference is that a file is considered outdated if it is older than |
959 |
|
its source. Some care on the programmers side is necessary since this |
960 |
|
scheme does not allow CM to detect the situation where a source file |
961 |
|
gets replaced by an older version of itself. |
962 |
|
|
963 |
|
\section{Tools} |
964 |
|
\label{sec:tools} |
965 |
|
|
966 |
|
CM's tool set is extensible: new tools can be added by writing a few |
967 |
|
lines of ML code. The necessary hooks for this are provided by a |
968 |
|
structure {\tt Tools} which is exported by the {\tt cm-tools.cm} |
969 |
|
library. |
970 |
|
|
971 |
|
If the tool is implemented as a ``typical'' shell command, then all |
972 |
|
that needs to be done is a single call to: |
973 |
|
|
974 |
|
\begin{verbatim} |
975 |
|
Tools.registerStdShellCmdTool |
976 |
|
\end{verbatim} |
977 |
|
|
978 |
|
For example, suppose you have made a |
979 |
|
new, improved version of ML-Yacc (``New-ML-Yacc'') and want to |
980 |
|
register it under a class called {\tt nmlyacc}. Here is what you |
981 |
|
write: |
982 |
|
|
983 |
|
\begin{verbatim} |
984 |
|
val command = Tools.newCmdGetterSetter ("NYACC", "new-ml-yacc") |
985 |
|
val _ = Tools.registerStdShellCmdTool |
986 |
|
{ tool = "New-ML-Yacc", |
987 |
|
class = "nmlyacc", |
988 |
|
suffixes = ["ngrm", "ny"], |
989 |
|
command = command, |
990 |
|
extensionStyle = Tools.EXTEND ["sig", "sml"], |
991 |
|
sml = true } |
992 |
|
\end{verbatim} |
993 |
|
|
994 |
|
This code can either by packaged as a CM library or entered at the |
995 |
|
interactive top level after loading the {\tt cm-tools.cm} library |
996 |
|
(e.g., via {\tt CM.autoload}). |
997 |
|
|
998 |
|
The call to {\tt Tools.newCmdGetterSetter} makes a `command |
999 |
|
getter-setter'' which is a value of type {\tt string option -> |
1000 |
|
string}. It can be invoked to query or set the command string for the |
1001 |
|
tool. Here, the default string is {\tt new-ml-yacc} and can be |
1002 |
|
customized at startup time using the environment variable {\tt |
1003 |
|
CM\_NYACC}. |
1004 |
|
|
1005 |
|
{\tt Tools.registerStdShellCmdTool} creates the class and installs the |
1006 |
|
tool for it. The arguments must be specified as follows: |
1007 |
|
|
1008 |
|
\begin{description} |
1009 |
|
\item[tool] a descriptive name of the tool (used in error messages) |
1010 |
|
\item[class] the name of the class; the string must not contain |
1011 |
|
upper-case letters |
1012 |
|
\item[suffixes] a list of file name suffixes that let CM automatically |
1013 |
|
recognize files of the class |
1014 |
|
\item[command] the command getter-setter from above |
1015 |
|
\item[extensionStyle] a specification of how the names of files |
1016 |
|
generated by the tool relate to the name of the tool input file; \\ |
1017 |
|
Currently, there are two possible cases: |
1018 |
|
\begin{enumerate} |
1019 |
|
\item ``{\tt Tools.EXTEND} $l$'' says that if the tool source file is |
1020 |
|
{\it file} then for each suffix {\it sfx} in $l$ there will be one tool |
1021 |
|
output file named {\it file}{\tt .}{\it sfx}. |
1022 |
|
\item ``{\tt Tools.REPLACE }$(l_1, l_2)$'' specifies that given the |
1023 |
|
base name {\it base} there will be one tool output file {\it base}{\tt |
1024 |
|
.}{\it sfx} for each suffix {\it sfx} in $l_2$. Here, {\it base} is |
1025 |
|
determined by the following rule: If the name of the tool input file |
1026 |
|
has a suffix that occurs in $l_1$ then {\it base} is the name without |
1027 |
|
that suffix. Otherwise, the whole file name is taken as {\it base} |
1028 |
|
(just like in the case of {\tt Tools.EXTEND}). |
1029 |
|
\end{enumerate} |
1030 |
|
\item[sml] a boolean flag that indicates whether or not the tool |
1031 |
|
output is always to be considered ML source code; \\ |
1032 |
|
If the flag is set to {\tt false}, then CM will take the names of the |
1033 |
|
output files and apply its usual classification mechanism---possibly |
1034 |
|
resulting in cascaded tool application. |
1035 |
|
\end{description} |
1036 |
|
|
1037 |
|
Less common kinds of rules can also be defined using the generic |
1038 |
|
interface {\tt Tools.registerClass}. |
1039 |
|
|
1040 |
\section{Some history} |
\section{Some history} |
1041 |
|
|
1042 |
Although its programming model is more general, CM's implementation is |
Although its programming model is more general, CM's implementation is |