Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /sml/trunk/src/cm/compile/generic.sml
ViewVC logotype

View of /sml/trunk/src/cm/compile/generic.sml

Parent Directory Parent Directory | Revision Log Revision Log

Revision 377 - (download) (annotate)
Wed Jul 7 06:55:18 1999 UTC (21 years, 6 months ago) by blume
File size: 4396 byte(s)
some pathconfig oddness rectified
 * The "generic" compilation traversal functor.
 *  (In fact, it is probably possible to use this for things other
 *   than compilation as well.)
 * (C) 1999 Lucent Technologies, Bell Laboratories
 * Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)
    structure GP = GeneralParams
    structure DG = DependencyGraph
    structure GG = GroupGraph
    functor CompileGenericFn (structure CT: COMPILATION_TYPE) :> TRAVERSAL
	where type envdelta = CT.envdelta
	  and type result = CT.result =

	type envdelta = CT.envdelta
	type env = CT.env
	type benv = CT.benv
	type result = CT.result

	type ts = CT.ts * envdelta option SmlInfoMap.map ref
	type tsnode = DependencyGraph.farsbnode * ts

	val stablecache = ref (StableMap.empty: envdelta option StableMap.map)

	fun reset () = stablecache := StableMap.empty

	fun start () = (CT.start (), ref SmlInfoMap.empty)
	fun finish (ctts, _) = CT.finish ctts
	fun clearErrors (_, smlcache) =
	    smlcache := SmlInfoMap.filter isSome (!smlcache)

	fun clearStableErrors () =
	    stablecache := StableMap.filter isSome (!stablecache)

	(* To implement "keep_going" we have two different ways of
	 * combining a "work" function with a "layer" function.
	 * One way is to give up and do no further work once there
	 * is a result of NONE, the other one is to continue
	 * working (but to ignore the results of such work). *)
	fun layerwork (k, layer, work) (x, NONE) =
	    (if k then ignore (work x) else (); NONE)
	  | layerwork (k, layer, work) (x, SOME e) =
	    case work x of
	      | SOME e' => SOME (layer (e', e))

	fun bnode ts (gp: GP.info) n = let

	    val (ctts, _) = ts
	    val k = #keep_going (#param gp)
	    val glob = foldl (layerwork (k, CT.blayer, farbnode ts gp))
	    val loc =
		foldl (layerwork (k, CT.blayer,
				  Option.map CT.bnofilter o bnode ts gp))

	    fun bn (DG.PNODE p) = SOME (CT.primitive gp p)
	      | bn (node as DG.BNODE n) = let
		    val { bininfo, localimports = li, globalimports = gi } = n
		    case StableMap.find (!stablecache, bininfo) of
			SOME r => r
		      | NONE => let
			    fun mkenv () =
				loc (glob (SOME (CT.bpervasive gp)) gi) li
			    val r =
				CT.dostable (bininfo, mkenv, gp, node, ctts)
			    stablecache :=
			       StableMap.insert (!stablecache, bininfo, r);
	    (* don't eta-reduce this -- it'll lead to an infinite loop! *)
	    bn n

	and farbnode ts gp (f, n) =
	    case (bnode ts gp n, f) of
		(NONE, _) => NONE
	      | (SOME d, NONE) => SOME (CT.bnofilter d)
	      | (SOME d, SOME s) => SOME (CT.bfilter (d, s))

	fun snode ts gp (node as DG.SNODE n) = let

	    val (ctts, smlcache) = ts
	    val k = #keep_going (#param gp)
	    val glob = foldl (layerwork (k, CT.layer, farsbnode ts gp))
	    val loc =
		foldl (layerwork (k, CT.layer,
				  Option.map CT.nofilter o snode ts gp))
	    val i = #smlinfo n
	    case SmlInfoMap.find (!smlcache, i) of
		SOME r => r
	      | NONE => let
		    val pe = SOME (CT.pervasive gp)
		    val ge = glob pe (#globalimports n)
		    val e = loc ge (#localimports n)
		    val r = case e of
		      | SOME e => CT.dosml (i, e, gp, node, ctts)
		    smlcache := SmlInfoMap.insert (!smlcache, i, r);

	and sbnode ts gp (DG.SB_BNODE b) = bnode ts gp b
	  | sbnode ts gp (DG.SB_SNODE s) = snode ts gp s

	and farsbnode ts gp (f, n) =
	    case (sbnode ts gp n, f) of
		(NONE, _) => NONE
	      | (SOME d, NONE) => SOME (CT.nofilter d)
	      | (SOME d, SOME s) => SOME (CT.filter (d, s))

	fun resume1 gp (n, ts) =
	    Option.map CT.env2result (farsbnode ts gp n)
	    before finish ts

	(* Only "resume" and "group" clear stable errors; other
	 * traversals must wait until "resume" or "group" has been
	 * re-run. *)
	fun resume getter gp m =
	    (clearStableErrors ();
	     SymbolMap.app (clearErrors o #2 o getter) m;
	     foldl (layerwork (#keep_going (#param gp),
			       resume1 gp o getter))
	           (SOME CT.empty)
		   (SymbolMap.listItems m))

	fun group gp (GG.GROUP { exports, ... }) = let
	    val ts = start ()
	    fun getter (n, _) = (n, ts)
	    resume getter gp exports

	fun withNewTs f gp n = let
	    val ts = start ()
	    f ts gp n before finish ts

	val bnode' = withNewTs bnode
	val snode' = withNewTs snode

ViewVC Help
Powered by ViewVC 1.0.0