src/Tools/Code/code_haskell.ML
changeset 49087 ace701efe203
parent 49018 1d11af40b106
child 49446 6efff142bb54
equal deleted inserted replaced
49086:d7864276bca8 49087:ace701efe203
    58       | print_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v;
    58       | print_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v;
    59     fun print_typdecl tyvars (tyco, vs) =
    59     fun print_typdecl tyvars (tyco, vs) =
    60       print_tyco_expr tyvars NOBR (tyco, map ITyVar vs);
    60       print_tyco_expr tyvars NOBR (tyco, map ITyVar vs);
    61     fun print_typscheme tyvars (vs, ty) =
    61     fun print_typscheme tyvars (vs, ty) =
    62       Pretty.block (print_typforall tyvars vs @ print_typcontext tyvars vs @| print_typ tyvars NOBR ty);
    62       Pretty.block (print_typforall tyvars vs @ print_typcontext tyvars vs @| print_typ tyvars NOBR ty);
    63     fun print_term tyvars some_thm vars fxy (IConst c) =
    63     fun print_term tyvars some_thm vars fxy (IConst const) =
    64           print_app tyvars some_thm vars fxy (c, [])
    64           print_app tyvars some_thm vars fxy (const, [])
    65       | print_term tyvars some_thm vars fxy (t as (t1 `$ t2)) =
    65       | print_term tyvars some_thm vars fxy (t as (t1 `$ t2)) =
    66           (case Code_Thingol.unfold_const_app t
    66           (case Code_Thingol.unfold_const_app t
    67            of SOME app => print_app tyvars some_thm vars fxy app
    67            of SOME app => print_app tyvars some_thm vars fxy app
    68             | _ =>
    68             | _ =>
    69                 brackify fxy [
    69                 brackify fxy [
    77       | print_term tyvars some_thm vars fxy (t as _ `|=> _) =
    77       | print_term tyvars some_thm vars fxy (t as _ `|=> _) =
    78           let
    78           let
    79             val (binds, t') = Code_Thingol.unfold_pat_abs t;
    79             val (binds, t') = Code_Thingol.unfold_pat_abs t;
    80             val (ps, vars') = fold_map (print_bind tyvars some_thm BR o fst) binds vars;
    80             val (ps, vars') = fold_map (print_bind tyvars some_thm BR o fst) binds vars;
    81           in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars some_thm vars' NOBR t') end
    81           in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars some_thm vars' NOBR t') end
    82       | print_term tyvars some_thm vars fxy (ICase (cases as (_, t0))) =
    82       | print_term tyvars some_thm vars fxy (ICase case_expr) =
    83           (case Code_Thingol.unfold_const_app t0
    83           (case Code_Thingol.unfold_const_app (#primitive case_expr)
    84            of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c)
    84            of SOME (app as ({ name = c, ... }, _)) => if is_none (const_syntax c)
    85                 then print_case tyvars some_thm vars fxy cases
    85                 then print_case tyvars some_thm vars fxy case_expr
    86                 else print_app tyvars some_thm vars fxy c_ts
    86                 else print_app tyvars some_thm vars fxy app
    87             | NONE => print_case tyvars some_thm vars fxy cases)
    87             | NONE => print_case tyvars some_thm vars fxy case_expr)
    88     and print_app_expr tyvars some_thm vars ((c, ((_, (arg_tys, result_ty)), annotate)), ts) =
    88     and print_app_expr tyvars some_thm vars ({ name = c, dom, range, annotate, ... }, ts) =
    89       let
    89       let
    90         val ty = Library.foldr (fn (ty1, ty2) => Code_Thingol.fun_tyco `%% [ty1, ty2]) (arg_tys, result_ty)
    90         val ty = Library.foldr (fn (ty1, ty2) => Code_Thingol.fun_tyco `%% [ty1, ty2]) (dom, range)
    91         val printed_const =
    91         val printed_const =
    92           if annotate then
    92           if annotate then
    93             brackets [(str o deresolve) c, str "::", print_typ tyvars NOBR ty]
    93             brackets [(str o deresolve) c, str "::", print_typ tyvars NOBR ty]
    94           else
    94           else
    95             (str o deresolve) c
    95             (str o deresolve) c
    96       in 
    96       in 
    97         printed_const :: map (print_term tyvars some_thm vars BR) ts
    97         printed_const :: map (print_term tyvars some_thm vars BR) ts
    98       end
    98       end
    99     and print_app tyvars = gen_print_app (print_app_expr tyvars) (print_term tyvars) const_syntax
    99     and print_app tyvars = gen_print_app (print_app_expr tyvars) (print_term tyvars) const_syntax
   100     and print_bind tyvars some_thm fxy p = gen_print_bind (print_term tyvars) some_thm fxy p
   100     and print_bind tyvars some_thm fxy p = gen_print_bind (print_term tyvars) some_thm fxy p
   101     and print_case tyvars some_thm vars fxy (cases as ((_, [_]), _)) =
   101     and print_case tyvars some_thm vars fxy { clauses = [], ... } =
   102           let
   102           (brackify fxy o Pretty.breaks o map str) ["error", "\"empty case\""]
   103             val (binds, body) = Code_Thingol.unfold_let (ICase cases);
   103       | print_case tyvars some_thm vars fxy (case_expr as { clauses = [_], ... }) =
       
   104           let
       
   105             val (binds, body) = Code_Thingol.unfold_let (ICase case_expr);
   104             fun print_match ((pat, _), t) vars =
   106             fun print_match ((pat, _), t) vars =
   105               vars
   107               vars
   106               |> print_bind tyvars some_thm BR pat
   108               |> print_bind tyvars some_thm BR pat
   107               |>> (fn p => semicolon [p, str "=", print_term tyvars some_thm vars NOBR t])
   109               |>> (fn p => semicolon [p, str "=", print_term tyvars some_thm vars NOBR t])
   108             val (ps, vars') = fold_map print_match binds vars;
   110             val (ps, vars') = fold_map print_match binds vars;
   109           in brackify_block fxy (str "let {")
   111           in brackify_block fxy (str "let {")
   110             ps
   112             ps
   111             (concat [str "}", str "in", print_term tyvars some_thm vars' NOBR body])
   113             (concat [str "}", str "in", print_term tyvars some_thm vars' NOBR body])
   112           end
   114           end
   113       | print_case tyvars some_thm vars fxy (((t, ty), clauses as _ :: _), _) =
   115       | print_case tyvars some_thm vars fxy { term = t, typ = ty, clauses = clauses as _ :: _, ... } =
   114           let
   116           let
   115             fun print_select (pat, body) =
   117             fun print_select (pat, body) =
   116               let
   118               let
   117                 val (p, vars') = print_bind tyvars some_thm NOBR pat vars;
   119                 val (p, vars') = print_bind tyvars some_thm NOBR pat vars;
   118               in semicolon [p, str "->", print_term tyvars some_thm vars' NOBR body] end;
   120               in semicolon [p, str "->", print_term tyvars some_thm vars' NOBR body] end;
   119           in Pretty.block_enclose
   121           in Pretty.block_enclose
   120             (concat [str "(case", print_term tyvars some_thm vars NOBR t, str "of", str "{"], str "})")
   122             (concat [str "(case", print_term tyvars some_thm vars NOBR t, str "of", str "{"], str "})")
   121             (map print_select clauses)
   123             (map print_select clauses)
   122           end
   124           end;
   123       | print_case tyvars some_thm vars fxy ((_, []), _) =
       
   124           (brackify fxy o Pretty.breaks o map str) ["error", "\"empty case\""];
       
   125     fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
   125     fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
   126           let
   126           let
   127             val tyvars = intro_vars (map fst vs) reserved;
   127             val tyvars = intro_vars (map fst vs) reserved;
   128             fun print_err n =
   128             fun print_err n =
   129               semicolon (
   129               semicolon (
   219                 str " where {"
   219                 str " where {"
   220               ],
   220               ],
   221               str "};"
   221               str "};"
   222             ) (map print_classparam classparams)
   222             ) (map print_classparam classparams)
   223           end
   223           end
   224       | print_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, (classparam_instances, _)))) =
   224       | print_stmt (_, Code_Thingol.Classinst { class, tyco, vs, inst_params, ... }) =
   225           let
   225           let
   226             val tyvars = intro_vars (map fst vs) reserved;
   226             val tyvars = intro_vars (map fst vs) reserved;
   227             fun requires_args classparam = case const_syntax classparam
   227             fun requires_args classparam = case const_syntax classparam
   228              of NONE => NONE
   228              of NONE => NONE
   229               | SOME (Code_Printer.Plain_const_syntax _) => SOME 0
   229               | SOME (Code_Printer.Plain_const_syntax _) => SOME 0
   235                       str "=",
   235                       str "=",
   236                       print_app tyvars (SOME thm) reserved NOBR (const, [])
   236                       print_app tyvars (SOME thm) reserved NOBR (const, [])
   237                     ]
   237                     ]
   238                 | SOME k =>
   238                 | SOME k =>
   239                     let
   239                     let
   240                       val (c, ((_, tys), _)) = const;
   240                       val { name = c, dom, range, ... } = const;
   241                       val (vs, rhs) = (apfst o map) fst
   241                       val (vs, rhs) = (apfst o map) fst
   242                         (Code_Thingol.unfold_abs (Code_Thingol.eta_expand k (const, [])));
   242                         (Code_Thingol.unfold_abs (Code_Thingol.eta_expand k (const, [])));
   243                       val s = if (is_some o const_syntax) c
   243                       val s = if (is_some o const_syntax) c
   244                         then NONE else (SOME o Long_Name.base_name o deresolve) c;
   244                         then NONE else (SOME o Long_Name.base_name o deresolve) c;
   245                       val vars = reserved
   245                       val vars = reserved
   246                         |> intro_vars (map_filter I (s :: vs));
   246                         |> intro_vars (map_filter I (s :: vs));
   247                       val lhs = IConst (classparam, ((([], []), tys), false)) `$$ map IVar vs;
   247                       val lhs = IConst { name = classparam, typargs = [],
       
   248                         dicts = [], dom = dom, range = range, annotate = false } `$$ map IVar vs;
   248                         (*dictionaries are not relevant at this late stage,
   249                         (*dictionaries are not relevant at this late stage,
   249                           and these consts never need type annotations for disambiguation *)
   250                           and these consts never need type annotations for disambiguation *)
   250                     in
   251                     in
   251                       semicolon [
   252                       semicolon [
   252                         print_term tyvars (SOME thm) vars NOBR lhs,
   253                         print_term tyvars (SOME thm) vars NOBR lhs,
   262                 str (class_name class ^ " "),
   263                 str (class_name class ^ " "),
   263                 print_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),
   264                 print_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),
   264                 str " where {"
   265                 str " where {"
   265               ],
   266               ],
   266               str "};"
   267               str "};"
   267             ) (map print_classparam_instance classparam_instances)
   268             ) (map print_classparam_instance inst_params)
   268           end;
   269           end;
   269   in print_stmt end;
   270   in print_stmt end;
   270 
   271 
   271 fun haskell_program_of_program labelled_name module_alias module_prefix reserved =
   272 fun haskell_program_of_program labelled_name module_alias module_prefix reserved =
   272   let
   273   let
   405   let
   406   let
   406     fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
   407     fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
   407      of SOME ((pat, ty), t') =>
   408      of SOME ((pat, ty), t') =>
   408           SOME ((SOME ((pat, ty), true), t1), t')
   409           SOME ((SOME ((pat, ty), true), t1), t')
   409       | NONE => NONE;
   410       | NONE => NONE;
   410     fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) =
   411     fun dest_monad c_bind_name (IConst { name = c, ... } `$ t1 `$ t2) =
   411           if c = c_bind_name then dest_bind t1 t2
   412           if c = c_bind_name then dest_bind t1 t2
   412           else NONE
   413           else NONE
   413       | dest_monad _ t = case Code_Thingol.split_let t
   414       | dest_monad _ t = case Code_Thingol.split_let t
   414          of SOME (((pat, ty), tbind), t') =>
   415          of SOME (((pat, ty), tbind), t') =>
   415               SOME ((SOME ((pat, ty), false), tbind), t')
   416               SOME ((SOME ((pat, ty), false), tbind), t')