src/Pure/Tools/codegen_serializer.ML
changeset 21882 04d8633fbd2f
parent 21858 05f57309170c
child 21895 6cbc0f69a21c
equal deleted inserted replaced
21881:c1ef5c2e3c68 21882:04d8633fbd2f
    56 
    56 
    57 fun eval_lrx L L = false
    57 fun eval_lrx L L = false
    58   | eval_lrx R R = false
    58   | eval_lrx R R = false
    59   | eval_lrx _ _ = true;
    59   | eval_lrx _ _ = true;
    60 
    60 
    61 fun eval_fxy NOBR _ = false
    61 fun eval_fxy NOBR NOBR = false
    62   | eval_fxy _ BR = true
    62   | eval_fxy BR NOBR = false
    63   | eval_fxy _ NOBR = false
    63   | eval_fxy NOBR BR = false
    64   | eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) =
    64   | eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) =
    65       pr < pr_ctxt
    65       pr < pr_ctxt
    66       orelse pr = pr_ctxt
    66       orelse pr = pr_ctxt
    67         andalso eval_lrx lr lr_ctxt
    67         andalso eval_lrx lr lr_ctxt
    68   | eval_fxy _ (INFX _) = false;
    68   | eval_fxy _ (INFX _) = false
       
    69   | eval_fxy _ _ = true;
    69 
    70 
    70 fun gen_brackify _ [p] = p
    71 fun gen_brackify _ [p] = p
    71   | gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps
    72   | gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps
    72   | gen_brackify false (ps as _::_) = Pretty.block ps;
    73   | gen_brackify false (ps as _::_) = Pretty.block ps;
    73 
    74 
    81   case const_syntax c
    82   case const_syntax c
    82    of NONE => brackify fxy (mk_app' app)
    83    of NONE => brackify fxy (mk_app' app)
    83     | SOME (i, pr) =>
    84     | SOME (i, pr) =>
    84         let
    85         let
    85           val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i
    86           val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i
    86         in if k <= length ts
    87         in if k = length ts
    87           then case chop i ts of (ts1, ts2) =>
    88           then 
    88             brackify fxy (pr fxy from_expr ts1 :: map (from_expr BR) ts2)
    89             pr fxy from_expr ts
       
    90           else if k < length ts
       
    91           then case chop k ts of (ts1, ts2) =>
       
    92             brackify fxy (pr NOBR from_expr ts1 :: map (from_expr BR) ts2)
    89           else from_expr fxy (CodegenThingol.eta_expand app k)
    93           else from_expr fxy (CodegenThingol.eta_expand app k)
    90         end;
    94         end;
    91 
    95 
    92 val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode;
    96 val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode;
    93 
    97 
   102 
   106 
   103 fun mk_mixfix (fixity_this, mfx) =
   107 fun mk_mixfix (fixity_this, mfx) =
   104   let
   108   let
   105     fun is_arg (Arg _) = true
   109     fun is_arg (Arg _) = true
   106       | is_arg _ = false;
   110       | is_arg _ = false;
   107     val i = (length o List.filter is_arg) mfx;
   111     val i = (length o filter is_arg) mfx;
   108     fun fillin _ [] [] =
   112     fun fillin _ [] [] =
   109           []
   113           []
   110       | fillin pr (Arg fxy :: mfx) (a :: args) =
   114       | fillin pr (Arg fxy :: mfx) (a :: args) =
   111           pr fxy a :: fillin pr mfx args
   115           pr fxy a :: fillin pr mfx args
   112       | fillin pr (Pretty p :: mfx) args =
   116       | fillin pr (Pretty p :: mfx) args =
   143    of ((_, p as [_]), []) => mk_mixfix (NOBR, p)
   147    of ((_, p as [_]), []) => mk_mixfix (NOBR, p)
   144     | ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p)
   148     | ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p)
   145     | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail ()
   149     | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail ()
   146   end;
   150   end;
   147 
   151 
   148 (*FIXME: use Args.syntax ???*)
       
   149 fun parse_args f args =
   152 fun parse_args f args =
   150   case f args
   153   case f args
   151    of (x, []) => x
   154    of (x, []) => x
   152     | (_, _) => error "bad serializer arguments";
   155     | (_, _) => error "bad serializer arguments";
   153 
   156 
   209       | pretty _ _ _ = error "bad arguments for imperative monad bind";
   212       | pretty _ _ _ = error "bad arguments for imperative monad bind";
   210   in (2, pretty) end;
   213   in (2, pretty) end;
   211 
   214 
   212 
   215 
   213 (* misc *)
   216 (* misc *)
   214 
       
   215 fun constructive_fun (name, (eqs, ty)) =
       
   216   let
       
   217     val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;
       
   218     fun is_pat (IConst (c, _)) = is_cons c
       
   219       | is_pat (IVar _) = true
       
   220       | is_pat (t1 `$ t2) =
       
   221           is_pat t1 andalso is_pat t2
       
   222       | is_pat (INum _) = true
       
   223       | is_pat (IChar _) = true
       
   224       | is_pat _ = false;
       
   225     fun check_eq (eq as (lhs, rhs)) =
       
   226       if forall is_pat lhs
       
   227       then SOME eq
       
   228       else (warning ("In function " ^ quote name ^ ", throwing away one "
       
   229         ^ "non-executable function clause"); NONE)
       
   230   in case map_filter check_eq eqs
       
   231    of [] => error ("In function " ^ quote name ^ ", no "
       
   232         ^ "executable function clauses found")
       
   233     | eqs => (name, (eqs, ty))
       
   234   end;
       
   235 
   217 
   236 fun dest_name name =
   218 fun dest_name name =
   237   let
   219   let
   238     val (names, name_base) = (split_last o NameSpace.explode) name;
   220     val (names, name_base) = (split_last o NameSpace.explode) name;
   239     val (names_mod, name_shallow) = split_last names;
   221     val (names_mod, name_shallow) = split_last names;
   418         | ps =>
   400         | ps =>
   419             if (is_none o const_syntax) c then
   401             if (is_none o const_syntax) c then
   420               brackify fxy ((str o deresolv) c :: (ps @ map (pr_term vars BR) ts))
   402               brackify fxy ((str o deresolv) c :: (ps @ map (pr_term vars BR) ts))
   421             else
   403             else
   422               error ("Cannot apply user defined serialization for function expecting dictionaries: " ^ quote c)
   404               error ("Cannot apply user defined serialization for function expecting dictionaries: " ^ quote c)
   423     fun eta_expand_poly_fun (funn as (_, (_::_, _))) =
   405     fun pr_def (MLFuns (funns as (funn :: funns'))) =
   424           funn
   406           let
   425       | eta_expand_poly_fun (funn as (_, ([_], ([], _)))) =
       
   426           funn
       
   427       | eta_expand_poly_fun (funn as (_, ([(_::_, _)], _))) =
       
   428           funn
       
   429       | eta_expand_poly_fun (funn as (_, ([(_, _ `|-> _)], _))) =
       
   430           funn
       
   431       | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) =
       
   432           if (null o fst o CodegenThingol.unfold_fun) ty
       
   433               orelse (not o null o filter_out (null o snd)) vs
       
   434             then funn
       
   435             else (name, ([([IVar "x"], t `$ IVar "x")], tysm));
       
   436     fun pr_def (MLFuns raw_funns) =
       
   437           let
       
   438             val funns as (funn :: funns') = map (eta_expand_poly_fun o constructive_fun) raw_funns;
       
   439             val definer =
   407             val definer =
   440               let
   408               let
   441                 fun mk [] [] = "val"
   409                 fun mk [] [] = "val"
   442                   | mk (_::_) _ = "fun"
   410                   | mk (_::_) _ = "fun"
   443                   | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun";
   411                   | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun";
   486                   str (deresolv co)
   454                   str (deresolv co)
   487               | pr_co (co, tys) =
   455               | pr_co (co, tys) =
   488                   (Pretty.block o Pretty.breaks) [
   456                   (Pretty.block o Pretty.breaks) [
   489                     str (deresolv co),
   457                     str (deresolv co),
   490                     str "of",
   458                     str "of",
   491                     Pretty.enum " *" "" "" (map (pr_typ (INFX (2, L))) tys)
   459                     Pretty.enum " *" "" "" (map (pr_typ (INFX (2, X))) tys)
   492                   ];
   460                   ];
   493             fun pr_data definer (tyco, (vs, cos)) =
   461             fun pr_data definer (tyco, (vs, cos)) =
   494               (Pretty.block o Pretty.breaks) (
   462               (Pretty.block o Pretty.breaks) (
   495                 str definer
   463                 str definer
   496                 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs)
   464                 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs)
   757       | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) =
   725       | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) =
   758           if (null o fst o CodegenThingol.unfold_fun) ty
   726           if (null o fst o CodegenThingol.unfold_fun) ty
   759               orelse (not o null o filter_out (null o snd)) vs
   727               orelse (not o null o filter_out (null o snd)) vs
   760             then funn
   728             then funn
   761             else (name, ([([IVar "x"], t `$ IVar "x")], tysm));
   729             else (name, ([([IVar "x"], t `$ IVar "x")], tysm));
   762     fun pr_def (MLFuns raw_funns) =
   730     fun pr_def (MLFuns (funns as (funn :: funns'))) =
   763           let
   731           let
   764             val funns as (funn :: funns') = map (eta_expand_poly_fun o constructive_fun) raw_funns;
       
   765             fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) =
   732             fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) =
   766               let
   733               let
   767                 val vs = filter_out (null o snd) raw_vs;
   734                 val vs = filter_out (null o snd) raw_vs;
   768                 val dummy_args = map_index (fn (i, _) => str ("x" ^ string_of_int i)) (fst eq);
   735                 val dummy_args = map_index (fn (i, _) => str ("x" ^ string_of_int i)) (fst eq);
   769                 fun pr_eq definer (ts, t) =
   736                 fun pr_eq definer (ts, t) =
   801                   str (deresolv co)
   768                   str (deresolv co)
   802               | pr_co (co, tys) =
   769               | pr_co (co, tys) =
   803                   (Pretty.block o Pretty.breaks) [
   770                   (Pretty.block o Pretty.breaks) [
   804                     str (deresolv co),
   771                     str (deresolv co),
   805                     str "of",
   772                     str "of",
   806                     Pretty.enum " *" "" "" (map (pr_typ (INFX (2, L))) tys)
   773                     Pretty.enum " *" "" "" (map (pr_typ (INFX (2, X))) tys)
   807                   ];
   774                   ];
   808             fun pr_data definer (tyco, (vs, cos)) =
   775             fun pr_data definer (tyco, (vs, cos)) =
   809               (Pretty.block o Pretty.breaks) (
   776               (Pretty.block o Pretty.breaks) (
   810                 str definer
   777                 str definer
   811                 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs)
   778                 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs)
  1007         |> map_nsp_yield modl' (mk defs)
   974         |> map_nsp_yield modl' (mk defs)
  1008         |-> (fn (base' :: bases', def') =>
   975         |-> (fn (base' :: bases', def') =>
  1009            apsnd (map_node modl' (Graph.new_node (name, (Def (base', SOME def')))
   976            apsnd (map_node modl' (Graph.new_node (name, (Def (base', SOME def')))
  1010               #> fold2 (fn name' => fn base' => Graph.new_node (name', (Def (base', NONE)))) names' bases')))
   977               #> fold2 (fn name' => fn base' => Graph.new_node (name', (Def (base', NONE)))) names' bases')))
  1011         |> apsnd (fold (fn defname => fold (add_dep defname) deps) defnames)
   978         |> apsnd (fold (fn defname => fold (add_dep defname) deps) defnames)
       
   979         |> apsnd (fold (map_node modl' o Graph.add_edge) (product names names))
  1012       end;
   980       end;
  1013     fun group_defs [(_, CodegenThingol.Bot)] =
   981     fun group_defs [(_, CodegenThingol.Bot)] =
  1014           I
   982           I
  1015       | group_defs ((defs as (_, CodegenThingol.Fun _)::_)) =
   983       | group_defs ((defs as (_, CodegenThingol.Fun _)::_)) =
  1016           add_group mk_funs defs
   984           add_group mk_funs defs
  1211           end
  1179           end
  1212     and pr_app' vars ((c, _), ts) =
  1180     and pr_app' vars ((c, _), ts) =
  1213       (str o deresolv) c :: map (pr_term vars BR) ts
  1181       (str o deresolv) c :: map (pr_term vars BR) ts
  1214     and pr_app vars fxy =
  1182     and pr_app vars fxy =
  1215       mk_app (pr_app' vars) (pr_term vars) const_syntax fxy;
  1183       mk_app (pr_app' vars) (pr_term vars) const_syntax fxy;
  1216     fun pr_def (name, CodegenThingol.Fun (funn as (eqs, (vs, ty)))) =
  1184     fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) =
  1217           let
  1185           let
  1218             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
  1186             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
  1219             fun pr_eq (ts, t) =
  1187             fun pr_eq (ts, t) =
  1220               let
  1188               let
  1221                 val consts = map_filter
  1189                 val consts = map_filter
  1237               Pretty.block [
  1205               Pretty.block [
  1238                 (str o suffix " ::" o deresolv_here) name,
  1206                 (str o suffix " ::" o deresolv_here) name,
  1239                 Pretty.brk 1,
  1207                 Pretty.brk 1,
  1240                 pr_typscheme tyvars (vs, ty)
  1208                 pr_typscheme tyvars (vs, ty)
  1241               ]
  1209               ]
  1242               :: (map pr_eq o fst o snd o constructive_fun) (name, funn)
  1210               :: map pr_eq eqs
  1243             )
  1211             )
  1244           end
  1212           end
  1245       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
  1213       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
  1246           let
  1214           let
  1247             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
  1215             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;