| ESkip => empty
| ESet (_, e) => expNeeded G e
- | EGet (x, _, e) => expNeeded (Env.bindVal G (x, dt, NONE)) e
+ | EGet (x, topt, _, e) =>
+ (case topt of
+ NONE => expNeeded (Env.bindVal G (x, dt, NONE)) e
+ | SOME t => unionCTE ((typNeeded G t, SS.empty),
+ expNeeded (Env.bindVal G (x, dt, NONE)) e))
| ESeq es => foldl (fn (e, ss) => unionCTE (ss, expNeeded G e))
empty es
| ELocal (e1, e2) => unionCTE (expNeeded G e1, expNeeded G e2)
SM.insert (provide, name, fname)))
m1 m2
-fun order fnames =
+fun order basisOpt fnames =
let
fun doFile (fname, (provideC, provideT, provideV, require)) =
let
val require = SM.mapi (fn (fname, ((rc, rt), rv)) =>
let
- fun consider (kind, provide) =
+ fun consider (kind, provide, lastChance) =
SS.foldl (fn (name, need) =>
case SM.find (provide, name) of
- NONE => (ErrorMsg.error NONE
- ("File "
- ^ fname
- ^ " uses undefined "
- ^ kind
- ^ " "
- ^ name);
- need)
+ NONE =>
+ if lastChance name then
+ need
+ else
+ (ErrorMsg.error NONE
+ ("File "
+ ^ fname
+ ^ " uses undefined "
+ ^ kind
+ ^ " "
+ ^ name);
+ need)
| SOME fname' =>
SS.add (need, fname'))
- val need = consider ("context", provideC)
+ val need = consider ("context", provideC,
+ case basisOpt of
+ NONE => (fn _ => false)
+ | SOME b => Env.lookupContext b)
SS.empty rc
- val need = consider ("type", provideT)
+ val need = consider ("type", provideT,
+ case basisOpt of
+ NONE => (fn _ => false)
+ | SOME b => Env.lookupType b)
need rt
- val need = consider ("value", provideV)
+ val need = consider ("value", provideV,
+ case basisOpt of
+ NONE => (fn _ => false)
+ | SOME b => (fn name => Option.isSome (Env.lookupVal b name)))
need rv
in
need