src/Tools/Code/code_haskell.ML
changeset 55150 0940309ed8f1
parent 55148 7e1b7cb54114
child 55153 eedd549de3ef
equal deleted inserted replaced
55149:626d8f08d479 55150:0940309ed8f1
    23   "{-# LANGUAGE " ^ commas language_extensions ^ " #-}";
    23   "{-# LANGUAGE " ^ commas language_extensions ^ " #-}";
    24 
    24 
    25 val language_params =
    25 val language_params =
    26   space_implode " " (map (prefix "-X") language_extensions);
    26   space_implode " " (map (prefix "-X") language_extensions);
    27 
    27 
       
    28 open Basic_Code_Symbol;
    28 open Basic_Code_Thingol;
    29 open Basic_Code_Thingol;
    29 open Code_Printer;
    30 open Code_Printer;
    30 
    31 
    31 infixr 5 @@;
    32 infixr 5 @@;
    32 infixr 5 @|;
    33 infixr 5 @|;
    35 (** Haskell serializer **)
    36 (** Haskell serializer **)
    36 
    37 
    37 fun print_haskell_stmt class_syntax tyco_syntax const_syntax
    38 fun print_haskell_stmt class_syntax tyco_syntax const_syntax
    38     reserved deresolve deriving_show =
    39     reserved deresolve deriving_show =
    39   let
    40   let
    40     val deresolve_const = deresolve o Code_Symbol.Constant;
    41     val deresolve_const = deresolve o Constant;
    41     val deresolve_tyco = deresolve o Code_Symbol.Type_Constructor;
    42     val deresolve_tyco = deresolve o Type_Constructor;
    42     val deresolve_class = deresolve o Code_Symbol.Type_Class;
    43     val deresolve_class = deresolve o Type_Class;
    43     fun class_name class = case class_syntax class
    44     fun class_name class = case class_syntax class
    44      of NONE => deresolve_class class
    45      of NONE => deresolve_class class
    45       | SOME class => class;
    46       | SOME class => class;
    46     fun print_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
    47     fun print_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
    47      of [] => []
    48      of [] => []
    82             val (binds, t') = Code_Thingol.unfold_pat_abs t;
    83             val (binds, t') = Code_Thingol.unfold_pat_abs t;
    83             val (ps, vars') = fold_map (print_bind tyvars some_thm BR o fst) binds vars;
    84             val (ps, vars') = fold_map (print_bind tyvars some_thm BR o fst) binds vars;
    84           in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars some_thm vars' NOBR t') end
    85           in brackets (str "\\" :: ps @ str "->" @@ print_term tyvars some_thm vars' NOBR t') end
    85       | print_term tyvars some_thm vars fxy (ICase case_expr) =
    86       | print_term tyvars some_thm vars fxy (ICase case_expr) =
    86           (case Code_Thingol.unfold_const_app (#primitive case_expr)
    87           (case Code_Thingol.unfold_const_app (#primitive case_expr)
    87            of SOME (app as ({ sym = Code_Symbol.Constant const, ... }, _)) =>
    88            of SOME (app as ({ sym = Constant const, ... }, _)) =>
    88                 if is_none (const_syntax const)
    89                 if is_none (const_syntax const)
    89                 then print_case tyvars some_thm vars fxy case_expr
    90                 then print_case tyvars some_thm vars fxy case_expr
    90                 else print_app tyvars some_thm vars fxy app
    91                 else print_app tyvars some_thm vars fxy app
    91             | NONE => print_case tyvars some_thm vars fxy case_expr)
    92             | NONE => print_case tyvars some_thm vars fxy case_expr)
    92     and print_app_expr tyvars some_thm vars ({ sym, dom, range, annotate, ... }, ts) =
    93     and print_app_expr tyvars some_thm vars ({ sym, dom, range, annotate, ... }, ts) =
   124               in semicolon [p, str "->", print_term tyvars some_thm vars' NOBR body] end;
   125               in semicolon [p, str "->", print_term tyvars some_thm vars' NOBR body] end;
   125           in Pretty.block_enclose
   126           in Pretty.block_enclose
   126             (concat [str "(case", print_term tyvars some_thm vars NOBR t, str "of", str "{"], str "})")
   127             (concat [str "(case", print_term tyvars some_thm vars NOBR t, str "of", str "{"], str "})")
   127             (map print_select clauses)
   128             (map print_select clauses)
   128           end;
   129           end;
   129     fun print_stmt (Code_Symbol.Constant const, Code_Thingol.Fun (((vs, ty), raw_eqs), _)) =
   130     fun print_stmt (Constant const, Code_Thingol.Fun (((vs, ty), raw_eqs), _)) =
   130           let
   131           let
   131             val tyvars = intro_vars (map fst vs) reserved;
   132             val tyvars = intro_vars (map fst vs) reserved;
   132             fun print_err n =
   133             fun print_err n =
   133               (semicolon o map str) (
   134               (semicolon o map str) (
   134                 deresolve_const const
   135                 deresolve_const const
   161               :: (case filter (snd o snd) raw_eqs
   162               :: (case filter (snd o snd) raw_eqs
   162                of [] => [print_err ((length o fst o Code_Thingol.unfold_fun) ty)]
   163                of [] => [print_err ((length o fst o Code_Thingol.unfold_fun) ty)]
   163                 | eqs => map print_eqn eqs)
   164                 | eqs => map print_eqn eqs)
   164             )
   165             )
   165           end
   166           end
   166       | print_stmt (Code_Symbol.Type_Constructor tyco, Code_Thingol.Datatype (vs, [])) =
   167       | print_stmt (Type_Constructor tyco, Code_Thingol.Datatype (vs, [])) =
   167           let
   168           let
   168             val tyvars = intro_vars vs reserved;
   169             val tyvars = intro_vars vs reserved;
   169           in
   170           in
   170             semicolon [
   171             semicolon [
   171               str "data",
   172               str "data",
   172               print_typdecl tyvars (deresolve_tyco tyco, vs)
   173               print_typdecl tyvars (deresolve_tyco tyco, vs)
   173             ]
   174             ]
   174           end
   175           end
   175       | print_stmt (Code_Symbol.Type_Constructor tyco, Code_Thingol.Datatype (vs, [((co, _), [ty])])) =
   176       | print_stmt (Type_Constructor tyco, Code_Thingol.Datatype (vs, [((co, _), [ty])])) =
   176           let
   177           let
   177             val tyvars = intro_vars vs reserved;
   178             val tyvars = intro_vars vs reserved;
   178           in
   179           in
   179             semicolon (
   180             semicolon (
   180               str "newtype"
   181               str "newtype"
   183               :: (str o deresolve_const) co
   184               :: (str o deresolve_const) co
   184               :: print_typ tyvars BR ty
   185               :: print_typ tyvars BR ty
   185               :: (if deriving_show tyco then [str "deriving (Read, Show)"] else [])
   186               :: (if deriving_show tyco then [str "deriving (Read, Show)"] else [])
   186             )
   187             )
   187           end
   188           end
   188       | print_stmt (Code_Symbol.Type_Constructor tyco, Code_Thingol.Datatype (vs, co :: cos)) =
   189       | print_stmt (Type_Constructor tyco, Code_Thingol.Datatype (vs, co :: cos)) =
   189           let
   190           let
   190             val tyvars = intro_vars vs reserved;
   191             val tyvars = intro_vars vs reserved;
   191             fun print_co ((co, _), tys) =
   192             fun print_co ((co, _), tys) =
   192               concat (
   193               concat (
   193                 (str o deresolve_const) co
   194                 (str o deresolve_const) co
   201               :: print_co co
   202               :: print_co co
   202               :: map ((fn p => Pretty.block [str "| ", p]) o print_co) cos
   203               :: map ((fn p => Pretty.block [str "| ", p]) o print_co) cos
   203               @ (if deriving_show tyco then [str "deriving (Read, Show)"] else [])
   204               @ (if deriving_show tyco then [str "deriving (Read, Show)"] else [])
   204             )
   205             )
   205           end
   206           end
   206       | print_stmt (Code_Symbol.Type_Class class, Code_Thingol.Class (v, (classrels, classparams))) =
   207       | print_stmt (Type_Class class, Code_Thingol.Class (v, (classrels, classparams))) =
   207           let
   208           let
   208             val tyvars = intro_vars [v] reserved;
   209             val tyvars = intro_vars [v] reserved;
   209             fun print_classparam (classparam, ty) =
   210             fun print_classparam (classparam, ty) =
   210               semicolon [
   211               semicolon [
   211                 (str o deresolve_const) classparam,
   212                 (str o deresolve_const) classparam,
   237                       str "=",
   238                       str "=",
   238                       print_app tyvars (SOME thm) reserved NOBR (const, [])
   239                       print_app tyvars (SOME thm) reserved NOBR (const, [])
   239                     ]
   240                     ]
   240                 | SOME k =>
   241                 | SOME k =>
   241                     let
   242                     let
   242                       val { sym = Code_Symbol.Constant c, dom, range, ... } = const;
   243                       val { sym = Constant c, dom, range, ... } = const;
   243                       val (vs, rhs) = (apfst o map) fst
   244                       val (vs, rhs) = (apfst o map) fst
   244                         (Code_Thingol.unfold_abs (Code_Thingol.eta_expand k (const, [])));
   245                         (Code_Thingol.unfold_abs (Code_Thingol.eta_expand k (const, [])));
   245                       val s = if (is_some o const_syntax) c
   246                       val s = if (is_some o const_syntax) c
   246                         then NONE else (SOME o Long_Name.base_name o deresolve_const) c;
   247                         then NONE else (SOME o Long_Name.base_name o deresolve_const) c;
   247                       val vars = reserved
   248                       val vars = reserved
   248                         |> intro_vars (map_filter I (s :: vs));
   249                         |> intro_vars (map_filter I (s :: vs));
   249                       val lhs = IConst { sym = Code_Symbol.Constant classparam, typargs = [],
   250                       val lhs = IConst { sym = Constant classparam, typargs = [],
   250                         dicts = [], dom = dom, range = range, annotate = false } `$$ map IVar vs;
   251                         dicts = [], dom = dom, range = range, annotate = false } `$$ map IVar vs;
   251                         (*dictionaries are not relevant at this late stage,
   252                         (*dictionaries are not relevant at this late stage,
   252                           and these consts never need type annotations for disambiguation *)
   253                           and these consts never need type annotations for disambiguation *)
   253                     in
   254                     in
   254                       semicolon [
   255                       semicolon [
   338     (* print statements *)
   339     (* print statements *)
   339     fun deriving_show tyco =
   340     fun deriving_show tyco =
   340       let
   341       let
   341         fun deriv _ "fun" = false
   342         fun deriv _ "fun" = false
   342           | deriv tycos tyco = member (op =) tycos tyco
   343           | deriv tycos tyco = member (op =) tycos tyco
   343               orelse case try (Code_Symbol.Graph.get_node program) (Code_Symbol.Type_Constructor tyco)
   344               orelse case try (Code_Symbol.Graph.get_node program) (Type_Constructor tyco)
   344                 of SOME (Code_Thingol.Datatype (_, cs)) => forall (deriv' (tyco :: tycos))
   345                 of SOME (Code_Thingol.Datatype (_, cs)) => forall (deriv' (tyco :: tycos))
   345                     (maps snd cs)
   346                     (maps snd cs)
   346                  | NONE => true
   347                  | NONE => true
   347         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
   348         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
   348               andalso forall (deriv' tycos) tys
   349               andalso forall (deriv' tycos) tys
   430   let
   431   let
   431     fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
   432     fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2
   432      of SOME ((pat, ty), t') =>
   433      of SOME ((pat, ty), t') =>
   433           SOME ((SOME ((pat, ty), true), t1), t')
   434           SOME ((SOME ((pat, ty), true), t1), t')
   434       | NONE => NONE;
   435       | NONE => NONE;
   435     fun dest_monad (IConst { sym = Code_Symbol.Constant c, ... } `$ t1 `$ t2) =
   436     fun dest_monad (IConst { sym = Constant c, ... } `$ t1 `$ t2) =
   436           if c = c_bind then dest_bind t1 t2
   437           if c = c_bind then dest_bind t1 t2
   437           else NONE
   438           else NONE
   438       | dest_monad t = case Code_Thingol.split_let t
   439       | dest_monad t = case Code_Thingol.split_let t
   439          of SOME (((pat, ty), tbind), t') =>
   440          of SOME (((pat, ty), tbind), t') =>
   440               SOME ((SOME ((pat, ty), false), tbind), t')
   441               SOME ((SOME ((pat, ty), false), tbind), t')
   465   let
   466   let
   466     val c_bind = Code.read_const thy raw_c_bind;
   467     val c_bind = Code.read_const thy raw_c_bind;
   467   in
   468   in
   468     if target = target' then
   469     if target = target' then
   469       thy
   470       thy
   470       |> Code_Target.set_printings (Code_Symbol.Constant (c_bind, [(target,
   471       |> Code_Target.set_printings (Constant (c_bind, [(target,
   471         SOME (Code_Printer.complex_const_syntax (pretty_haskell_monad c_bind)))]))
   472         SOME (Code_Printer.complex_const_syntax (pretty_haskell_monad c_bind)))]))
   472     else error "Only Haskell target allows for monad syntax"
   473     else error "Only Haskell target allows for monad syntax"
   473   end;
   474   end;
   474 
   475 
   475 
   476 
   485     (target, { serializer = serializer, literals = literals,
   486     (target, { serializer = serializer, literals = literals,
   486       check = { env_var = "ISABELLE_GHC", make_destination = I,
   487       check = { env_var = "ISABELLE_GHC", make_destination = I,
   487         make_command = fn module_name =>
   488         make_command = fn module_name =>
   488           "\"$ISABELLE_GHC\" " ^ language_params  ^ " -odir build -hidir build -stubdir build -e \"\" " ^
   489           "\"$ISABELLE_GHC\" " ^ language_params  ^ " -odir build -hidir build -stubdir build -e \"\" " ^
   489             module_name ^ ".hs" } })
   490             module_name ^ ".hs" } })
   490   #> Code_Target.set_printings (Code_Symbol.Type_Constructor ("fun",
   491   #> Code_Target.set_printings (Type_Constructor ("fun",
   491     [(target, SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
   492     [(target, SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
   492       brackify_infix (1, R) fxy (
   493       brackify_infix (1, R) fxy (
   493         print_typ (INFX (1, X)) ty1,
   494         print_typ (INFX (1, X)) ty1,
   494         str "->",
   495         str "->",
   495         print_typ (INFX (1, R)) ty2
   496         print_typ (INFX (1, R)) ty2