src/Pure/Tools/codegen_serializer.ML
author haftmann
Mon, 21 Nov 2005 16:51:57 +0100
changeset 18217 e0b08c9534ff
parent 18216 db7d43b25c99
child 18231 2eea98bbf650
permissions -rw-r--r--
added codegen package
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/Tools/codegen_serializer.ML
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     2
    ID:         $Id$
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     4
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     5
Serializer from intermediate language ("Thin-gol") to
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
     6
target languages (like ML or Haskell).
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     7
*)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     8
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     9
signature CODEGEN_SERIALIZER =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    10
sig
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    11
  type primitives;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    12
  val empty_prims: primitives;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    13
  val add_prim: string * (string * string list) -> primitives -> primitives;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    14
  val merge_prims: primitives * primitives -> primitives;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    15
  val has_prim: primitives -> string -> bool;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    16
  val mk_prims: primitives -> string;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    17
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    18
  type 'a pretty_syntax = string -> Pretty.T list -> ('a -> Pretty.T)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    19
    -> (string list * Pretty.T) option;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    20
  type serializer = CodegenThingol.itype pretty_syntax -> CodegenThingol.iexpr pretty_syntax
18217
e0b08c9534ff added codegen package
haftmann
parents: 18216
diff changeset
    21
    -> primitives -> string list option -> CodegenThingol.module -> Pretty.T;
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    22
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    23
  val ml_from_thingol: string list list -> string -> serializer;
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    24
end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    25
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    26
structure CodegenSerializer: CODEGEN_SERIALIZER =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    27
struct
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    28
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    29
open CodegenThingol;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    30
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    31
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    32
(** target language primitives **)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    33
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    34
type primitives = string Graph.T;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    35
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    36
val empty_prims = Graph.empty;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    37
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    38
fun add_prim (f, (def, deps)) prims =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    39
  prims
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    40
  |> Graph.new_node (f, def)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    41
  |> fold (fn dep => Graph.add_edge (f, dep)) deps;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    42
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    43
val merge_prims = Graph.merge (op =) : primitives * primitives -> primitives;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    44
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    45
val has_prim : primitives -> string -> bool = can o Graph.get_node;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    46
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    47
fun get_prims prims defs =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    48
  defs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    49
  |> filter (can (Graph.get_node prims))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    50
  |> `I
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    51
  ||> Graph.all_succs prims
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    52
  ||> (fn gr => Graph.subgraph gr prims)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    53
  ||> Graph.strong_conn
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    54
  ||> rev
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    55
  ||> Library.flat
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    56
  ||> map (Graph.get_node prims)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    57
  ||> separate ""
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    58
  ||> cat_lines
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    59
  ||> suffix "\n";
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    60
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    61
fun mk_prims prims = get_prims prims (Graph.keys prims) |> snd;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    62
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    63
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    64
(** generic serialization **)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    65
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    66
type 'a pretty_syntax = string -> Pretty.T list -> ('a -> Pretty.T)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    67
  -> (string list * Pretty.T) option;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    68
type serializer = CodegenThingol.itype pretty_syntax -> CodegenThingol.iexpr pretty_syntax
18217
e0b08c9534ff added codegen package
haftmann
parents: 18216
diff changeset
    69
  -> primitives -> string list option -> CodegenThingol.module -> Pretty.T;
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    70
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    71
datatype lrx = L | R | X;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    72
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    73
datatype brack =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    74
    BR
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    75
  | NOBR
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    76
  | INFX of (int * lrx);
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    77
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    78
fun eval_lrx L L = false
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    79
  | eval_lrx R R = false
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    80
  | eval_lrx _ _ = true;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    81
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    82
fun eval_br BR _ = true
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    83
  | eval_br NOBR _ = false
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    84
  | eval_br (INFX (pr1, lr1)) (INFX (pr2, lr2)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    85
      pr1 > pr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    86
      orelse pr1 = pr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    87
      andalso eval_lrx lr1 lr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    88
  | eval_br (INFX _) _ = false;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    89
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    90
fun eval_br_postfix BR _ = false
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    91
  | eval_br_postfix NOBR _ = false
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    92
  | eval_br_postfix (INFX (pr1, lr1)) (INFX (pr2, lr2)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    93
      pr1 > pr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    94
      orelse pr1 = pr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    95
      andalso eval_lrx lr1 lr2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    96
  | eval_br_postfix (INFX _) _ = false;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    97
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    98
fun brackify _ [p] = p
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
    99
  | brackify true (ps as _::_) = Pretty.enclose "(" ")" (Pretty.breaks ps)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   100
  | brackify false (ps as _::_) = Pretty.block (Pretty.breaks ps);
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   101
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   102
fun postify [] f = [f]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   103
  | postify [p] f = [p, Pretty.brk 1, f]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   104
  | postify (ps as _::_) f = [Pretty.list "(" ")" ps, Pretty.brk 1, f];
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   105
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   106
fun praetify [] f = [f]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   107
  | praetify [p] f = [f, Pretty.str " of ", p]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   108
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   109
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   110
(** ML serializer **)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   111
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   112
local
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   113
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   114
fun ml_validator prims name =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   115
  let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   116
    fun replace_invalid c =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   117
      if (Char.isAlphaNum o the o Char.fromString) c orelse c = "'"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   118
      andalso not (NameSpace.separator = c)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   119
      then c
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   120
      else "_"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   121
    fun suffix_it name =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   122
      name
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   123
      |> member (op =) ThmDatabase.ml_reserved ? suffix "'"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   124
      |> member (op =) CodegenThingol.prims ? suffix "'"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   125
      |> has_prim prims ? suffix "'"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   126
      |> (fn name' => if name = name' then name else suffix_it name')
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   127
  in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   128
    name
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   129
    |> translate_string replace_invalid
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   130
    |> suffix_it
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   131
    |> (fn name' => if name = name' then NONE else SOME name')
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   132
  end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   133
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   134
val ml_label_uniq = translate_string (fn "'" => "''" | "." => "'" | c => c);
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   135
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   136
fun ml_from_defs styco sconst resolv ds =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   137
  let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   138
    fun chunk_defs ps = 
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   139
      let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   140
        val (p_init, p_last) = split_last ps
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   141
      in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   142
        Pretty.chunks (p_init @ [Pretty.block ([p_last, Pretty.str ";"])])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   143
    end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   144
    fun ml_from_typ br (IType ("Pair", [t1, t2])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   145
          brackify (eval_br_postfix br (INFX (2, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   146
            ml_from_typ (INFX (2, X)) t1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   147
            Pretty.str "*",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   148
            ml_from_typ (INFX (2, X)) t2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   149
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   150
      | ml_from_typ br (IType ("Bool", [])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   151
          Pretty.str "bool"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   152
      | ml_from_typ br (IType ("Integer", [])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   153
          Pretty.str "IntInf.int"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   154
      | ml_from_typ br (IType ("List", [ty])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   155
          postify ([ml_from_typ BR ty]) (Pretty.str "list")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   156
          |> Pretty.block
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   157
      | ml_from_typ br (IType (tyco, typs)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   158
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   159
            val tyargs = (map (ml_from_typ BR) typs)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   160
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   161
            case styco tyco tyargs (ml_from_typ BR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   162
             of NONE =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   163
                  postify tyargs ((Pretty.str o resolv) tyco)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   164
                  |> Pretty.block
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   165
              | SOME ([], p) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   166
                  p
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   167
              | SOME (_, p) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   168
                  error ("cannot serialize partial type application to ML, while serializing "
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   169
                    ^ quote (tyco ^ " " ^ Pretty.output (Pretty.list "(" ")" tyargs)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   170
          end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   171
      | ml_from_typ br (IFun (t1, t2)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   172
          brackify (eval_br_postfix br (INFX (1, R))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   173
            ml_from_typ (INFX (1, X)) t1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   174
            Pretty.str "->",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   175
            ml_from_typ (INFX (1, R)) t2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   176
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   177
      | ml_from_typ _ (IVarT (v, [])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   178
          Pretty.str ("'" ^ v)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   179
      | ml_from_typ _ (IVarT (_, sort)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   180
          "cannot serialize sort constrained type variable to ML: " ^ commas sort |> error
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   181
      | ml_from_typ _ (IDictT fs) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   182
          (Pretty.enclose "{" "}" o Pretty.breaks) (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   183
            map (fn (f, ty) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   184
              Pretty.block [Pretty.str (ml_label_uniq f ^ ": "), ml_from_typ NOBR ty]) fs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   185
          );
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   186
    fun ml_from_pat br (ICons (("True", []), _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   187
          Pretty.str "true"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   188
      | ml_from_pat br (ICons (("False", []), _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   189
          Pretty.str "false"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   190
      | ml_from_pat br (ICons (("Pair", ps), _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   191
          ps
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   192
          |> map (ml_from_pat NOBR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   193
          |> Pretty.list "(" ")"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   194
      | ml_from_pat br (ICons (("Nil", []), _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   195
          Pretty.str "[]"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   196
      | ml_from_pat br (p as ICons (("Cons", _), _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   197
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   198
            fun dest_cons (ICons (("Cons", [ICons (("Pair", [p1, p2]), _)]), _)) = SOME (p1, p2)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   199
              | dest_cons p = NONE
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   200
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   201
            case unfoldr dest_cons p
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   202
             of (ps, (ICons (("Nil", []), _))) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   203
                  ps
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   204
                  |> map (ml_from_pat NOBR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   205
                  |> Pretty.list "[" "]"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   206
              | (ps, p) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   207
                  (ps @ [p])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   208
                  |> map (ml_from_pat (INFX (5, X)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   209
                  |> separate (Pretty.str "::")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   210
                  |> brackify (eval_br br (INFX (5, R)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   211
          end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   212
      | ml_from_pat br (ICons ((f, ps), ty)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   213
          ps
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   214
          |> map (ml_from_pat BR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   215
          |> cons ((Pretty.str o resolv) f)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   216
          |> brackify (eval_br br BR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   217
      | ml_from_pat br (IVarP (v, IType ("Integer", []))) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   218
          Pretty.str ("(" ^ v ^ ":IntInf.int)")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   219
      | ml_from_pat br (IVarP (v, _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   220
          Pretty.str v;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   221
    fun ml_from_iexpr br (e as (IApp (IConst ("Cons", _), _))) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   222
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   223
            fun dest_cons (IApp (IConst ("Cons", _),
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   224
                  IApp (IApp (IConst ("Pair", _), e1), e2))) = SOME (e1, e2)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   225
              | dest_cons p = NONE
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   226
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   227
            case unfoldr dest_cons e
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   228
             of (es, (IConst ("Nil", _))) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   229
                  es
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   230
                  |> map (ml_from_iexpr NOBR) 
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   231
                  |> Pretty.list "[" "]"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   232
              | (es, e) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   233
                  (es @ [e])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   234
                  |> map (ml_from_iexpr (INFX (5, X)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   235
                  |> separate (Pretty.str "::")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   236
                  |> brackify (eval_br br (INFX (5, R)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   237
          end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   238
      | ml_from_iexpr br (e as IApp (e1, e2)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   239
          (case (unfold_app e)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   240
           of (e as (IConst (f, _)), es) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   241
                ml_from_app br (f, es)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   242
            | _ => 
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   243
                brackify (eval_br br BR) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   244
                  ml_from_iexpr NOBR e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   245
                  ml_from_iexpr BR e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   246
                ])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   247
      | ml_from_iexpr br (e as IConst (f, _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   248
          ml_from_app br (f, [])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   249
      | ml_from_iexpr br (IVarE (v, _)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   250
          Pretty.str v
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   251
      | ml_from_iexpr br (IAbs ((v, _), e)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   252
          brackify (eval_br br BR) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   253
            Pretty.str ("fn " ^ v ^ " =>"),
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   254
            ml_from_iexpr BR e
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   255
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   256
      | ml_from_iexpr br (e as ICase (_, [_])) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   257
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   258
            val (ps, e) = unfold_let e;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   259
            fun mk_val (p, e) = Pretty.block [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   260
                Pretty.str "val ",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   261
                ml_from_pat BR p,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   262
                Pretty.str " =",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   263
                Pretty.brk 1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   264
                ml_from_iexpr NOBR e,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   265
                Pretty.str ";"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   266
              ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   267
          in Pretty.chunks [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   268
            [Pretty.str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   269
            [Pretty.str ("in"), Pretty.fbrk, ml_from_iexpr NOBR e] |> Pretty.block,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   270
            Pretty.str ("end")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   271
          ] end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   272
      | ml_from_iexpr br (ICase (e, c::cs)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   273
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   274
            fun mk_clause definer (p, e) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   275
              Pretty.block [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   276
                Pretty.str definer,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   277
                ml_from_pat NOBR p,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   278
                Pretty.str " =>",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   279
                Pretty.brk 1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   280
                ml_from_iexpr NOBR e
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   281
              ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   282
          in brackify (eval_br br BR) (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   283
            Pretty.str "case "
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   284
            :: ml_from_iexpr NOBR e
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   285
            :: mk_clause "of " c
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   286
            :: map (mk_clause "|") cs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   287
          ) end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   288
      | ml_from_iexpr br (IInst _) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   289
          error "cannot serialize poly instant to ML"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   290
      | ml_from_iexpr br (IDictE fs) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   291
          (Pretty.enclose "{" "}" o Pretty.breaks) (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   292
            map (fn (f, e) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   293
              Pretty.block [Pretty.str (ml_label_uniq f ^ " = "), ml_from_iexpr NOBR e]) fs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   294
          )
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   295
      | ml_from_iexpr br (ILookup (ls, v)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   296
          brackify (eval_br br BR) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   297
            Pretty.str "(",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   298
            ls |> map ((fn s => "#" ^ s) o ml_label_uniq) |> foldr1 (fn (l, e) => l ^ " o " ^ e) |> Pretty.str,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   299
            Pretty.str ")",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   300
            Pretty.str " ",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   301
            Pretty.str v
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   302
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   303
    and mk_app_p br p args =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   304
      brackify (eval_br br BR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   305
        (p :: map (ml_from_iexpr BR) args)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   306
    and ml_from_app br ("Nil", []) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   307
          Pretty.str "[]"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   308
      | ml_from_app br ("True", []) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   309
          Pretty.str "true"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   310
      | ml_from_app br ("False", []) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   311
          Pretty.str "false"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   312
      | ml_from_app br ("primeq", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   313
          brackify (eval_br br (INFX (4, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   314
            ml_from_iexpr (INFX (4, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   315
            Pretty.str "=",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   316
            ml_from_iexpr (INFX (4, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   317
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   318
      | ml_from_app br ("Pair", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   319
          Pretty.list "(" ")" [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   320
            ml_from_iexpr NOBR e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   321
            ml_from_iexpr NOBR e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   322
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   323
      | ml_from_app br ("and", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   324
          brackify (eval_br br (INFX (~1, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   325
            ml_from_iexpr (INFX (~1, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   326
            Pretty.str "andalso",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   327
            ml_from_iexpr (INFX (~1, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   328
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   329
      | ml_from_app br ("or", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   330
          brackify (eval_br br (INFX (~2, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   331
            ml_from_iexpr (INFX (~2, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   332
            Pretty.str "orelse",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   333
            ml_from_iexpr (INFX (~2, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   334
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   335
      | ml_from_app br ("if", [b, e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   336
          brackify (eval_br br BR) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   337
            Pretty.str "if",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   338
            ml_from_iexpr BR b,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   339
            Pretty.str "then",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   340
            ml_from_iexpr BR e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   341
            Pretty.str "else",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   342
            ml_from_iexpr BR e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   343
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   344
      | ml_from_app br ("add", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   345
          brackify (eval_br br (INFX (6, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   346
            ml_from_iexpr (INFX (6, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   347
            Pretty.str "+",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   348
            ml_from_iexpr (INFX (6, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   349
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   350
      | ml_from_app br ("mult", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   351
          brackify (eval_br br (INFX (7, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   352
            ml_from_iexpr (INFX (7, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   353
            Pretty.str "+",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   354
            ml_from_iexpr (INFX (7, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   355
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   356
      | ml_from_app br ("lt", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   357
          brackify (eval_br br (INFX (4, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   358
            ml_from_iexpr (INFX (4, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   359
            Pretty.str "<",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   360
            ml_from_iexpr (INFX (4, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   361
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   362
      | ml_from_app br ("le", [e1, e2]) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   363
          brackify (eval_br br (INFX (7, L))) [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   364
            ml_from_iexpr (INFX (4, L)) e1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   365
            Pretty.str "<=",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   366
            ml_from_iexpr (INFX (4, X)) e2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   367
          ]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   368
      | ml_from_app br ("minus", es) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   369
          mk_app_p br (Pretty.str "~") es
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   370
      | ml_from_app br ("wfrec", es) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   371
          mk_app_p br (Pretty.str "wfrec") es
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   372
      | ml_from_app br (f, es) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   373
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   374
            val args = map (ml_from_iexpr BR) es
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   375
            val brackify' = K (eval_br br BR) ? (single #> Pretty.enclose "(" ")")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   376
            fun prepend_abs v body =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   377
              Pretty.block [Pretty.str ("fn " ^ v ^ " =>"), Pretty.brk 1, body]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   378
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   379
            case sconst f args (ml_from_iexpr BR)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   380
             of NONE =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   381
                  brackify (eval_br br BR) (Pretty.str (resolv f) :: args)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   382
              | SOME ([], p) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   383
                  brackify' p
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   384
              | SOME (vars, p) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   385
                  p 
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   386
                  |> fold_rev prepend_abs vars
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   387
                  |> brackify'
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   388
          end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   389
    fun ml_from_funs (ds as d::ds_tl) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   390
      let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   391
        fun mk_definer [] = "val"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   392
          | mk_definer _ = "fun"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   393
        fun check_args (_, Fun ((pats, _)::_, _)) NONE =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   394
              SOME (mk_definer pats)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   395
          | check_args (_, Fun ((pats, _)::_, _)) (SOME definer) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   396
              if mk_definer pats = definer
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   397
              then SOME definer
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   398
              else error ("Mixing simultaneous vals and funs not implemented")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   399
          | check_args _ _ =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   400
              error ("Function definition block containing other definitions than functions")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   401
        val definer = the (fold check_args ds NONE);
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   402
        fun mk_eq definer f' ty (pats, expr) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   403
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   404
            val lhs = [Pretty.str (definer ^ " " ^ f')]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   405
                       @ (if null pats
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   406
                          then [Pretty.str ":", ml_from_typ NOBR ty]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   407
                          else map (ml_from_pat BR) pats)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   408
            val rhs = [Pretty.str "=", ml_from_iexpr NOBR expr]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   409
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   410
            Pretty.block (separate (Pretty.brk 1) (lhs @ rhs))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   411
          end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   412
        fun mk_fun definer (f, Fun (eqs as eq::eq_tl, (_, ty))) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   413
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   414
            val (pats_hd::pats_tl) = (fst o split_list) eqs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   415
            val _ = fold (fn x => fn y => (x ~~ y; y)) pats_tl pats_hd
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   416
              (*check for equal length of argument lists*)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   417
          in (Pretty.block o Pretty.fbreaks) (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   418
               (*Pretty.block [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   419
                 Pretty.brk 1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   420
                 Pretty.str ": ",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   421
                 ml_from_typ NOBR ty
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   422
               ]*)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   423
               mk_eq definer f ty eq
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   424
               :: map (mk_eq "|" f ty) eq_tl
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   425
             )
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   426
          end
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   427
      in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   428
        chunk_defs (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   429
          mk_fun definer d
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   430
          :: map (mk_fun "and") ds_tl
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   431
        )
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   432
      end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   433
    fun ml_from_datatypes ds =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   434
      let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   435
        val _ = debug 9 (fn _ => map (pretty_def o snd) ds |> Pretty.chunks |> Pretty.output) ();
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   436
        fun check_typ_dup ty xs =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   437
          if AList.defined (op =) xs ty
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   438
          then error ("double datatype definition: " ^ quote ty)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   439
          else xs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   440
        fun check_typ_miss ty xs =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   441
          if AList.defined (op =) xs ty
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   442
          then xs
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   443
          else error ("missing datatype definition: " ^ quote ty)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   444
        fun group (name, Datatype (vs, _, _)) ts =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   445
              (map (fn (_, []) => () | _ => error "can't serialize sort constrained datatype declaration to ML") vs;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   446
              ts
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   447
              |> apsnd (check_typ_dup name)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   448
              |> apsnd (AList.update (op =) (name, (vs, []))))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   449
          | group (_, Datatypecons (_, _::_::_)) _ =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   450
              error ("Datatype constructor containing more than one parameter")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   451
          | group (name, Datatypecons (ty, tys)) ts =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   452
              ts
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   453
              |> apfst (AList.default (op =) (resolv ty, []))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   454
              |> apfst (AList.map_entry (op =) (resolv ty) (cons (name, tys)))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   455
          | group _ _ =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   456
              error ("Datatype block containing other statements than datatype or constructor definitions")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   457
        fun group_cons (ty, co) ts =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   458
          ts
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   459
          |> check_typ_miss ty
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   460
          |> AList.map_entry (op =) ty (rpair co o fst)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   461
        fun mk_datatypes (ds as d::ds_tl) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   462
          let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   463
            fun mk_cons (co, typs) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   464
              (Pretty.block oo praetify)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   465
                (map (ml_from_typ NOBR) typs)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   466
                (Pretty.str (resolv co))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   467
            fun mk_datatype definer (t, (vs, cs)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   468
              Pretty.block (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   469
                [Pretty.str definer]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   470
                @ postify (map (ml_from_typ BR o IVarT) vs)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   471
                    (Pretty.str t)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   472
                @ [Pretty.str " =",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   473
                  Pretty.brk 1]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   474
                @ separate (Pretty.block [Pretty.brk 1, Pretty.str "| "]) (map mk_cons cs)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   475
              )
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   476
          in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   477
            chunk_defs (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   478
              mk_datatype "datatype " d
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   479
              :: map (mk_datatype "and ") ds_tl
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   480
            )
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   481
          end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   482
      in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   483
        ([], [])
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   484
        |> fold group ds
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   485
        |-> (fn cons => fold group_cons cons)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   486
        |> mk_datatypes
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   487
      end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   488
    fun ml_from_def (name, Typesyn (vs, ty)) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   489
        (map (fn (vname, []) => () | _ => error "can't serialize sort constrained type declaration to ML") vs;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   490
         Pretty.block (
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   491
          Pretty.str "type "
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   492
          :: postify (map (Pretty.str o fst) vs) (Pretty.str name)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   493
          @ [Pretty.str " =",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   494
          Pretty.brk 1,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   495
          ml_from_typ NOBR ty,
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   496
          Pretty.str ";"
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   497
        ]))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   498
      | ml_from_def (name, Nop) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   499
          if exists (fn query => (is_some o query) name)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   500
            [(fn name => styco name [] (ml_from_typ NOBR)),
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   501
             (fn name => sconst name [] (ml_from_iexpr NOBR))]
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   502
          then Pretty.str ""
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   503
          else error ("empty statement during serialization: " ^ quote name)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   504
      | ml_from_def (name, Class _) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   505
          error ("can't serialize class declaration " ^ quote name ^ " to ML")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   506
      | ml_from_def (name, Classinst _) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   507
          error ("can't serialize instance declaration " ^ quote name ^ " to ML")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   508
  in case (snd o hd) ds
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   509
   of Fun _ => ml_from_funs ds
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   510
    | Datatypecons _ => ml_from_datatypes ds
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   511
    | Datatype _ => ml_from_datatypes ds
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   512
    | _ => (case ds of [d] => ml_from_def d)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   513
  end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   514
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   515
in
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   516
18217
e0b08c9534ff added codegen package
haftmann
parents: 18216
diff changeset
   517
fun ml_from_thingol nspgrp name_root styco sconst prims select module =
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   518
  let
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   519
    fun ml_from_module (name, ps) =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   520
      Pretty.chunks ([
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   521
        Pretty.str ("structure " ^ name ^ " = "),
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   522
        Pretty.str "struct",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   523
        Pretty.str ""
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   524
      ] @ ps @ [
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   525
        Pretty.str "",
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   526
        Pretty.str ("end; (* struct " ^ name ^ " *)")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   527
      ]);
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   528
    fun eta_expander "Pair" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   529
      | eta_expander "Cons" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   530
      | eta_expander "primeq" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   531
      | eta_expander "and" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   532
      | eta_expander "or" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   533
      | eta_expander "if" = 3
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   534
      | eta_expander "add" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   535
      | eta_expander "mult" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   536
      | eta_expander "lt" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   537
      | eta_expander "le" = 2
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   538
      | eta_expander s =
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   539
          if NameSpace.is_qualified s
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   540
          then case get_def module s
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   541
            of Datatypecons (_ , tys) =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   542
                if length tys >= 2 then length tys else 0
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   543
             | _ =>
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   544
              (case sconst s [] (K (Pretty.str ""))
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   545
               of NONE => 0
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   546
                | SOME (xs, _) => length xs)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   547
          else 0
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   548
  in 
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   549
    module
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   550
    |> debug 5 (Pretty.output o pretty_module)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   551
    |> debug 3 (fn _ => "connecting datatypes and classdecls...")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   552
    |> connect_datatypes_clsdecls
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   553
    |> debug 3 (fn _ => "selecting submodule...")
18217
e0b08c9534ff added codegen package
haftmann
parents: 18216
diff changeset
   554
    |> (if is_some select then (partof o the) select else I)
18216
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   555
    |> debug 3 (fn _ => "eta-expanding...")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   556
    |> eta_expand eta_expander
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   557
    |> debug 5 (Pretty.output o pretty_module)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   558
    |> debug 3 (fn _ => "tupelizing datatypes...")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   559
    |> tupelize_cons
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   560
    |> debug 3 (fn _ => "eliminating classes...")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   561
    |> eliminate_classes
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   562
    |> debug 3 (fn _ => "generating...")
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   563
    |> serialize (ml_from_defs styco sconst) ml_from_module (ml_validator prims) nspgrp name_root
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   564
  end;
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   565
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   566
(* ML infix precedence
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   567
   7 / * div mod
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   568
   6 + - ^
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   569
   5 :: @
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   570
   4 = <> < > <= >=
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   571
   3 := o *)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   572
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   573
end; (* local *)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   574
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   575
end; (* struct *)
db7d43b25c99 added serializer
haftmann
parents: 18169
diff changeset
   576