src/Pure/Tools/codegen_thingol.ML
changeset 19607 07eeb832f28d
parent 19597 8ced57ffc090
child 19616 2545e8ab59a5
equal deleted inserted replaced
19606:01e23aa70d3a 19607:07eeb832f28d
    26   datatype iexpr =
    26   datatype iexpr =
    27       IConst of string * (iclasslookup list list * itype)
    27       IConst of string * (iclasslookup list list * itype)
    28     | IVar of vname
    28     | IVar of vname
    29     | `$ of iexpr * iexpr
    29     | `$ of iexpr * iexpr
    30     | `|-> of (vname * itype) * iexpr
    30     | `|-> of (vname * itype) * iexpr
    31     | INum of (IntInf.int (*positive!*) * itype) * unit
    31     | INum of IntInf.int (*positive!*) * unit
       
    32     | IChar of string (*length one!*) * iexpr
    32     | IAbs of ((iexpr * itype) * iexpr) * iexpr
    33     | IAbs of ((iexpr * itype) * iexpr) * iexpr
    33         (* (((binding expression (ve), binding type (vty)),
    34         (* (((binding expression (ve), binding type (vty)),
    34                 body expression (be)), native expression (e0)) *)
    35                 body expression (be)), native expression (e0)) *)
    35     | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
    36     | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
    36         (* ((discrimendum expression (de), discrimendum type (dty)),
    37         (* ((discrimendum expression (de), discrimendum type (dty)),
    56     ((string * (iclasslookup list list * itype)) * iexpr list) option;
    57     ((string * (iclasslookup list list * itype)) * iexpr list) option;
    57   val add_constnames: iexpr -> string list -> string list;
    58   val add_constnames: iexpr -> string list -> string list;
    58   val add_varnames: iexpr -> string list -> string list;
    59   val add_varnames: iexpr -> string list -> string list;
    59   val is_pat: iexpr -> bool;
    60   val is_pat: iexpr -> bool;
    60   val map_pure: (iexpr -> 'a) -> iexpr -> 'a;
    61   val map_pure: (iexpr -> 'a) -> iexpr -> 'a;
       
    62   val resolve_tycos: (string -> string) -> itype * iexpr list -> itype * iexpr list;
       
    63   val resolve_consts: (string -> string) -> iexpr -> iexpr;
       
    64   val eta_expand: (string * (iclasslookup list list * itype)) * iexpr list -> int -> iexpr;
       
    65   
    61 
    66 
    62   type funn = (iexpr list * iexpr) list * (sortcontext * itype);
    67   type funn = (iexpr list * iexpr) list * (sortcontext * itype);
    63   type datatyp = sortcontext * (string * itype list) list;
    68   type datatyp = sortcontext * (string * itype list) list;
    64   datatype prim =
    69   datatype prim =
    65       Pretty of Pretty.T
    70       Pretty of Pretty.T
    96   val fail: string -> transact -> 'a transact_fin;
   101   val fail: string -> transact -> 'a transact_fin;
    97   val ensure_def: (string * (string -> transact -> def transact_fin)) list -> string
   102   val ensure_def: (string * (string -> transact -> def transact_fin)) list -> string
    98     -> string -> transact -> transact;
   103     -> string -> transact -> transact;
    99   val start_transact: string option -> (transact -> 'a * transact) -> module -> 'a * module;
   104   val start_transact: string option -> (transact -> 'a * transact) -> module -> 'a * module;
   100 
   105 
   101   val eta_expand: (string -> int) -> module -> module;
       
   102   val eta_expand_poly: module -> module;
       
   103   val unclash_vars_tvars: module -> module;
       
   104 
       
   105   val debug: bool ref;
   106   val debug: bool ref;
   106   val debug_msg: ('a -> string) -> 'a -> 'a;
   107   val debug_msg: ('a -> string) -> 'a -> 'a;
   107   val soft_exc: bool ref;
   108   val soft_exc: bool ref;
   108 
   109 
   109   val serialize:
   110   val serialize:
   169 datatype iexpr =
   170 datatype iexpr =
   170     IConst of string * (iclasslookup list list * itype)
   171     IConst of string * (iclasslookup list list * itype)
   171   | IVar of vname
   172   | IVar of vname
   172   | `$ of iexpr * iexpr
   173   | `$ of iexpr * iexpr
   173   | `|-> of (vname * itype) * iexpr
   174   | `|-> of (vname * itype) * iexpr
   174   | INum of (IntInf.int (*positive!*) * itype) * unit
   175   | INum of IntInf.int (*positive!*) * unit
       
   176   | IChar of string (*length one!*) * iexpr
   175   | IAbs of ((iexpr * itype) * iexpr) * iexpr
   177   | IAbs of ((iexpr * itype) * iexpr) * iexpr
   176   | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
   178   | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
   177     (*see also signature*)
   179     (*see also signature*)
   178 
   180 
   179 (*
   181 (*
   223       (Pretty.enclose "(" ")" o Pretty.breaks)
   225       (Pretty.enclose "(" ")" o Pretty.breaks)
   224         [pretty_iexpr e1, pretty_iexpr e2]
   226         [pretty_iexpr e1, pretty_iexpr e2]
   225   | pretty_iexpr ((v, ty) `|-> e) =
   227   | pretty_iexpr ((v, ty) `|-> e) =
   226       (Pretty.enclose "(" ")" o Pretty.breaks)
   228       (Pretty.enclose "(" ")" o Pretty.breaks)
   227         [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iexpr e]
   229         [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iexpr e]
   228   | pretty_iexpr (INum ((n, _), _)) =
   230   | pretty_iexpr (INum (n, _)) =
   229       (Pretty.str o IntInf.toString) n
   231       (Pretty.str o IntInf.toString) n
       
   232   | pretty_iexpr (IChar (c, _)) =
       
   233       (Pretty.str o quote) c
   230   | pretty_iexpr (IAbs (((e1, _), e2), _)) =
   234   | pretty_iexpr (IAbs (((e1, _), e2), _)) =
   231       (Pretty.enclose "(" ")" o Pretty.breaks)
   235       (Pretty.enclose "(" ")" o Pretty.breaks)
   232         [pretty_iexpr e1, Pretty.str "|->", pretty_iexpr e2]
   236         [pretty_iexpr e1, Pretty.str "|->", pretty_iexpr e2]
   233   | pretty_iexpr (ICase (((e, _), cs), _)) =
   237   | pretty_iexpr (ICase (((e, _), cs), _)) =
   234       (Pretty.enclose "(" ")" o Pretty.breaks) [
   238       (Pretty.enclose "(" ")" o Pretty.breaks) [
   269       ty
   273       ty
   270   | map_itype f (tyco `%% tys) =
   274   | map_itype f (tyco `%% tys) =
   271       tyco `%% map f tys
   275       tyco `%% map f tys
   272   | map_itype f (t1 `-> t2) =
   276   | map_itype f (t1 `-> t2) =
   273       f t1 `-> f t2;
   277       f t1 `-> f t2;
   274 
       
   275 fun map_iexpr _ (e as IConst _) =
       
   276       e
       
   277   | map_iexpr _ (e as IVar _) =
       
   278       e
       
   279   | map_iexpr f (e1 `$ e2) =
       
   280       f e1 `$ f e2
       
   281   | map_iexpr f ((v, ty) `|-> e) =
       
   282       (v, ty) `|-> f e
       
   283   | map_iexpr _ (e as INum _) =
       
   284       e
       
   285   | map_iexpr f (IAbs (((ve, vty), be), e0)) =
       
   286       IAbs (((f ve, vty), f be), e0)
       
   287   | map_iexpr f (ICase (((de, dty), bses), e0)) =
       
   288       ICase (((f de, dty), map (fn (se, be) => (f se, f be)) bses), e0);
       
   289 
       
   290 fun map_iexpr_itype f =
       
   291   let
       
   292     fun mapp ((v, ty) `|-> e) = (v, f ty) `|-> mapp e
       
   293       | mapp (INum ((n, ty), e)) = INum ((n, f ty), e)
       
   294       | mapp (IAbs (((ve, vty), be), e0)) =
       
   295           IAbs (((mapp ve, f vty), mapp be), e0)
       
   296       | mapp (ICase (((de, dty), bses), e0)) =
       
   297           ICase (((mapp de, f dty), map (fn (se, be) => (mapp se, mapp be)) bses), e0)
       
   298       | mapp e = map_iexpr mapp e;
       
   299   in mapp end;
       
   300 
   278 
   301 fun eq_ityp ((sctxt1, ty1), (sctxt2, ty2)) =
   279 fun eq_ityp ((sctxt1, ty1), (sctxt2, ty2)) =
   302   let
   280   let
   303     exception NO_MATCH;
   281     exception NO_MATCH;
   304     fun eq_sctxt subs sctxt1 sctxt2 =
   282     fun eq_sctxt subs sctxt1 sctxt2 =
   335 fun is_pat (e as IConst (_, ([], _))) = true
   313 fun is_pat (e as IConst (_, ([], _))) = true
   336   | is_pat (e as IVar _) = true
   314   | is_pat (e as IVar _) = true
   337   | is_pat (e as (e1 `$ e2)) =
   315   | is_pat (e as (e1 `$ e2)) =
   338       is_pat e1 andalso is_pat e2
   316       is_pat e1 andalso is_pat e2
   339   | is_pat (e as INum _) = true
   317   | is_pat (e as INum _) = true
       
   318   | is_pat (e as IChar _) = true
   340   | is_pat e = false;
   319   | is_pat e = false;
   341 
   320 
   342 fun map_pure f (e as IConst _) =
   321 fun map_pure f (e as IConst _) =
   343       f e
   322       f e
   344   | map_pure f (e as IVar _) =
   323   | map_pure f (e as IVar _) =
   347       f e
   326       f e
   348   | map_pure f (e as _ `|-> _) =
   327   | map_pure f (e as _ `|-> _) =
   349       f e
   328       f e
   350   | map_pure _ (INum _) =
   329   | map_pure _ (INum _) =
   351       error ("sorry, no pure representation of numerals so far")
   330       error ("sorry, no pure representation of numerals so far")
       
   331   | map_pure f (IChar (_, e0)) =
       
   332       f e0
   352   | map_pure f (IAbs (_, e0)) =
   333   | map_pure f (IAbs (_, e0)) =
   353       f e0
   334       f e0
   354   | map_pure f (ICase (_, e0)) =
   335   | map_pure f (ICase (_, e0)) =
   355       f e0;
   336       f e0;
   356 
   337 
   357 fun has_tyvars (_ `%% tys) =
   338 fun resolve_tycos _ = error "";
   358       exists has_tyvars tys
   339 fun resolve_consts _ = error "";
   359   | has_tyvars (ITyVar _) =
       
   360       true
       
   361   | has_tyvars (ty1 `-> ty2) =
       
   362       has_tyvars ty1 orelse has_tyvars ty2;
       
   363 
   340 
   364 fun add_constnames (IConst (c, _)) =
   341 fun add_constnames (IConst (c, _)) =
   365       insert (op =) c
   342       insert (op =) c
   366   | add_constnames (IVar _) =
   343   | add_constnames (IVar _) =
   367       I
   344       I
   369       add_constnames e1 #> add_constnames e2
   346       add_constnames e1 #> add_constnames e2
   370   | add_constnames (_ `|-> e) =
   347   | add_constnames (_ `|-> e) =
   371       add_constnames e
   348       add_constnames e
   372   | add_constnames (INum _) =
   349   | add_constnames (INum _) =
   373       I
   350       I
       
   351   | add_constnames (IChar _) =
       
   352       I
   374   | add_constnames (IAbs (_, e)) =
   353   | add_constnames (IAbs (_, e)) =
   375       add_constnames e
   354       add_constnames e
   376   | add_constnames (ICase (_, e)) =
   355   | add_constnames (ICase (_, e)) =
   377       add_constnames e;
   356       add_constnames e;
   378 
   357 
   384       add_varnames e1 #> add_varnames e2
   363       add_varnames e1 #> add_varnames e2
   385   | add_varnames ((v, _) `|-> e) =
   364   | add_varnames ((v, _) `|-> e) =
   386       insert (op =) v #> add_varnames e
   365       insert (op =) v #> add_varnames e
   387   | add_varnames (INum _) =
   366   | add_varnames (INum _) =
   388       I
   367       I
       
   368   | add_varnames (IChar _) =
       
   369       I
   389   | add_varnames (IAbs (((ve, _), be), _)) =
   370   | add_varnames (IAbs (((ve, _), be), _)) =
   390       add_varnames ve #> add_varnames be
   371       add_varnames ve #> add_varnames be
   391   | add_varnames (ICase (((de, _), bses), _)) =
   372   | add_varnames (ICase (((de, _), bses), _)) =
   392       add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses;
   373       add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses;
   393 
   374 
   394 fun invent seed used =
   375 fun invent seed used =
   395   let
   376   let
   396     val x = Term.variant used seed
   377     val x = Term.variant used seed
   397   in (x, x :: used) end;
   378   in (x, x :: used) end;
       
   379 
       
   380 fun eta_expand (c as (_, (_, ty)), es) k =
       
   381   let
       
   382     val j = length es;
       
   383     val l = k - j;
       
   384     val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty;
       
   385     val vs = [] |> fold add_varnames es |> fold_map invent (replicate l "x") |> fst;
       
   386   in vs ~~ tys `|--> IConst c `$$ es @ map IVar vs end;
   398 
   387 
   399 
   388 
   400 
   389 
   401 (** language module system - definitions, modules, transactions **)
   390 (** language module system - definitions, modules, transactions **)
   402 
   391 
   956     |-> (fn x => fn (_, module) => (x, module))
   945     |-> (fn x => fn (_, module) => (x, module))
   957   end;
   946   end;
   958 
   947 
   959 
   948 
   960 
   949 
   961 (** generic transformation **)
       
   962 
       
   963 fun map_def_fun f (Fun funn) =
       
   964       Fun (f funn)
       
   965   | map_def_fun _ def = def;
       
   966 
       
   967 fun map_def_fun_expr f (eqs, cty) =
       
   968   (map (fn (ps, rhs) => (map f ps, f rhs)) eqs, cty);
       
   969 
       
   970 fun eta_expand query =
       
   971   let
       
   972     fun eta e =
       
   973      case unfold_const_app e
       
   974       of SOME (const as (c, (_, ty)), es) =>
       
   975           let
       
   976             val delta = query c - length es;
       
   977             val add_n = if delta < 0 then 0 else delta;
       
   978             val tys =
       
   979               (fst o unfold_fun) ty
       
   980               |> curry Library.drop (length es)
       
   981               |> curry Library.take add_n
       
   982             val vs = (Term.invent_names (fold add_varnames es []) "x" add_n)
       
   983           in
       
   984             vs ~~ tys `|--> IConst const `$$ map eta es `$$ map IVar vs
       
   985           end
       
   986        | NONE => map_iexpr eta e;
       
   987   in (map_defs o map_def_fun o map_def_fun_expr) eta end;
       
   988 
       
   989 val eta_expand_poly =
       
   990   let
       
   991     fun eta (funn as ([([], e)], cty as (sctxt, (ty as (ty1 `-> ty2))))) =
       
   992           if (not o null) sctxt
       
   993             orelse (not o has_tyvars) ty
       
   994           then funn
       
   995           else (case unfold_abs e
       
   996            of ([], e) =>
       
   997               let
       
   998                 val add_var = IVar (hd (Term.invent_names (add_varnames e []) "x" 1))
       
   999               in (([([add_var], e `$ add_var)], cty)) end
       
  1000             | _ =>  funn)
       
  1001       | eta funn = funn;
       
  1002   in (map_defs o map_def_fun) eta end;
       
  1003 
       
  1004 val unclash_vars_tvars = 
       
  1005   let
       
  1006     fun unclash (eqs, (sortctxt, ty)) =
       
  1007       let
       
  1008         val used_expr =
       
  1009           fold (fn (pats, rhs) => fold add_varnames pats #> add_varnames rhs) eqs [];
       
  1010         val used_type = map fst sortctxt;
       
  1011         val clash = gen_union (op =) (used_expr, used_type);
       
  1012         val rename_map = fold_map (fn c => invent c #-> (fn c' => pair (c, c'))) clash [] |> fst;
       
  1013         val rename =
       
  1014           perhaps (AList.lookup (op =) rename_map);
       
  1015         val rename_typ = instant_itype (ITyVar o rename);
       
  1016         val rename_expr = map_iexpr_itype rename_typ;
       
  1017         fun rename_eq (args, rhs) = (map rename_expr args, rename_expr rhs)
       
  1018       in
       
  1019         (map rename_eq eqs, (map (apfst rename) sortctxt, rename_typ ty))
       
  1020       end;
       
  1021   in (map_defs o map_def_fun) unclash end;
       
  1022 
       
  1023 
       
  1024 (** generic serialization **)
   950 (** generic serialization **)
  1025 
   951 
  1026 (* resolving *)
   952 (* resolving *)
  1027 
   953 
  1028 structure NameMangler = NameManglerFun (
   954 structure NameMangler = NameManglerFun (