src/Pure/config.ML
changeset 56438 7f6b2634d853
parent 56294 85911b8a6868
child 57858 39d9c7f175e0
equal deleted inserted replaced
56437:b14bd153a753 56438:7f6b2634d853
    22   val map_global: 'a T -> ('a -> 'a) -> theory -> theory
    22   val map_global: 'a T -> ('a -> 'a) -> theory -> theory
    23   val put_global: 'a T -> 'a -> theory -> theory
    23   val put_global: 'a T -> 'a -> theory -> theory
    24   val get_generic: Context.generic -> 'a T -> 'a
    24   val get_generic: Context.generic -> 'a T -> 'a
    25   val map_generic: 'a T -> ('a -> 'a) -> Context.generic -> Context.generic
    25   val map_generic: 'a T -> ('a -> 'a) -> Context.generic -> Context.generic
    26   val put_generic: 'a T -> 'a -> Context.generic -> Context.generic
    26   val put_generic: 'a T -> 'a -> Context.generic -> Context.generic
    27   val declare: string -> (Context.generic -> value) -> raw
    27   val declare: string * Position.T -> (Context.generic -> value) -> raw
    28   val declare_global: string -> (Context.generic -> value) -> raw
    28   val declare_global: string * Position.T -> (Context.generic -> value) -> raw
    29   val declare_option: string -> raw
    29   val declare_option: string * Position.T -> raw
    30   val declare_option_global: string -> raw
    30   val declare_option_global: string * Position.T -> raw
    31   val name_of: 'a T -> string
    31   val name_of: 'a T -> string
       
    32   val pos_of: 'a T -> Position.T
    32 end;
    33 end;
    33 
    34 
    34 structure Config: CONFIG =
    35 structure Config: CONFIG =
    35 struct
    36 struct
    36 
    37 
    57   | same_type (Int _) (Int _) = true
    58   | same_type (Int _) (Int _) = true
    58   | same_type (Real _) (Real _) = true
    59   | same_type (Real _) (Real _) = true
    59   | same_type (String _) (String _) = true
    60   | same_type (String _) (String _) = true
    60   | same_type _ _ = false;
    61   | same_type _ _ = false;
    61 
    62 
    62 fun type_check name f value =
    63 fun type_check (name, pos) f value =
    63   let
    64   let
    64     val value' = f value;
    65     val value' = f value;
    65     val _ = same_type value value' orelse
    66     val _ = same_type value value' orelse
    66       error ("Ill-typed configuration option " ^ quote name ^ ": " ^
    67       error ("Ill-typed configuration option " ^ quote name ^ Position.here pos ^ ": " ^
    67         print_type value ^ " expected,\nbut " ^ print_type value' ^ " was found");
    68         print_type value ^ " expected,\nbut " ^ print_type value' ^ " was found");
    68   in value' end;
    69   in value' end;
    69 
    70 
    70 
    71 
    71 (* abstract configuration options *)
    72 (* abstract configuration options *)
    72 
    73 
    73 datatype 'a T = Config of
    74 datatype 'a T = Config of
    74  {name: string,
    75  {name: string,
       
    76   pos: Position.T,
    75   get_value: Context.generic -> 'a,
    77   get_value: Context.generic -> 'a,
    76   map_value: ('a -> 'a) -> Context.generic -> Context.generic};
    78   map_value: ('a -> 'a) -> Context.generic -> Context.generic};
    77 
    79 
    78 type raw = value T;
    80 type raw = value T;
    79 
    81 
    80 fun coerce make dest (Config {name, get_value, map_value}) = Config
    82 fun coerce make dest (Config {name, pos, get_value, map_value}) = Config
    81  {name = name,
    83  {name = name,
       
    84   pos = pos,
    82   get_value = dest o get_value,
    85   get_value = dest o get_value,
    83   map_value = fn f => map_value (make o f o dest)};
    86   map_value = fn f => map_value (make o f o dest)};
    84 
    87 
    85 val bool = coerce Bool (fn Bool b => b);
    88 val bool = coerce Bool (fn Bool b => b);
    86 val int = coerce Int (fn Int i => i);
    89 val int = coerce Int (fn Int i => i);
   110   fun merge data = Inttab.merge (K true) data;
   113   fun merge data = Inttab.merge (K true) data;
   111 );
   114 );
   112 
   115 
   113 local
   116 local
   114 
   117 
   115 fun declare_generic global name default =
   118 fun declare_generic global (name, pos) default =
   116   let
   119   let
   117     val id = serial ();
   120     val id = serial ();
   118 
   121 
   119     fun get_value context =
   122     fun get_value context =
   120       (case Inttab.lookup (Value.get context) id of
   123       (case Inttab.lookup (Value.get context) id of
   121         SOME value => value
   124         SOME value => value
   122       | NONE => default context);
   125       | NONE => default context);
   123 
   126 
   124     fun update_value f context =
   127     fun update_value f context =
   125       Value.map (Inttab.update (id, type_check name f (get_value context))) context;
   128       Value.map (Inttab.update (id, type_check (name, pos) f (get_value context))) context;
   126 
   129 
   127     fun map_value f (context as Context.Proof ctxt) =
   130     fun map_value f (context as Context.Proof ctxt) =
   128           let val context' = update_value f context in
   131           let val context' = update_value f context in
   129             if global andalso
   132             if global andalso
   130               Context_Position.is_visible ctxt andalso
   133               Context_Position.is_visible ctxt andalso
   135                 warning ("Ignoring local change of global option " ^ quote name)
   138                 warning ("Ignoring local change of global option " ^ quote name)
   136               else (); context)
   139               else (); context)
   137             else context'
   140             else context'
   138           end
   141           end
   139       | map_value f context = update_value f context;
   142       | map_value f context = update_value f context;
   140   in Config {name = name, get_value = get_value, map_value = map_value} end;
   143   in Config {name = name, pos = pos, get_value = get_value, map_value = map_value} end;
   141 
   144 
   142 fun declare_option_generic global name =
   145 fun declare_option_generic global (name, pos) =
   143   let
   146   let
   144     val typ = Options.default_typ name;
   147     val typ = Options.default_typ name;
   145     val default =
   148     val default =
   146       if typ = Options.boolT then fn _ => Bool (Options.default_bool name)
   149       if typ = Options.boolT then fn _ => Bool (Options.default_bool name)
   147       else if typ = Options.intT then fn _ => Int (Options.default_int name)
   150       else if typ = Options.intT then fn _ => Int (Options.default_int name)
   148       else if typ = Options.realT then fn _ => Real (Options.default_real name)
   151       else if typ = Options.realT then fn _ => Real (Options.default_real name)
   149       else if typ = Options.stringT then fn _ => String (Options.default_string name)
   152       else if typ = Options.stringT then fn _ => String (Options.default_string name)
   150       else error ("Unknown type for option " ^ quote name ^ " : " ^ quote typ);
   153       else error ("Unknown type for option " ^ quote name ^ Position.here pos ^ " : " ^ quote typ);
   151   in declare_generic global name default end;
   154   in declare_generic global (name, pos) default end;
   152 
   155 
   153 in
   156 in
   154 
   157 
   155 val declare = declare_generic false;
   158 val declare = declare_generic false;
   156 val declare_global = declare_generic true;
   159 val declare_global = declare_generic true;
   158 val declare_option_global = declare_option_generic true;
   161 val declare_option_global = declare_option_generic true;
   159 
   162 
   160 end;
   163 end;
   161 
   164 
   162 fun name_of (Config {name, ...}) = name;
   165 fun name_of (Config {name, ...}) = name;
       
   166 fun pos_of (Config {pos, ...}) = pos;
   163 
   167 
   164 
   168 
   165 (*final declarations of this structure!*)
   169 (*final declarations of this structure!*)
   166 val get = get_ctxt;
   170 val get = get_ctxt;
   167 val map = map_ctxt;
   171 val map = map_ctxt;