| author | wenzelm | 
| Fri, 05 May 2006 21:59:43 +0200 | |
| changeset 19575 | 2d9940cd52d3 | 
| parent 19482 | 9f11af8f7ef9 | 
| child 19597 | 8ced57ffc090 | 
| permissions | -rw-r--r-- | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 1 | (* Title: Pure/Tools/codegen_thingol.ML | 
| 18169 
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 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 8 | infix 8 `%%; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 9 | infixr 6 `->; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 10 | infixr 6 `-->; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 11 | infix 4 `$; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 12 | infix 4 `$$; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 13 | infixr 3 `|->; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 14 | infixr 3 `|-->; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 15 | |
| 19136 | 16 | signature BASIC_CODEGEN_THINGOL = | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 17 | sig | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 18 | type vname = string; | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 19 | type sortcontext = ClassPackage.sortcontext; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 20 | datatype iclasslookup = Instance of string * iclasslookup list list | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 21 | | Lookup of class list * (string * int); | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 22 | datatype itype = | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 23 | `%% of string * itype list | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 24 | | `-> of itype * itype | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 25 | | ITyVar of vname; | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 26 | datatype iexpr = | 
| 19202 | 27 | IConst of string * (iclasslookup list list * itype) | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 28 | | IVar of vname | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 29 | | `$ of iexpr * iexpr | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 30 | | `|-> of (vname * itype) * iexpr | 
| 19202 | 31 | | INum of (IntInf.int (*positive!*) * itype) * unit | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 32 | | IAbs of ((iexpr * itype) * iexpr) * iexpr | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 33 | (* (((binding expression (ve), binding type (vty)), | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 34 | body expression (be)), native expression (e0)) *) | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 35 | | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 36 | (* ((discrimendum expression (de), discrimendum type (dty)), | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 37 | [(selector expression (se), body expression (be))]), | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 38 | native expression (e0)) *) | 
| 19136 | 39 | end; | 
| 40 | ||
| 41 | signature CODEGEN_THINGOL = | |
| 42 | sig | |
| 43 | include BASIC_CODEGEN_THINGOL; | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 44 | val `--> : itype list * itype -> itype; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 45 | val `$$ : iexpr * iexpr list -> iexpr; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 46 | val `|--> : (vname * itype) list * iexpr -> iexpr; | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 47 | val pretty_itype: itype -> Pretty.T; | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 48 | val pretty_iexpr: iexpr -> Pretty.T; | 
| 18216 | 49 |   val unfoldl: ('a -> ('a * 'b) option) -> 'a -> 'a * 'b list;
 | 
| 50 |   val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a;
 | |
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 51 | val unfold_fun: itype -> itype list * itype; | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 52 | val unfold_app: iexpr -> iexpr * iexpr list; | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 53 | val unfold_abs: iexpr -> (iexpr * itype) list * iexpr; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 54 | val unfold_let: iexpr -> ((iexpr * itype) * iexpr) list * iexpr; | 
| 18865 | 55 | val unfold_const_app: iexpr -> | 
| 19202 | 56 | ((string * (iclasslookup list list * itype)) * iexpr list) option; | 
| 57 | val add_constnames: iexpr -> string list -> string list; | |
| 58 | val add_varnames: iexpr -> string list -> string list; | |
| 59 | val is_pat: iexpr -> bool; | |
| 60 | val map_pure: (iexpr -> 'a) -> iexpr -> 'a; | |
| 18170 | 61 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 62 | type funn = (iexpr list * iexpr) list * (sortcontext * itype); | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 63 | type datatyp = sortcontext * (string * itype list) list; | 
| 18850 | 64 | datatype prim = | 
| 65 | Pretty of Pretty.T | |
| 18963 | 66 | | Name; | 
| 18170 | 67 | datatype def = | 
| 18702 | 68 | Undef | 
| 18963 | 69 | | Prim of (string * prim list) list | 
| 18702 | 70 | | Fun of funn | 
| 19038 | 71 | | Typesyn of (vname * sort) list * itype | 
| 19042 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 72 | | Datatype of datatyp | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 73 | | Datatypecons of string | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 74 | | Class of class list * (vname * (string * (sortcontext * itype)) list) | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 75 | | Classmember of class | 
| 18865 | 76 | | Classinst of ((class * (string * (vname * sort) list)) | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 77 | * (class * (string * iclasslookup list list)) list) | 
| 19253 | 78 | * (string * ((string * funn) * iclasslookup list list)) list | 
| 19213 | 79 | | Classinstmember; | 
| 18170 | 80 | type module; | 
| 81 | type transact; | |
| 82 | type 'dst transact_fin; | |
| 83 | val pretty_def: def -> Pretty.T; | |
| 18282 | 84 | val pretty_module: module -> Pretty.T; | 
| 18360 | 85 | val pretty_deps: module -> Pretty.T; | 
| 18170 | 86 | val empty_module: module; | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 87 | val get_def: module -> string -> def; | 
| 18963 | 88 | val add_prim: string -> (string * prim list) -> module -> module; | 
| 18702 | 89 | val ensure_prim: string -> string -> module -> module; | 
| 18170 | 90 | val merge_module: module * module -> module; | 
| 19042 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 91 | val diff_module: module * module -> (string * def) list; | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 92 | val project_module: string list -> module -> module; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 93 | val purge_module: string list -> module -> module; | 
| 18516 | 94 | val has_nsp: string -> string -> bool; | 
| 18170 | 95 | val succeed: 'a -> transact -> 'a transact_fin; | 
| 96 | val fail: string -> transact -> 'a transact_fin; | |
| 19136 | 97 | val ensure_def: (string * (string -> transact -> def transact_fin)) list -> string | 
| 18170 | 98 | -> string -> transact -> transact; | 
| 18963 | 99 | val start_transact: string option -> (transact -> 'a * transact) -> module -> 'a * module; | 
| 18216 | 100 | |
| 18172 | 101 | val eta_expand: (string -> int) -> module -> module; | 
| 18216 | 102 | val eta_expand_poly: module -> module; | 
| 18963 | 103 | val unclash_vars_tvars: module -> module; | 
| 18172 | 104 | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 105 | val debug: bool ref; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 106 |   val debug_msg: ('a -> string) -> 'a -> 'a;
 | 
| 18231 | 107 | val soft_exc: bool ref; | 
| 18216 | 108 | |
| 109 | val serialize: | |
| 19038 | 110 | ((string -> string -> string) -> string -> (string * def) list -> 'a option) | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 111 | -> ((string -> string) -> string list -> (string * string) * 'a list -> 'a option) | 
| 18216 | 112 | -> (string -> string option) | 
| 18919 | 113 | -> (string * string -> string) | 
| 18850 | 114 | -> string list list -> string -> module -> 'a option; | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 115 | end; | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 116 | |
| 18850 | 117 | structure CodegenThingol: CODEGEN_THINGOL = | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 118 | struct | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 119 | |
| 18170 | 120 | (** auxiliary **) | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 121 | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 122 | val debug = ref false; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 123 | fun debug_msg f x = (if !debug then Output.debug (f x) else (); x); | 
| 18231 | 124 | val soft_exc = ref true; | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 125 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 126 | fun unfoldl dest x = | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 127 | case dest x | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 128 | of NONE => (x, []) | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 129 | | SOME (x1, x2) => | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 130 | 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 | 131 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 132 | fun unfoldr dest x = | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 133 | case dest x | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 134 | of NONE => ([], x) | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 135 | | SOME (x1, x2) => | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 136 | 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 | 137 | |
| 18172 | 138 | fun map_yield f [] = ([], []) | 
| 139 | | map_yield f (x::xs) = | |
| 140 | let | |
| 141 | val (y, x') = f x | |
| 142 | val (ys, xs') = map_yield f xs | |
| 143 | in (y::ys, x'::xs') end; | |
| 144 | ||
| 18454 | 145 | fun get_prefix eq ([], ys) = ([], ([], ys)) | 
| 146 | | get_prefix eq (xs, []) = ([], (xs, [])) | |
| 18170 | 147 | | get_prefix eq (xs as x::xs', ys as y::ys') = | 
| 148 | if eq (x, y) then | |
| 18454 | 149 | let val (ps', xys'') = get_prefix eq (xs', ys') | 
| 150 | in (x::ps', xys'') end | |
| 151 | else ([], (xs, ys)); | |
| 18170 | 152 | |
| 153 | ||
| 154 | (** language core - types, pattern, expressions **) | |
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 155 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 156 | (* language representation *) | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 157 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 158 | type vname = string; | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 159 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 160 | type sortcontext = ClassPackage.sortcontext; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 161 | datatype iclasslookup = Instance of string * iclasslookup list list | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 162 | | Lookup of class list * (string * int); | 
| 18885 | 163 | |
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 164 | datatype itype = | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 165 | `%% of string * itype list | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 166 | | `-> of itype * itype | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 167 | | ITyVar of vname; | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 168 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 169 | datatype iexpr = | 
| 19202 | 170 | IConst of string * (iclasslookup list list * itype) | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 171 | | IVar of vname | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 172 | | `$ of iexpr * iexpr | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 173 | | `|-> of (vname * itype) * iexpr | 
| 19202 | 174 | | INum of (IntInf.int (*positive!*) * itype) * unit | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 175 | | IAbs of ((iexpr * itype) * iexpr) * iexpr | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 176 | | ICase of ((iexpr * itype) * (iexpr * iexpr) list) * iexpr; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 177 | (*see also signature*) | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 178 | |
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 179 | (* | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 180 | variable naming conventions | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 181 | |
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 182 | bare names: | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 183 | variable names v | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 184 | class names cls | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 185 | type constructor names tyco | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 186 | datatype names dtco | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 187 | const names (general) c | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 188 | constructor names co | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 189 | class member names m | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 190 | arbitrary name s | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 191 | |
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 192 | constructs: | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 193 | sort sort | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 194 | type ty | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 195 | expression e | 
| 18702 | 196 | pattern p, pat | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 197 | instance (cls, tyco) inst | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 198 | variable (v, ty) var | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 199 | class member (m, ty) membr | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 200 | constructors (co, tys) constr | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 201 | *) | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 202 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 203 | val op `--> = Library.foldr (op `->); | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 204 | val op `$$ = Library.foldl (op `$); | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 205 | val op `|--> = Library.foldr (op `|->); | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 206 | |
| 19150 | 207 | val pretty_sortcontext = | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 208 |   Pretty.list "(" ")" o Pretty.commas o map (fn (v, sort) => (Pretty.block o Pretty.breaks)
 | 
| 19150 | 209 | [Pretty.str v, Pretty.str "::", Pretty.enum "&" "" "" (map Pretty.str sort)]); | 
| 210 | ||
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 211 | fun pretty_itype (tyco `%% tys) = | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 212 |       Pretty.enum "" "(" ")" (Pretty.str tyco :: map pretty_itype tys)
 | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 213 | | pretty_itype (ty1 `-> ty2) = | 
| 18885 | 214 |       Pretty.enum "" "(" ")" [pretty_itype ty1, Pretty.str "->", pretty_itype ty2]
 | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 215 | | pretty_itype (ITyVar v) = | 
| 19150 | 216 | Pretty.str v; | 
| 18885 | 217 | |
| 19202 | 218 | fun pretty_iexpr (IConst (c, _)) = | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 219 | Pretty.str c | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 220 | | pretty_iexpr (IVar v) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 221 |       Pretty.str ("?" ^ v)
 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 222 | | pretty_iexpr (e1 `$ e2) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 223 |       (Pretty.enclose "(" ")" o Pretty.breaks)
 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 224 | [pretty_iexpr e1, pretty_iexpr e2] | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 225 | | pretty_iexpr ((v, ty) `|-> e) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 226 |       (Pretty.enclose "(" ")" o Pretty.breaks)
 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 227 | [Pretty.str v, Pretty.str "::", pretty_itype ty, Pretty.str "|->", pretty_iexpr e] | 
| 19202 | 228 | | pretty_iexpr (INum ((n, _), _)) = | 
| 229 | (Pretty.str o IntInf.toString) n | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 230 | | pretty_iexpr (IAbs (((e1, _), e2), _)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 231 |       (Pretty.enclose "(" ")" o Pretty.breaks)
 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 232 | [pretty_iexpr e1, Pretty.str "|->", pretty_iexpr e2] | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 233 | | pretty_iexpr (ICase (((e, _), cs), _)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 234 |       (Pretty.enclose "(" ")" o Pretty.breaks) [
 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 235 | Pretty.str "case", | 
| 18885 | 236 | pretty_iexpr e, | 
| 237 |         Pretty.enclose "(" ")" (map (fn (p, e) =>
 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 238 | (Pretty.block o Pretty.breaks) [ | 
| 18885 | 239 | pretty_iexpr p, | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 240 | Pretty.str "=>", | 
| 18885 | 241 | pretty_iexpr e | 
| 242 | ] | |
| 243 | ) cs) | |
| 244 | ]; | |
| 245 | ||
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 246 | val unfold_fun = unfoldr | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 247 | (fn op `-> t => SOME t | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 248 | | _ => NONE); | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 249 | |
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 250 | val unfold_app = unfoldl | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 251 | (fn op `$ e => SOME e | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 252 | | _ => NONE); | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 253 | |
| 18282 | 254 | val unfold_abs = unfoldr | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 255 | (fn (v, ty) `|-> e => SOME ((IVar v, ty), e) | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 256 | | IAbs (((e1, ty), e2), _) => SOME ((e1, ty), e2) | 
| 18282 | 257 | | _ => NONE) | 
| 258 | ||
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 259 | val unfold_let = unfoldr | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 260 | (fn ICase (((de, dty), [(se, be)]), _) => SOME (((se, dty), de), be) | 
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 261 | | _ => NONE); | 
| 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 262 | |
| 18865 | 263 | fun unfold_const_app e = | 
| 264 | case unfold_app e | |
| 265 | of (IConst x, es) => SOME (x, es) | |
| 266 | | _ => NONE; | |
| 267 | ||
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 268 | fun map_itype _ (ty as ITyVar _) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 269 | ty | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 270 | | map_itype f (tyco `%% tys) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 271 | tyco `%% map f tys | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 272 | | map_itype f (t1 `-> t2) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 273 | f t1 `-> f t2; | 
| 18172 | 274 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 275 | fun map_iexpr _ (e as IConst _) = | 
| 18172 | 276 | e | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 277 | | map_iexpr _ (e as IVar _) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 278 | e | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 279 | | map_iexpr f (e1 `$ e2) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 280 | f e1 `$ f e2 | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 281 | | map_iexpr f ((v, ty) `|-> e) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 282 | (v, ty) `|-> f e | 
| 19202 | 283 | | map_iexpr _ (e as INum _) = | 
| 284 | e | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 285 | | map_iexpr f (IAbs (((ve, vty), be), e0)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 286 | IAbs (((f ve, vty), f be), e0) | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 287 | | map_iexpr f (ICase (((de, dty), bses), e0)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 288 | ICase (((f de, dty), map (fn (se, be) => (f se, f be)) bses), e0); | 
| 18885 | 289 | |
| 290 | fun map_iexpr_itype f = | |
| 291 | let | |
| 19202 | 292 | fun mapp ((v, ty) `|-> e) = (v, f ty) `|-> mapp e | 
| 293 | | mapp (INum ((n, ty), e)) = INum ((n, f ty), e) | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 294 | | mapp (IAbs (((ve, vty), be), e0)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 295 | IAbs (((mapp ve, f vty), mapp be), e0) | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 296 | | mapp (ICase (((de, dty), bses), e0)) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 297 | ICase (((mapp de, f dty), map (fn (se, be) => (mapp se, mapp be)) bses), e0) | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 298 | | mapp e = map_iexpr mapp e; | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 299 | in mapp end; | 
| 18282 | 300 | |
| 19150 | 301 | fun eq_ityp ((sctxt1, ty1), (sctxt2, ty2)) = | 
| 18282 | 302 | let | 
| 303 | exception NO_MATCH; | |
| 19150 | 304 | fun eq_sctxt subs sctxt1 sctxt2 = | 
| 305 | map (fn (v, sort) => case AList.lookup (op =) subs v | |
| 306 | of NONE => raise NO_MATCH | |
| 307 | | SOME v' => case AList.lookup (op =) sctxt2 v' | |
| 308 | of NONE => raise NO_MATCH | |
| 309 | | SOME sort' => if sort <> sort' then raise NO_MATCH else ()) sctxt1 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 310 | fun eq (ITyVar v1) (ITyVar v2) subs = | 
| 19150 | 311 | (case AList.lookup (op =) subs v1 | 
| 312 | of NONE => subs |> AList.update (op =) (v1, v2) | |
| 313 | | SOME v1' => | |
| 314 | if v1' <> v2 | |
| 315 | then raise NO_MATCH | |
| 316 | else subs) | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 317 | | eq (tyco1 `%% tys1) (tyco2 `%% tys2) subs = | 
| 18282 | 318 | if tyco1 <> tyco2 | 
| 319 | then raise NO_MATCH | |
| 320 | else subs |> fold2 eq tys1 tys2 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 321 | | eq (ty11 `-> ty12) (ty21 `-> ty22) subs = | 
| 18282 | 322 | subs |> eq ty11 ty21 |> eq ty12 ty22 | 
| 323 | | eq _ _ _ = raise NO_MATCH; | |
| 324 | in | |
| 325 | (eq ty1 ty2 []; true) | |
| 326 | handle NO_MATCH => false | |
| 327 | end; | |
| 328 | ||
| 18885 | 329 | fun instant_itype f = | 
| 330 | let | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 331 | fun instant (ITyVar x) = f x | 
| 18885 | 332 | | instant y = map_itype instant y; | 
| 19215 | 333 | in instant end; | 
| 18885 | 334 | |
| 19202 | 335 | fun is_pat (e as IConst (_, ([], _))) = true | 
| 336 | | is_pat (e as IVar _) = true | |
| 337 | | is_pat (e as (e1 `$ e2)) = | |
| 338 | is_pat e1 andalso is_pat e2 | |
| 339 | | is_pat (e as INum _) = true | |
| 340 | | is_pat e = false; | |
| 341 | ||
| 342 | fun map_pure f (e as IConst _) = | |
| 343 | f e | |
| 344 | | map_pure f (e as IVar _) = | |
| 345 | f e | |
| 346 | | map_pure f (e as _ `$ _) = | |
| 347 | f e | |
| 348 | | map_pure f (e as _ `|-> _) = | |
| 349 | f e | |
| 350 | | map_pure _ (INum _) = | |
| 351 |       error ("sorry, no pure representation of numerals so far")
 | |
| 352 | | map_pure f (IAbs (_, e0)) = | |
| 353 | f e0 | |
| 354 | | map_pure f (ICase (_, e0)) = | |
| 355 | f e0; | |
| 18912 | 356 | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 357 | fun has_tyvars (_ `%% tys) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 358 | exists has_tyvars tys | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 359 | | has_tyvars (ITyVar _) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 360 | true | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 361 | | has_tyvars (ty1 `-> ty2) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 362 | has_tyvars ty1 orelse has_tyvars ty2; | 
| 18216 | 363 | |
| 19202 | 364 | fun add_constnames (IConst (c, _)) = | 
| 365 | insert (op =) c | |
| 366 | | add_constnames (IVar _) = | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 367 | I | 
| 19202 | 368 | | add_constnames (e1 `$ e2) = | 
| 369 | add_constnames e1 #> add_constnames e2 | |
| 370 | | add_constnames (_ `|-> e) = | |
| 371 | add_constnames e | |
| 372 | | add_constnames (INum _) = | |
| 373 | I | |
| 374 | | add_constnames (IAbs (_, e)) = | |
| 375 | add_constnames e | |
| 376 | | add_constnames (ICase (_, e)) = | |
| 377 | add_constnames e; | |
| 378 | ||
| 379 | fun add_varnames (IConst _) = | |
| 380 | I | |
| 381 | | add_varnames (IVar v) = | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 382 | insert (op =) v | 
| 19202 | 383 | | add_varnames (e1 `$ e2) = | 
| 384 | add_varnames e1 #> add_varnames e2 | |
| 385 | | add_varnames ((v, _) `|-> e) = | |
| 386 | insert (op =) v #> add_varnames e | |
| 387 | | add_varnames (INum _) = | |
| 388 | I | |
| 389 | | add_varnames (IAbs (((ve, _), be), _)) = | |
| 390 | add_varnames ve #> add_varnames be | |
| 391 | | add_varnames (ICase (((de, _), bses), _)) = | |
| 392 | add_varnames de #> fold (fn (be, se) => add_varnames be #> add_varnames se) bses; | |
| 18885 | 393 | |
| 394 | fun invent seed used = | |
| 395 | let | |
| 396 | val x = Term.variant used seed | |
| 397 | in (x, x :: used) end; | |
| 398 | ||
| 18304 | 399 | |
| 18282 | 400 | |
| 18170 | 401 | (** language module system - definitions, modules, transactions **) | 
| 402 | ||
| 403 | (* type definitions *) | |
| 404 | ||
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 405 | type funn = (iexpr list * iexpr) list * (sortcontext * itype); | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 406 | type datatyp = sortcontext * (string * itype list) list; | 
| 18702 | 407 | |
| 18850 | 408 | datatype prim = | 
| 409 | Pretty of Pretty.T | |
| 18963 | 410 | | Name; | 
| 18850 | 411 | |
| 18170 | 412 | datatype def = | 
| 18702 | 413 | Undef | 
| 18963 | 414 | | Prim of (string * prim list) list | 
| 18702 | 415 | | Fun of funn | 
| 19038 | 416 | | Typesyn of (vname * sort) list * itype | 
| 19042 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 417 | | Datatype of datatyp | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 418 | | Datatypecons of string | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 419 | | Class of class list * (vname * (string * (sortcontext * itype)) list) | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 420 | | Classmember of class | 
| 18865 | 421 | | Classinst of ((class * (string * (vname * sort) list)) | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 422 | * (class * (string * iclasslookup list list)) list) | 
| 19253 | 423 | * (string * ((string * funn) * iclasslookup list list)) list | 
| 19213 | 424 | | Classinstmember; | 
| 18170 | 425 | |
| 426 | datatype node = Def of def | Module of node Graph.T; | |
| 427 | type module = node Graph.T; | |
| 18702 | 428 | type transact = Graph.key option * module; | 
| 18231 | 429 | datatype 'dst transact_res = Succeed of 'dst | Fail of string list * exn option; | 
| 18702 | 430 | type 'dst transact_fin = 'dst transact_res * module; | 
| 18231 | 431 | exception FAIL of string list * exn option; | 
| 18170 | 432 | |
| 433 | val eq_def = (op =); | |
| 434 | ||
| 435 | (* simple diagnosis *) | |
| 436 | ||
| 18702 | 437 | fun pretty_def Undef = | 
| 438 | Pretty.str "<UNDEF>" | |
| 439 | | pretty_def (Prim prims) = | |
| 440 |       Pretty.str ("<PRIM " ^ (commas o map fst) prims ^ ">")
 | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 441 | | pretty_def (Fun (eqs, (sortctxt, ty))) = | 
| 18812 | 442 | Pretty.enum " |" "" "" ( | 
| 18170 | 443 | map (fn (ps, body) => | 
| 444 | Pretty.block [ | |
| 18865 | 445 | Pretty.enum "," "[" "]" (map pretty_iexpr ps), | 
| 18170 | 446 | Pretty.str " |->", | 
| 447 | Pretty.brk 1, | |
| 448 | pretty_iexpr body, | |
| 449 | Pretty.str "::", | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 450 | pretty_sortcontext sortctxt, | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 451 | Pretty.str "/", | 
| 18170 | 452 | pretty_itype ty | 
| 453 | ]) eqs | |
| 454 | ) | |
| 18172 | 455 | | pretty_def (Typesyn (vs, ty)) = | 
| 18170 | 456 | Pretty.block [ | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 457 | pretty_sortcontext vs, | 
| 18170 | 458 | Pretty.str " |=> ", | 
| 459 | pretty_itype ty | |
| 460 | ] | |
| 19038 | 461 | | pretty_def (Datatype (vs, cs)) = | 
| 18170 | 462 | Pretty.block [ | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 463 | pretty_sortcontext vs, | 
| 18170 | 464 | Pretty.str " |=> ", | 
| 18852 | 465 | Pretty.enum " |" "" "" | 
| 18850 | 466 | (map (fn (c, tys) => (Pretty.block o Pretty.breaks) | 
| 19038 | 467 | (Pretty.str c :: map pretty_itype tys)) cs) | 
| 18170 | 468 | ] | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 469 | | pretty_def (Datatypecons dtname) = | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 470 |       Pretty.str ("cons " ^ dtname)
 | 
| 19038 | 471 | | pretty_def (Class (supcls, (v, mems))) = | 
| 18170 | 472 | Pretty.block [ | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 473 |         Pretty.str ("class var " ^ v ^ "extending "),
 | 
| 18812 | 474 | Pretty.enum "," "[" "]" (map Pretty.str supcls), | 
| 18282 | 475 | Pretty.str " with ", | 
| 18852 | 476 | Pretty.enum "," "[" "]" | 
| 18850 | 477 | (map (fn (m, (_, ty)) => Pretty.block | 
| 19038 | 478 | [Pretty.str (m ^ "::"), pretty_itype ty]) mems) | 
| 18231 | 479 | ] | 
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 480 | | pretty_def (Classmember clsname) = | 
| 18231 | 481 | Pretty.block [ | 
| 482 | Pretty.str "class member belonging to ", | |
| 18282 | 483 | Pretty.str clsname | 
| 18231 | 484 | ] | 
| 18865 | 485 | | pretty_def (Classinst (((clsname, (tyco, arity)), _), _)) = | 
| 18231 | 486 | Pretty.block [ | 
| 487 |         Pretty.str "class instance (",
 | |
| 18282 | 488 | Pretty.str clsname, | 
| 18231 | 489 |         Pretty.str ", (",
 | 
| 490 | Pretty.str tyco, | |
| 491 | Pretty.str ", ", | |
| 18852 | 492 |         Pretty.enum "," "[" "]" (map (Pretty.enum "," "{" "}" o
 | 
| 18850 | 493 | map Pretty.str o snd) arity), | 
| 18515 | 494 | Pretty.str "))" | 
| 19213 | 495 | ] | 
| 496 | | pretty_def Classinstmember = | |
| 497 | Pretty.str "class instance member"; | |
| 18170 | 498 | |
| 499 | fun pretty_module modl = | |
| 500 | let | |
| 501 | fun pretty (name, Module modl) = | |
| 502 | Pretty.block ( | |
| 503 |             Pretty.str ("module " ^ name ^ " {")
 | |
| 504 | :: Pretty.brk 1 | |
| 505 | :: Pretty.chunks (map pretty (AList.make (Graph.get_node modl) | |
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19466diff
changeset | 506 | (Graph.strong_conn modl |> flat |> rev))) | 
| 18170 | 507 | :: Pretty.str "}" :: nil | 
| 508 | ) | |
| 509 | | pretty (name, Def def) = | |
| 510 | Pretty.block [Pretty.str name, Pretty.str " :=", Pretty.brk 1, pretty_def def] | |
| 511 |   in pretty ("//", Module modl) end;
 | |
| 512 | ||
| 18360 | 513 | fun pretty_deps modl = | 
| 514 | let | |
| 515 | fun one_node key = | |
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 516 | let | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 517 | val preds_ = Graph.imm_preds modl key; | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 518 | val succs_ = Graph.imm_succs modl key; | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 519 | val mutbs = gen_inter (op =) (preds_, succs_); | 
| 19300 | 520 | val preds = subtract (op =) mutbs preds_; | 
| 521 | val succs = subtract (op =) mutbs succs_; | |
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 522 | in | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 523 | (Pretty.block o Pretty.fbreaks) ( | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 524 | Pretty.str key | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 525 |           :: map (fn s => Pretty.str ("<-> " ^ s)) mutbs
 | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 526 |           @ map (fn s => Pretty.str ("<-- " ^ s)) preds
 | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 527 |           @ map (fn s => Pretty.str ("--> " ^ s)) succs
 | 
| 18850 | 528 | @ (the_list oo Option.mapPartial) | 
| 529 | ((fn Module modl' => SOME (pretty_deps modl') | |
| 530 | | _ => NONE) o Graph.get_node modl) (SOME key) | |
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 531 | ) | 
| 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 532 | end | 
| 18360 | 533 | in | 
| 534 | modl | |
| 535 | |> Graph.strong_conn | |
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19466diff
changeset | 536 | |> flat | 
| 18360 | 537 | |> rev | 
| 538 | |> map one_node | |
| 539 | |> Pretty.chunks | |
| 540 | end; | |
| 541 | ||
| 18170 | 542 | |
| 543 | (* name handling *) | |
| 544 | ||
| 545 | fun dest_name name = | |
| 546 | let | |
| 547 | val name' = NameSpace.unpack name | |
| 548 | val (name'', name_base) = split_last name' | |
| 549 | val (modl, shallow) = split_last name'' | |
| 550 | in (modl, NameSpace.pack [shallow, name_base]) end | |
| 551 |   handle Empty => error ("not a qualified name: " ^ quote name);
 | |
| 552 | ||
| 18516 | 553 | fun has_nsp name shallow = | 
| 554 | NameSpace.is_qualified name | |
| 555 | andalso let | |
| 556 | val name' = NameSpace.unpack name | |
| 557 | val (name'', _) = split_last name' | |
| 558 | val (_, shallow') = split_last name'' | |
| 559 | in shallow' = shallow end; | |
| 560 | ||
| 18170 | 561 | fun dest_modl (Module m) = m; | 
| 562 | fun dest_def (Def d) = d; | |
| 563 | ||
| 564 | ||
| 565 | (* modules *) | |
| 566 | ||
| 567 | val empty_module = Graph.empty; (*read: "depends on"*) | |
| 568 | ||
| 569 | fun get_def modl name = | |
| 570 | case dest_name name | |
| 571 | of (modlname, base) => | |
| 572 | let | |
| 573 | fun get (Module node) [] = | |
| 574 | (dest_def o Graph.get_node node) base | |
| 575 | | get (Module node) (m::ms) = | |
| 576 | get (Graph.get_node node m) ms | |
| 577 | in get (Module modl) modlname end; | |
| 578 | ||
| 579 | fun add_def (name, def) = | |
| 580 | let | |
| 581 | val (modl, base) = dest_name name; | |
| 582 | fun add [] = | |
| 583 | Graph.new_node (base, Def def) | |
| 584 | | add (m::ms) = | |
| 585 | Graph.default_node (m, Module empty_module) | |
| 586 | #> Graph.map_node m (Module o add ms o dest_modl) | |
| 587 | in add modl end; | |
| 588 | ||
| 589 | fun add_dep (name1, name2) modl = | |
| 590 | if name1 = name2 then modl | |
| 591 | else | |
| 592 | let | |
| 593 | val m1 = dest_name name1 |> apsnd single |> (op @); | |
| 594 | val m2 = dest_name name2 |> apsnd single |> (op @); | |
| 18454 | 595 | val (ms, (r1, r2)) = get_prefix (op =) (m1, m2); | 
| 596 | val (ms, (s1::r1, s2::r2)) = get_prefix (op =) (m1, m2); | |
| 18170 | 597 | val add_edge = | 
| 598 | if null r1 andalso null r2 | |
| 599 | then Graph.add_edge | |
| 19038 | 600 | else fn edge => (Graph.add_edge_acyclic edge | 
| 601 |           handle Graph.CYCLES _ => error ("adding dependency "
 | |
| 602 | ^ quote name1 ^ " -> " ^ quote name2 ^ " would result in module dependency cycle")) | |
| 18170 | 603 | fun add [] node = | 
| 604 | node | |
| 605 | |> add_edge (s1, s2) | |
| 606 | | add (m::ms) node = | |
| 607 | node | |
| 608 | |> Graph.map_node m (Module o add ms o dest_modl); | |
| 609 | in add ms modl end; | |
| 610 | ||
| 18885 | 611 | fun map_def name f = | 
| 612 | let | |
| 613 | val (modl, base) = dest_name name; | |
| 614 | fun mapp [] = | |
| 615 | Graph.map_node base (Def o f o dest_def) | |
| 616 | | mapp (m::ms) = | |
| 617 | Graph.map_node m (Module o mapp ms o dest_modl) | |
| 618 | in mapp modl end; | |
| 619 | ||
| 620 | fun map_defs f = | |
| 621 | let | |
| 622 | fun mapp (Def def) = | |
| 623 | (Def o f) def | |
| 624 | | mapp (Module modl) = | |
| 625 | (Module o Graph.map_nodes mapp) modl | |
| 626 | in dest_modl o mapp o Module end; | |
| 627 | ||
| 628 | fun fold_defs f = | |
| 629 | let | |
| 630 | fun fol prfix (name, Def def) = | |
| 631 | f (NameSpace.pack (prfix @ [name]), def) | |
| 632 | | fol prfix (name, Module modl) = | |
| 633 | Graph.fold_nodes (fol (prfix @ [name])) modl | |
| 634 | in Graph.fold_nodes (fol []) end; | |
| 635 | ||
| 636 | fun add_deps f modl = | |
| 637 | modl | |
| 638 | |> fold add_dep ([] |> fold_defs (append o f) modl); | |
| 639 | ||
| 19136 | 640 | fun add_def_incr (name, Undef) module = | 
| 18885 | 641 | (case try (get_def module) name | 
| 642 | of NONE => (error "attempted to add Undef to module") | |
| 643 | | SOME Undef => (error "attempted to add Undef to module") | |
| 644 | | SOME def' => map_def name (K def') module) | |
| 19136 | 645 | | add_def_incr (name, def) module = | 
| 18885 | 646 | (case try (get_def module) name | 
| 647 | of NONE => add_def (name, def) module | |
| 648 | | SOME Undef => map_def name (K def) module | |
| 649 | | SOME def' => if eq_def (def, def') | |
| 650 | then module | |
| 651 |             else error ("tried to overwrite definition " ^ name));
 | |
| 652 | ||
| 18963 | 653 | fun add_prim name (target, primdef as _::_) = | 
| 18516 | 654 | let | 
| 655 | val (modl, base) = dest_name name; | |
| 656 | fun add [] module = | |
| 657 | (case try (Graph.get_node module) base | |
| 658 | of NONE => | |
| 659 | module | |
| 18963 | 660 | |> Graph.new_node (base, (Def o Prim) [(target, primdef)]) | 
| 18516 | 661 | | SOME (Def (Prim prim)) => | 
| 18702 | 662 | if AList.defined (op =) prim target | 
| 18850 | 663 |                 then error ("already primitive definition (" ^ target
 | 
| 664 | ^ ") present for " ^ name) | |
| 18516 | 665 | else | 
| 666 | module | |
| 18850 | 667 | |> Graph.map_node base ((K o Def o Prim) (AList.update (op =) | 
| 18963 | 668 | (target, primdef) prim)) | 
| 18516 | 669 |             | _ => error ("already non-primitive definition present for " ^ name))
 | 
| 670 | | add (m::ms) module = | |
| 671 | module | |
| 672 | |> Graph.default_node (m, Module empty_module) | |
| 673 | |> Graph.map_node m (Module o add ms o dest_modl) | |
| 18963 | 674 | in add modl end; | 
| 18516 | 675 | |
| 18702 | 676 | fun ensure_prim name target = | 
| 18516 | 677 | let | 
| 678 | val (modl, base) = dest_name name; | |
| 679 | fun ensure [] module = | |
| 680 | (case try (Graph.get_node module) base | |
| 681 | of NONE => | |
| 682 | module | |
| 18963 | 683 | |> Graph.new_node (base, (Def o Prim) [(target, [])]) | 
| 18702 | 684 | | SOME (Def (Prim prim)) => | 
| 18516 | 685 | module | 
| 18850 | 686 | |> Graph.map_node base ((K o Def o Prim) (AList.default (op =) | 
| 18963 | 687 | (target, []) prim)) | 
| 18850 | 688 | | _ => module) | 
| 18516 | 689 | | ensure (m::ms) module = | 
| 690 | module | |
| 691 | |> Graph.default_node (m, Module empty_module) | |
| 692 | |> Graph.map_node m (Module o ensure ms o dest_modl) | |
| 693 | in ensure modl end; | |
| 694 | ||
| 18170 | 695 | fun merge_module modl12 = | 
| 696 | let | |
| 19025 | 697 | fun join_module _ (Module m1, Module m2) = | 
| 698 | Module (merge_module (m1, m2)) | |
| 699 | | join_module name (Def d1, Def d2) = | |
| 700 | if eq_def (d1, d2) then Def d1 else raise Graph.DUP name | |
| 701 | | join_module name _ = raise Graph.DUP name | |
| 702 | in Graph.join join_module modl12 end; | |
| 18170 | 703 | |
| 19042 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 704 | fun diff_module modl12 = | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 705 | let | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 706 | fun diff_entry prefix modl2 (name, Def def1) = | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 707 | let | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 708 | val e2 = try (Graph.get_node modl2) name | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 709 | in if is_some e2 andalso eq_def (def1, (dest_def o the) e2) | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 710 | then I | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 711 | else cons (NameSpace.pack (prefix @ [name]), def1) | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 712 | end | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 713 | | diff_entry prefix modl2 (name, Module modl1) = | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 714 | diff_modl (prefix @ [name]) (modl1, | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 715 | (the_default empty_module o Option.map dest_modl o try (Graph.get_node modl2)) name) | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 716 | and diff_modl prefix (modl1, modl2) = | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 717 | fold (diff_entry prefix modl2) | 
| 19466 | 718 | ((AList.make (Graph.get_node modl1) o flat o Graph.strong_conn) modl1) | 
| 19042 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 719 | in diff_modl [] modl12 [] end; | 
| 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 haftmann parents: 
19038diff
changeset | 720 | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 721 | local | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 722 | |
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 723 | fun project_trans f names modl = | 
| 18335 | 724 | let | 
| 725 | datatype pathnode = PN of (string list * (string * pathnode) list); | |
| 726 | fun mk_ipath ([], base) (PN (defs, modls)) = | |
| 727 | PN (base :: defs, modls) | |
| 728 | | mk_ipath (n::ns, base) (PN (defs, modls)) = | |
| 729 | modls | |
| 730 | |> AList.default (op =) (n, PN ([], [])) | |
| 731 | |> AList.map_entry (op =) n (mk_ipath (ns, base)) | |
| 732 | |> (pair defs #> PN); | |
| 733 | fun select (PN (defs, modls)) (Module module) = | |
| 734 | module | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 735 | |> f (Graph.all_succs module (defs @ map fst modls)) | 
| 18335 | 736 | |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls | 
| 737 | |> Module; | |
| 738 | in | |
| 739 | Module modl | |
| 18850 | 740 | |> select (fold (mk_ipath o dest_name) | 
| 741 | (filter NameSpace.is_qualified names) (PN ([], []))) | |
| 18335 | 742 | |> dest_modl | 
| 743 | end; | |
| 18170 | 744 | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 745 | in | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 746 | |
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 747 | val project_module = project_trans Graph.subgraph; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 748 | val purge_module = project_trans Graph.del_nodes; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 749 | |
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 750 | end; (*local*) | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 751 | |
| 18850 | 752 | fun imports_of modl name = | 
| 18702 | 753 | let | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 754 | (*fun submodules prfx modl = | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 755 | cons prfx | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 756 | #> Graph.fold_nodes | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 757 | (fn (m, Module modl) => submodules (prfx @ [m]) modl | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 758 | | (_, Def _) => I) modl; | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 759 | fun get_modl name = | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 760 | fold (fn n => fn modl => (dest_modl oo Graph.get_node) modl n) name modl*) | 
| 18702 | 761 | fun imports prfx [] modl = | 
| 762 | [] | |
| 763 | | imports prfx (m::ms) modl = | |
| 764 | map (cons m) (imports (prfx @ [m]) ms ((dest_modl oo Graph.get_node) modl m)) | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 765 | @ map single (Graph.imm_succs modl m) | 
| 18702 | 766 | in | 
| 18850 | 767 | modl | 
| 768 | |> imports [] name | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 769 | (*|> cons name | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 770 | |> map (fn name => submodules name (get_modl name) []) | 
| 19466 | 771 | |> flat | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 772 | |> remove (op =) name*) | 
| 18702 | 773 | |> map NameSpace.pack | 
| 774 | end; | |
| 775 | ||
| 776 | fun check_samemodule names = | |
| 777 | fold (fn name => | |
| 778 | let | |
| 779 | val modn = (fst o dest_name) name | |
| 780 | in | |
| 781 | fn NONE => SOME modn | |
| 18850 | 782 | | SOME mod' => if modn = mod' then SOME modn | 
| 783 | else error "inconsistent name prefix for simultanous names" | |
| 18702 | 784 | end | 
| 785 | ) names NONE; | |
| 786 | ||
| 787 | fun check_funeqs eqs = | |
| 788 | (fold (fn (pats, _) => | |
| 789 | let | |
| 790 | val l = length pats | |
| 791 | in | |
| 792 | fn NONE => SOME l | |
| 18850 | 793 | | SOME l' => if l = l' then SOME l | 
| 794 | else error "function definition with different number of arguments" | |
| 18702 | 795 | end | 
| 796 | ) eqs NONE; eqs); | |
| 797 | ||
| 798 | fun check_prep_def modl Undef = | |
| 799 | Undef | |
| 800 | | check_prep_def modl (d as Prim _) = | |
| 801 | d | |
| 802 | | check_prep_def modl (Fun (eqs, d)) = | |
| 803 | Fun (check_funeqs eqs, d) | |
| 804 | | check_prep_def modl (d as Typesyn _) = | |
| 805 | d | |
| 19038 | 806 | | check_prep_def modl (d as Datatype _) = | 
| 807 | d | |
| 18702 | 808 | | check_prep_def modl (Datatypecons dtco) = | 
| 809 | error "attempted to add bare datatype constructor" | |
| 19038 | 810 | | check_prep_def modl (d as Class _) = | 
| 811 | d | |
| 18702 | 812 | | check_prep_def modl (Classmember _) = | 
| 813 | error "attempted to add bare class member" | |
| 18865 | 814 | | check_prep_def modl (Classinst ((d as ((class, (tyco, arity)), _), memdefs))) = | 
| 18170 | 815 | let | 
| 19038 | 816 | val Class (_, (v, membrs)) = get_def modl class; | 
| 18702 | 817 | val _ = if length memdefs > length memdefs | 
| 818 | then error "too many member definitions given" | |
| 819 | else (); | |
| 19150 | 820 | fun instant (w, ty) v = | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 821 | if v = w then ty else ITyVar v; | 
| 19150 | 822 | fun mk_memdef (m, (sortctxt, ty)) = | 
| 18702 | 823 | case AList.lookup (op =) memdefs m | 
| 824 |            of NONE => error ("missing definition for member " ^ quote m)
 | |
| 19253 | 825 | | SOME ((m', (eqs, (sortctxt', ty'))), lss) => | 
| 19215 | 826 | let | 
| 827 | val sortctxt'' = sortctxt |> fold (fn v_sort => AList.update (op =) v_sort) arity; | |
| 828 | val ty'' = instant_itype (instant (v, tyco `%% map (ITyVar o fst) arity)) ty; | |
| 829 | in if eq_ityp ((sortctxt'', ty''), (sortctxt', ty')) | |
| 19253 | 830 | then (m, ((m', (check_funeqs eqs, (sortctxt', ty'))), lss)) | 
| 19215 | 831 | else | 
| 832 |                   error ("inconsistent type for member definition " ^ quote m ^ " [" ^ v ^ "]: "
 | |
| 833 | ^ (Pretty.output o Pretty.block o Pretty.breaks) [ | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 834 | pretty_sortcontext sortctxt'', | 
| 19215 | 835 | Pretty.str "|=>", | 
| 836 | pretty_itype ty'' | |
| 837 | ] ^ " vs. " ^ (Pretty.output o Pretty.block o Pretty.breaks) [ | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 838 | pretty_sortcontext sortctxt', | 
| 19215 | 839 | Pretty.str "|=>", | 
| 840 | pretty_itype ty' | |
| 841 | ] | |
| 842 | ) | |
| 843 | end | |
| 19213 | 844 | in Classinst (d, map mk_memdef membrs) end | 
| 845 | | check_prep_def modl Classinstmember = | |
| 846 | error "attempted to add bare class instance member"; | |
| 18170 | 847 | |
| 19038 | 848 | fun postprocess_def (name, Datatype (_, constrs)) = | 
| 18702 | 849 | (check_samemodule (name :: map fst constrs); | 
| 850 | fold (fn (co, _) => | |
| 19136 | 851 | add_def_incr (co, Datatypecons name) | 
| 18702 | 852 | #> add_dep (co, name) | 
| 853 | #> add_dep (name, co) | |
| 854 | ) constrs | |
| 855 | ) | |
| 19038 | 856 | | postprocess_def (name, Class (_, (_, membrs))) = | 
| 18702 | 857 | (check_samemodule (name :: map fst membrs); | 
| 858 | fold (fn (m, _) => | |
| 19136 | 859 | add_def_incr (m, Classmember name) | 
| 18702 | 860 | #> add_dep (m, name) | 
| 861 | #> add_dep (name, m) | |
| 862 | ) membrs | |
| 863 | ) | |
| 19213 | 864 | | postprocess_def (name, Classinst (_, memdefs)) = | 
| 19253 | 865 | (check_samemodule (name :: map (fst o fst o snd) memdefs); | 
| 866 | fold (fn (_, ((m', _), _)) => | |
| 19213 | 867 | add_def_incr (m', Classinstmember) | 
| 868 | ) memdefs | |
| 869 | ) | |
| 18702 | 870 | | postprocess_def _ = | 
| 871 | I; | |
| 18380 
9668764224a7
substantial improvements for class code generation
 haftmann parents: 
18361diff
changeset | 872 | |
| 18702 | 873 | fun succeed some (_, modl) = (Succeed some, modl); | 
| 874 | fun fail msg (_, modl) = (Fail ([msg], NONE), modl); | |
| 18170 | 875 | |
| 18231 | 876 | fun check_fail _ (Succeed dst, trns) = (dst, trns) | 
| 877 | | check_fail msg (Fail (msgs, e), _) = raise FAIL (msg::msgs, e); | |
| 18170 | 878 | |
| 18702 | 879 | fun select_generator _ src [] modl = | 
| 880 |       (SOME src, modl) |> fail ("no code generator available")
 | |
| 18231 | 881 | | select_generator mk_msg src gens modl = | 
| 882 | let | |
| 883 | fun handle_fail msgs f = | |
| 884 | let | |
| 885 | in | |
| 886 | if ! soft_exc | |
| 887 | then | |
| 18702 | 888 | (SOME src, modl) |> f | 
| 889 | handle FAIL exc => (Fail exc, modl) | |
| 890 | | e => (Fail (msgs, SOME e), modl) | |
| 18231 | 891 | else | 
| 18702 | 892 | (SOME src, modl) |> f | 
| 893 | handle FAIL exc => (Fail exc, modl) | |
| 18231 | 894 | end; | 
| 895 | fun select msgs [(gname, gen)] = | |
| 18702 | 896 | handle_fail (msgs @ [mk_msg gname]) (gen src) | 
| 897 | | select msgs ((gname, gen)::gens) = | |
| 898 | let | |
| 899 | val msgs' = msgs @ [mk_msg gname] | |
| 900 | in case handle_fail msgs' (gen src) | |
| 901 | of (Fail (_, NONE), _) => | |
| 902 | select msgs' gens | |
| 903 | | result => result | |
| 18231 | 904 | end; | 
| 905 | in select [] gens end; | |
| 18170 | 906 | |
| 19136 | 907 | fun ensure_def defgens msg name (dep, modl) = | 
| 18170 | 908 | let | 
| 18702 | 909 | val msg' = case dep | 
| 910 | of NONE => msg | |
| 911 | | SOME dep => msg ^ ", with dependency " ^ quote dep; | |
| 912 | fun add_dp NONE = I | |
| 913 | | add_dp (SOME dep) = | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 914 | debug_msg (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name) | 
| 18702 | 915 | #> add_dep (dep, name); | 
| 916 | fun prep_def def modl = | |
| 917 | (check_prep_def modl def, modl); | |
| 18170 | 918 | in | 
| 919 | modl | |
| 18702 | 920 | |> (if can (get_def modl) name | 
| 921 | then | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 922 | debug_msg (fn _ => "asserting node " ^ quote name) | 
| 18702 | 923 | #> add_dp dep | 
| 924 | else | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 925 | debug_msg (fn _ => "allocating node " ^ quote name) | 
| 18702 | 926 | #> add_def (name, Undef) | 
| 927 | #> add_dp dep | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 928 | #> debug_msg (fn _ => "creating node " ^ quote name) | 
| 18850 | 929 | #> select_generator (fn gname => "trying code generator " | 
| 930 | ^ gname ^ " for definition of " ^ quote name) name defgens | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 931 | #> debug_msg (fn _ => "checking creation of node " ^ quote name) | 
| 18702 | 932 | #> check_fail msg' | 
| 933 | #-> (fn def => prep_def def) | |
| 934 | #-> (fn def => | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 935 | debug_msg (fn _ => "addition of " ^ name ^ " := " ^ (Pretty.output o pretty_def) def) | 
| 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 936 | #> debug_msg (fn _ => "adding") | 
| 19136 | 937 | #> add_def_incr (name, def) | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 938 | #> debug_msg (fn _ => "postprocessing") | 
| 18702 | 939 | #> postprocess_def (name, def) | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 940 | #> debug_msg (fn _ => "adding done") | 
| 18702 | 941 | )) | 
| 942 | |> pair dep | |
| 18170 | 943 | end; | 
| 944 | ||
| 18963 | 945 | fun start_transact init f modl = | 
| 18231 | 946 | let | 
| 18963 | 947 | fun handle_fail f x = | 
| 948 | (f x | |
| 18231 | 949 | handle FAIL (msgs, NONE) => | 
| 950 |         (error o cat_lines) ("code generation failed, while:" :: msgs))
 | |
| 951 | handle FAIL (msgs, SOME e) => | |
| 952 |         ((writeln o cat_lines) ("code generation failed, while:" :: msgs); raise e);
 | |
| 953 | in | |
| 18963 | 954 | (init, modl) | 
| 18231 | 955 | |> handle_fail f | 
| 956 | |-> (fn x => fn (_, module) => (x, module)) | |
| 957 | end; | |
| 18172 | 958 | |
| 959 | ||
| 18335 | 960 | |
| 961 | (** generic transformation **) | |
| 18304 | 962 | |
| 18885 | 963 | fun map_def_fun f (Fun funn) = | 
| 964 | Fun (f funn) | |
| 965 | | map_def_fun _ def = def; | |
| 966 | ||
| 967 | fun map_def_fun_expr f (eqs, cty) = | |
| 968 | (map (fn (ps, rhs) => (map f ps, f rhs)) eqs, cty); | |
| 969 | ||
| 18172 | 970 | fun eta_expand query = | 
| 971 | let | |
| 18885 | 972 | fun eta e = | 
| 18865 | 973 | case unfold_const_app e | 
| 19202 | 974 | of SOME (const as (c, (_, ty)), es) => | 
| 18885 | 975 | let | 
| 19202 | 976 | val delta = query c - length es; | 
| 18885 | 977 | val add_n = if delta < 0 then 0 else delta; | 
| 978 | val tys = | |
| 979 | (fst o unfold_fun) ty | |
| 980 | |> curry Library.drop (length es) | |
| 981 | |> curry Library.take add_n | |
| 19202 | 982 | val vs = (Term.invent_names (fold add_varnames es []) "x" add_n) | 
| 18885 | 983 | in | 
| 19202 | 984 | vs ~~ tys `|--> IConst const `$$ map eta es `$$ map IVar vs | 
| 18885 | 985 | end | 
| 986 | | NONE => map_iexpr eta e; | |
| 987 | in (map_defs o map_def_fun o map_def_fun_expr) eta end; | |
| 18172 | 988 | |
| 18216 | 989 | val eta_expand_poly = | 
| 990 | let | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 991 | fun eta (funn as ([([], e)], cty as (sctxt, (ty as (ty1 `-> ty2))))) = | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 992 | if (not o null) sctxt | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 993 | orelse (not o has_tyvars) ty | 
| 18885 | 994 | then funn | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 995 | else (case unfold_abs e | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 996 | of ([], e) => | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 997 | let | 
| 19202 | 998 | val add_var = IVar (hd (Term.invent_names (add_varnames e []) "x" 1)) | 
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 999 | in (([([add_var], e `$ add_var)], cty)) end | 
| 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 1000 | | _ => funn) | 
| 18885 | 1001 | | eta funn = funn; | 
| 1002 | in (map_defs o map_def_fun) eta end; | |
| 1003 | ||
| 18963 | 1004 | val unclash_vars_tvars = | 
| 18885 | 1005 | let | 
| 1006 | fun unclash (eqs, (sortctxt, ty)) = | |
| 1007 | let | |
| 1008 | val used_expr = | |
| 19202 | 1009 | fold (fn (pats, rhs) => fold add_varnames pats #> add_varnames rhs) eqs []; | 
| 18885 | 1010 | val used_type = map fst sortctxt; | 
| 1011 | val clash = gen_union (op =) (used_expr, used_type); | |
| 1012 | val rename_map = fold_map (fn c => invent c #-> (fn c' => pair (c, c'))) clash [] |> fst; | |
| 19150 | 1013 | val rename = | 
| 1014 | perhaps (AList.lookup (op =) rename_map); | |
| 19167 
f237c0cb3882
refined representation of codegen intermediate language
 haftmann parents: 
19150diff
changeset | 1015 | val rename_typ = instant_itype (ITyVar o rename); | 
| 18885 | 1016 | val rename_expr = map_iexpr_itype rename_typ; | 
| 1017 | fun rename_eq (args, rhs) = (map rename_expr args, rename_expr rhs) | |
| 1018 | in | |
| 19150 | 1019 | (map rename_eq eqs, (map (apfst rename) sortctxt, rename_typ ty)) | 
| 18885 | 1020 | end; | 
| 1021 | in (map_defs o map_def_fun) unclash end; | |
| 18216 | 1022 | |
| 18172 | 1023 | |
| 18216 | 1024 | (** generic serialization **) | 
| 1025 | ||
| 1026 | (* resolving *) | |
| 1027 | ||
| 18885 | 1028 | structure NameMangler = NameManglerFun ( | 
| 1029 | type ctxt = (string * string -> string) * (string -> string option); | |
| 18516 | 1030 | type src = string * string; | 
| 1031 | val ord = prod_ord string_ord string_ord; | |
| 18963 | 1032 | fun mk (postprocess, validate) ((shallow, name), 0) = | 
| 1033 | let | |
| 1034 | val name' = postprocess (shallow, name); | |
| 1035 | in case validate name' | |
| 1036 | of NONE => name' | |
| 1037 | | _ => mk (postprocess, validate) ((shallow, name), 1) | |
| 1038 | end | |
| 1039 |     | mk (postprocess, validate) (("", name), i) =
 | |
| 19150 | 1040 |         postprocess ("", name ^ replicate_string i "'")
 | 
| 1041 | |> perhaps validate | |
| 1042 | | mk (postprocess, validate) ((shallow, name), 1) = | |
| 1043 | postprocess (shallow, shallow ^ "_" ^ name) | |
| 18885 | 1044 | |> perhaps validate | 
| 18963 | 1045 | | mk (postprocess, validate) ((shallow, name), i) = | 
| 19150 | 1046 | postprocess (shallow, name ^ replicate_string i "'") | 
| 18516 | 1047 | |> perhaps validate; | 
| 1048 | fun is_valid _ _ = true; | |
| 1049 | fun maybe_unique _ _ = NONE; | |
| 1050 |   fun re_mangle _ dst = error ("no such definition name: " ^ quote dst);
 | |
| 1051 | ); | |
| 1052 | ||
| 18963 | 1053 | fun mk_deresolver module nsp_conn postprocess validate = | 
| 18885 | 1054 | let | 
| 1055 | datatype tabnode = N of string * tabnode Symtab.table option; | |
| 1056 | fun mk module manglers tab = | |
| 1057 | let | |
| 1058 | fun mk_name name = | |
| 1059 | case NameSpace.unpack name | |
| 1060 |            of [n] => ("", n)
 | |
| 1061 | | [s, n] => (s, n); | |
| 1062 | fun in_conn (shallow, conn) = | |
| 1063 | member (op = : string * string -> bool) conn shallow; | |
| 1064 | fun add_name name = | |
| 1065 | let | |
| 1066 | val n as (shallow, _) = mk_name name; | |
| 1067 | in | |
| 1068 | AList.map_entry_yield in_conn shallow ( | |
| 18963 | 1069 | NameMangler.declare (postprocess, validate) n | 
| 18885 | 1070 | #-> (fn n' => pair (name, n')) | 
| 18963 | 1071 | ) #> apfst the | 
| 18885 | 1072 | end; | 
| 1073 | val (renamings, manglers') = | |
| 1074 | fold_map add_name (Graph.keys module) manglers; | |
| 1075 | fun extend_tab (n, n') = | |
| 1076 | if (length o NameSpace.unpack) n = 1 | |
| 1077 | then | |
| 1078 | Symtab.update_new | |
| 1079 | (n, N (n', SOME (mk ((dest_modl o Graph.get_node module) n) manglers' Symtab.empty))) | |
| 1080 | else | |
| 1081 | Symtab.update_new (n, N (n', NONE)); | |
| 1082 | in fold extend_tab renamings tab end; | |
| 1083 | fun get_path_name [] tab = | |
| 1084 | ([], SOME tab) | |
| 1085 | | get_path_name [p] tab = | |
| 1086 | let | |
| 1087 | val SOME (N (p', tab')) = Symtab.lookup tab p | |
| 1088 | in ([p'], tab') end | |
| 1089 | | get_path_name [p1, p2] tab = | |
| 18919 | 1090 | (case Symtab.lookup tab p1 | 
| 18885 | 1091 | of SOME (N (p', SOME tab')) => | 
| 1092 | let | |
| 1093 | val (ps', tab'') = get_path_name [p2] tab' | |
| 1094 | in (p' :: ps', tab'') end | |
| 1095 | | NONE => | |
| 1096 | let | |
| 1097 | val SOME (N (p', NONE)) = Symtab.lookup tab (NameSpace.pack [p1, p2]) | |
| 18919 | 1098 | in ([p'], NONE) end) | 
| 18885 | 1099 | | get_path_name (p::ps) tab = | 
| 1100 | let | |
| 1101 | val SOME (N (p', SOME tab')) = Symtab.lookup tab p | |
| 1102 | val (ps', tab'') = get_path_name ps tab' | |
| 1103 | in (p' :: ps', tab'') end; | |
| 1104 | fun deresolv tab prefix name = | |
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 1105 | let | 
| 18885 | 1106 | val (common, (_, rem)) = get_prefix (op =) (prefix, NameSpace.unpack name); | 
| 1107 | val (_, SOME tab') = get_path_name common tab; | |
| 1108 | val (name', _) = get_path_name rem tab'; | |
| 1109 | in NameSpace.pack name' end; | |
| 1110 | in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end; | |
| 1111 | ||
| 18216 | 1112 | |
| 1113 | (* serialization *) | |
| 1114 | ||
| 18963 | 1115 | fun serialize seri_defs seri_module validate postprocess nsp_conn name_root module = | 
| 18216 | 1116 | let | 
| 18963 | 1117 | val resolver = mk_deresolver module nsp_conn postprocess validate; | 
| 19038 | 1118 | fun sresolver s = (resolver o NameSpace.unpack) s | 
| 18702 | 1119 | fun mk_name prfx name = | 
| 18850 | 1120 | let | 
| 1121 | val name_qual = NameSpace.pack (prfx @ [name]) | |
| 1122 | in (name_qual, resolver prfx name_qual) end; | |
| 18756 | 1123 | fun mk_contents prfx module = | 
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19466diff
changeset | 1124 | map_filter (seri prfx) | 
| 18850 | 1125 | ((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module) | 
| 18756 | 1126 | and seri prfx ([(name, Module modl)]) = | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 1127 | seri_module (resolver []) (map (resolver []) (imports_of module (prfx @ [name]))) | 
| 18850 | 1128 | (mk_name prfx name, mk_contents (prfx @ [name]) modl) | 
| 18756 | 1129 | | seri prfx ds = | 
| 19038 | 1130 | seri_defs sresolver (NameSpace.pack prfx) | 
| 18912 | 1131 | (map (fn (name, Def def) => (fst (mk_name prfx name), def)) ds) | 
| 18216 | 1132 | in | 
| 19341 
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
 haftmann parents: 
19300diff
changeset | 1133 | seri_module (resolver []) (imports_of module []) | 
| 19482 
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
 wenzelm parents: 
19466diff
changeset | 1134 | (*map (resolver []) (Graph.strong_conn module |> flat |> rev)*) | 
| 18850 | 1135 |       (("", name_root), (mk_contents [] module))
 | 
| 18216 | 1136 | end; | 
| 1137 | ||
| 18169 
45def66f86cb
added modules for code generator generation two, not operational yet
 haftmann parents: diff
changeset | 1138 | end; (* struct *) | 
| 19136 | 1139 | |
| 19300 | 1140 | structure BasicCodegenThingol: BASIC_CODEGEN_THINGOL = CodegenThingol; |