src/Tools/Code/code_haskell.ML
changeset 31874 f172346ba805
parent 31775 2b04504fcb69
child 31888 626c075fd457
equal deleted inserted replaced
31873:00878e406bf5 31874:f172346ba805
    23 
    23 
    24 (** Haskell serializer **)
    24 (** Haskell serializer **)
    25 
    25 
    26 fun pr_haskell_bind pr_term =
    26 fun pr_haskell_bind pr_term =
    27   let
    27   let
    28     fun pr_bind ((NONE, NONE), _) = str "_"
    28     fun pr_bind (NONE, _) = str "_"
    29       | pr_bind ((SOME v, NONE), _) = str v
    29       | pr_bind (SOME p, _) = p;
    30       | pr_bind ((NONE, SOME p), _) = p
       
    31       | pr_bind ((SOME v, SOME p), _) = brackets [str v, str "@", p];
       
    32   in gen_pr_bind pr_bind pr_term end;
    30   in gen_pr_bind pr_bind pr_term end;
    33 
    31 
    34 fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const
    32 fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const
    35     init_syms deresolve is_cons contr_classparam_typs deriving_show =
    33     init_syms deresolve is_cons contr_classparam_typs deriving_show =
    36   let
    34   let
    70                 ])
    68                 ])
    71       | pr_term tyvars thm vars fxy (IVar v) =
    69       | pr_term tyvars thm vars fxy (IVar v) =
    72           (str o Code_Printer.lookup_var vars) v
    70           (str o Code_Printer.lookup_var vars) v
    73       | pr_term tyvars thm vars fxy (t as _ `|=> _) =
    71       | pr_term tyvars thm vars fxy (t as _ `|=> _) =
    74           let
    72           let
    75             val (binds, t') = Code_Thingol.unfold_abs t;
    73             val (binds, t') = Code_Thingol.unfold_pat_abs t;
    76             fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty);
    74             val (ps, vars') = fold_map (pr_bind tyvars thm BR) binds vars;
    77             val (ps, vars') = fold_map pr binds vars;
       
    78           in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars thm vars' NOBR t') end
    75           in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars thm vars' NOBR t') end
    79       | pr_term tyvars thm vars fxy (ICase (cases as (_, t0))) =
    76       | pr_term tyvars thm vars fxy (ICase (cases as (_, t0))) =
    80           (case Code_Thingol.unfold_const_app t0
    77           (case Code_Thingol.unfold_const_app t0
    81            of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
    78            of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
    82                 then pr_case tyvars thm vars fxy cases
    79                 then pr_case tyvars thm vars fxy cases
   101     and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) =
    98     and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) =
   102           let
    99           let
   103             val (binds, body) = Code_Thingol.unfold_let (ICase cases);
   100             val (binds, body) = Code_Thingol.unfold_let (ICase cases);
   104             fun pr ((pat, ty), t) vars =
   101             fun pr ((pat, ty), t) vars =
   105               vars
   102               vars
   106               |> pr_bind tyvars thm BR ((NONE, SOME pat), ty)
   103               |> pr_bind tyvars thm BR (SOME pat, ty)
   107               |>> (fn p => semicolon [p, str "=", pr_term tyvars thm vars NOBR t])
   104               |>> (fn p => semicolon [p, str "=", pr_term tyvars thm vars NOBR t])
   108             val (ps, vars') = fold_map pr binds vars;
   105             val (ps, vars') = fold_map pr binds vars;
   109           in brackify_block fxy (str "let {")
   106           in brackify_block fxy (str "let {")
   110             ps
   107             ps
   111             (concat [str "}", str "in", pr_term tyvars thm vars' NOBR body])
   108             (concat [str "}", str "in", pr_term tyvars thm vars' NOBR body])
   112           end
   109           end
   113       | pr_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) =
   110       | pr_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) =
   114           let
   111           let
   115             fun pr (pat, body) =
   112             fun pr (pat, body) =
   116               let
   113               let
   117                 val (p, vars') = pr_bind tyvars thm NOBR ((NONE, SOME pat), ty) vars;
   114                 val (p, vars') = pr_bind tyvars thm NOBR (SOME pat, ty) vars;
   118               in semicolon [p, str "->", pr_term tyvars thm vars' NOBR body] end;
   115               in semicolon [p, str "->", pr_term tyvars thm vars' NOBR body] end;
   119           in brackify_block fxy
   116           in brackify_block fxy
   120             (concat [str "case", pr_term tyvars thm vars NOBR t, str "of", str "{"])
   117             (concat [str "case", pr_term tyvars thm vars NOBR t, str "of", str "{"])
   121             (map pr clauses)
   118             (map pr clauses)
   122             (str "}") 
   119             (str "}") 
   238               str "};"
   235               str "};"
   239             ) (map pr_classparam classparams)
   236             ) (map pr_classparam classparams)
   240           end
   237           end
   241       | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) =
   238       | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) =
   242           let
   239           let
   243             val split_abs_pure = (fn (v, _) `|=> t => SOME (v, t) | _ => NONE);
       
   244             val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure;
       
   245             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   240             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   246             fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam
   241             fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam
   247              of NONE => semicolon [
   242              of NONE => semicolon [
   248                     (str o deresolve_base) classparam,
   243                     (str o deresolve_base) classparam,
   249                     str "=",
   244                     str "=",
   253                   let
   248                   let
   254                     val (c_inst_name, (_, tys)) = c_inst;
   249                     val (c_inst_name, (_, tys)) = c_inst;
   255                     val const = if (is_some o syntax_const) c_inst_name
   250                     val const = if (is_some o syntax_const) c_inst_name
   256                       then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name;
   251                       then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name;
   257                     val proto_rhs = Code_Thingol.eta_expand k (c_inst, []);
   252                     val proto_rhs = Code_Thingol.eta_expand k (c_inst, []);
   258                     val (vs, rhs) = unfold_abs_pure proto_rhs;
   253                     val (vs, rhs) = (apfst o map) fst (Code_Thingol.unfold_abs proto_rhs);
   259                     val vars = init_syms
   254                     val vars = init_syms
   260                       |> Code_Printer.intro_vars (the_list const)
   255                       |> Code_Printer.intro_vars (the_list const)
   261                       |> Code_Printer.intro_vars vs;
   256                       |> Code_Printer.intro_vars vs;
   262                     val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs;
   257                     val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs;
   263                       (*dictionaries are not relevant at this late stage*)
   258                       (*dictionaries are not relevant at this late stage*)
   445 
   440 
   446 (** optional monad syntax **)
   441 (** optional monad syntax **)
   447 
   442 
   448 fun pretty_haskell_monad c_bind =
   443 fun pretty_haskell_monad c_bind =
   449   let
   444   let
   450     fun dest_bind t1 t2 = case Code_Thingol.split_abs t2
   445     fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
   451      of SOME (((v, pat), ty), t') =>
   446      of SOME ((some_pat, ty), t') =>
   452           SOME ((SOME (((SOME v, pat), ty), true), t1), t')
   447           SOME ((SOME ((some_pat, ty), true), t1), t')
   453       | NONE => NONE;
   448       | NONE => NONE;
   454     fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) =
   449     fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) =
   455           if c = c_bind_name then dest_bind t1 t2
   450           if c = c_bind_name then dest_bind t1 t2
   456           else NONE
   451           else NONE
   457       | dest_monad _ t = case Code_Thingol.split_let t
   452       | dest_monad _ t = case Code_Thingol.split_let t
   458          of SOME (((pat, ty), tbind), t') =>
   453          of SOME (((pat, ty), tbind), t') =>
   459               SOME ((SOME (((NONE, SOME pat), ty), false), tbind), t')
   454               SOME ((SOME ((SOME pat, ty), false), tbind), t')
   460           | NONE => NONE;
   455           | NONE => NONE;
   461     fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name);
   456     fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name);
   462     fun pr_monad pr_bind pr (NONE, t) vars =
   457     fun pr_monad pr_bind pr (NONE, t) vars =
   463           (semicolon [pr vars NOBR t], vars)
   458           (semicolon [pr vars NOBR t], vars)
   464       | pr_monad pr_bind pr (SOME (bind, true), t) vars = vars
   459       | pr_monad pr_bind pr (SOME (bind, true), t) vars = vars