src/Pure/ML/ml_env.ML
author wenzelm
Fri, 16 Apr 2010 11:39:08 +0200
changeset 36163 823c9400eb62
parent 33519 e31a85f92ce9
child 36165 310a3f2f0e7e
permissions -rw-r--r--
proper checking of ML functors (in Poly/ML 5.2 or later);
eliminated pathetic comments;
wenzelm@31359
     1
(*  Title:      Pure/ML/ml_env.ML
wenzelm@31359
     2
    Author:     Makarius
wenzelm@31359
     3
wenzelm@31470
     4
Local environment of ML results.
wenzelm@31359
     5
*)
wenzelm@31359
     6
wenzelm@31359
     7
signature ML_ENV =
wenzelm@31359
     8
sig
wenzelm@31359
     9
  val inherit: Context.generic -> Context.generic -> Context.generic
wenzelm@31359
    10
  val name_space: ML_Name_Space.T
wenzelm@31359
    11
  val local_context: use_context
wenzelm@36163
    12
  val check_functor: string -> unit
wenzelm@31359
    13
end
wenzelm@31359
    14
wenzelm@31359
    15
structure ML_Env: ML_ENV =
wenzelm@31359
    16
struct
wenzelm@31359
    17
wenzelm@31362
    18
(* context data *)
wenzelm@31362
    19
wenzelm@33519
    20
structure Env = Generic_Data
wenzelm@31359
    21
(
wenzelm@31359
    22
  type T =
wenzelm@31434
    23
    ML_Name_Space.valueVal Symtab.table *
wenzelm@31434
    24
    ML_Name_Space.typeVal Symtab.table *
wenzelm@31434
    25
    ML_Name_Space.fixityVal Symtab.table *
wenzelm@31434
    26
    ML_Name_Space.structureVal Symtab.table *
wenzelm@31434
    27
    ML_Name_Space.signatureVal Symtab.table *
wenzelm@31434
    28
    ML_Name_Space.functorVal Symtab.table;
wenzelm@31434
    29
  val empty = (Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty, Symtab.empty);
wenzelm@31359
    30
  val extend = I;
wenzelm@33519
    31
  fun merge
wenzelm@31434
    32
   ((val1, type1, fixity1, structure1, signature1, functor1),
wenzelm@31434
    33
    (val2, type2, fixity2, structure2, signature2, functor2)) : T =
wenzelm@31362
    34
    (Symtab.merge (K true) (val1, val2),
wenzelm@31362
    35
     Symtab.merge (K true) (type1, type2),
wenzelm@31362
    36
     Symtab.merge (K true) (fixity1, fixity2),
wenzelm@31362
    37
     Symtab.merge (K true) (structure1, structure2),
wenzelm@31362
    38
     Symtab.merge (K true) (signature1, signature2),
wenzelm@31434
    39
     Symtab.merge (K true) (functor1, functor2));
wenzelm@31359
    40
);
wenzelm@31359
    41
wenzelm@31359
    42
val inherit = Env.put o Env.get;
wenzelm@31359
    43
wenzelm@31362
    44
wenzelm@31362
    45
(* results *)
wenzelm@31362
    46
wenzelm@31359
    47
val name_space: ML_Name_Space.T =
wenzelm@31359
    48
  let
wenzelm@31359
    49
    fun lookup sel1 sel2 name =
wenzelm@31359
    50
      Context.thread_data ()
wenzelm@31434
    51
      |> (fn NONE => NONE | SOME context => Symtab.lookup (sel1 (Env.get context)) name)
wenzelm@31359
    52
      |> (fn NONE => sel2 ML_Name_Space.global name | some => some);
wenzelm@31359
    53
wenzelm@31359
    54
    fun all sel1 sel2 () =
wenzelm@31359
    55
      Context.thread_data ()
wenzelm@31434
    56
      |> (fn NONE => [] | SOME context => Symtab.dest (sel1 (Env.get context)))
wenzelm@31359
    57
      |> append (sel2 ML_Name_Space.global ())
wenzelm@31359
    58
      |> sort_distinct (string_ord o pairself #1);
wenzelm@31359
    59
wenzelm@31359
    60
    fun enter ap1 sel2 entry =
wenzelm@31359
    61
      if is_some (Context.thread_data ()) then
wenzelm@31434
    62
        Context.>> (Env.map (ap1 (Symtab.update entry)))
wenzelm@31359
    63
      else sel2 ML_Name_Space.global entry;
wenzelm@31359
    64
  in
wenzelm@31359
    65
   {lookupVal    = lookup #1 #lookupVal,
wenzelm@31359
    66
    lookupType   = lookup #2 #lookupType,
wenzelm@31359
    67
    lookupFix    = lookup #3 #lookupFix,
wenzelm@31359
    68
    lookupStruct = lookup #4 #lookupStruct,
wenzelm@31359
    69
    lookupSig    = lookup #5 #lookupSig,
wenzelm@31359
    70
    lookupFunct  = lookup #6 #lookupFunct,
wenzelm@31359
    71
    enterVal     = enter (fn h => fn (a, b, c, d, e, f) => (h a, b, c, d, e, f)) #enterVal,
wenzelm@31359
    72
    enterType    = enter (fn h => fn (a, b, c, d, e, f) => (a, h b, c, d, e, f)) #enterType,
wenzelm@31359
    73
    enterFix     = enter (fn h => fn (a, b, c, d, e, f) => (a, b, h c, d, e, f)) #enterFix,
wenzelm@31359
    74
    enterStruct  = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, h d, e, f)) #enterStruct,
wenzelm@31359
    75
    enterSig     = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, d, h e, f)) #enterSig,
wenzelm@31359
    76
    enterFunct   = enter (fn h => fn (a, b, c, d, e, f) => (a, b, c, d, e, h f)) #enterFunct,
wenzelm@31359
    77
    allVal       = all #1 #allVal,
wenzelm@31359
    78
    allType      = all #2 #allType,
wenzelm@31359
    79
    allFix       = all #3 #allFix,
wenzelm@31359
    80
    allStruct    = all #4 #allStruct,
wenzelm@31359
    81
    allSig       = all #5 #allSig,
wenzelm@31359
    82
    allFunct     = all #6 #allFunct}
wenzelm@31359
    83
  end;
wenzelm@31359
    84
wenzelm@31359
    85
val local_context: use_context =
wenzelm@31359
    86
 {tune_source = ML_Parse.fix_ints,
wenzelm@31359
    87
  name_space = name_space,
wenzelm@31359
    88
  str_of_pos = Position.str_of oo Position.line_file,
wenzelm@31359
    89
  print = writeln,
wenzelm@31359
    90
  error = error};
wenzelm@31359
    91
wenzelm@36163
    92
val is_functor = is_some o #lookupFunct name_space;
wenzelm@36163
    93
wenzelm@36163
    94
fun check_functor name =
wenzelm@36163
    95
  if is_functor "Table" (*lookup actually works*) andalso is_functor name then ()
wenzelm@36163
    96
  else error ("Unknown ML functor: " ^ quote name);
wenzelm@36163
    97
wenzelm@31359
    98
end;
wenzelm@31359
    99