| author | haftmann |
| Fri, 03 Feb 2006 08:48:33 +0100 | |
| changeset 18916 | fda5b8dbbef6 |
| parent 18912 | dd168daf172d |
| child 18918 | 5590770e1b09 |
| permissions | -rw-r--r-- |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1 |
(* Title: Pure/Tools/codegen_serializer.ML |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
2 |
ID: $Id$ |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
4 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
5 |
Serializer from intermediate language ("Thin-gol") to
|
| 18216 | 6 |
target languages (like ML or Haskell). |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
7 |
*) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
8 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
9 |
signature CODEGEN_SERIALIZER = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
10 |
sig |
| 18702 | 11 |
type 'a pretty_syntax; |
12 |
type serializer = |
|
13 |
string list list |
|
| 18756 | 14 |
-> OuterParse.token list -> |
| 18865 | 15 |
((string -> string option) |
16 |
* (string -> CodegenThingol.itype pretty_syntax option) |
|
| 18702 | 17 |
* (string -> CodegenThingol.iexpr pretty_syntax option) |
18 |
-> string list option |
|
| 18756 | 19 |
-> CodegenThingol.module -> unit) |
20 |
* OuterParse.token list; |
|
| 18702 | 21 |
val parse_syntax: (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
22 |
('b -> 'a pretty_syntax * 'b) * OuterParse.token list;
|
|
23 |
val parse_targetdef: (string -> string) -> string -> string; |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
24 |
val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax; |
| 18702 | 25 |
val serializers: {
|
| 18865 | 26 |
ml: string * (string * string * (string -> bool) -> serializer), |
| 18702 | 27 |
haskell: string * (string -> serializer) |
28 |
} |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
29 |
end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
30 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
31 |
structure CodegenSerializer: CODEGEN_SERIALIZER = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
32 |
struct |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
33 |
|
| 18850 | 34 |
open CodegenThingol; |
| 18702 | 35 |
infix 8 `%%; |
36 |
infixr 6 `->; |
|
37 |
infixr 6 `-->; |
|
38 |
infix 4 `$; |
|
39 |
infix 4 `$$; |
|
| 18885 | 40 |
infixr 3 `|->; |
41 |
infixr 3 `|-->; |
|
| 18216 | 42 |
|
| 18850 | 43 |
|
| 18216 | 44 |
(** generic serialization **) |
45 |
||
| 18702 | 46 |
(* precedences *) |
47 |
||
| 18216 | 48 |
datatype lrx = L | R | X; |
49 |
||
| 18516 | 50 |
datatype fixity = |
| 18216 | 51 |
BR |
52 |
| NOBR |
|
53 |
| INFX of (int * lrx); |
|
54 |
||
| 18702 | 55 |
datatype 'a mixfix = |
56 |
Arg of fixity |
|
57 |
| Ignore |
|
58 |
| Pretty of Pretty.T |
|
59 |
| Quote of 'a; |
|
| 18516 | 60 |
|
| 18865 | 61 |
type 'a pretty_syntax = (int * int) * (fixity -> (fixity -> 'a -> Pretty.T) |
62 |
-> 'a list -> Pretty.T); |
|
| 18516 | 63 |
|
| 18216 | 64 |
fun eval_lrx L L = false |
65 |
| eval_lrx R R = false |
|
66 |
| eval_lrx _ _ = true; |
|
67 |
||
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
68 |
fun eval_fxy NOBR _ = false |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
69 |
| eval_fxy _ BR = true |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
70 |
| eval_fxy _ NOBR = false |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
71 |
| eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
72 |
pr < pr_ctxt |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
73 |
orelse pr = pr_ctxt |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
74 |
andalso eval_lrx lr lr_ctxt |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
75 |
| eval_fxy _ (INFX _) = false; |
| 18216 | 76 |
|
| 18702 | 77 |
val str = setmp print_mode [] Pretty.str; |
| 18216 | 78 |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
79 |
fun gen_brackify _ [p] = p |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
80 |
| gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
81 |
| gen_brackify false (ps as _::_) = Pretty.block ps; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
82 |
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
83 |
fun brackify fxy_ctxt ps = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
84 |
gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps); |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
85 |
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
86 |
fun brackify_infix infx fxy_ctxt ps = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
87 |
gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps); |
| 18216 | 88 |
|
| 18865 | 89 |
fun from_app mk_app from_expr const_syntax fxy (c, es) = |
| 18702 | 90 |
let |
91 |
fun mk NONE es = |
|
| 18865 | 92 |
brackify fxy (mk_app c es) |
| 18702 | 93 |
| mk (SOME ((i, k), pr)) es = |
94 |
let |
|
| 18865 | 95 |
val (es1, es2) = splitAt (k, es); |
| 18702 | 96 |
in |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
97 |
brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2) |
| 18702 | 98 |
end; |
| 18865 | 99 |
in mk (const_syntax c) es end; |
100 |
||
101 |
val _ : (string -> iexpr list -> Pretty.T list) |
|
102 |
-> (fixity -> iexpr -> Pretty.T) |
|
103 |
-> (string |
|
104 |
-> ((int * int) |
|
105 |
* (fixity |
|
106 |
-> (fixity -> iexpr -> Pretty.T) |
|
107 |
-> iexpr list -> Pretty.T)) option) |
|
108 |
-> fixity -> string * iexpr list -> Pretty.T = from_app; |
|
| 18702 | 109 |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
110 |
fun fillin_mixfix fxy_this ms fxy_ctxt pr args = |
| 18702 | 111 |
let |
112 |
fun fillin [] [] = |
|
113 |
[] |
|
114 |
| fillin (Arg fxy :: ms) (a :: args) = |
|
115 |
pr fxy a :: fillin ms args |
|
116 |
| fillin (Ignore :: ms) args = |
|
117 |
fillin ms args |
|
118 |
| fillin (Pretty p :: ms) args = |
|
119 |
p :: fillin ms args |
|
120 |
| fillin (Quote q :: ms) args = |
|
121 |
pr BR q :: fillin ms args; |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
122 |
in gen_brackify (eval_fxy fxy_this fxy_ctxt) (fillin ms args) end; |
| 18702 | 123 |
|
124 |
||
125 |
(* user-defined syntax *) |
|
126 |
||
127 |
val (atomK, infixK, infixlK, infixrK) = |
|
| 18756 | 128 |
("target_atom", "infix", "infixl", "infixr");
|
129 |
val _ = OuterSyntax.add_keywords [atomK, infixK, infixlK, infixrK]; |
|
| 18216 | 130 |
|
| 18702 | 131 |
fun parse_infix (fixity as INFX (i, x)) s = |
132 |
let |
|
133 |
val l = case x of L => fixity |
|
134 |
| _ => INFX (i, X); |
|
135 |
val r = case x of R => fixity |
|
136 |
| _ => INFX (i, X); |
|
137 |
in |
|
138 |
pair [Arg l, (Pretty o Pretty.brk) 1, (Pretty o str) s, (Pretty o Pretty.brk) 1, Arg r] |
|
139 |
end; |
|
140 |
||
141 |
fun parse_mixfix reader s ctxt = |
|
| 18335 | 142 |
let |
| 18702 | 143 |
fun sym s = Scan.lift ($$ s); |
144 |
fun lift_reader ctxt s = |
|
145 |
ctxt |
|
146 |
|> reader s |
|
147 |
|-> (fn x => pair (Quote x)); |
|
148 |
val sym_any = Scan.lift (Scan.one Symbol.not_eof); |
|
149 |
val parse = Scan.repeat ( |
|
150 |
(sym "_" -- sym "_" >> K (Arg NOBR)) |
|
151 |
|| (sym "_" >> K (Arg BR)) |
|
152 |
|| (sym "?" >> K Ignore) |
|
153 |
|| (sym "/" |-- Scan.repeat (sym " ") >> (Pretty o Pretty.brk o length)) |
|
154 |
|| Scan.depend (fn ctxt => $$ "{" |-- $$ "*" |-- Scan.repeat1
|
|
155 |
( $$ "'" |-- Scan.one Symbol.not_eof |
|
156 |
|| Scan.unless ($$ "*" -- $$ "}") (Scan.one Symbol.not_eof)) --| |
|
157 |
$$ "*" --| $$ "}" >> (implode #> lift_reader ctxt #> swap)) |
|
158 |
|| (Scan.repeat1 |
|
159 |
( sym "'" |-- sym_any |
|
160 |
|| Scan.unless (sym "_" || sym "?" || sym "/" || sym "{" |-- sym "*")
|
|
161 |
sym_any) >> (Pretty o str o implode))); |
|
162 |
in case Scan.finite' Symbol.stopper parse (ctxt, Symbol.explode s) |
|
163 |
of (p, (ctxt, [])) => (p, ctxt) |
|
164 |
| _ => error ("Malformed mixfix annotation: " ^ quote s)
|
|
165 |
end; |
|
166 |
||
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
167 |
fun parse_nonatomic_mixfix reader s ctxt = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
168 |
case parse_mixfix reader s ctxt |
| 18865 | 169 |
of ([Pretty _], _) => |
170 |
error ("mixfix contains just one pretty element; either declare as "
|
|
171 |
^ quote atomK ^ " or consider adding a break") |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
172 |
| x => x; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
173 |
|
| 18702 | 174 |
fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- (
|
| 18865 | 175 |
OuterParse.$$$ infixK |-- OuterParse.nat |
176 |
>> (fn i => (parse_infix (INFX (i, X)), INFX (i, X))) |
|
177 |
|| OuterParse.$$$ infixlK |-- OuterParse.nat |
|
178 |
>> (fn i => (parse_infix (INFX (i, L)), INFX (i, L))) |
|
179 |
|| OuterParse.$$$ infixrK |-- OuterParse.nat |
|
180 |
>> (fn i => (parse_infix (INFX (i, R)), INFX (i, R))) |
|
| 18702 | 181 |
|| OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR) |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
182 |
|| pair (parse_nonatomic_mixfix reader, BR) |
| 18702 | 183 |
) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy)); |
| 18282 | 184 |
|
| 18702 | 185 |
fun parse_syntax reader = |
| 18335 | 186 |
let |
| 18702 | 187 |
fun is_arg (Arg _) = true |
188 |
| is_arg Ignore = true |
|
189 |
| is_arg _ = false; |
|
190 |
fun mk fixity mfx = |
|
191 |
let |
|
192 |
val i = length (List.filter is_arg mfx) |
|
193 |
in ((i, i), fillin_mixfix fixity mfx) end; |
|
194 |
in |
|
195 |
parse_syntax_proto reader |
|
196 |
#-> (fn (mfx_reader, fixity) : ('Z -> 'Y mixfix list * 'Z) * fixity =>
|
|
197 |
pair (mfx_reader #-> (fn mfx => pair (mk fixity mfx))) |
|
198 |
) |
|
199 |
end; |
|
200 |
||
201 |
fun newline_correct s = |
|
202 |
s |
|
203 |
|> Symbol.strip_blanks |
|
204 |
|> space_explode "\n" |
|
205 |
|> map (implode o (fn [] => [] |
|
206 |
| (" "::xs) => xs
|
|
207 |
| xs => xs) o explode) |
|
208 |
|> space_implode "\n"; |
|
209 |
||
210 |
fun parse_named_quote resolv s = |
|
211 |
case Scan.finite Symbol.stopper (Scan.repeat ( |
|
212 |
($$ "`" |-- $$ "`") |
|
213 |
|| ($$ "`" |-- Scan.repeat1 (Scan.unless ($$ "`") (Scan.one Symbol.not_eof)) |
|
214 |
--| $$ "`" >> (resolv o implode)) |
|
215 |
|| Scan.repeat1 |
|
216 |
(Scan.unless ($$ "`") (Scan.one Symbol.not_eof)) >> implode |
|
217 |
) >> implode) (Symbol.explode s) |
|
218 |
of (p, []) => p |
|
219 |
| (p, ss) => error ("Malformed definition: " ^ quote p ^ " - " ^ commas ss);
|
|
220 |
||
221 |
fun parse_targetdef resolv = parse_named_quote resolv o newline_correct; |
|
222 |
||
223 |
||
224 |
(* abstract serializer *) |
|
| 18282 | 225 |
|
| 18702 | 226 |
type serializer = |
227 |
string list list |
|
| 18756 | 228 |
-> OuterParse.token list -> |
| 18865 | 229 |
((string -> string option) |
230 |
* (string -> CodegenThingol.itype pretty_syntax option) |
|
| 18702 | 231 |
* (string -> CodegenThingol.iexpr pretty_syntax option) |
232 |
-> string list option |
|
| 18756 | 233 |
-> CodegenThingol.module -> unit) |
234 |
* OuterParse.token list; |
|
| 18702 | 235 |
|
| 18850 | 236 |
fun pretty_of_prim target resolv (name, primdef) = |
237 |
let |
|
238 |
fun pr (CodegenThingol.Pretty p) = p |
|
239 |
| pr (CodegenThingol.Name s) = resolv s; |
|
240 |
in case AList.lookup (op = : string * string -> bool) primdef target |
|
241 |
of NONE => error ("no primitive definition for " ^ quote name)
|
|
242 |
| SOME ps => (Pretty.block o map pr) ps |
|
243 |
end; |
|
244 |
||
245 |
fun abstract_serializer (target, nspgrp) name_root (from_defs, from_module, validator) |
|
| 18865 | 246 |
postprocess preprocess (class_syntax : string -> string option, tyco_syntax, const_syntax) |
247 |
select module = |
|
| 18702 | 248 |
let |
249 |
fun from_prim (name, prim) = |
|
| 18756 | 250 |
case AList.lookup (op = : string * string -> bool) prim target |
| 18702 | 251 |
of NONE => error ("no primitive definition for " ^ quote name)
|
252 |
| SOME p => p; |
|
| 18850 | 253 |
fun from_module' imps ((name_qual, name), defs) = |
254 |
from_module imps ((name_qual, name), defs) |> postprocess name_qual; |
|
| 18702 | 255 |
in |
256 |
module |
|
257 |
|> debug 3 (fn _ => "selecting submodule...") |
|
258 |
|> (if is_some select then (partof o the) select else I) |
|
259 |
|> tap (Pretty.writeln o pretty_deps) |
|
260 |
|> debug 3 (fn _ => "preprocessing...") |
|
261 |
|> preprocess |
|
262 |
|> debug 3 (fn _ => "serializing...") |
|
| 18865 | 263 |
|> serialize (from_defs (from_prim, (class_syntax, tyco_syntax, const_syntax))) |
| 18850 | 264 |
from_module' validator nspgrp name_root |
265 |
|> K () |
|
| 18702 | 266 |
end; |
267 |
||
268 |
fun abstract_validator keywords name = |
|
269 |
let |
|
270 |
fun replace_invalid c = |
|
271 |
if (Char.isAlphaNum o the o Char.fromString) c orelse c = "'" |
|
272 |
andalso not (NameSpace.separator = c) |
|
273 |
then c |
|
274 |
else "_" |
|
275 |
fun suffix_it name = |
|
276 |
name |
|
277 |
|> member (op =) keywords ? suffix "'" |
|
278 |
|> (fn name' => if name = name' then name else suffix_it name') |
|
279 |
in |
|
280 |
name |
|
281 |
|> translate_string replace_invalid |
|
282 |
|> suffix_it |
|
283 |
|> (fn name' => if name = name' then NONE else SOME name') |
|
284 |
end; |
|
285 |
||
| 18850 | 286 |
fun write_file mkdir path p = ( |
287 |
if mkdir |
|
288 |
then |
|
289 |
File.mkdir (Path.dir path) |
|
290 |
else (); |
|
291 |
File.write path (Pretty.output p ^ "\n"); |
|
292 |
p |
|
293 |
); |
|
294 |
||
295 |
fun mk_module_file postprocess_module ext path name p = |
|
296 |
let |
|
297 |
val prfx = Path.dir path; |
|
298 |
val name' = case name |
|
299 |
of "" => Path.base path |
|
300 |
| _ => (Path.ext ext o Path.unpack o implode o separate "/" o NameSpace.unpack) name; |
|
301 |
in |
|
302 |
p |
|
303 |
|> write_file true (Path.append prfx name') |
|
304 |
|> postprocess_module name |
|
305 |
end; |
|
306 |
||
| 18756 | 307 |
fun parse_single_file serializer = |
| 18850 | 308 |
OuterParse.path |
309 |
>> (fn path => serializer |
|
310 |
(fn "" => write_file false path #> K NONE |
|
311 |
| _ => SOME)); |
|
312 |
||
313 |
fun parse_multi_file postprocess_module ext serializer = |
|
314 |
OuterParse.path |
|
315 |
>> (fn path => (serializer o mk_module_file postprocess_module ext) path); |
|
| 18702 | 316 |
|
| 18756 | 317 |
fun parse_internal serializer = |
318 |
OuterParse.name |
|
| 18850 | 319 |
>> (fn "-" => serializer |
320 |
(fn "" => (fn p => (use_text Context.ml_output false (Pretty.output p); NONE)) |
|
321 |
| _ => SOME) |
|
| 18756 | 322 |
| _ => Scan.fail ()); |
| 18702 | 323 |
|
| 18282 | 324 |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
325 |
(* list serializer *) |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
326 |
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
327 |
fun pretty_list thingol_nil thingol_cons (target_pred, target_cons) = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
328 |
let |
| 18865 | 329 |
fun dest_cons (IApp (IApp (IConst ((c, _), _), e1), e2)) = |
| 18850 | 330 |
if c = thingol_cons |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
331 |
then SOME (e1, e2) |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
332 |
else NONE |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
333 |
| dest_cons _ = NONE; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
334 |
fun pretty_default fxy pr e1 e2 = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
335 |
brackify_infix (target_pred, R) fxy [ |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
336 |
pr (INFX (target_pred, X)) e1, |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
337 |
str target_cons, |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
338 |
pr (INFX (target_pred, R)) e2 |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
339 |
]; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
340 |
fun pretty_compact fxy pr [e1, e2] = |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
341 |
case unfoldr dest_cons e2 |
| 18865 | 342 |
of (es, IConst ((c, _), _)) => |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
343 |
if c = thingol_nil |
| 18812 | 344 |
then Pretty.enum "," "[" "]" (map (pr NOBR) (e1::es)) |
| 18853 | 345 |
else pretty_default fxy pr e1 e2 |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
346 |
| _ => pretty_default fxy pr e1 e2; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
347 |
in ((2, 2), pretty_compact) end; |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
348 |
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
349 |
|
| 18216 | 350 |
|
351 |
(** ML serializer **) |
|
352 |
||
353 |
local |
|
354 |
||
| 18702 | 355 |
fun ml_from_defs (is_cons, needs_type) |
| 18865 | 356 |
(from_prim, (_, tyco_syntax, const_syntax)) resolv defs = |
| 18216 | 357 |
let |
| 18282 | 358 |
fun chunk_defs ps = |
| 18216 | 359 |
let |
360 |
val (p_init, p_last) = split_last ps |
|
361 |
in |
|
| 18702 | 362 |
Pretty.chunks (p_init @ [Pretty.block ([p_last, str ";"])]) |
| 18515 | 363 |
end; |
| 18865 | 364 |
val ml_from_label = |
365 |
resolv |
|
366 |
#> NameSpace.base |
|
367 |
#> translate_string (fn "_" => "__" | "." => "_" | c => c) |
|
368 |
#> str; |
|
| 18885 | 369 |
fun ml_from_label' l = |
370 |
Pretty.block [str "#", ml_from_label l]; |
|
371 |
fun ml_from_lookup fxy [] p = |
|
372 |
p |
|
373 |
| ml_from_lookup fxy [l] p = |
|
374 |
brackify fxy [ |
|
375 |
ml_from_label' l, |
|
376 |
p |
|
377 |
] |
|
378 |
| ml_from_lookup fxy ls p = |
|
379 |
brackify fxy [ |
|
380 |
Pretty.enum " o" "(" ")" (map ml_from_label' ls),
|
|
381 |
p |
|
382 |
]; |
|
383 |
fun ml_from_sortlookup fxy ls = |
|
384 |
let |
|
385 |
fun from_classlookup fxy (Instance (inst, lss)) = |
|
386 |
brackify fxy ( |
|
387 |
(str o resolv) inst |
|
388 |
:: map (ml_from_sortlookup BR) lss |
|
389 |
) |
|
390 |
| from_classlookup fxy (Lookup (classes, (v, ~1))) = |
|
391 |
ml_from_lookup BR classes (str v) |
|
392 |
| from_classlookup fxy (Lookup (classes, (v, i))) = |
|
393 |
ml_from_lookup BR (string_of_int (i+1) :: classes) (str v) |
|
394 |
in case ls |
|
395 |
of [l] => from_classlookup fxy l |
|
396 |
| ls => (Pretty.list "(" ")" o map (from_classlookup NOBR)) ls
|
|
397 |
end; |
|
398 |
val ml_from_label = |
|
399 |
resolv |
|
400 |
#> NameSpace.base |
|
401 |
#> translate_string (fn "_" => "__" | "." => "_" | c => c) |
|
402 |
#> str; |
|
| 18702 | 403 |
fun ml_from_type fxy (IType (tyco, tys)) = |
404 |
(case tyco_syntax tyco |
|
405 |
of NONE => |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
406 |
let |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
407 |
val f' = (str o resolv) tyco |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
408 |
in case map (ml_from_type BR) tys |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
409 |
of [] => f' |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
410 |
| [p] => Pretty.block [p, Pretty.brk 1, f'] |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
411 |
| (ps as _::_) => Pretty.block [Pretty.list "(" ")" ps, Pretty.brk 1, f']
|
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
412 |
end |
| 18702 | 413 |
| SOME ((i, k), pr) => |
414 |
if not (i <= length tys andalso length tys <= k) |
|
415 |
then error ("number of argument mismatch in customary serialization: "
|
|
| 18865 | 416 |
^ (string_of_int o length) tys ^ " given, " |
417 |
^ string_of_int i ^ " to " ^ string_of_int k |
|
| 18702 | 418 |
^ " expected") |
419 |
else pr fxy ml_from_type tys) |
|
420 |
| ml_from_type fxy (IFun (t1, t2)) = |
|
| 18216 | 421 |
let |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
422 |
val brackify = gen_brackify |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
423 |
(case fxy |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
424 |
of BR => false |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
425 |
| _ => eval_fxy (INFX (1, R)) fxy) o Pretty.breaks; |
| 18216 | 426 |
in |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
427 |
brackify [ |
| 18702 | 428 |
ml_from_type (INFX (1, X)) t1, |
429 |
str "->", |
|
430 |
ml_from_type (INFX (1, R)) t2 |
|
431 |
] |
|
| 18216 | 432 |
end |
| 18865 | 433 |
| ml_from_type _ (IVarT (v, _)) = |
| 18885 | 434 |
str ("'" ^ v);
|
435 |
fun ml_from_expr fxy (e as IApp (e1, e2)) = |
|
| 18865 | 436 |
(case unfold_const_app e |
| 18885 | 437 |
of SOME x => ml_from_app fxy x |
| 18865 | 438 |
| NONE => |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
439 |
brackify fxy [ |
| 18885 | 440 |
ml_from_expr NOBR e1, |
441 |
ml_from_expr BR e2 |
|
| 18216 | 442 |
]) |
| 18885 | 443 |
| ml_from_expr fxy (e as IConst x) = |
444 |
ml_from_app fxy (x, []) |
|
445 |
| ml_from_expr fxy (IVarE (v, _)) = |
|
| 18702 | 446 |
str v |
| 18885 | 447 |
| ml_from_expr fxy (IAbs ((v, _), e)) = |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
448 |
brackify fxy [ |
| 18702 | 449 |
str ("fn " ^ v ^ " =>"),
|
| 18885 | 450 |
ml_from_expr NOBR e |
| 18216 | 451 |
] |
| 18885 | 452 |
| ml_from_expr fxy (e as ICase (_, [_])) = |
| 18216 | 453 |
let |
454 |
val (ps, e) = unfold_let e; |
|
455 |
fun mk_val (p, e) = Pretty.block [ |
|
| 18702 | 456 |
str "val ", |
| 18885 | 457 |
ml_from_expr fxy p, |
| 18702 | 458 |
str " =", |
| 18216 | 459 |
Pretty.brk 1, |
| 18885 | 460 |
ml_from_expr NOBR e, |
| 18702 | 461 |
str ";" |
| 18216 | 462 |
] |
463 |
in Pretty.chunks [ |
|
| 18702 | 464 |
[str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block,
|
| 18885 | 465 |
[str ("in"), Pretty.fbrk, ml_from_expr NOBR e] |> Pretty.block,
|
| 18702 | 466 |
str ("end")
|
| 18216 | 467 |
] end |
| 18885 | 468 |
| ml_from_expr fxy (ICase (e, c::cs)) = |
| 18216 | 469 |
let |
470 |
fun mk_clause definer (p, e) = |
|
471 |
Pretty.block [ |
|
| 18702 | 472 |
str definer, |
| 18885 | 473 |
ml_from_expr NOBR p, |
| 18702 | 474 |
str " =>", |
| 18216 | 475 |
Pretty.brk 1, |
| 18885 | 476 |
ml_from_expr NOBR e |
| 18216 | 477 |
] |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
478 |
in brackify fxy ( |
| 18702 | 479 |
str "case" |
| 18885 | 480 |
:: ml_from_expr NOBR e |
| 18216 | 481 |
:: mk_clause "of " c |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
482 |
:: map (mk_clause "| ") cs |
| 18216 | 483 |
) end |
| 18885 | 484 |
| ml_from_expr _ e = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
485 |
error ("dubious expression: " ^ (Pretty.output o pretty_iexpr) e)
|
| 18885 | 486 |
and ml_mk_app f es = |
| 18702 | 487 |
if is_cons f andalso length es > 1 |
488 |
then |
|
| 18885 | 489 |
[(str o resolv) f, Pretty.enum " *" "(" ")" (map (ml_from_expr BR) es)]
|
| 18702 | 490 |
else |
| 18885 | 491 |
(str o resolv) f :: map (ml_from_expr BR) es |
492 |
and ml_from_app fxy (((c, _), lss), es) = |
|
493 |
case map (ml_from_sortlookup BR) lss |
|
494 |
of [] => |
|
495 |
from_app ml_mk_app ml_from_expr const_syntax fxy (c, es) |
|
496 |
| lss => |
|
497 |
brackify fxy ( |
|
498 |
(str o resolv) c |
|
499 |
:: (lss |
|
500 |
@ map (ml_from_expr BR) es) |
|
501 |
); |
|
| 18912 | 502 |
fun ml_from_funs (defs as def::defs_tl) = |
| 18216 | 503 |
let |
504 |
fun mk_definer [] = "val" |
|
| 18702 | 505 |
| mk_definer _ = "fun"; |
| 18216 | 506 |
fun check_args (_, Fun ((pats, _)::_, _)) NONE = |
507 |
SOME (mk_definer pats) |
|
508 |
| check_args (_, Fun ((pats, _)::_, _)) (SOME definer) = |
|
509 |
if mk_definer pats = definer |
|
510 |
then SOME definer |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
511 |
else error ("mixing simultaneous vals and funs not implemented")
|
| 18216 | 512 |
| check_args _ _ = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
513 |
error ("function definition block containing other definitions than functions")
|
| 18912 | 514 |
fun mk_fun definer (name, Fun (eqs as eq::eq_tl, (sortctxt, ty))) = |
| 18216 | 515 |
let |
| 18912 | 516 |
val shift = if null eq_tl then I else map (Pretty.block o single); |
517 |
fun mk_eq definer (pats, expr) = |
|
518 |
(Pretty.block o Pretty.breaks) ( |
|
519 |
[str definer, (str o resolv) name] |
|
520 |
@ (if null pats |
|
521 |
then [str ":", ml_from_type NOBR ty] |
|
522 |
else map (str o fst) sortctxt @ map (ml_from_expr BR) pats) |
|
523 |
@ [str "=", ml_from_expr NOBR expr] |
|
524 |
) |
|
| 18216 | 525 |
in |
| 18912 | 526 |
(Pretty.block o Pretty.fbreaks o shift) ( |
527 |
mk_eq definer eq |
|
528 |
:: map (mk_eq "|") eq_tl |
|
529 |
) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
530 |
end; |
| 18216 | 531 |
in |
532 |
chunk_defs ( |
|
| 18912 | 533 |
mk_fun (the (fold check_args defs NONE)) def |
534 |
:: map (mk_fun "and") defs_tl |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
535 |
) |> SOME |
| 18216 | 536 |
end; |
| 18282 | 537 |
fun ml_from_datatypes defs = |
| 18216 | 538 |
let |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
539 |
val defs' = List.mapPartial |
| 18912 | 540 |
(fn (name, Datatype info) => SOME (resolv name, info) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
541 |
| (name, Datatypecons _) => NONE |
| 18865 | 542 |
| (name, def) => error ("datatype block containing illegal def: "
|
543 |
^ (Pretty.output o pretty_def) def) |
|
| 18702 | 544 |
) defs |
545 |
fun mk_cons (co, []) = |
|
546 |
str (resolv co) |
|
547 |
| mk_cons (co, tys) = |
|
548 |
Pretty.block ( |
|
549 |
str (resolv co) |
|
550 |
:: str " of" |
|
551 |
:: Pretty.brk 1 |
|
| 18865 | 552 |
:: separate (Pretty.block [str " *", Pretty.brk 1]) |
553 |
(map (ml_from_type NOBR) tys) |
|
| 18702 | 554 |
) |
555 |
fun mk_datatype definer (t, ((vs, cs), _)) = |
|
| 18912 | 556 |
(Pretty.block o Pretty.breaks) ( |
| 18702 | 557 |
str definer |
558 |
:: ml_from_type NOBR (t `%% map IVarT vs) |
|
| 18912 | 559 |
:: str "=" |
560 |
:: separate (str "|") (map mk_cons cs) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
561 |
) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
562 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
563 |
case defs' |
| 18912 | 564 |
of (def::defs_tl) => |
| 18216 | 565 |
chunk_defs ( |
| 18912 | 566 |
mk_datatype "datatype " def |
567 |
:: map (mk_datatype "and ") defs_tl |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
568 |
) |> SOME |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
569 |
| _ => NONE |
| 18702 | 570 |
end |
571 |
fun ml_from_def (name, Undef) = |
|
572 |
error ("empty definition during serialization: " ^ quote name)
|
|
| 18516 | 573 |
| ml_from_def (name, Prim prim) = |
| 18702 | 574 |
from_prim (name, prim) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
575 |
| ml_from_def (name, Typesyn (vs, ty)) = |
| 18865 | 576 |
(map (fn (vname, []) => () | _ => |
577 |
error "can't serialize sort constrained type declaration to ML") vs; |
|
| 18702 | 578 |
Pretty.block [ |
579 |
str "type ", |
|
580 |
ml_from_type NOBR (name `%% map IVarT vs), |
|
581 |
str " =", |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
582 |
Pretty.brk 1, |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
583 |
ml_from_type NOBR ty, |
| 18702 | 584 |
str ";" |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
585 |
] |
| 18702 | 586 |
) |> SOME |
| 18865 | 587 |
| ml_from_def (name, Class ((supclasses, (v, membrs)), _)) = |
588 |
let |
|
589 |
val pv = str ("'" ^ v);
|
|
590 |
fun from_supclass class = |
|
591 |
Pretty.block [ |
|
592 |
ml_from_label class, |
|
593 |
str ":", |
|
594 |
Pretty.brk 1, |
|
595 |
pv, |
|
596 |
Pretty.brk 1, |
|
597 |
(str o resolv) class |
|
598 |
] |
|
599 |
fun from_membr (m, (_, ty)) = |
|
600 |
Pretty.block [ |
|
601 |
ml_from_label m, |
|
602 |
str ":", |
|
603 |
Pretty.brk 1, |
|
604 |
ml_from_type NOBR ty |
|
605 |
] |
|
606 |
in |
|
607 |
Pretty.block [ |
|
608 |
str "type", |
|
609 |
Pretty.brk 1, |
|
610 |
pv, |
|
611 |
Pretty.brk 1, |
|
612 |
(str o resolv) name, |
|
613 |
Pretty.brk 1, |
|
614 |
str "=", |
|
615 |
Pretty.brk 1, |
|
616 |
Pretty.enum "," "{" "};" (
|
|
617 |
map from_supclass supclasses @ map from_membr membrs |
|
618 |
) |
|
619 |
] |> SOME |
|
620 |
end |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
621 |
| ml_from_def (_, Classmember _) = |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
622 |
NONE |
| 18865 | 623 |
| ml_from_def (name, Classinst (((class, (tyco, arity)), suparities), memdefs)) = |
624 |
let |
|
625 |
val definer = if null arity then "val" else "fun" |
|
| 18885 | 626 |
fun from_supclass (supclass, lss) = |
627 |
(Pretty.block o Pretty.breaks) ( |
|
628 |
ml_from_label supclass |
|
629 |
:: str "=" |
|
630 |
:: map (ml_from_sortlookup NOBR) lss |
|
631 |
); |
|
| 18865 | 632 |
fun from_memdef (m, def) = |
633 |
((the o ml_from_funs) [(m, Fun def)], Pretty.block [ |
|
| 18885 | 634 |
ml_from_label m, |
| 18865 | 635 |
Pretty.brk 1, |
636 |
str "=", |
|
637 |
Pretty.brk 1, |
|
638 |
(str o resolv) m |
|
| 18885 | 639 |
]); |
| 18865 | 640 |
fun mk_memdefs supclassexprs [] = |
641 |
Pretty.enum "," "{" "};" (
|
|
642 |
supclassexprs |
|
643 |
) |
|
644 |
| mk_memdefs supclassexprs memdefs = |
|
645 |
let |
|
646 |
val (defs, assigns) = (split_list o map from_memdef) memdefs; |
|
647 |
in |
|
648 |
Pretty.chunks [ |
|
649 |
[str ("let"), Pretty.fbrk, defs |> Pretty.chunks]
|
|
650 |
|> Pretty.block, |
|
651 |
[str ("in "), Pretty.enum "," "{" "};" (supclassexprs @ assigns)]
|
|
652 |
|> Pretty.block |
|
653 |
] |
|
654 |
end; |
|
655 |
in |
|
656 |
Pretty.block [ |
|
657 |
(Pretty.block o Pretty.breaks) ( |
|
658 |
str definer |
|
| 18912 | 659 |
:: (str o resolv) name |
| 18865 | 660 |
:: map (str o fst) arity |
661 |
), |
|
662 |
Pretty.brk 1, |
|
663 |
str "=", |
|
664 |
Pretty.brk 1, |
|
665 |
mk_memdefs (map from_supclass suparities) memdefs |
|
666 |
] |> SOME |
|
667 |
end; |
|
| 18850 | 668 |
in case defs |
| 18702 | 669 |
of (_, Fun _)::_ => ml_from_funs defs |
670 |
| (_, Datatypecons _)::_ => ml_from_datatypes defs |
|
671 |
| (_, Datatype _)::_ => ml_from_datatypes defs |
|
| 18850 | 672 |
| [def] => ml_from_def def |
| 18216 | 673 |
end; |
674 |
||
675 |
in |
|
676 |
||
| 18865 | 677 |
fun ml_from_thingol target (nsp_dtcon, nsp_class, is_int_tyco) nspgrp = |
| 18216 | 678 |
let |
| 18702 | 679 |
val reserved_ml = ThmDatabase.ml_reserved @ [ |
| 18865 | 680 |
"bool", "int", "list", "true", "false", "o" |
| 18702 | 681 |
]; |
| 18850 | 682 |
fun ml_from_module _ ((_, name), ps) = |
| 18756 | 683 |
Pretty.chunks ([ |
| 18702 | 684 |
str ("structure " ^ name ^ " = "),
|
685 |
str "struct", |
|
686 |
str "" |
|
687 |
] @ separate (str "") ps @ [ |
|
688 |
str "", |
|
689 |
str ("end; (* struct " ^ name ^ " *)")
|
|
| 18756 | 690 |
]); |
| 18702 | 691 |
fun needs_type (IType (tyco, _)) = |
| 18516 | 692 |
has_nsp tyco nsp_class |
| 18865 | 693 |
orelse is_int_tyco tyco |
| 18702 | 694 |
| needs_type _ = |
| 18516 | 695 |
false; |
| 18702 | 696 |
fun is_cons c = has_nsp c nsp_dtcon; |
| 18756 | 697 |
val serializer = abstract_serializer (target, nspgrp) |
| 18850 | 698 |
"ROOT" (ml_from_defs (is_cons, needs_type), ml_from_module, abstract_validator reserved_ml); |
| 18756 | 699 |
fun eta_expander module const_syntax s = |
| 18702 | 700 |
case const_syntax s |
701 |
of SOME ((i, _), _) => i |
|
702 |
| _ => if has_nsp s nsp_dtcon |
|
703 |
then case get_def module s |
|
704 |
of Datatypecons dtname => case get_def module dtname |
|
705 |
of Datatype ((_, cs), _) => |
|
706 |
let val l = AList.lookup (op =) cs s |> the |> length |
|
707 |
in if l >= 2 then l else 0 end |
|
708 |
else 0; |
|
| 18756 | 709 |
fun preprocess const_syntax module = |
| 18702 | 710 |
module |
711 |
|> tap (Pretty.writeln o pretty_deps) |
|
712 |
|> debug 3 (fn _ => "eta-expanding...") |
|
| 18756 | 713 |
|> eta_expand (eta_expander module const_syntax) |
| 18702 | 714 |
|> debug 3 (fn _ => "eta-expanding polydefs...") |
| 18885 | 715 |
|> eta_expand_poly |
716 |
|> debug 3 (fn _ => "unclashing expression/type variables...") |
|
717 |
|> unclash_vars; |
|
| 18850 | 718 |
val parse_multi = |
719 |
OuterParse.name |
|
720 |
#-> (fn "dir" => |
|
721 |
parse_multi_file |
|
722 |
(K o SOME o str o suffix ";" o prefix "val _ = use " |
|
723 |
o quote o suffix ".ML" o translate_string (fn "." => "/" | s => s)) "ML" serializer |
|
724 |
| _ => Scan.fail ()); |
|
| 18282 | 725 |
in |
| 18850 | 726 |
(parse_multi |
727 |
|| parse_internal serializer |
|
728 |
|| parse_single_file serializer) |
|
| 18865 | 729 |
>> (fn seri => fn (class_syntax, tyco_syntax, const_syntax) => seri |
730 |
(preprocess const_syntax) (class_syntax, tyco_syntax, const_syntax)) |
|
| 18216 | 731 |
end; |
732 |
||
733 |
end; (* local *) |
|
734 |
||
| 18282 | 735 |
local |
736 |
||
| 18865 | 737 |
fun hs_from_defs is_cons (from_prim, (class_syntax, tyco_syntax, const_syntax)) |
738 |
resolv defs = |
|
| 18282 | 739 |
let |
| 18702 | 740 |
fun upper_first s = |
741 |
let |
|
742 |
val (pr, b) = split_last (NameSpace.unpack s); |
|
743 |
val (c::cs) = String.explode b; |
|
744 |
in NameSpace.pack (pr @ [String.implode (Char.toUpper c :: cs)]) end; |
|
745 |
fun lower_first s = |
|
746 |
let |
|
747 |
val (pr, b) = split_last (NameSpace.unpack s); |
|
748 |
val (c::cs) = String.explode b; |
|
749 |
in NameSpace.pack (pr @ [String.implode (Char.toLower c :: cs)]) end; |
|
| 18282 | 750 |
val resolv = fn s => |
751 |
let |
|
752 |
val (prfix, base) = (split_last o NameSpace.unpack o resolv) s |
|
753 |
in |
|
754 |
NameSpace.pack (map upper_first prfix @ [base]) |
|
755 |
end; |
|
756 |
fun resolv_const f = |
|
| 18335 | 757 |
if NameSpace.is_qualified f |
758 |
then |
|
759 |
if is_cons f |
|
760 |
then (upper_first o resolv) f |
|
761 |
else (lower_first o resolv) f |
|
762 |
else |
|
763 |
f; |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
764 |
fun hs_from_sctxt vs = |
| 18282 | 765 |
let |
| 18865 | 766 |
fun from_class cls = |
767 |
case class_syntax cls |
|
768 |
of NONE => (upper_first o resolv) cls |
|
769 |
| SOME cls => cls |
|
| 18702 | 770 |
fun from_sctxt [] = str "" |
| 18282 | 771 |
| from_sctxt vs = |
772 |
vs |
|
| 18865 | 773 |
|> map (fn (v, cls) => str (from_class cls ^ " " ^ lower_first v)) |
| 18812 | 774 |
|> Pretty.enum "," "(" ")"
|
| 18702 | 775 |
|> (fn p => Pretty.block [p, str " => "]) |
| 18282 | 776 |
in |
777 |
vs |
|
778 |
|> map (fn (v, sort) => map (pair v) sort) |
|
779 |
|> Library.flat |
|
780 |
|> from_sctxt |
|
781 |
end; |
|
| 18865 | 782 |
fun hs_from_type fxy (IType (tyco, tys)) = |
783 |
(case tyco_syntax tyco |
|
| 18335 | 784 |
of NONE => |
| 18865 | 785 |
brackify fxy ((str o upper_first o resolv) tyco :: map (hs_from_type BR) tys) |
| 18702 | 786 |
| SOME ((i, k), pr) => |
| 18865 | 787 |
if not (i <= length tys andalso length tys <= k) |
| 18702 | 788 |
then error ("number of argument mismatch in customary serialization: "
|
| 18865 | 789 |
^ (string_of_int o length) tys ^ " given, " |
790 |
^ string_of_int i ^ " to " ^ string_of_int k |
|
| 18702 | 791 |
^ " expected") |
| 18865 | 792 |
else pr fxy hs_from_type tys) |
793 |
| hs_from_type fxy (IFun (t1, t2)) = |
|
794 |
brackify_infix (1, R) fxy [ |
|
795 |
hs_from_type (INFX (1, X)) t1, |
|
796 |
str "->", |
|
797 |
hs_from_type (INFX (1, R)) t2 |
|
798 |
] |
|
799 |
| hs_from_type fxy (IVarT (v, _)) = |
|
| 18885 | 800 |
(str o lower_first) v; |
| 18865 | 801 |
fun hs_from_sctxt_type (sctxt, ty) = |
802 |
Pretty.block [hs_from_sctxt sctxt, hs_from_type NOBR ty] |
|
803 |
fun hs_from_expr fxy (e as IApp (e1, e2)) = |
|
804 |
(case unfold_const_app e |
|
805 |
of SOME x => hs_from_app fxy x |
|
| 18282 | 806 |
| _ => |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
807 |
brackify fxy [ |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
808 |
hs_from_expr NOBR e1, |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
809 |
hs_from_expr BR e2 |
| 18282 | 810 |
]) |
| 18865 | 811 |
| hs_from_expr fxy (e as IConst x) = |
812 |
hs_from_app fxy (x, []) |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
813 |
| hs_from_expr fxy (IVarE (v, _)) = |
| 18702 | 814 |
(str o lower_first) v |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
815 |
| hs_from_expr fxy (e as IAbs _) = |
| 18282 | 816 |
let |
817 |
val (vs, body) = unfold_abs e |
|
818 |
in |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
819 |
brackify fxy ( |
| 18702 | 820 |
str "\\" |
821 |
:: map (str o lower_first o fst) vs @ [ |
|
822 |
str "->", |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
823 |
hs_from_expr NOBR body |
| 18282 | 824 |
]) |
825 |
end |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
826 |
| hs_from_expr fxy (e as ICase (_, [_])) = |
| 18282 | 827 |
let |
828 |
val (ps, body) = unfold_let e; |
|
829 |
fun mk_bind (p, e) = Pretty.block [ |
|
| 18865 | 830 |
hs_from_expr BR p, |
| 18702 | 831 |
str " =", |
| 18282 | 832 |
Pretty.brk 1, |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
833 |
hs_from_expr NOBR e |
| 18282 | 834 |
]; |
835 |
in Pretty.chunks [ |
|
| 18702 | 836 |
[str ("let"), Pretty.fbrk, map mk_bind ps |> Pretty.chunks] |> Pretty.block,
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
837 |
[str ("in "), hs_from_expr NOBR body] |> Pretty.block
|
| 18282 | 838 |
] end |
| 18850 | 839 |
| hs_from_expr fxy (ICase (e, cs)) = |
| 18282 | 840 |
let |
| 18850 | 841 |
fun mk_clause (p, e) = |
| 18282 | 842 |
Pretty.block [ |
| 18865 | 843 |
hs_from_expr NOBR p, |
| 18702 | 844 |
str " ->", |
| 18282 | 845 |
Pretty.brk 1, |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
846 |
hs_from_expr NOBR e |
| 18282 | 847 |
] |
| 18850 | 848 |
in Pretty.block [ |
849 |
str "case", |
|
850 |
Pretty.brk 1, |
|
851 |
hs_from_expr NOBR e, |
|
852 |
Pretty.brk 1, |
|
853 |
str "of", |
|
854 |
Pretty.fbrk, |
|
855 |
(Pretty.chunks o map mk_clause) cs |
|
856 |
] end |
|
| 18865 | 857 |
and hs_mk_app c es = |
858 |
(str o resolv_const) c :: map (hs_from_expr BR) es |
|
859 |
and hs_from_app fxy (((c, _), ls), es) = |
|
860 |
from_app hs_mk_app hs_from_expr const_syntax fxy (c, es); |
|
861 |
fun hs_from_funeqs (name, eqs) = |
|
862 |
let |
|
863 |
fun from_eq name (args, rhs) = |
|
864 |
Pretty.block [ |
|
| 18912 | 865 |
(str o lower_first o resolv) name, |
| 18865 | 866 |
Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args), |
867 |
Pretty.brk 1, |
|
868 |
str ("="),
|
|
869 |
Pretty.brk 1, |
|
870 |
hs_from_expr NOBR rhs |
|
871 |
] |
|
872 |
in Pretty.chunks (map (from_eq name) eqs) end; |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
873 |
fun hs_from_def (name, Undef) = |
| 18702 | 874 |
error ("empty statement during serialization: " ^ quote name)
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
875 |
| hs_from_def (name, Prim prim) = |
| 18702 | 876 |
from_prim (name, prim) |
| 18865 | 877 |
| hs_from_def (name, Fun (eqs, (sctxt, ty))) = |
| 18912 | 878 |
Pretty.chunks [ |
879 |
Pretty.block [ |
|
880 |
(str o lower_first o resolv) (name ^ " ::"), |
|
881 |
Pretty.brk 1, |
|
882 |
hs_from_sctxt_type (sctxt, ty) |
|
883 |
], |
|
884 |
hs_from_funeqs (name, eqs) |
|
885 |
] |> SOME |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
886 |
| hs_from_def (name, Typesyn (vs, ty)) = |
| 18282 | 887 |
Pretty.block [ |
| 18702 | 888 |
str "type ", |
| 18865 | 889 |
hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs)), |
| 18702 | 890 |
str " =", |
| 18282 | 891 |
Pretty.brk 1, |
| 18865 | 892 |
hs_from_sctxt_type ([], ty) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
893 |
] |> SOME |
| 18865 | 894 |
| hs_from_def (name, Datatype ((vs, constrs), _)) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
895 |
let |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
896 |
fun mk_cons (co, tys) = |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
897 |
(Pretty.block o Pretty.breaks) ( |
| 18702 | 898 |
str ((upper_first o resolv) co) |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
899 |
:: map (hs_from_type NOBR) tys |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
900 |
) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
901 |
in |
| 18865 | 902 |
Pretty.block (( |
| 18702 | 903 |
str "data " |
| 18865 | 904 |
:: hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs)) |
| 18702 | 905 |
:: str " =" |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
906 |
:: Pretty.brk 1 |
| 18702 | 907 |
:: separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs) |
| 18865 | 908 |
) @ [ |
909 |
Pretty.brk 1, |
|
910 |
str "deriving Show" |
|
911 |
]) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
912 |
end |> SOME |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
913 |
| hs_from_def (_, Datatypecons _) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
914 |
NONE |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
915 |
| hs_from_def (name, Class ((supclasss, (v, membrs)), _)) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
916 |
let |
| 18865 | 917 |
fun mk_member (m, (sctxt, ty)) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
918 |
Pretty.block [ |
| 18702 | 919 |
str (resolv m ^ " ::"), |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
920 |
Pretty.brk 1, |
| 18865 | 921 |
hs_from_sctxt_type (sctxt, ty) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
922 |
] |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
923 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
924 |
Pretty.block [ |
| 18702 | 925 |
str "class ", |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
926 |
hs_from_sctxt (map (fn class => (v, [class])) supclasss), |
| 18912 | 927 |
str ((upper_first o resolv) name ^ " " ^ v), |
| 18702 | 928 |
str " where", |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
929 |
Pretty.fbrk, |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
930 |
Pretty.chunks (map mk_member membrs) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
931 |
] |> SOME |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
932 |
end |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
933 |
| hs_from_def (name, Classmember _) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
934 |
NONE |
| 18865 | 935 |
| hs_from_def (_, Classinst (((clsname, (tyco, arity)), _), memdefs)) = |
| 18385 | 936 |
Pretty.block [ |
| 18702 | 937 |
str "instance ", |
| 18865 | 938 |
hs_from_sctxt_type (arity, IType ((upper_first o resolv) clsname, map (IVarT o rpair [] o fst) arity)), |
| 18702 | 939 |
str " ", |
| 18865 | 940 |
hs_from_sctxt_type (arity, IType (tyco, map (IVarT o rpair [] o fst) arity)), |
| 18702 | 941 |
str " where", |
| 18385 | 942 |
Pretty.fbrk, |
| 18912 | 943 |
Pretty.chunks (map (fn (m, (eqs, _)) => hs_from_funeqs (m, eqs)) memdefs) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
944 |
] |> SOME |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
945 |
in |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
946 |
case List.mapPartial (fn (name, def) => hs_from_def (name, def)) defs |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
947 |
of [] => NONE |
| 18702 | 948 |
| l => (SOME o Pretty.chunks o separate (str "")) l |
| 18282 | 949 |
end; |
950 |
||
951 |
in |
|
952 |
||
| 18756 | 953 |
fun hs_from_thingol target nsp_dtcon nspgrp = |
| 18282 | 954 |
let |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
955 |
val reserved_hs = [ |
| 18702 | 956 |
"hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
957 |
"import", "default", "forall", "let", "in", "class", "qualified", "data", |
|
958 |
"newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
|
959 |
] @ [ |
|
960 |
"Bool", "fst", "snd", "Integer", "True", "False", "negate" |
|
961 |
]; |
|
962 |
fun upper_first s = |
|
963 |
let |
|
964 |
val (pr, b) = split_last (NameSpace.unpack s); |
|
965 |
val (c::cs) = String.explode b; |
|
966 |
in NameSpace.pack (pr @ [String.implode (Char.toUpper c :: cs)]) end; |
|
| 18850 | 967 |
fun hs_from_module imps ((_, name), ps) = |
968 |
(Pretty.block o Pretty.fbreaks) ( |
|
969 |
str ("module " ^ (upper_first name) ^ " where")
|
|
970 |
:: map (str o prefix "import ") imps @ [ |
|
971 |
str "", |
|
| 18702 | 972 |
Pretty.chunks (separate (str "") ps) |
| 18850 | 973 |
]); |
| 18702 | 974 |
fun is_cons c = has_nsp c nsp_dtcon; |
| 18756 | 975 |
val serializer = abstract_serializer (target, nspgrp) |
| 18850 | 976 |
"Main" (hs_from_defs is_cons, hs_from_module, abstract_validator reserved_hs); |
| 18756 | 977 |
fun eta_expander const_syntax c = |
| 18702 | 978 |
const_syntax c |
979 |
|> Option.map (fst o fst) |
|
980 |
|> the_default 0; |
|
| 18756 | 981 |
fun preprocess const_syntax module = |
| 18702 | 982 |
module |
983 |
|> tap (Pretty.writeln o pretty_deps) |
|
984 |
|> debug 3 (fn _ => "eta-expanding...") |
|
| 18756 | 985 |
|> eta_expand (eta_expander const_syntax); |
| 18282 | 986 |
in |
| 18850 | 987 |
parse_multi_file ((K o K) NONE) "hs" serializer |
| 18865 | 988 |
>> (fn seri => fn (class_syntax, tyco_syntax, const_syntax) => seri |
989 |
(preprocess const_syntax) (class_syntax, tyco_syntax, const_syntax)) |
|
| 18282 | 990 |
end; |
991 |
||
992 |
end; (* local *) |
|
993 |
||
| 18702 | 994 |
|
995 |
(** lookup record **) |
|
996 |
||
997 |
val serializers = |
|
998 |
let |
|
999 |
fun seri s f = (s, f s); |
|
1000 |
in {
|
|
1001 |
ml = seri "ml" ml_from_thingol, |
|
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
1002 |
haskell = seri "haskell" hs_from_thingol |
| 18702 | 1003 |
} end; |
1004 |
||
| 18216 | 1005 |
end; (* struct *) |