src/Pure/Tools/codegen_thingol.ML
changeset 20105 454f4be984b7
parent 20071 8f3e1ddb50e6
child 20175 0a8ca32f6e64
equal deleted inserted replaced
20104:f8e7c71926e4 20105:454f4be984b7
    22     | Lookup of class list * (vname * int);
    22     | Lookup of class list * (vname * int);
    23   datatype itype =
    23   datatype itype =
    24       `%% of string * itype list
    24       `%% of string * itype list
    25     | `-> of itype * itype
    25     | `-> of itype * itype
    26     | ITyVar of vname;
    26     | ITyVar of vname;
    27   datatype iexpr =
    27   datatype iterm =
    28       IConst of string * (iclasslookup list list * itype)
    28       IConst of string * (iclasslookup list list * itype)
    29     | IVar of vname
    29     | IVar of vname
    30     | `$ of iexpr * iexpr
    30     | `$ of iterm * iterm
    31     | `|-> of (vname * itype) * iexpr
    31     | `|-> of (vname * itype) * iterm
    32     | INum of IntInf.int (*non-negative!*) * iexpr
    32     | INum of IntInf.int (*non-negative!*) * iterm
    33     | IChar of string (*length one!*) * iexpr
    33     | IChar of string (*length one!*) * iterm
    34     | IAbs of ((iexpr * itype) * iexpr) * iexpr
    34     | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
    35         (* (((binding expression (ve), binding type (vty)),
       
    36                 body expression (be)), native expression (e0)) *)
       
    37     | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
       
    38         (* ((discrimendum expression (de), discrimendum type (dty)),
    35         (* ((discrimendum expression (de), discrimendum type (dty)),
    39                 [(selector expression (se), body expression (be))]),
    36                 [(selector expression (se), body expression (be))]),
    40                 native expression (e0)) *)
    37                 native expression (e0)) *)
    41 end;
    38 end;
    42 
    39 
    43 signature CODEGEN_THINGOL =
    40 signature CODEGEN_THINGOL =
    44 sig
    41 sig
    45   include BASIC_CODEGEN_THINGOL;
    42   include BASIC_CODEGEN_THINGOL;
    46   val `--> : itype list * itype -> itype;
    43   val `--> : itype list * itype -> itype;
    47   val `$$ : iexpr * iexpr list -> iexpr;
    44   val `$$ : iterm * iterm list -> iterm;
    48   val `|--> : (vname * itype) list * iexpr -> iexpr;
    45   val `|--> : (vname * itype) list * iterm -> iterm;
    49   val pretty_itype: itype -> Pretty.T;
    46   val pretty_itype: itype -> Pretty.T;
    50   val pretty_iexpr: iexpr -> Pretty.T;
    47   val pretty_iterm: iterm -> Pretty.T;
    51   val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
    48   val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
    52   val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a;
    49   val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a;
    53   val unfold_fun: itype -> itype list * itype;
    50   val unfold_fun: itype -> itype list * itype;
    54   val unfold_app: iexpr -> iexpr * iexpr list;
    51   val unfold_app: iterm -> iterm * iterm list;
    55   val unfold_abs: iexpr -> (iexpr * itype) list * iexpr;
    52   val unfold_abs: iterm -> (iterm * itype) list * iterm;
    56   val unfold_let: iexpr -> ((iexpr * itype) * iexpr) list * iexpr;
    53   val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm;
    57   val unfold_const_app: iexpr ->
    54   val unfold_const_app: iterm ->
    58     ((string * (iclasslookup list list * itype)) * iexpr list) option;
    55     ((string * (iclasslookup list list * itype)) * iterm list) option;
    59   val add_constnames: iexpr -> string list -> string list;
    56   val add_constnames: iterm -> string list -> string list;
    60   val add_varnames: iexpr -> string list -> string list;
    57   val add_varnames: iterm -> string list -> string list;
    61   val is_pat: (string -> bool) -> iexpr -> bool;
    58   val is_pat: (string -> bool) -> iterm -> bool;
    62   val map_pure: (iexpr -> 'a) -> iexpr -> 'a;
    59   val vars_distinct: iterm list -> bool;
    63   val resolve_tycos: (string -> string) -> itype * iexpr list -> itype * iexpr list;
    60   val map_pure: (iterm -> 'a) -> iterm -> 'a;
    64   val resolve_consts: (string -> string) -> iexpr -> iexpr;
    61   val eta_expand: (string * (iclasslookup list list * itype)) * iterm list -> int -> iterm;
    65   val eta_expand: (string * (iclasslookup list list * itype)) * iexpr list -> int -> iexpr;
    62   val proper_name: string -> string;
    66 
    63   val invent_name: string list -> string;
    67   type funn = (iexpr list * iexpr) list * (sortcontext * itype);
    64   val give_names: string list -> 'a list -> (string * 'a) list;
       
    65   val resolve_tycos: (string -> string) -> itype * iterm list -> itype * iterm list;
       
    66   val resolve_consts: (string -> string) -> iterm -> iterm;
       
    67 
       
    68   type funn = (iterm list * iterm) list * (sortcontext * itype);
    68   type datatyp = sortcontext * (string * itype list) list;
    69   type datatyp = sortcontext * (string * itype list) list;
    69   datatype def =
    70   datatype def =
    70       Bot
    71       Bot
    71     | Fun of funn
    72     | Fun of funn
    72     | Typesyn of (vname * sort) list * itype
    73     | Typesyn of (vname * sort) list * itype
   129   case dest x
   130   case dest x
   130    of NONE => ([], x)
   131    of NONE => ([], x)
   131     | SOME (x1, x2) =>
   132     | SOME (x1, x2) =>
   132         let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end;
   133         let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end;
   133 
   134 
   134 fun map_yield f [] = ([], [])
   135 fun proper_name s =
   135   | map_yield f (x::xs) =
   136   let
   136       let
   137     fun replace_invalid c =
   137         val (y, x') = f x
   138       if (Char.isAlphaNum o the o Char.fromString) c orelse c = "'"
   138         val (ys, xs') = map_yield f xs
   139         andalso not (NameSpace.separator = c)
   139       in (y::ys, x'::xs') end;
   140       then c
   140 
   141       else "_";
   141 fun get_prefix eq ([], ys) = ([], ([], ys))
   142     fun contract "_" (acc as "_" :: _) = acc
   142   | get_prefix eq (xs, []) = ([], (xs, []))
   143       | contract c acc = c :: acc;
   143   | get_prefix eq (xs as x::xs', ys as y::ys') =
   144     fun contract_underscores s =
   144       if eq (x, y) then
   145       implode (fold_rev contract (explode s) []);
   145         let val (ps', xys'') = get_prefix eq (xs', ys')
   146     fun ensure_char s =
   146         in (x::ps', xys'') end
   147       if forall (Char.isDigit o the o Char.fromString) (explode s)
   147       else ([], (xs, ys));
   148         then prefix "x" s
       
   149         else s
       
   150   in
       
   151     s
       
   152     |> translate_string replace_invalid
       
   153     |> contract_underscores
       
   154     |> ensure_char
       
   155   end;
   148 
   156 
   149 
   157 
   150 (** language core - types, pattern, expressions **)
   158 (** language core - types, pattern, expressions **)
   151 
   159 
   152 (* language representation *)
   160 (* language representation *)
   161 datatype itype =
   169 datatype itype =
   162     `%% of string * itype list
   170     `%% of string * itype list
   163   | `-> of itype * itype
   171   | `-> of itype * itype
   164   | ITyVar of vname;
   172   | ITyVar of vname;
   165 
   173 
   166 datatype iexpr =
   174 datatype iterm =
   167     IConst of string * (iclasslookup list list * itype)
   175     IConst of string * (iclasslookup list list * itype)
   168   | IVar of vname
   176   | IVar of vname
   169   | `$ of iexpr * iexpr
   177   | `$ of iterm * iterm
   170   | `|-> of (vname * itype) * iexpr
   178   | `|-> of (vname * itype) * iterm
   171   | INum of IntInf.int (*non-negative!*) * iexpr
   179   | INum of IntInf.int * iterm
   172   | IChar of string (*length one!*) * iexpr
   180   | IChar of string * iterm
   173   | IAbs of ((iexpr * itype) * iexpr) * iexpr
   181   | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
   174   | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr;
       
   175     (*see also signature*)
   182     (*see also signature*)
   176 
   183 
   177 (*
   184 (*
   178   variable naming conventions
   185   variable naming conventions
   179 
   186 
   211   | pretty_itype (ty1 `-> ty2) =
   218   | pretty_itype (ty1 `-> ty2) =
   212       Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
   219       Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
   213   | pretty_itype (ITyVar v) =
   220   | pretty_itype (ITyVar v) =
   214       Pretty.str v;
   221       Pretty.str v;
   215 
   222 
   216 fun pretty_iexpr (IConst (c, _)) =
   223 fun pretty_iterm (IConst (c, _)) =
   217       Pretty.str c
   224       Pretty.str c
   218   | pretty_iexpr (IVar v) =
   225   | pretty_iterm (IVar v) =
   219       Pretty.str ("?" ^ v)
   226       Pretty.str ("?" ^ v)
   220   | pretty_iexpr (e1 `$ e2) =
   227   | pretty_iterm (e1 `$ e2) =
   221       (Pretty.enclose "(" ")" o Pretty.breaks)
   228       (Pretty.enclose "(" ")" o Pretty.breaks)
   222         [pretty_iexpr e1, pretty_iexpr e2]
   229         [pretty_iterm e1, pretty_iterm e2]
   223   | pretty_iexpr ((v, ty) `|-> e) =
   230   | pretty_iterm ((v, ty) `|-> e) =
   224       (Pretty.enclose "(" ")" o Pretty.breaks)
   231       (Pretty.enclose "(" ")" o Pretty.breaks)
   225         [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iexpr e]
   232         [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iterm e]
   226   | pretty_iexpr (INum (n, _)) =
   233   | pretty_iterm (INum (n, _)) =
   227       (Pretty.str o IntInf.toString) n
   234       (Pretty.str o IntInf.toString) n
   228   | pretty_iexpr (IChar (c, _)) =
   235   | pretty_iterm (IChar (c, _)) =
   229       (Pretty.str o quote) c
   236       (Pretty.str o quote) c
   230   | pretty_iexpr (IAbs (((e1, _), e2), _)) =
   237   | pretty_iterm (ICase (((e, _), cs), _)) =
   231       (Pretty.enclose "(" ")" o Pretty.breaks)
       
   232         [pretty_iexpr e1, Pretty.str "|->", pretty_iexpr e2]
       
   233   | pretty_iexpr (ICase (((e, _), cs), _)) =
       
   234       (Pretty.enclose "(" ")" o Pretty.breaks) [
   238       (Pretty.enclose "(" ")" o Pretty.breaks) [
   235         Pretty.str "case",
   239         Pretty.str "case",
   236         pretty_iexpr e,
   240         pretty_iterm e,
   237         Pretty.enclose "(" ")" (map (fn (p, e) =>
   241         Pretty.enclose "(" ")" (map (fn (p, e) =>
   238           (Pretty.block o Pretty.breaks) [
   242           (Pretty.block o Pretty.breaks) [
   239             pretty_iexpr p,
   243             pretty_iterm p,
   240             Pretty.str "=>",
   244             Pretty.str "=>",
   241             pretty_iexpr e
   245             pretty_iterm e
   242           ]
   246           ]
   243         ) cs)
   247         ) cs)
   244       ];
   248       ];
   245 
   249 
   246 val unfold_fun = unfoldr
   250 val unfold_fun = unfoldr
   250 val unfold_app = unfoldl
   254 val unfold_app = unfoldl
   251   (fn op `$ e => SOME e
   255   (fn op `$ e => SOME e
   252     | _ => NONE);
   256     | _ => NONE);
   253 
   257 
   254 val unfold_abs = unfoldr
   258 val unfold_abs = unfoldr
   255   (fn (v, ty) `|-> e => SOME ((IVar v, ty), e)
   259   (fn (v, ty) `|-> (e as ICase (((IVar w, _), [(se, be)]), _)) => 
   256     | IAbs (((e1, ty), e2), _) => SOME ((e1, ty), e2)
   260         if v = w then SOME ((se, ty), be) else SOME ((IVar v, ty), e)
       
   261     | (v, ty) `|-> e => SOME ((IVar v, ty), e)
   257     | _ => NONE)
   262     | _ => NONE)
   258 
   263 
   259 val unfold_let = unfoldr
   264 val unfold_let = unfoldr
   260   (fn ICase (((de, dty), [(se, be)]), _) => SOME (((se, dty), de), be)
   265   (fn ICase (((de, dty), [(se, be)]), _) => SOME (((se, dty), de), be)
   261     | _ => NONE);
   266     | _ => NONE);
   324       f e
   329       f e
   325   | map_pure _ (INum _) =
   330   | map_pure _ (INum _) =
   326       error ("sorry, no pure representation for numerals so far")
   331       error ("sorry, no pure representation for numerals so far")
   327   | map_pure f (IChar (_, e0)) =
   332   | map_pure f (IChar (_, e0)) =
   328       f e0
   333       f e0
   329   | map_pure f (IAbs (_, e0)) =
       
   330       f e0
       
   331   | map_pure f (ICase (_, e0)) =
   334   | map_pure f (ICase (_, e0)) =
   332       f e0;
   335       f e0;
   333 
   336 
   334 fun resolve_tycos _ = error "";
   337 fun resolve_tycos _ = error "";
   335 fun resolve_consts _ = error "";
   338 fun resolve_consts _ = error "";
   344       add_constnames e
   347       add_constnames e
   345   | add_constnames (INum _) =
   348   | add_constnames (INum _) =
   346       I
   349       I
   347   | add_constnames (IChar _) =
   350   | add_constnames (IChar _) =
   348       I
   351       I
   349   | add_constnames (IAbs (_, e)) =
       
   350       add_constnames e
       
   351   | add_constnames (ICase (_, e)) =
   352   | add_constnames (ICase (_, e)) =
   352       add_constnames e;
   353       add_constnames e;
   353 
   354 
   354 fun add_varnames (IConst _) =
   355 fun add_varnames (IConst _) =
   355       I
   356       I
   361       insert (op =) v #> add_varnames e
   362       insert (op =) v #> add_varnames e
   362   | add_varnames (INum _) =
   363   | add_varnames (INum _) =
   363       I
   364       I
   364   | add_varnames (IChar _) =
   365   | add_varnames (IChar _) =
   365       I
   366       I
   366   | add_varnames (IAbs (((ve, _), be), _)) =
       
   367       add_varnames ve #> add_varnames be
       
   368   | add_varnames (ICase (((de, _), bses), _)) =
   367   | add_varnames (ICase (((de, _), bses), _)) =
   369       add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses;
   368       add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses;
   370 
   369 
   371 fun invent seed used =
   370 fun vars_distinct es =
   372   let
   371   let
   373     val x = Name.variant used seed
   372     fun distinct _ NONE =
   374   in (x, x :: used) end;
   373           NONE
       
   374       | distinct (IConst _) x =
       
   375           x
       
   376       | distinct (IVar v) (SOME vs) =
       
   377           if member (op =) vs v then NONE else SOME (v::vs)
       
   378       | distinct (e1 `$ e2) x =
       
   379           x |> distinct e1 |> distinct e2
       
   380       | distinct (_ `|-> e) x =
       
   381           x |> distinct e
       
   382       | distinct (INum _) x =
       
   383           x
       
   384       | distinct (IChar _) x =
       
   385           x
       
   386       | distinct (ICase (((de, _), bses), _)) x =
       
   387           x |> distinct de |> fold (fn (be, se) => distinct be #> distinct se) bses;
       
   388   in is_some (fold distinct es (SOME [])) end;
       
   389 
       
   390 fun invent_name used = hd (Name.invent_list used "a" 1);
       
   391 
       
   392 fun give_names used xs =
       
   393   Name.invent_list used "a" (length xs) ~~ xs;
   375 
   394 
   376 fun eta_expand (c as (_, (_, ty)), es) k =
   395 fun eta_expand (c as (_, (_, ty)), es) k =
   377   let
   396   let
   378     val j = length es;
   397     val j = length es;
   379     val l = k - j;
   398     val l = k - j;
   380     val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty;
   399     val tys = (curry Library.take l o curry Library.drop j o fst o unfold_fun) ty;
   381     val vs = [] |> fold add_varnames es |> fold_map invent (replicate l "x") |> fst;
   400     val vs_tys = give_names (fold add_varnames es []) tys;
   382   in vs ~~ tys `|--> IConst c `$$ es @ map IVar vs end;
   401   in vs_tys `|--> IConst c `$$ es @ map (fn (v, _) => IVar v) vs_tys end;
   383 
   402 
   384 
   403 
   385 
   404 
   386 (** language module system - definitions, modules, transactions **)
   405 (** language module system - definitions, modules, transactions **)
   387 
   406 
   388 (* type definitions *)
   407 (* type definitions *)
   389 
   408 
   390 type funn = (iexpr list * iexpr) list * (sortcontext * itype);
   409 type funn = (iterm list * iterm) list * (sortcontext * itype);
   391 type datatyp = sortcontext * (string * itype list) list;
   410 type datatyp = sortcontext * (string * itype list) list;
   392 
   411 
   393 datatype def =
   412 datatype def =
   394     Bot
   413     Bot
   395   | Fun of funn
   414   | Fun of funn
   417       Pretty.str "<Bot>"
   436       Pretty.str "<Bot>"
   418   | pretty_def (Fun (eqs, (sortctxt, ty))) =
   437   | pretty_def (Fun (eqs, (sortctxt, ty))) =
   419       Pretty.enum " |" "" "" (
   438       Pretty.enum " |" "" "" (
   420         map (fn (ps, body) =>
   439         map (fn (ps, body) =>
   421           Pretty.block [
   440           Pretty.block [
   422             Pretty.enum "," "[" "]" (map pretty_iexpr ps),
   441             Pretty.enum "," "[" "]" (map pretty_iterm ps),
   423             Pretty.str " |->",
   442             Pretty.str " |->",
   424             Pretty.brk 1,
   443             Pretty.brk 1,
   425             pretty_iexpr body,
   444             pretty_iterm body,
   426             Pretty.str "::",
   445             Pretty.str "::",
   427             pretty_sortcontext sortctxt,
   446             pretty_sortcontext sortctxt,
   428             Pretty.str "/",
   447             Pretty.str "/",
   429             pretty_itype ty
   448             pretty_itype ty
   430           ]) eqs
   449           ]) eqs
   613   if name1 = name2 then modl
   632   if name1 = name2 then modl
   614   else
   633   else
   615     let
   634     let
   616       val m1 = dest_name name1 |> apsnd single |> (op @);
   635       val m1 = dest_name name1 |> apsnd single |> (op @);
   617       val m2 = dest_name name2 |> apsnd single |> (op @);
   636       val m2 = dest_name name2 |> apsnd single |> (op @);
   618       val (ms, (r1, r2)) = get_prefix (op =) (m1, m2);
   637       val (ms, (r1, r2)) = chop_prefix (op =) (m1, m2);
   619       val (ms, (s1::r1, s2::r2)) = get_prefix (op =) (m1, m2);
   638       val (ms, (s1::r1, s2::r2)) = chop_prefix (op =) (m1, m2);
   620       val add_edge =
   639       val add_edge =
   621         if null r1 andalso null r2
   640         if null r1 andalso null r2
   622         then Graph.add_edge
   641         then Graph.add_edge
   623         else fn edge => fn gr => (Graph.add_edge_acyclic edge gr
   642         else fn edge => fn gr => (Graph.add_edge_acyclic edge gr
   624           handle Graph.CYCLES _ =>
   643           handle Graph.CYCLES _ =>
   977             val SOME (N (p', SOME tab')) = Symtab.lookup tab p
   996             val SOME (N (p', SOME tab')) = Symtab.lookup tab p
   978             val (ps', tab'') = get_path_name ps tab'
   997             val (ps', tab'') = get_path_name ps tab'
   979           in (p' :: ps', tab'') end;
   998           in (p' :: ps', tab'') end;
   980     fun deresolv tab prefix name =
   999     fun deresolv tab prefix name =
   981       let
  1000       let
   982         val (common, (_, rem)) = get_prefix (op =) (prefix, NameSpace.unpack name);
  1001         val (common, (_, rem)) = chop_prefix (op =) (prefix, NameSpace.unpack name);
   983         val (_, SOME tab') = get_path_name common tab;
  1002         val (_, SOME tab') = get_path_name common tab;
   984         val (name', _) = get_path_name rem tab';
  1003         val (name', _) = get_path_name rem tab';
   985       in NameSpace.pack name' end;
  1004       in NameSpace.pack name' end;
   986   in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end;
  1005   in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end;
   987 
  1006