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