src/Pure/Tools/codegen_thingol.ML
author haftmann
Mon, 14 Nov 2005 16:26:40 +0100
changeset 18170 73ce773f12de
parent 18169 45def66f86cb
child 18172 8ff5bcfae27a
permissions -rw-r--r--
added module system
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_thingol.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
Intermediate language ("Thin-gol") for code extraction.
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     6
*)
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
signature CODEGEN_THINGOL =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
     9
sig
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    10
  type vname = string;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    11
  datatype itype =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    12
      IType of string * itype list
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    13
    | IFun of itype * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    14
    | IVarT of vname * sort;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    15
  datatype ipat =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    16
      ICons of (string * ipat list) * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    17
    | IVarP of vname * itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    18
  datatype iexpr =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    19
      IConst of string * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    20
    | IVarE of vname * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    21
    | IApp of iexpr * iexpr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    22
    | IInst of iexpr * ClassPackage.sortlookup list list
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    23
    | IAbs of (vname * itype) * iexpr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    24
    | ICase of iexpr * (ipat * iexpr) list;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    25
  val eq_itype: itype * itype -> bool
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    26
  val eq_ipat: ipat * ipat -> bool
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    27
  val eq_iexpr: iexpr * iexpr -> bool
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    28
  val mk_funs: itype list * itype -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    29
  val mk_apps: iexpr * iexpr list -> iexpr;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    30
  val pretty_itype: itype -> Pretty.T;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    31
  val pretty_ipat: ipat -> Pretty.T;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    32
  val pretty_iexpr: iexpr -> Pretty.T;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    33
  val unfold_fun: itype -> itype list * itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    34
  val unfold_app: iexpr -> iexpr * iexpr list;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    35
  val unfold_let: iexpr -> (ipat * iexpr) list * iexpr;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    36
  val itype_of_iexpr: iexpr -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    37
  val itype_of_ipat: ipat -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    38
  val ipat_of_iexpr: iexpr -> ipat;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    39
  val vars_of_ipats: ipat list -> vname list;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    40
  val instant_itype: vname * itype -> itype -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    41
  val invent_tvar_names: itype list -> int -> vname list -> vname -> vname list;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    42
  val invent_evar_names: iexpr list -> int -> vname list -> vname -> vname list;
