[MLton] cvs commit: world no longer contains a preprocessed basis library

Matthew Fluet fluet@cs.cornell.edu
Mon, 15 Dec 2003 16:12:37 -0500 (EST)

I'm changing the example a little (getting the directory structure correct
and changing the second and third sources.cm files to Library):

> 	sources.cm:  Group
> 	               structure Main
> 	             in
> 	               AB/sources.cm
> 	               main.sml (* uses structure A *)
> 	AB/sources.cm:  Library
> 	                  structure A
> 	                  structure B
> 	                in
> 	                  ../XYZ/sources.cm
> 	                  a.sml (* uses structure X *)
> 	                  b.sml (* uses structure Y *)
> 	XYZ/sources.cm:  Group
> 	                   structure X
> 	                   structure Y
> 	                   structure Z
> 	                 in
> 	                   x.sml
> 	                   y.sml
> 	                   z.sml

So, here's what CM gives us:

- val SOME {graph, imports, ...} = CM.Graph.graph "sources.cm";
val graph =
    {defs=[DEF {lhs="str2",rhs=SYM (STR,"A")},
           DEF {lhs="ss1",rhs=SYMS ["str2"]},
           DEF {lhs="e3",rhs=IMPORT {lib="l4",syms="ss1"}},
           DEF {lhs="str6",rhs=SYM (STR,"Main")},
           DEF {lhs="ss5",rhs=SYMS ["str6"]},
           DEF {lhs="e0",
                rhs=COMPILE {env="e3",
     export="e0",imports=["l4"]} : ?.PortableGraph.graph
val imports = ["AB/sources.cm"] : string list

So, we can infer that "main.sml" depends upon  structure A  which is
described in  "AB/sources.cm".  Note, that to make this inference, we need
to examine the environment which is used in the COMPILE node, noting that
it is an IMPORT node, whose syms is exactly (STR, "A").  As of yet, we
don't know what file (referenced by "AB/sources.cm") defines  structure A.
We could (naively, and as is done in my cmcat), just decide to import the
entire "AB/sources.cm".

Next, CM gives us:

- val SOME {graph, imports, ...} = CM.Graph.graph "AB/sources.cm";
val graph =
    {defs=[DEF {lhs="str2",rhs=SYM (STR,"Y")},
           DEF {lhs="ss1",rhs=SYMS ["str2"]},
           DEF {lhs="e3",rhs=IMPORT {lib="l4",syms="ss1"}},
           DEF {lhs="str6",rhs=SYM (STR,"B")},
           DEF {lhs="ss5",rhs=SYMS ["str6"]},
           DEF {lhs="e0",
                rhs=COMPILE {env="e3",
           DEF {lhs="str9",rhs=SYM (STR,"X")},
           DEF {lhs="ss8",rhs=SYMS ["str9"]},
           DEF {lhs="e10",rhs=IMPORT {lib="l4",syms="ss8"}},
           DEF {lhs="str12",rhs=SYM (STR,"A")},
           DEF {lhs="ss11",rhs=SYMS ["str12"]},
           DEF {lhs="e7",
                rhs=COMPILE {env="e10",
           DEF {lhs="e13",
                rhs=MERGE ["e7","e0"]}],
     export="e13",imports=["l4"]} : ?.PortableGraph.graph
val imports = ["XYZ/sources.cm"] : string list

While  DEF {lhs="str12",rhs=SYM (STR,"A")} is the only  structure A  in
the graph, that's not necessarily always the case.  That is, we can't just
decide that  "a.sml"  defines  structure A  because there is a COMPILE
node that yields an environment with (STR,"A").  Really, we would need to
determine which (STR,"A") symbol reaches the export node.  But, in any
case, we can determine that  "a.sml"  depends upon  structure X  defined
in "XYZ/sources.cm".

So, I believe that depends can be extracted from the graph, with some
work.  And, my feeling is that given the work necessary to extract the
depends function, one might as well just build the dependency graph.

Anyways, I'm not arguing that this is the way to go (for cmcat).  I think
that CM is "being nice" in that it will only compile the portion of a
Library necessary for the task at hand.  I think it would be perfectly
legitimate for CM.make "sources.cm" to force the compilation of the entire
"AB/sources.cm" Library because Main depends upon some structure from that