src/Pure/Tools/codegen_serializer.ML
changeset 22306 a532c39c8917
parent 22248 74ea64617c89
child 22355 f9d35783d28d
equal deleted inserted replaced
22305:0e56750a092b 22306:a532c39c8917
     1 (*  Title:      Pure/Tools/codegen_serializer.ML
     1     (*  Title:      Pure/Tools/codegen_serializer.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Florian Haftmann, TU Muenchen
     3     Author:     Florian Haftmann, TU Muenchen
     4 
     4 
     5 Serializer from intermediate language ("Thin-gol") to
     5 Serializer from intermediate language ("Thin-gol") to
     6 target languages (like SML or Haskell).
     6 target languages (like SML or Haskell).
    17    -> (string -> string) -> (string -> string) -> string -> theory -> theory;
    17    -> (string -> string) -> (string -> string) -> string -> theory -> theory;
    18   val add_undefined: string -> string -> string -> theory -> theory;
    18   val add_undefined: string -> string -> string -> theory -> theory;
    19   val add_pretty_imperative_monad_bind: string -> string -> theory -> theory;
    19   val add_pretty_imperative_monad_bind: string -> string -> theory -> theory;
    20 
    20 
    21   type serializer;
    21   type serializer;
    22   val add_serializer : string * serializer -> theory -> theory;
    22   val add_serializer: string * serializer -> theory -> theory;
    23   val get_serializer: theory -> string -> Args.T list
    23   val get_serializer: theory -> string -> Args.T list -> (theory -> string -> string)
    24     -> string list option -> CodegenThingol.code -> unit;
    24     -> string list option -> CodegenThingol.code -> unit;
    25   val assert_serializer: theory -> string -> string;
    25   val assert_serializer: theory -> string -> string;
    26 
    26 
    27   val const_has_serialization: theory -> string list -> string -> bool;
    27   val const_has_serialization: theory -> string list -> string -> bool;
    28   val tyco_has_serialization: theory -> string list -> string -> bool;
    28   val tyco_has_serialization: theory -> string list -> string -> bool;
    29 
    29 
    30   val eval_verbose: bool ref;
    30   val eval_verbose: bool ref;
    31   val eval_term: theory -> CodegenThingol.code
    31   val eval_term: theory -> (theory -> string -> string) -> CodegenThingol.code
    32     -> (string * 'a option ref) * CodegenThingol.iterm -> 'a;
    32     -> (string * 'a option ref) * CodegenThingol.iterm -> 'a;
    33   val code_width: int ref;
    33   val code_width: int ref;
    34 end;
    34 end;
    35 
    35 
    36 structure CodegenSerializer: CODEGEN_SERIALIZER =
    36 structure CodegenSerializer: CODEGEN_SERIALIZER =
    59     BR
    59     BR
    60   | NOBR
    60   | NOBR
    61   | INFX of (int * lrx);
    61   | INFX of (int * lrx);
    62 
    62 
    63 val APP = INFX (~1, L);
    63 val APP = INFX (~1, L);
    64 
       
    65 type typ_syntax = int * ((fixity -> itype -> Pretty.T)
       
    66   -> fixity -> itype list -> Pretty.T);
       
    67 type term_syntax = int * ((CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T)
       
    68   -> CodegenNames.var_ctxt ->  fixity -> iterm list -> Pretty.T);
       
    69 
    64 
    70 fun eval_lrx L L = false
    65 fun eval_lrx L L = false
    71   | eval_lrx R R = false
    66   | eval_lrx R R = false
    72   | eval_lrx _ _ = true;
    67   | eval_lrx _ _ = true;
    73 
    68 
    91   gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps);
    86   gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps);
    92 
    87 
    93 fun brackify_infix infx fxy_ctxt ps =
    88 fun brackify_infix infx fxy_ctxt ps =
    94   gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps);
    89   gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps);
    95 
    90 
       
    91 type class_syntax = string * (string -> string option);
       
    92 type typ_syntax = int * ((fixity -> itype -> Pretty.T)
       
    93   -> fixity -> itype list -> Pretty.T);
       
    94 type term_syntax = int * ((CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T)
       
    95   -> CodegenNames.var_ctxt -> fixity -> (iterm * itype) list -> Pretty.T);
       
    96 
    96 
    97 
    97 (* user-defined syntax *)
    98 (* user-defined syntax *)
    98 
    99 
    99 datatype 'a mixfix =
   100 datatype 'a mixfix =
   100     Arg of fixity
   101     Arg of fixity
   101   | Pretty of Pretty.T;
   102   | Pretty of Pretty.T;
   102 
   103 
   103 fun mk_mixfix (fixity_this, mfx) =
   104 fun mk_mixfix prep_arg (fixity_this, mfx) =
   104   let
   105   let
   105     fun is_arg (Arg _) = true
   106     fun is_arg (Arg _) = true
   106       | is_arg _ = false;
   107       | is_arg _ = false;
   107     val i = (length o filter is_arg) mfx;
   108     val i = (length o filter is_arg) mfx;
   108     fun fillin _ [] [] =
   109     fun fillin _ [] [] =
   109           []
   110           []
   110       | fillin pr (Arg fxy :: mfx) (a :: args) =
   111       | fillin pr (Arg fxy :: mfx) (a :: args) =
   111           pr fxy a :: fillin pr mfx args
   112           (pr fxy o prep_arg) a :: fillin pr mfx args
   112       | fillin pr (Pretty p :: mfx) args =
   113       | fillin pr (Pretty p :: mfx) args =
   113           p :: fillin pr mfx args
   114           p :: fillin pr mfx args
   114       | fillin _ [] _ =
   115       | fillin _ [] _ =
   115           error ("Inconsistent mixfix: too many arguments")
   116           error ("Inconsistent mixfix: too many arguments")
   116       | fillin _ _ [] =
   117       | fillin _ _ [] =
   118   in
   119   in
   119     (i, fn pr => fn fixity_ctxt => fn args =>
   120     (i, fn pr => fn fixity_ctxt => fn args =>
   120       gen_brackify (eval_fxy fixity_this fixity_ctxt) (fillin pr mfx args))
   121       gen_brackify (eval_fxy fixity_this fixity_ctxt) (fillin pr mfx args))
   121   end;
   122   end;
   122 
   123 
   123 fun parse_infix (x, i) s =
   124 fun parse_infix prep_arg (x, i) s =
   124   let
   125   let
   125     val l = case x of L => INFX (i, L) | _ => INFX (i, X);
   126     val l = case x of L => INFX (i, L) | _ => INFX (i, X);
   126     val r = case x of R => INFX (i, R) | _ => INFX (i, X);
   127     val r = case x of R => INFX (i, R) | _ => INFX (i, X);
   127   in
   128   in
   128     mk_mixfix (INFX (i, x), [Arg l, (Pretty o Pretty.brk) 1, (Pretty o str) s, (Pretty o Pretty.brk) 1, Arg r])
   129     mk_mixfix prep_arg (INFX (i, x), [Arg l, (Pretty o Pretty.brk) 1, (Pretty o str) s, (Pretty o Pretty.brk) 1, Arg r])
   129   end;
   130   end;
   130 
   131 
   131 fun parse_mixfix s =
   132 fun parse_mixfix prep_arg s =
   132   let
   133   let
   133     val sym_any = Scan.one Symbol.not_eof;
   134     val sym_any = Scan.one Symbol.not_eof;
   134     val parse = Scan.optional ($$ "!" >> K true) false -- Scan.repeat (
   135     val parse = Scan.optional ($$ "!" >> K true) false -- Scan.repeat (
   135          ($$ "(" -- $$ "_" -- $$ ")" >> K (Arg NOBR))
   136          ($$ "(" -- $$ "_" -- $$ ")" >> K (Arg NOBR))
   136       || ($$ "_" >> K (Arg BR))
   137       || ($$ "_" >> K (Arg BR))
   138       || (Scan.repeat1
   139       || (Scan.repeat1
   139            (   $$ "'" |-- sym_any
   140            (   $$ "'" |-- sym_any
   140             || Scan.unless ($$ "_" || $$ "/" || $$ "(" |-- $$ "_" |-- $$ ")")
   141             || Scan.unless ($$ "_" || $$ "/" || $$ "(" |-- $$ "_" |-- $$ ")")
   141                  sym_any) >> (Pretty o str o implode)));
   142                  sym_any) >> (Pretty o str o implode)));
   142   in case Scan.finite Symbol.stopper parse (Symbol.explode s)
   143   in case Scan.finite Symbol.stopper parse (Symbol.explode s)
   143    of ((_, p as [_]), []) => mk_mixfix (NOBR, p)
   144    of ((_, p as [_]), []) => mk_mixfix prep_arg (NOBR, p)
   144     | ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p)
   145     | ((b, p as _ :: _ :: _), []) => mk_mixfix prep_arg (if b then NOBR else BR, p)
   145     | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail ()
   146     | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail ()
   146   end;
   147   end;
   147 
   148 
   148 fun parse_args f args =
   149 fun parse_args f args =
   149   case Scan.read Args.stopper f args
   150   case Scan.read Args.stopper f args
   151     | NONE => error "Bad serializer arguments";
   152     | NONE => error "Bad serializer arguments";
   152 
   153 
   153 
   154 
   154 (* generic serializer combinators *)
   155 (* generic serializer combinators *)
   155 
   156 
   156 fun gen_pr_app pr_app' pr_term const_syntax vars fxy (app as ((c, (_, ty)), ts)) =
   157 fun gen_pr_app pr_app' pr_term const_syntax vars fxy (app as ((c, (_, tys)), ts)) =
   157   case const_syntax c
   158   case const_syntax c
   158    of NONE => brackify fxy (pr_app' vars app)
   159    of NONE => brackify fxy (pr_app' vars app)
   159     | SOME (i, pr) =>
   160     | SOME (i, pr) =>
   160         let
   161         let
   161           val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i
   162           val k = if i < 0 then length tys else i;
       
   163           fun pr' fxy ts = pr pr_term vars fxy (ts ~~ curry Library.take k tys);
   162         in if k = length ts
   164         in if k = length ts
   163           then 
   165           then pr' fxy ts
   164             pr pr_term vars fxy ts
   166         else if k < length ts
   165           else if k < length ts
   167           then case chop k ts of (ts1, ts2) => brackify fxy (pr' APP ts1 :: map (pr_term vars BR) ts2)
   166           then case chop k ts of (ts1, ts2) =>
       
   167             brackify fxy (pr pr_term vars APP ts1 :: map (pr_term vars BR) ts2)
       
   168           else pr_term vars fxy (CodegenThingol.eta_expand app k)
   168           else pr_term vars fxy (CodegenThingol.eta_expand app k)
   169         end;
   169         end;
   170 
   170 
   171 fun gen_pr_bind pr_bind' pr_term fxy ((v, pat), ty) vars =
   171 fun gen_pr_bind pr_bind' pr_term fxy ((v, pat), ty) vars =
   172   let
   172   let
   215             | NONE => NONE;
   215             | NONE => NONE;
   216   in CodegenThingol.unfoldr dest_monad t end;
   216   in CodegenThingol.unfoldr dest_monad t end;
   217 
   217 
   218 fun pretty_ml_string c_nil c_cons mk_char mk_string target_implode =
   218 fun pretty_ml_string c_nil c_cons mk_char mk_string target_implode =
   219   let
   219   let
   220     fun pretty pr vars fxy [t] =
   220     fun pretty pr vars fxy [(t, _)] =
   221       case implode_list c_nil c_cons t
   221       case implode_list c_nil c_cons t
   222        of SOME ts => (case implode_string mk_char mk_string ts
   222        of SOME ts => (case implode_string mk_char mk_string ts
   223            of SOME p => p
   223            of SOME p => p
   224             | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr vars BR t])
   224             | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr vars BR t])
   225         | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr vars BR t]
   225         | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr vars BR t]
   231       brackify_infix (target_fxy, R) fxy [
   231       brackify_infix (target_fxy, R) fxy [
   232         pr (INFX (target_fxy, X)) t1,
   232         pr (INFX (target_fxy, X)) t1,
   233         str target_cons,
   233         str target_cons,
   234         pr (INFX (target_fxy, R)) t2
   234         pr (INFX (target_fxy, R)) t2
   235       ];
   235       ];
   236     fun pretty pr vars fxy [t1, t2] =
   236     fun pretty pr vars fxy [(t1, _), (t2, _)] =
   237       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   237       case Option.map (cons t1) (implode_list c_nil c_cons t2)
   238        of SOME ts =>
   238        of SOME ts =>
   239             (case mk_char_string
   239             (case mk_char_string
   240              of SOME (mk_char, mk_string) =>
   240              of SOME (mk_char, mk_string) =>
   241                   (case implode_string mk_char mk_string ts
   241                   (case implode_string mk_char mk_string ts
   245         | NONE => default (pr vars) fxy t1 t2;
   245         | NONE => default (pr vars) fxy t1 t2;
   246   in (2, pretty) end;
   246   in (2, pretty) end;
   247 
   247 
   248 val pretty_imperative_monad_bind =
   248 val pretty_imperative_monad_bind =
   249   let
   249   let
   250     fun pretty (pr : CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T) vars fxy [t1, (v, ty) `|-> t2] =
   250     fun pretty (pr : CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T)
   251           pr vars fxy (ICase ((t1, ty), ([(IVar v, t2)])))
   251           vars fxy [(t1, _), ((v, ty) `|-> t2, _)] =
   252       | pretty pr vars fxy [t1, t2] =
   252             pr vars fxy (ICase ((t1, ty), ([(IVar v, t2)])))
       
   253       | pretty pr vars fxy [(t1, _), (t2, ty2)] =
   253           let
   254           let
   254             (*this code suffers from the lack of a proper concept for bindings*)
   255             (*this code suffers from the lack of a proper concept for bindings*)
   255             val vs = CodegenThingol.fold_varnames cons t2 [];
   256             val vs = CodegenThingol.fold_varnames cons t2 [];
   256             val v = Name.variant vs "x";
   257             val v = Name.variant vs "x";
   257             val vars' = CodegenNames.intro_vars [v] vars;
   258             val vars' = CodegenNames.intro_vars [v] vars;
   258             val var = IVar v;
   259             val var = IVar v;
   259             val ty = "" `%% []; (*an approximation*)
   260             val ty = (hd o fst o CodegenThingol.unfold_fun) ty2;
   260           in pr vars' fxy (ICase ((t1, ty), ([(var, t2 `$ var)]))) end;
   261           in pr vars' fxy (ICase ((t1, ty), ([(var, t2 `$ var)]))) end;
   261   in (2, pretty) end;
   262   in (2, pretty) end;
   262 
   263 
   263 
   264 
   264 
   265 
   299   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   300   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   300   | MLClassinst of string * ((class * (string * (vname * sort) list))
   301   | MLClassinst of string * ((class * (string * (vname * sort) list))
   301         * ((class * (string * (string * dict list list))) list
   302         * ((class * (string * (string * dict list list))) list
   302       * (string * iterm) list));
   303       * (string * iterm) list));
   303 
   304 
   304 fun pr_sml tyco_syntax const_syntax keyword_vars deresolv is_cons ml_def =
   305 fun pr_sml tyco_syntax const_syntax labelled_name keyword_vars deresolv is_cons ml_def =
   305   let
   306   let
   306     val pr_label = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   307     val pr_label = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   307     fun pr_dicts fxy ds =
   308     fun pr_dicts fxy ds =
   308       let
   309       let
   309         fun pr_dictvar (v, (_, 1)) = first_upper v ^ "_"
   310         fun pr_dictvar (v, (_, 1)) = first_upper v ^ "_"
   401               :: pr_term vars NOBR td
   402               :: pr_term vars NOBR td
   402               :: pr "of" b
   403               :: pr "of" b
   403               :: map (pr "|") bs
   404               :: map (pr "|") bs
   404             )
   405             )
   405           end
   406           end
   406     and pr_app' vars (app as ((c, (iss, ty)), ts)) =
   407     and pr_app' vars (app as ((c, (iss, tys)), ts)) =
   407       if is_cons c then let
   408       if is_cons c then let
   408         val k = (length o fst o CodegenThingol.unfold_fun) ty
   409         val k = length tys
   409       in if k < 2 then 
   410       in if k < 2 then 
   410         (str o deresolv) c :: map (pr_term vars BR) ts
   411         (str o deresolv) c :: map (pr_term vars BR) ts
   411       else if k = length ts then
   412       else if k = length ts then
   412         [(str o deresolv) c, Pretty.enum "," "(" ")" (map (pr_term vars NOBR) ts)]
   413         [(str o deresolv) c, Pretty.enum "," "(" ")" (map (pr_term vars NOBR) ts)]
   413       else [pr_term vars BR (CodegenThingol.eta_expand app k)] end else
   414       else [pr_term vars BR (CodegenThingol.eta_expand app k)] end else
   427                   | mk (_::_) _ = "fun"
   428                   | mk (_::_) _ = "fun"
   428                   | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun";
   429                   | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun";
   429                 fun chk (_, ((ts, _) :: _, (vs, _))) NONE = SOME (mk ts vs)
   430                 fun chk (_, ((ts, _) :: _, (vs, _))) NONE = SOME (mk ts vs)
   430                   | chk (_, ((ts, _) :: _, (vs, _))) (SOME defi) =
   431                   | chk (_, ((ts, _) :: _, (vs, _))) (SOME defi) =
   431                       if defi = mk ts vs then SOME defi
   432                       if defi = mk ts vs then SOME defi
   432                       else error ("Mixing simultaneous vals and funs not implemented");
   433                       else error ("Mixing simultaneous vals and funs not implemented: "
       
   434                         ^ commas (map (labelled_name o fst) funns));
   433               in the (fold chk funns NONE) end;
   435               in the (fold chk funns NONE) end;
   434             fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) =
   436             fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) =
   435               let
   437               let
   436                 val vs = filter_out (null o snd) raw_vs;
   438                 val vs = filter_out (null o snd) raw_vs;
   437                 val shift = if null eqs' then I else
   439                 val shift = if null eqs' then I else
   571   ] @ content @ [
   573   ] @ content @ [
   572     str "",
   574     str "",
   573     str ("end; (*struct " ^ name ^ "*)")
   575     str ("end; (*struct " ^ name ^ "*)")
   574   ]);
   576   ]);
   575 
   577 
   576 fun pr_ocaml tyco_syntax const_syntax keyword_vars deresolv is_cons ml_def =
   578 fun pr_ocaml tyco_syntax const_syntax labelled_name keyword_vars deresolv is_cons ml_def =
   577   let
   579   let
   578     fun pr_dicts fxy ds =
   580     fun pr_dicts fxy ds =
   579       let
   581       let
   580         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   582         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   581           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   583           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   662               :: pr_term vars NOBR td
   664               :: pr_term vars NOBR td
   663               :: pr "with" b
   665               :: pr "with" b
   664               :: map (pr "|") bs
   666               :: map (pr "|") bs
   665             )
   667             )
   666           end
   668           end
   667     and pr_app' vars (app as ((c, (iss, ty)), ts)) =
   669     and pr_app' vars (app as ((c, (iss, tys)), ts)) =
   668       if is_cons c then
   670       if is_cons c then
   669         if (length o fst o CodegenThingol.unfold_fun) ty = length ts
   671         if length tys = length ts
   670         then case ts
   672         then case ts
   671          of [] => [(str o deresolv) c]
   673          of [] => [(str o deresolv) c]
   672           | [t] => [(str o deresolv) c, pr_term vars BR t]
   674           | [t] => [(str o deresolv) c, pr_term vars BR t]
   673           | _ => [(str o deresolv) c, Pretty.enum "," "(" ")" (map (pr_term vars NOBR) ts)]
   675           | _ => [(str o deresolv) c, Pretty.enum "," "(" ")" (map (pr_term vars NOBR) ts)]
   674         else [pr_term vars BR (CodegenThingol.eta_expand app ((length o fst o CodegenThingol.unfold_fun) ty))]
   676         else [pr_term vars BR (CodegenThingol.eta_expand app (length tys))]
   675       else (str o deresolv) c
   677       else (str o deresolv) c
   676         :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term vars BR) ts)
   678         :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term vars BR) ts)
   677     and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars
   679     and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars
   678     and pr_bind' ((NONE, NONE), _) = str "_"
   680     and pr_bind' ((NONE, NONE), _) = str "_"
   679       | pr_bind' ((SOME v, NONE), _) = str v
   681       | pr_bind' ((SOME v, NONE), _) = str v
   866   ]);
   868   ]);
   867 
   869 
   868 val code_width = ref 80;
   870 val code_width = ref 80;
   869 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   871 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   870 
   872 
   871 fun seri_ml pr_def pr_modl output reserved_user module_alias module_prolog
   873 fun seri_ml pr_def pr_modl output labelled_name reserved_user module_alias module_prolog
   872   (_ : string -> (string * (string -> string option)) option) tyco_syntax const_syntax code =
   874   (_ : string -> class_syntax option) tyco_syntax const_syntax code =
   873   let
   875   let
   874     val is_cons = fn node => case CodegenThingol.get_def code node
   876     val is_cons = fn node => case CodegenThingol.get_def code node
   875      of CodegenThingol.Datatypecons _ => true
   877      of CodegenThingol.Datatypecons _ => true
   876       | _ => false;
   878       | _ => false;
   877     datatype node =
   879     datatype node =
   915       in (x, (nsp_fun, nsp_typ')) end;
   917       in (x, (nsp_fun, nsp_typ')) end;
   916     fun mk_funs defs =
   918     fun mk_funs defs =
   917       fold_map
   919       fold_map
   918         (fn (name, CodegenThingol.Fun info) =>
   920         (fn (name, CodegenThingol.Fun info) =>
   919               map_nsp_fun (name_def false name) >> (fn base => (base, (name, info)))
   921               map_nsp_fun (name_def false name) >> (fn base => (base, (name, info)))
   920           | (name, def) => error ("Function block containing illegal def: " ^ quote name)
   922           | (name, def) => error ("Function block containing illegal definition: " ^ labelled_name name)
   921         ) defs
   923         ) defs
   922       >> (split_list #> apsnd MLFuns);
   924       >> (split_list #> apsnd MLFuns);
   923     fun mk_datatype defs =
   925     fun mk_datatype defs =
   924       fold_map
   926       fold_map
   925         (fn (name, CodegenThingol.Datatype info) =>
   927         (fn (name, CodegenThingol.Datatype info) =>
   926               map_nsp_typ (name_def false name) >> (fn base => (base, SOME (name, info)))
   928               map_nsp_typ (name_def false name) >> (fn base => (base, SOME (name, info)))
   927           | (name, CodegenThingol.Datatypecons _) =>
   929           | (name, CodegenThingol.Datatypecons _) =>
   928               map_nsp_fun (name_def true name) >> (fn base => (base, NONE))
   930               map_nsp_fun (name_def true name) >> (fn base => (base, NONE))
   929           | (name, def) => error ("Datatype block containing illegal def: " ^ quote name)
   931           | (name, def) => error ("Datatype block containing illegal definition: " ^ labelled_name name)
   930         ) defs
   932         ) defs
   931       >> (split_list #> apsnd (map_filter I
   933       >> (split_list #> apsnd (map_filter I
   932         #> (fn [] => error ("Datatype block without data: " ^ (commas o map (quote o fst)) defs)
   934         #> (fn [] => error ("Datatype block without data definition: " ^ (commas o map (labelled_name o fst)) defs)
   933              | infos => MLDatas infos)));
   935              | infos => MLDatas infos)));
   934     fun mk_class defs =
   936     fun mk_class defs =
   935       fold_map
   937       fold_map
   936         (fn (name, CodegenThingol.Class info) =>
   938         (fn (name, CodegenThingol.Class info) =>
   937               map_nsp_typ (name_def false name) >> (fn base => (base, SOME (name, info)))
   939               map_nsp_typ (name_def false name) >> (fn base => (base, SOME (name, info)))
   938           | (name, CodegenThingol.Classrel _) =>
   940           | (name, CodegenThingol.Classrel _) =>
   939               map_nsp_fun (name_def false name) >> (fn base => (base, NONE))
   941               map_nsp_fun (name_def false name) >> (fn base => (base, NONE))
   940           | (name, CodegenThingol.Classop _) =>
   942           | (name, CodegenThingol.Classop _) =>
   941               map_nsp_fun (name_def false name) >> (fn base => (base, NONE))
   943               map_nsp_fun (name_def false name) >> (fn base => (base, NONE))
   942           | (name, def) => error ("Class block containing illegal def: " ^ quote name)
   944           | (name, def) => error ("Class block containing illegal definition: " ^ labelled_name name)
   943         ) defs
   945         ) defs
   944       >> (split_list #> apsnd (map_filter I
   946       >> (split_list #> apsnd (map_filter I
   945         #> (fn [] => error ("Class block without class: " ^ (commas o map (quote o fst)) defs)
   947         #> (fn [] => error ("Class block without class definition: " ^ (commas o map (labelled_name o fst)) defs)
   946              | [info] => MLClass info)));
   948              | [info] => MLClass info)));
   947     fun mk_inst [(name, CodegenThingol.Classinst info)] =
   949     fun mk_inst [(name, CodegenThingol.Classinst info)] =
   948       map_nsp_fun (name_def false name)
   950       map_nsp_fun (name_def false name)
   949       >> (fn base => ([base], MLClassinst (name, info)));
   951       >> (fn base => ([base], MLClassinst (name, info)));
   950     fun add_group mk defs nsp_nodes =
   952     fun add_group mk defs nsp_nodes =
   955           |> fold (fold (insert (op =)) o Graph.imm_succs code) names
   957           |> fold (fold (insert (op =)) o Graph.imm_succs code) names
   956           |> subtract (op =) names;
   958           |> subtract (op =) names;
   957         val (modls, _) = (split_list o map dest_name) names;
   959         val (modls, _) = (split_list o map dest_name) names;
   958         val modl = (the_single o distinct (op =)) modls
   960         val modl = (the_single o distinct (op =)) modls
   959           handle Empty =>
   961           handle Empty =>
   960             error ("Illegal mutual dependencies: " ^ commas names);
   962             error ("Illegal mutual dependencies: " ^ commas (map labelled_name names));
   961         val modl' = name_modl modl;
   963         val modl' = name_modl modl;
   962         val modl_explode = NameSpace.explode modl';
   964         val modl_explode = NameSpace.explode modl';
   963         fun add_dep name name'' =
   965         fun add_dep name name'' =
   964           let
   966           let
   965             val modl'' = (name_modl o fst o dest_name) name'';
   967             val modl'' = (name_modl o fst o dest_name) name'';
   998           add_group mk_class defs
  1000           add_group mk_class defs
   999       | group_defs ((defs as (_, CodegenThingol.Classop _)::_)) =
  1001       | group_defs ((defs as (_, CodegenThingol.Classop _)::_)) =
  1000           add_group mk_class defs
  1002           add_group mk_class defs
  1001       | group_defs ((defs as [(_, CodegenThingol.Classinst _)])) =
  1003       | group_defs ((defs as [(_, CodegenThingol.Classinst _)])) =
  1002           add_group mk_inst defs
  1004           add_group mk_inst defs
  1003       | group_defs defs = error ("Illegal mutual dependencies: " ^ (commas o map fst) defs)
  1005       | group_defs defs = error ("Illegal mutual dependencies: " ^ (commas o map (labelled_name o fst)) defs)
  1004     val (_, nodes) =
  1006     val (_, nodes) =
  1005       empty_module
  1007       empty_module
  1006       |> fold group_defs (map (AList.make (Graph.get_node code))
  1008       |> fold group_defs (map (AList.make (Graph.get_node code))
  1007           (rev (Graph.strong_conn code)))
  1009           (rev (Graph.strong_conn code)))
  1008     fun deresolver prefix name = 
  1010     fun deresolver prefix name = 
  1016               of Module (_, (_, g)) => g) modl'
  1018               of Module (_, (_, g)) => g) modl'
  1017           |> (fn g => case Graph.get_node g name of Def (defname, _) => defname);
  1019           |> (fn g => case Graph.get_node g name of Def (defname, _) => defname);
  1018       in
  1020       in
  1019         NameSpace.implode (remainder @ [defname'])
  1021         NameSpace.implode (remainder @ [defname'])
  1020       end handle Graph.UNDEF _ =>
  1022       end handle Graph.UNDEF _ =>
  1021         error "Unknown name: " ^ quote name;
  1023         error ("Unknown definition name: " ^ labelled_name name);
  1022     fun the_prolog modlname = case module_prolog modlname
  1024     fun the_prolog modlname = case module_prolog modlname
  1023      of NONE => []
  1025      of NONE => []
  1024       | SOME p => [p, str ""];
  1026       | SOME p => [p, str ""];
  1025     fun pr_node prefix (Def (_, NONE)) =
  1027     fun pr_node prefix (Def (_, NONE)) =
  1026           NONE
  1028           NONE
  1027       | pr_node prefix (Def (_, SOME def)) =
  1029       | pr_node prefix (Def (_, SOME def)) =
  1028           SOME (pr_def tyco_syntax const_syntax init_vars (deresolver prefix) is_cons def)
  1030           SOME (pr_def tyco_syntax const_syntax labelled_name init_vars (deresolver prefix) is_cons def)
  1029       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1031       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1030           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1032           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1031             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1033             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1032                 o rev o flat o Graph.strong_conn) nodes)));
  1034                 o rev o flat o Graph.strong_conn) nodes)));
  1033     val p = pr_modl "ROOT" (the_prolog "" @ separate (str "") ((map_filter
  1035     val p = pr_modl "ROOT" (the_prolog "" @ separate (str "") ((map_filter
  1068 
  1070 
  1069 val pr_bind_haskell = gen_pr_bind pr_bind';
  1071 val pr_bind_haskell = gen_pr_bind pr_bind';
  1070 
  1072 
  1071 in
  1073 in
  1072 
  1074 
  1073 fun pr_haskell class_syntax tyco_syntax const_syntax keyword_vars deresolv_here deresolv deriving_show def =
  1075 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name keyword_vars deresolv_here deresolv deriving_show def =
  1074   let
  1076   let
  1075     fun class_name class = case class_syntax class
  1077     fun class_name class = case class_syntax class
  1076      of NONE => deresolv class
  1078      of NONE => deresolv class
  1077       | SOME (class, _) => class;
  1079       | SOME (class, _) => class;
  1078     fun classop_name class classop = case class_syntax class
  1080     fun classop_name class classop = case class_syntax class
  1283           end;
  1285           end;
  1284   in pr_def def end;
  1286   in pr_def def end;
  1285 
  1287 
  1286 fun pretty_haskell_monad c_mbind c_kbind =
  1288 fun pretty_haskell_monad c_mbind c_kbind =
  1287   let
  1289   let
  1288     fun pretty pr vars fxy [t] =
  1290     fun pretty pr vars fxy [(t, _)] =
  1289       let
  1291       let
  1290         val pr_bind = pr_bind_haskell pr;
  1292         val pr_bind = pr_bind_haskell pr;
  1291         fun pr_mbind (NONE, t) vars =
  1293         fun pr_mbind (NONE, t) vars =
  1292               (semicolon [pr vars NOBR t], vars)
  1294               (semicolon [pr vars NOBR t], vars)
  1293           | pr_mbind (SOME (bind, true), t) vars = vars
  1295           | pr_mbind (SOME (bind, true), t) vars = vars
  1308   "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
  1310   "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
  1309   "import", "default", "forall", "let", "in", "class", "qualified", "data",
  1311   "import", "default", "forall", "let", "in", "class", "qualified", "data",
  1310   "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
  1312   "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
  1311 ];
  1313 ];
  1312 
  1314 
  1313 fun seri_haskell module_prefix destination string_classes reserved_user module_alias module_prolog
  1315 fun seri_haskell module_prefix destination string_classes labelled_name reserved_user module_alias module_prolog
  1314   class_syntax tyco_syntax const_syntax code =
  1316   class_syntax tyco_syntax const_syntax code =
  1315   let
  1317   let
  1316     val _ = Option.map File.check destination;
  1318     val _ = Option.map File.check destination;
  1317     val empty_names = Name.make_context (reserved_haskell @ reserved_user);
  1319     val empty_names = Name.make_context (reserved_haskell @ reserved_user);
  1318     val name_modl = mk_modl_name_tab empty_names module_prefix module_alias code
  1320     val name_modl = mk_modl_name_tab empty_names module_prefix module_alias code
  1319     fun add_def (name, (def, deps : string list)) =
  1321     fun add_def (name, (def, deps)) =
  1320       let
  1322       let
  1321         val (modl, base) = dest_name name;
  1323         val (modl, base) = dest_name name;
  1322         fun name_def base = Name.variants [base] #>> the_single;
  1324         fun name_def base = Name.variants [base] #>> the_single;
  1323         fun add_fun upper (nsp_fun, nsp_typ) =
  1325         fun add_fun upper (nsp_fun, nsp_typ) =
  1324           let
  1326           let
  1361         (Graph.strong_conn code |> flat)) Symtab.empty;
  1363         (Graph.strong_conn code |> flat)) Symtab.empty;
  1362     val init_vars = CodegenNames.make_vars (reserved_haskell @ reserved_user);
  1364     val init_vars = CodegenNames.make_vars (reserved_haskell @ reserved_user);
  1363     fun deresolv name =
  1365     fun deresolv name =
  1364       (fst o fst o the o AList.lookup (op =) ((fst o snd o the
  1366       (fst o fst o the o AList.lookup (op =) ((fst o snd o the
  1365         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1367         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1366         handle Option => "(error \"undefined name " ^ name ^ "\")";
  1368         handle Option => error ("Unknown definition name: " ^ labelled_name name);
  1367     fun deresolv_here name =
  1369     fun deresolv_here name =
  1368       (snd o fst o the o AList.lookup (op =) ((fst o snd o the
  1370       (snd o fst o the o AList.lookup (op =) ((fst o snd o the
  1369         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1371         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1370         handle Option => "(error \"undefined name " ^ name ^ "\")";
  1372         handle Option => error ("Unknown definition name: " ^ labelled_name name);
  1371     fun deriving_show tyco =
  1373     fun deriving_show tyco =
  1372       let
  1374       let
  1373         fun deriv _ "fun" = false
  1375         fun deriv _ "fun" = false
  1374           | deriv tycos tyco = member (op =) tycos tyco orelse
  1376           | deriv tycos tyco = member (op =) tycos tyco orelse
  1375               case the_default CodegenThingol.Bot (try (Graph.get_node code) tyco)
  1377               case the_default CodegenThingol.Bot (try (Graph.get_node code) tyco)
  1378                     (maps snd cs)
  1380                     (maps snd cs)
  1379         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1381         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1380               andalso forall (deriv' tycos) tys
  1382               andalso forall (deriv' tycos) tys
  1381           | deriv' _ (ITyVar _) = true
  1383           | deriv' _ (ITyVar _) = true
  1382       in deriv [] tyco end;
  1384       in deriv [] tyco end;
  1383     fun seri_def qualified = pr_haskell class_syntax tyco_syntax const_syntax init_vars
  1385     fun seri_def qualified = pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_vars
  1384       deresolv_here (if qualified then deresolv else deresolv_here) (if string_classes then deriving_show else K false);
  1386       deresolv_here (if qualified then deresolv else deresolv_here)
       
  1387       (if string_classes then deriving_show else K false);
  1385     fun write_module (SOME destination) modlname =
  1388     fun write_module (SOME destination) modlname =
  1386           let
  1389           let
  1387             val filename = case modlname
  1390             val filename = case modlname
  1388              of "" => Path.explode "Main.hs"
  1391              of "" => Path.explode "Main.hs"
  1389               | _ => (Path.ext "hs" o Path.explode o implode o separate "/" o NameSpace.explode) modlname;
  1392               | _ => (Path.ext "hs" o Path.explode o implode o separate "/" o NameSpace.explode) modlname;
  1434       seri_haskell module_prefix (Option.map Path.explode destination) string_classes));
  1437       seri_haskell module_prefix (Option.map Path.explode destination) string_classes));
  1435 
  1438 
  1436 
  1439 
  1437 (** diagnosis serializer **)
  1440 (** diagnosis serializer **)
  1438 
  1441 
  1439 fun seri_diagnosis _ _ _ _ _ code =
  1442 fun seri_diagnosis labelled_name _ _ _ _ _ code =
  1440   let
  1443   let
  1441     val init_vars = CodegenNames.make_vars reserved_haskell;
  1444     val init_vars = CodegenNames.make_vars reserved_haskell;
  1442     val pr = pr_haskell (K NONE) (K NONE) (K NONE) init_vars I I (K false);
  1445     val pr = pr_haskell (K NONE) (K NONE) (K NONE) labelled_name init_vars I I (K false);
  1443   in
  1446   in
  1444     []
  1447     []
  1445     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1448     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1446     |> Pretty.chunks2
  1449     |> Pretty.chunks2
  1447     |> code_output
  1450     |> code_output
  1487     Symtab.merge (op =) (alias1, alias2),
  1490     Symtab.merge (op =) (alias1, alias2),
  1488     Symtab.merge (op =) (prolog1, prolog2)
  1491     Symtab.merge (op =) (prolog1, prolog2)
  1489   );
  1492   );
  1490 
  1493 
  1491 type serializer = Args.T list
  1494 type serializer = Args.T list
       
  1495   -> (string -> string)
  1492   -> string list
  1496   -> string list
  1493   -> (string -> string option)
  1497   -> (string -> string option)
  1494   -> (string -> Pretty.T option)
  1498   -> (string -> Pretty.T option)
  1495   -> (string -> (string * (string -> string option)) option)
  1499   -> (string -> class_syntax option)
  1496   -> (string -> typ_syntax option)
  1500   -> (string -> typ_syntax option)
  1497   -> (string -> term_syntax option)
  1501   -> (string -> term_syntax option)
  1498   -> CodegenThingol.code -> unit;
  1502   -> CodegenThingol.code -> unit;
  1499 
  1503 
  1500 datatype target = Target of {
  1504 datatype target = Target of {
  1572   #> add_serializer (target_OCaml, isar_seri_ocaml)
  1576   #> add_serializer (target_OCaml, isar_seri_ocaml)
  1573   #> add_serializer (target_Haskell, isar_seri_haskell)
  1577   #> add_serializer (target_Haskell, isar_seri_haskell)
  1574   #> add_serializer (target_diag, (fn _ => fn _ => seri_diagnosis))
  1578   #> add_serializer (target_diag, (fn _ => fn _ => seri_diagnosis))
  1575 );
  1579 );
  1576 
  1580 
  1577 fun get_serializer thy target args = fn cs =>
  1581 fun get_serializer thy target args labelled_name = fn cs =>
  1578   let
  1582   let
  1579     val data = case Symtab.lookup (CodegenSerializerData.get thy) target
  1583     val data = case Symtab.lookup (CodegenSerializerData.get thy) target
  1580      of SOME data => data
  1584      of SOME data => data
  1581       | NONE => error ("Unknown code target language: " ^ quote target);
  1585       | NONE => error ("Unknown code target language: " ^ quote target);
  1582     val seri = the_serializer data;
  1586     val seri = the_serializer data;
  1586     fun fun_of sys = (Option.map fst oo Symtab.lookup) sys;
  1590     fun fun_of sys = (Option.map fst oo Symtab.lookup) sys;
  1587     val project = if target = target_diag then I
  1591     val project = if target = target_diag then I
  1588       else CodegenThingol.project_code
  1592       else CodegenThingol.project_code
  1589         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const) cs;
  1593         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const) cs;
  1590   in
  1594   in
  1591     project #> seri args reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1595     project #> seri args (labelled_name thy) reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1592       (fun_of class) (fun_of tyco) (fun_of const)
  1596       (fun_of class) (fun_of tyco) (fun_of const)
  1593   end;
  1597   end;
  1594 
  1598 
  1595 val eval_verbose = ref false;
  1599 val eval_verbose = ref false;
  1596 
  1600 
  1597 fun eval_term thy code ((ref_name, reff), t) =
  1601 fun eval_term thy labelled_name code ((ref_name, reff), t) =
  1598   let
  1602   let
  1599     val val_name = "eval.EVAL.EVAL";
  1603     val val_name = "eval.EVAL.EVAL";
  1600     val val_name' = "ROOT.eval.EVAL";
  1604     val val_name' = "ROOT.eval.EVAL";
  1601     val data = (the o Symtab.lookup (CodegenSerializerData.get thy)) "SML"
  1605     val data = (the o Symtab.lookup (CodegenSerializerData.get thy)) "SML"
  1602     val reserved = the_reserved data;
  1606     val reserved = the_reserved data;
  1619     code
  1623     code
  1620     |> CodegenThingol.add_eval_def (val_name, t)
  1624     |> CodegenThingol.add_eval_def (val_name, t)
  1621     |> CodegenThingol.project_code
  1625     |> CodegenThingol.project_code
  1622         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const)
  1626         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const)
  1623           (SOME [val_name])
  1627           (SOME [val_name])
  1624     |> seri_ml pr_sml pr_sml_modl I reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1628     |> seri_ml pr_sml pr_sml_modl I (labelled_name thy) reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1625         (fun_of class) (fun_of tyco) (fun_of const)
  1629         (fun_of class) (fun_of tyco) (fun_of const)
  1626     |> eval
  1630     |> eval
  1627   end;
  1631   end;
  1628 
  1632 
  1629 fun assert_serializer thy target =
  1633 fun assert_serializer thy target =
  1760     val pr = pretty_haskell_monad c_mbind'' c_kbind''
  1764     val pr = pretty_haskell_monad c_mbind'' c_kbind''
  1761   in
  1765   in
  1762     thy
  1766     thy
  1763     |> gen_add_syntax_const (K I) target_Haskell c_run' (SOME pr)
  1767     |> gen_add_syntax_const (K I) target_Haskell c_run' (SOME pr)
  1764     |> gen_add_syntax_const (K I) target_Haskell c_mbind'
  1768     |> gen_add_syntax_const (K I) target_Haskell c_mbind'
  1765           (no_bindings (SOME (parse_infix (L, 1) ">>=")))
  1769           (no_bindings (SOME (parse_infix fst (L, 1) ">>=")))
  1766     |> gen_add_syntax_const (K I) target_Haskell c_kbind'
  1770     |> gen_add_syntax_const (K I) target_Haskell c_kbind'
  1767           (no_bindings (SOME (parse_infix (L, 1) ">>")))
  1771           (no_bindings (SOME (parse_infix fst (L, 1) ">>")))
  1768   end;
  1772   end;
  1769 
  1773 
  1770 val add_syntax_class = gen_add_syntax_class read_class CodegenConsts.read_const;
  1774 val add_syntax_class = gen_add_syntax_class read_class CodegenConsts.read_const;
  1771 val add_syntax_inst = gen_add_syntax_inst read_class read_type;
  1775 val add_syntax_inst = gen_add_syntax_inst read_class read_type;
  1772 val add_syntax_tyco = gen_add_syntax_tyco read_type;
  1776 val add_syntax_tyco = gen_add_syntax_tyco read_type;
  1797   #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
  1801   #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
  1798         (zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")"));
  1802         (zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")"));
  1799 
  1803 
  1800 val (infixK, infixlK, infixrK) = ("infix", "infixl", "infixr");
  1804 val (infixK, infixlK, infixrK) = ("infix", "infixl", "infixr");
  1801 
  1805 
  1802 fun parse_syntax xs =
  1806 fun parse_syntax prep_arg xs =
  1803   Scan.option ((
  1807   Scan.option ((
  1804       ((P.$$$ infixK  >> K X)
  1808       ((P.$$$ infixK  >> K X)
  1805         || (P.$$$ infixlK >> K L)
  1809         || (P.$$$ infixlK >> K L)
  1806         || (P.$$$ infixrK >> K R))
  1810         || (P.$$$ infixrK >> K R))
  1807         -- P.nat >> parse_infix
  1811         -- P.nat >> parse_infix prep_arg
  1808       || Scan.succeed parse_mixfix)
  1812       || Scan.succeed (parse_mixfix prep_arg))
  1809       -- P.string
  1813       -- P.string
  1810       >> (fn (parse, s) => parse s)) xs;
  1814       >> (fn (parse, s) => parse s)) xs;
  1811 
  1815 
  1812 val (code_classK, code_instanceK, code_typeK, code_constK, code_monadK,
  1816 val (code_classK, code_instanceK, code_typeK, code_constK, code_monadK,
  1813   code_reservedK, code_modulenameK, code_moduleprologK) =
  1817   code_reservedK, code_modulenameK, code_moduleprologK) =
  1874           fold (fn (raw_inst, add_del) => add_syntax_inst target raw_inst add_del) syns)
  1878           fold (fn (raw_inst, add_del) => add_syntax_inst target raw_inst add_del) syns)
  1875   );
  1879   );
  1876 
  1880 
  1877 val code_typeP =
  1881 val code_typeP =
  1878   OuterSyntax.command code_typeK "define code syntax for type constructor" K.thy_decl (
  1882   OuterSyntax.command code_typeK "define code syntax for type constructor" K.thy_decl (
  1879     parse_multi_syntax P.xname parse_syntax
  1883     parse_multi_syntax P.xname (parse_syntax I)
  1880     >> (Toplevel.theory oo fold) (fn (target, syns) =>
  1884     >> (Toplevel.theory oo fold) (fn (target, syns) =>
  1881           fold (fn (raw_tyco, syn) => add_syntax_tyco target raw_tyco syn) syns)
  1885           fold (fn (raw_tyco, syn) => add_syntax_tyco target raw_tyco syn) syns)
  1882   );
  1886   );
  1883 
  1887 
  1884 val code_constP =
  1888 val code_constP =
  1885   OuterSyntax.command code_constK "define code syntax for constant" K.thy_decl (
  1889   OuterSyntax.command code_constK "define code syntax for constant" K.thy_decl (
  1886     parse_multi_syntax P.term parse_syntax
  1890     parse_multi_syntax P.term (parse_syntax fst)
  1887     >> (Toplevel.theory oo fold) (fn (target, syns) =>
  1891     >> (Toplevel.theory oo fold) (fn (target, syns) =>
  1888           fold (fn (raw_const, syn) => add_syntax_const target raw_const (no_bindings syn)) syns)
  1892           fold (fn (raw_const, syn) => add_syntax_const target raw_const (no_bindings syn)) syns)
  1889   );
  1893   );
  1890 
  1894 
  1891 val code_monadP =
  1895 val code_monadP =