18170
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    43
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    44
  datatype def =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    45
      Nop
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    46
    | Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    47
    | Typsyn of (vname * string list) list * itype
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    48
    | Datatyp of (vname * string list) list * string list * string list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    49
    | Datatypcons of string * itype list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    50
    | Class of string list * string list * string list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    51
    | Classmember of string * vname * itype
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    52
    | Classinst of string * (string * string list list) * (string * string) list;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    53
  type module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    54
  type transact;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    55
  type 'dst transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    56
  type ('src, 'dst) gen_codegen = 'src -> transact -> 'dst transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    57
  type gen_defgen = string -> transact -> (def * string list) transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    58
  val eq_def: def * def -> bool;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    59
  val pretty_def: def -> Pretty.T;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    60
  val pretty_module: module -> Pretty.T;  
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    61
  val empty_module: module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    62
  val get_def: module -> string -> def;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    63
  val map_defs: (def -> def) -> module -> module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    64
  val add_deps: (string * def -> (string * string) list) -> module -> module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    65
  val fold_defs: (string * def -> 'a -> 'a) -> module -> 'a -> 'a;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    66
  val fold_map_defs: (string * def -> 'a -> def * 'a) -> module -> 'a -> module * 'a;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    67
  val merge_module: module * module -> module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    68
  val partof: string list -> module -> module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    69
  val succeed: 'a -> transact -> 'a transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    70
  val fail: string -> transact -> 'a transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    71
  val gen_invoke: (string * ('src, 'dst) gen_codegen) list -> string
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    72
    -> 'src -> transact -> 'dst * transact;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    73
  val gen_ensure_def: (string * gen_defgen) list -> string
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    74
    -> string -> transact -> transact;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    75
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    76
  val debug_level : int ref;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    77
  val debug : int -> ('a -> string) -> 'a -> 'a;
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    78
end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    79
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    80
signature CODEGEN_THINGOL_OP =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    81
sig
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    82
  include CODEGEN_THINGOL;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    83
  val `%% : string * itype list -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    84
  val `-> : itype * itype -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    85
  val `--> : itype list * itype -> itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    86
  val `$ : iexpr * iexpr -> iexpr;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    87
  val `$$ : iexpr * iexpr list -> iexpr;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    88
end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    89
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    90
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    91
structure CodegenThingolOp: CODEGEN_THINGOL_OP =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    92
struct
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    93
18170
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    94
(** auxiliary **)
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    95
18170
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    96
val debug_level = ref 0;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
    97
fun debug d f x = (if d <= !debug_level then Output.debug (f x) else (); x);
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    98
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
    99
fun foldl' f (l, []) = the l
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   100
  | foldl' f (_, (r::rs)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   101
      let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   102
        fun itl (l, [])  = l
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   103
          | itl (l, r::rs) = itl (f (l, r), rs)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   104
      in itl (r, rs) end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   105
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   106
fun foldr' f ([], r) = the r
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   107
  | foldr' f (ls, _) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   108
      let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   109
        fun itr [l] = l
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   110
          | itr (l::ls) = f (l, itr ls)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   111
      in itr ls end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   112
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   113
fun unfoldl dest x =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   114
  case dest x
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   115
   of NONE => (x, [])
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   116
    | SOME (x1, x2) =>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   117
        let val (x', xs') = unfoldl dest x1 in (x', xs' @ [x2]) end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   118
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   119
fun unfoldr dest x =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   120
  case dest x
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   121
   of NONE => ([], x)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   122
    | SOME (x1, x2) =>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   123
        let val (xs', x') = unfoldr dest x2 in (x1::xs', x') end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   124
18170
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   125
fun get_prefix eq ([], ys) = ([], [], ys)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   126
  | get_prefix eq (xs, []) = ([], xs, [])
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   127
  | get_prefix eq (xs as x::xs', ys as y::ys') =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   128
      if eq (x, y) then
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   129
        let val (ps', xs'', ys'') = get_prefix eq (xs', ys')
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   130
        in (x::ps', xs'', ys'') end
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   131
      else ([], xs, ys);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   132
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   133
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   134
(** language core - types, pattern, expressions **)
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   135
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   136
(* language representation *)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   137
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   138
infix 8 `%%;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   139
infixr 6 `->;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   140
infixr 6 `-->;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   141
infix 4 `$;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   142
infix 4 `$$;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   143
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   144
type vname = string;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   145
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   146
datatype itype =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   147
    IType of string * itype list
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   148
  | IFun of itype * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   149
  | IVarT of vname * sort;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   150
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   151
datatype ipat =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   152
    ICons of (string * ipat list) * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   153
  | IVarP of vname * itype;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   154
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   155
datatype iexpr =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   156
    IConst of string * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   157
  | IVarE of vname * itype
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   158
  | IApp of iexpr * iexpr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   159
  | IInst of iexpr * ClassPackage.sortlookup list list
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   160
  | IAbs of (vname * itype) * iexpr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   161
  | ICase of iexpr * (ipat * iexpr) list;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   162
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   163
val eq_itype = (op =);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   164
val eq_ipat = (op =);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   165
val eq_iexpr = (op =);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   166
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   167
val mk_funs = Library.foldr IFun;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   168
val mk_apps = Library.foldl IApp;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   170
fun tyco `%% tys = IType (tyco, tys);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   171
val op `-> = IFun;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   172
fun f `$ x = IApp (f, x);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   173
val op `--> = mk_funs;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   174
val op `$$ = mk_apps;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   175
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   176
val unfold_fun = unfoldr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   177
  (fn IFun t => SOME t
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   178
    | _ => NONE);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   179
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   180
val unfold_app = unfoldl
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   181
  (fn IApp e => SOME e
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   182
    | _ => NONE);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   183
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   184
val unfold_let = unfoldr
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   185
  (fn ICase (e, [(p, e')]) => SOME ((p, e), e')
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   186
    | _ => NONE);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   187
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   188
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   189
(* simple diagnosis *)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   190
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   191
fun pretty_itype (IType (tyco, tys)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   192
      Pretty.gen_list "" "(" ")" (Pretty.str tyco :: map pretty_itype tys)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   193
  | pretty_itype (IFun (ty1, ty2)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   194
      Pretty.gen_list "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   195
  | pretty_itype (IVarT (v, sort)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   196
      Pretty.str (v ^ enclose "|" "|" (space_implode "|" sort))
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   197
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   198
fun pretty_ipat (ICons ((cons, ps), ty)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   199
      Pretty.gen_list " " "(" ")"
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   200
        (Pretty.str cons :: map pretty_ipat ps @ [Pretty.str ":: ", pretty_itype ty])
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   201
  | pretty_ipat (IVarP (v, ty)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   202
      Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   203
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   204
fun pretty_iexpr (IConst (f, ty)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   205
      Pretty.block [Pretty.str (f ^ "::"), pretty_itype ty]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   206
  | pretty_iexpr (IVarE (v, ty)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   207
      Pretty.block [Pretty.str ("?" ^ v ^ "::"), pretty_itype ty]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   208
  | pretty_iexpr (IApp (e1, e2)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   209
      Pretty.enclose "(" ")" [pretty_iexpr e1, Pretty.brk 1, pretty_iexpr e2]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   210
  | pretty_iexpr (IInst (e, c)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   211
      pretty_iexpr e
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   212
  | pretty_iexpr (IAbs ((v, ty), e)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   213
      Pretty.enclose "(" ")" [Pretty.str ("?" ^ v ^ " |->"), Pretty.brk 1, pretty_iexpr e]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   214
  | pretty_iexpr (ICase (e, cs)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   215
      Pretty.enclose "(" ")" [
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   216
        Pretty.str "case ",
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   217
        pretty_iexpr e,
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   218
        Pretty.enclose "(" ")" (map (fn (p, e) =>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   219
          Pretty.block [
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   220
            pretty_ipat p,
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   221
            Pretty.str " => ",
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   222
            pretty_iexpr e
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   223
          ]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   224
        ) cs)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   225
      ]
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   226
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   227
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   228
(* language auxiliary *)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   229
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   230
fun itype_of_iexpr (IConst (_, ty)) = ty
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   231
  | itype_of_iexpr (IVarE (_, ty)) = ty
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   232
  | itype_of_iexpr (e as IApp (e1, e2)) = (case itype_of_iexpr e1
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   233
      of (IFun (ty2, ty')) =>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   234
            if ty2 = itype_of_iexpr e2
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   235
            then ty'
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   236
            else error ("inconsistent application: in " ^ Pretty.output (pretty_iexpr e)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   237
              ^ ", " ^ (Pretty.output o pretty_itype) ty2 ^ " vs. " ^ (Pretty.output o pretty_itype o itype_of_iexpr) e2)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   238
       | _ => error ("expression is not a function: " ^ Pretty.output (pretty_iexpr e1)))
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   239
  | itype_of_iexpr (IInst (e, cs)) = error ""
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   240
  | itype_of_iexpr (IAbs ((_, ty1), e2)) = ty1 `-> itype_of_iexpr e2
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   241
  | itype_of_iexpr (ICase ((_, [(_, e)]))) = itype_of_iexpr e;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   242
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   243
fun itype_of_ipat (ICons (_, ty)) = ty
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   244
  | itype_of_ipat (IVarP (_, ty)) = ty
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   245
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   246
fun ipat_of_iexpr (IConst (f, ty)) = ICons ((f, []), ty)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   247
  | ipat_of_iexpr (IVarE v) = IVarP v
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   248
  | ipat_of_iexpr (e as IApp _) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   249
      case unfold_app e of (IConst (f, ty), es) =>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   250
        ICons ((f, map ipat_of_iexpr es), (snd o unfold_fun) ty);
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   251
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   252
fun vars_of_ipats ps =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   253
  let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   254
    fun vars (ICons ((_, ps), _)) = fold vars ps
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   255
      | vars (IVarP (v, _)) = cons v
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   256
  in fold vars ps [] end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   257
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   258
fun instant_itype (v, sty) ty =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   259
  let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   260
    fun instant (IType (tyco, tys)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   261
          tyco `%% map instant tys
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   262
      | instant (IFun (ty1, ty2)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   263
          instant ty1 `-> instant ty2
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   264
      | instant (w as (IVarT (u, _))) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   265
          if v = u then sty else w
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   266
  in instant ty end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   267
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   268
fun invent_tvar_names tys n used a =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   269
  let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   270
    fun invent (IType (_, tys)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   271
          fold invent tys
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   272
      | invent (IFun (ty1, ty2)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   273
          invent ty1 #> invent ty2
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   274
      | invent (IVarT (v, _)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   275
          cons v
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   276
in Term.invent_names (fold invent tys used) a n end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   277
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   278
fun invent_evar_names es n used a =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   279
  let
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   280
    fun invent (IConst (f, _)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   281
          I
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   282
      | invent (IVarE (v, _)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   283
          cons v
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   284
      | invent (IApp (e1, e2)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   285
          invent e1 #> invent e2
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   286
      | invent (IAbs ((v, _), e)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   287
          cons v #> invent e
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   288
      | invent (ICase (e, cs)) =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   289
          invent e
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   290
          #>
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   291
          fold (fn (p, e) => append (vars_of_ipats [p]) #> invent e) cs
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   292
  in Term.invent_names (fold invent es used) a n end;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   293
18170
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   294
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   295
(** language module system - definitions, modules, transactions **)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   296
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   297
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   298
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   299
(* type definitions *)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   300
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   301
datatype def =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   302
    Nop
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   303
  | Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   304
  | Typsyn of (vname * string list) list * itype
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   305
  | Datatyp of (vname * string list) list * string list * string list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   306
  | Datatypcons of string * itype list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   307
  | Class of string list * string list * string list
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   308
  | Classmember of string * string * itype
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   309
  | Classinst of string * (string * string list list) * (string * string) list;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   310
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   311
datatype node = Def of def | Module of node Graph.T;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   312
type module = node Graph.T;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   313
type transact = Graph.key list * module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   314
datatype 'dst transact_res = Succeed of 'dst | Fail of string;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   315
type 'dst transact_fin = 'dst transact_res * transact;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   316
type ('src, 'dst) gen_codegen = 'src -> transact -> 'dst transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   317
type gen_defgen = string -> transact -> (def * string list) transact_fin;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   318
exception FAIL of string;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   319
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   320
val eq_def = (op =);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   321
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   322
(* simple diagnosis *)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   323
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   324
fun pretty_def Nop =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   325
      Pretty.str "<NOP>"
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   326
  | pretty_def (Fun (eqs, (_, ty))) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   327
      Pretty.gen_list " |" "" "" (
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   328
        map (fn (ps, body) =>
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   329
          Pretty.block [
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   330
            Pretty.gen_list "," "[" "]" (map pretty_ipat ps),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   331
            Pretty.str " |->",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   332
            Pretty.brk 1,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   333
            pretty_iexpr body,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   334
            Pretty.str "::",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   335
            pretty_itype ty
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   336
          ]) eqs
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   337
        )
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   338
  | pretty_def (Typsyn (vs, ty)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   339
      Pretty.block [
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   340
        Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   341
        Pretty.str " |=> ",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   342
        pretty_itype ty
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   343
      ]
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   344
  | pretty_def (Datatyp (vs, cs, clss)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   345
      Pretty.block [
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   346
        Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   347
        Pretty.str " |=> ",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   348
        Pretty.gen_list " |" "" "" (map Pretty.str cs),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   349
        Pretty.str ", instance of ",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   350
        Pretty.gen_list "," "[" "]" (map Pretty.str clss)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   351
      ]
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   352
  | pretty_def (Datatypcons (dtname, tys)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   353
      Pretty.block [
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   354
        Pretty.str "cons ",
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   355
        Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname])
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   356
      ]
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   357
  | pretty_def (Class (supcls, mems, insts)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   358
      Pretty.str "Class ..."
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   359
  | pretty_def (Classmember (cls, v, ty)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   360
      Pretty.str "Classmember ..."
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   361
  | pretty_def (Classinst (cls, insts, mems)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   362
      Pretty.str "Classinst ..."
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   363
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   364
fun pretty_module modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   365
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   366
    fun pretty (name, Module modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   367
          Pretty.block (
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   368
            Pretty.str ("module " ^ name ^ " {")
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   369
            :: Pretty.brk 1
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   370
            :: Pretty.chunks (map pretty (AList.make (Graph.get_node modl)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   371
                 (Graph.strong_conn modl |> List.concat |> rev)))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   372
            :: Pretty.str "}" :: nil
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   373
          )
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   374
      | pretty (name, Def def) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   375
          Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def]
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   376
  in pretty ("//", Module modl) end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   377
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   378
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   379
(* name handling *)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   380
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   381
fun dest_name name =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   382
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   383
    val name' = NameSpace.unpack name
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   384
    val (name'', name_base) = split_last name'
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   385
    val (modl, shallow) = split_last name''
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   386
  in (modl, NameSpace.pack [shallow, name_base]) end
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   387
  handle Empty => error ("not a qualified name: " ^ quote name);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   388
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   389
fun dest_modl (Module m) = m;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   390
fun dest_def (Def d) = d;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   391
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   392
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   393
(* modules *)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   394
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   395
val empty_module = Graph.empty; (*read: "depends on"*)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   396
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   397
fun get_def modl name =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   398
  case dest_name name
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   399
   of (modlname, base) =>
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   400
        let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   401
          fun get (Module node) [] =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   402
                (dest_def o Graph.get_node node) base
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   403
            | get (Module node) (m::ms) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   404
                get (Graph.get_node node m) ms
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   405
        in get (Module modl) modlname end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   406
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   407
fun add_def (name, def) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   408
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   409
    val (modl, base) = dest_name name;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   410
    fun add [] =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   411
          Graph.new_node (base, Def def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   412
      | add (m::ms) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   413
          Graph.default_node (m, Module empty_module)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   414
          #> Graph.map_node m (Module o add ms o dest_modl)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   415
  in add modl end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   416
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   417
fun map_def name f =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   418
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   419
    val (modl, base) = dest_name name;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   420
    fun mapp [] =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   421
          Graph.map_node base (Def o f o dest_def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   422
      | mapp (m::ms) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   423
          Graph.map_node m (Module o mapp ms o dest_modl)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   424
  in mapp modl end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   425
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   426
fun add_dep (name1, name2) modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   427
  if name1 = name2 then modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   428
  else
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   429
    let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   430
      val m1 = dest_name name1 |> apsnd single |> (op @);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   431
      val m2 = dest_name name2 |> apsnd single |> (op @);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   432
      val (ms, r1, r2) = get_prefix (op =) (m1, m2);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   433
      val (ms, s1::r1, s2::r2) = get_prefix (op =) (m1, m2);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   434
      val add_edge =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   435
        if null r1 andalso null r2
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   436
        then Graph.add_edge
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   437
        else Graph.add_edge_acyclic
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   438
      fun add [] node =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   439
            node
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   440
            |> add_edge (s1, s2)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   441
        | add (m::ms) node =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   442
            node
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   443
            |> Graph.map_node m (Module o add ms o dest_modl);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   444
    in add ms modl end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   445
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   446
fun map_defs f =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   447
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   448
    fun mapp (Def def) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   449
          (Def o f) def
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   450
      | mapp (Module modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   451
          (Module o Graph.map_nodes mapp) modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   452
  in dest_modl o mapp o Module end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   453
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   454
fun fold_defs f =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   455
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   456
    fun fol prfix (name, Def def) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   457
          f (NameSpace.pack (prfix @ [name]), def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   458
      | fol prfix (name, Module modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   459
          Graph.fold_nodes (fol (prfix @ [name])) modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   460
  in Graph.fold_nodes (fol []) end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   461
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   462
fun add_deps f modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   463
  modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   464
  |> fold add_dep ([] |> fold_defs (append o f) modl);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   465
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   466
fun fold_map_defs f =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   467
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   468
    fun foldmap prfix (name, Def def) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   469
          apfst Def o f (NameSpace.pack (prfix @ [name]), def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   470
      | foldmap prfix (name, Module modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   471
          apfst Module o Graph.fold_map_nodes (foldmap (prfix @ [name])) modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   472
  in Graph.fold_map_nodes (foldmap []) end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   473
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   474
fun merge_module modl12 =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   475
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   476
    fun join_module (Module m1, Module m2) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   477
          (SOME o Module) (merge_module (m1, m2))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   478
      | join_module (Def d1, Def d2) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   479
          if eq_def (d1, d2) then (SOME o Def) d1 else NONE
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   480
      | join_module _ =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   481
          NONE
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   482
  in Graph.join (K join_module) modl12 end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   483
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   484
fun partof names modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   485
      let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   486
        datatype pathnode = PN of (string list * (string * pathnode) list);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   487
        fun mk_path ([], base) (PN (defs, modls)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   488
              PN (base :: defs, modls)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   489
          | mk_path (n::ns, base) (PN (defs, modls)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   490
              modls
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   491
              |> AList.default (op =) (n, PN ([], []))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   492
              |> AList.map_entry (op =) n (mk_path (ns, base))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   493
              |> (pair defs #> PN);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   494
        fun select (PN (defs, modls)) (Module module) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   495
          module
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   496
          |> Graph.subgraph (Graph.all_succs module (defs @ map fst modls))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   497
          |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   498
          |> Module;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   499
      in
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   500
        Module modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   501
        |> select (fold (mk_path o dest_name) (filter NameSpace.is_qualified names) (PN ([], [])))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   502
        |> dest_modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   503
      end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   504
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   505
fun add_check_transform (name, (Datatypcons (dtname, _))) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   506
      ([([dtname],
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   507
          fn [Datatyp (_, _, [])] => NONE | _ => "attempted to add constructor to already instantiating datatype" |> SOME)],
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   508
       [(dtname,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   509
          fn Datatyp (vs, cs, clss) => Datatyp (vs, name::cs, clss)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   510
           | def => "attempted to add datatype constructor to non-datatype: "
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   511
              ^ (Pretty.output o pretty_def) def |> error)])
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   512
  | add_check_transform (name, Classmember (clsname, v, ty)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   513
      let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   514
        fun check_var (IType (tyco, tys)) s =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   515
              fold check_var tys s
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   516
          | check_var (IFun (ty1, ty2)) s =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   517
              s
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   518
              |> check_var ty1
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   519
              |> check_var ty2
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   520
          | check_var (IVarT (w, sort)) s =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   521
              if v = w
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   522
              andalso member (op =) sort clsname
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   523
              then "additional class appears at type variable" |> SOME
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   524
              else NONE
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   525
      in
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   526
        ([([], fn [] => check_var ty NONE),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   527
          ([clsname],
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   528
             fn [Class (_, _, [])] => NONE
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   529
              | _ => "attempted to add class member to witnessed class" |> SOME)],
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   530
         [(clsname,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   531
             fn Class (supcs, mems, insts) => Class (supcs, name::mems, insts)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   532
              | def => "attempted to add class member to non-class"
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   533
                 ^ (Pretty.output o pretty_def) def |> error)])
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   534
      end
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   535
  | add_check_transform (name, Classinst (clsname, (tyco, arity), memdefs)) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   536
      let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   537
        fun check [Classmember (_, v, mtyp_c), Fun (_, (_, mtyp_i))] =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   538
          let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   539
            val mtyp_i' = instant_itype (v, tyco `%%
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   540
              map2 IVarT ((invent_tvar_names [mtyp_c] (length arity) [] "a"), arity)) mtyp_c;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   541
          in if eq_itype (mtyp_i', mtyp_i) (*! PERHAPS TOO STRICT !*)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   542
          then NONE
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   543
          else "wrong type signature for class member: "
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   544
            ^ (Pretty.output o pretty_itype) mtyp_i' ^ " expected,"
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   545
            ^ (Pretty.output o pretty_itype) mtyp_i ^ " given" |> SOME end
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   546
      in
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   547
        (map (fn (memname, memprim) => ((writeln memname; writeln memprim; [memname, memprim]), check)) memdefs,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   548
          [(clsname,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   549
              fn Class (supcs, mems, insts) => Class (supcs, mems, name::insts)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   550
               | def => "attempted to add class instance to non-class"
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   551
                  ^ (Pretty.output o pretty_def) def |> error),
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   552
           (tyco,
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   553
              fn Datatyp (vs, cs, clss) => Datatyp (vs, cs, clsname::clss)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   554
               | Nop => Nop
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   555
               | def => "attempted to instantiate non-type to class instance"
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   556
                  ^ (Pretty.output o pretty_def) def |> error)])
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   557
      end
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   558
  | add_check_transform _ = ([], []);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   559
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   560
fun succeed some = (pair o Succeed) some;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   561
fun fail msg = (pair o Fail) msg;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   562
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   563
fun check_fail msg' (Succeed dst, trns) = (dst, trns)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   564
  | check_fail msg' (Fail errmsg, _) = (tracing ("ROLLBACK CHECK: " ^ errmsg ^ "\n" ^ msg'); raise FAIL errmsg);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   565
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   566
fun handle_fail msg f modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   567
  f modl handle FAIL msg' => ([], modl) |> fail (msg ^ "\n" ^ msg');
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   568
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   569
fun select_generator print_msg src [] trns =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   570
      fail ("no code generator available") trns
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   571
  | select_generator print_msg src [(gname, cgen)] trns =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   572
      (print_msg gname; cgen src trns)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   573
  | select_generator print_msg src ((gname, cgen)::cgens) trns =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   574
      case cgen src trns
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   575
       of result as (Succeed _, _) =>
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   576
            (print_msg gname; result)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   577
        | _ => select_generator print_msg src cgens trns
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   578
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   579
fun gen_invoke codegens msg src (deps, modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   580
  ([], modl)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   581
  |> select_generator (fn gname => "choosing code generator " ^ gname ^ " for source " ^ quote msg)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   582
       src codegens
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   583
  |> check_fail msg
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   584
  ||> (fn (deps', modl') => (append deps' deps, modl'));
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   585
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   586
fun gen_ensure_def defgens msg name (deps, modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   587
  let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   588
    fun add (name, def) (deps, modl) =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   589
      let
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   590
        val (checks, trans) = add_check_transform (name, def);
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   591
        fun check (check_defs, checker) modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   592
          case checker (check_defs |> filter NameSpace.is_qualified |> map (get_def modl))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   593
           of NONE => modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   594
            | SOME e => raise FAIL e;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   595
        fun transform (name, f) modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   596
          modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   597
          |> K (NameSpace.is_qualified name) ? map_def name f;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   598
      in
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   599
        modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   600
        |> fold check checks
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   601
        |> fold (curry add_dep name) deps
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   602
        |> map_def name (fn _ => def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   603
        |> fold transform trans
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   604
      end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   605
    fun ensure_node name modl =
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   606
      if can (get_def modl) name
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   607
      then ([name], modl)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   608
      else
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   609
        ([], modl |> add_def (name, Nop))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   610
        |> select_generator (fn gname => "choosing code generator " ^ gname ^ " for definition of " ^ quote name)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   611
             name defgens
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   612
        |> check_fail msg
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   613
        |-> (fn (def, names') =>
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   614
           add (name, def)
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   615
           #> fold_map ensure_node names')
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   616
        |-> (fn names' => pair (name :: Library.flat names'))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   617
  in
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   618
    modl
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   619
    |> ensure_node name
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   620
    |-> (fn names => pair (names@deps))
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   621
  end;
73ce773f12de added module system
haftmann
parents: 18169
diff changeset
   622
18169
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   623
end; (* struct *)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   624
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   625
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   626
structure CodegenThingol : CODEGEN_THINGOL =
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   627
struct
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   628
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   629
open CodegenThingolOp;
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   630
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   631
end; (* struct *)
45def66f86cb added modules for code generator generation two, not operational yet
haftmann
parents:
diff changeset
   632