diff options
author | Samuel Mimram <smimram@debian.org> | 2008-07-25 15:12:53 +0200 |
---|---|---|
committer | Samuel Mimram <smimram@debian.org> | 2008-07-25 15:12:53 +0200 |
commit | a0cfa4f118023d35b767a999d5a2ac4b082857b4 (patch) | |
tree | dabcac548e299fee1da464c93b3dba98484f45b1 /contrib/extraction/haskell.ml | |
parent | 2281410e38ef99d025ea77194585a9bc019fdaa9 (diff) |
Imported Upstream version 8.2~beta3+dfsgupstream/8.2.beta3+dfsg
Diffstat (limited to 'contrib/extraction/haskell.ml')
-rw-r--r-- | contrib/extraction/haskell.ml | 134 |
1 files changed, 71 insertions, 63 deletions
diff --git a/contrib/extraction/haskell.ml b/contrib/extraction/haskell.ml index f924396c..0ef225c0 100644 --- a/contrib/extraction/haskell.ml +++ b/contrib/extraction/haskell.ml @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(*i $Id: haskell.ml 8930 2006-06-09 02:14:34Z letouzey $ i*) +(*i $Id: haskell.ml 10233 2007-10-17 23:29:08Z letouzey $ i*) (*s Production of Haskell syntax. *) @@ -18,7 +18,7 @@ open Libnames open Table open Miniml open Mlutil -open Ocaml +open Common (*s Haskell renaming issues. *) @@ -30,22 +30,19 @@ let keywords = "as"; "qualified"; "hiding" ; "unit" ; "unsafeCoerce" ] Idset.empty -let preamble prm used_modules (mldummy,tdummy,tunknown) magic = - let pp_mp = function - | MPfile d -> pr_upper_id (List.hd (repr_dirpath d)) - | _ -> assert false - in - (if not magic then mt () +let preamble mod_name used_modules usf = + let pp_import mp = str ("import qualified "^ string_of_modfile mp ^"\n") + in + (if not usf.magic then mt () else str "{-# OPTIONS_GHC -cpp -fglasgow-exts #-}\n" ++ str "{- For Hugs, use the option -F\"cpp -P -traditional\" -}\n\n") ++ - str "module " ++ pr_upper_id prm.mod_name ++ str " where" ++ fnl () - ++ fnl() ++ - str "import qualified Prelude" ++ fnl() ++ - prlist (fun mp -> str "import qualified " ++ pp_mp mp ++ fnl ()) used_modules - ++ fnl () ++ - (if not magic then mt () + str "module " ++ pr_upper_id mod_name ++ str " where" ++ fnl2 () ++ + str "import qualified Prelude" ++ fnl () ++ + prlist pp_import used_modules ++ fnl () ++ + (if used_modules = [] then mt () else fnl ()) ++ + (if not usf.magic then mt () else str "\ #ifdef __GLASGOW_HASKELL__ import qualified GHC.Base @@ -54,16 +51,10 @@ unsafeCoerce = GHC.Base.unsafeCoerce# -- HUGS import qualified IOExts unsafeCoerce = IOExts.unsafeCoerce -#endif") - ++ - fnl() ++ fnl() +#endif" ++ fnl2 ()) ++ - (if not mldummy then mt () - else - str "__ = Prelude.error \"Logical or arity value used\"" - ++ fnl () ++ fnl()) - -let preamble_sig prm used_modules (mldummy,tdummy,tunknown) = failwith "TODO" + (if not usf.mldummy then mt () + else str "__ = Prelude.error \"Logical or arity value used\"" ++ fnl2 ()) let pp_abst = function | [] -> (mt ()) @@ -73,17 +64,11 @@ let pp_abst = function let pr_lower_id id = pr_id (lowercase_id id) -(*s The pretty-printing functor. *) +(*s The pretty-printer for haskell syntax *) -module Make = functor(P : Mlpp_param) -> struct - -let local_mpl = ref ([] : module_path list) - -let pp_global r = +let pp_global k r = if is_inline_custom r then str (find_custom r) - else P.pp_global !local_mpl r - -let empty_env () = [], P.globals() + else str (Common.pp_global k r) (*s Pretty-printing of types. [par] is a boolean indicating whether parentheses are needed or not. *) @@ -96,13 +81,14 @@ let rec pp_type par vl t = let rec pp_rec par = function | Tmeta _ | Tvar' _ -> assert false | Tvar i -> (try pr_id (List.nth vl (pred i)) with _ -> (str "a" ++ int i)) - | Tglob (r,[]) -> pp_global r + | Tglob (r,[]) -> pp_global Type r | Tglob (r,l) -> if r = IndRef (kn_sig,0) then pp_type true vl (List.hd l) else pp_par par - (pp_global r ++ spc () ++ prlist_with_sep spc (pp_type true vl) l) + (pp_global Type r ++ spc () ++ + prlist_with_sep spc (pp_type true vl) l) | Tarr (t1,t2) -> pp_par par (pp_rec true t1 ++ spc () ++ str "->" ++ spc () ++ pp_rec false t2) @@ -151,20 +137,20 @@ let rec pp_expr par env args = spc () ++ str "in") ++ spc () ++ hov 0 pp_a2))) | MLglob r -> - apply (pp_global r) + apply (pp_global Term r) | MLcons (_,r,[]) -> - assert (args=[]); pp_global r + assert (args=[]); pp_global Cons r | MLcons (_,r,[a]) -> assert (args=[]); - pp_par par (pp_global r ++ spc () ++ pp_expr true env [] a) + pp_par par (pp_global Cons r ++ spc () ++ pp_expr true env [] a) | MLcons (_,r,args') -> assert (args=[]); - pp_par par (pp_global r ++ spc () ++ + pp_par par (pp_global Cons r ++ spc () ++ prlist_with_sep spc (pp_expr true env []) args') - | MLcase (_,t, pv) -> + | MLcase ((_,factors),t, pv) -> apply (pp_par par' (v 0 (str "case " ++ pp_expr false env [] t ++ str " of" ++ - fnl () ++ str " " ++ pp_pat env pv))) + fnl () ++ str " " ++ pp_pat env factors pv))) | MLfix (i,ids,defs) -> let ids',env' = push_vars (List.rev (Array.to_list ids)) env in pp_fix par env' i (Array.of_list (List.rev ids'),defs) args @@ -177,11 +163,11 @@ let rec pp_expr par env args = pp_apply (str "unsafeCoerce") par (pp_expr true env [] a :: args) | MLaxiom -> pp_par par (str "Prelude.error \"AXIOM TO BE REALIZED\"") -and pp_pat env pv = +and pp_pat env factors pv = let pp_one_pat (name,ids,t) = let ids,env' = push_vars (List.rev ids) env in let par = expr_needs_par t in - hov 2 (pp_global name ++ + hov 2 (pp_global Cons name ++ (match ids with | [] -> mt () | _ -> (str " " ++ @@ -189,7 +175,18 @@ and pp_pat env pv = (fun () -> (spc ())) pr_id (List.rev ids))) ++ str " ->" ++ spc () ++ pp_expr par env' [] t) in - (prvect_with_sep (fun () -> (fnl () ++ str " ")) pp_one_pat pv) + prvecti + (fun i x -> if List.mem i factors then mt () else + (pp_one_pat pv.(i) ++ + if factors = [] && i = Array.length pv - 1 then mt () + else fnl () ++ str " ")) pv + ++ + match factors with + | [] -> mt () + | i::_ -> + let (_,ids,t) = pv.(i) in + let t = ast_lift (-List.length ids) t in + hov 2 (str "_ ->" ++ spc () ++ pp_expr (expr_needs_par t) env [] t) (*s names of the functions ([ids]) are already pushed in [env], and passed here just for convenience. *) @@ -223,7 +220,7 @@ let pp_logical_ind packet = let pp_singleton kn packet = let l = rename_tvars keywords packet.ip_vars in let l' = List.rev l in - hov 2 (str "type " ++ pp_global (IndRef (kn,0)) ++ spc () ++ + hov 2 (str "type " ++ pp_global Type (IndRef (kn,0)) ++ spc () ++ prlist_with_sep spc pr_id l ++ (if l <> [] then str " " else mt ()) ++ str "=" ++ spc () ++ pp_type false l' (List.hd packet.ip_types.(0)) ++ fnl () ++ @@ -233,7 +230,7 @@ let pp_singleton kn packet = let pp_one_ind ip pl cv = let pl = rename_tvars keywords pl in let pp_constructor (r,l) = - (pp_global r ++ + (pp_global Cons r ++ match l with | [] -> (mt ()) | _ -> (str " " ++ @@ -241,7 +238,7 @@ let pp_one_ind ip pl cv = (fun () -> (str " ")) (pp_type true pl) l)) in str (if Array.length cv = 0 then "type " else "data ") ++ - pp_global (IndRef ip) ++ str " " ++ + pp_global Type (IndRef ip) ++ str " " ++ prlist_with_sep (fun () -> str " ") pr_lower_id pl ++ (if pl = [] then mt () else str " ") ++ if Array.length cv = 0 then str "= () -- empty inductive" @@ -269,9 +266,7 @@ let rec pp_ind first kn i ind = let pp_string_parameters ids = prlist (fun id -> str id ++ str " ") -let pp_decl mpl = - local_mpl := mpl; - function +let pp_decl = function | Dind (kn,i) when i.ind_info = Singleton -> pp_singleton kn i.ind_packets.(0) ++ fnl () | Dind (kn,i) -> hov 0 (pp_ind true kn 0 i) @@ -288,38 +283,51 @@ let pp_decl mpl = if t = Taxiom then str "= () -- AXIOM TO BE REALIZED\n" else str "=" ++ spc () ++ pp_type false l t in - hov 2 (str "type " ++ pp_global r ++ spc () ++ st) ++ fnl () ++ fnl () + hov 2 (str "type " ++ pp_global Type r ++ spc () ++ st) ++ fnl2 () | Dfix (rv, defs, typs) -> let max = Array.length rv in let rec iter i = if i = max then mt () else - let e = pp_global rv.(i) in + let e = pp_global Term rv.(i) in e ++ str " :: " ++ pp_type false [] typs.(i) ++ fnl () - ++ pp_function (empty_env ()) e defs.(i) ++ fnl () ++ fnl () + ++ pp_function (empty_env ()) e defs.(i) ++ fnl2 () ++ iter (i+1) in iter 0 | Dterm (r, a, t) -> if is_inline_custom r then mt () else - let e = pp_global r in + let e = pp_global Term r in e ++ str " :: " ++ pp_type false [] t ++ fnl () ++ if is_custom r then - hov 0 (e ++ str " = " ++ str (find_custom r) ++ fnl() ++ fnl ()) + hov 0 (e ++ str " = " ++ str (find_custom r) ++ fnl2 ()) else - hov 0 (pp_function (empty_env ()) e a ++ fnl () ++ fnl ()) + hov 0 (pp_function (empty_env ()) e a ++ fnl2 ()) -let pp_structure_elem mpl = function - | (l,SEdecl d) -> pp_decl mpl d +let pp_structure_elem = function + | (l,SEdecl d) -> pp_decl d | (l,SEmodule m) -> failwith "TODO: Haskell extraction of modules not implemented yet" | (l,SEmodtype m) -> failwith "TODO: Haskell extraction of modules not implemented yet" let pp_struct = - prlist (fun (mp,sel) -> prlist (pp_structure_elem [mp]) sel) - -let pp_signature s = failwith "TODO" - -end - + let pp_sel (mp,sel) = + push_visible mp; + let p = prlist_strict pp_structure_elem sel in + pop_visible (); p + in + prlist_strict pp_sel + + +let haskell_descr = { + keywords = keywords; + file_suffix = ".hs"; + capital_file = true; + preamble = preamble; + pp_struct = pp_struct; + sig_suffix = None; + sig_preamble = (fun _ _ _ -> mt ()); + pp_sig = (fun _ -> mt ()); + pp_decl = pp_decl; +} |