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