author | haftmann |
Mon, 21 Aug 2006 11:02:40 +0200 | |
changeset 20401 | f01ae74f29f2 |
parent 20389 | 8b6ecb22ef35 |
child 20428 | 67fa1c6ba89e |
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; |
20191 | 12 |
type serializer = |
18702 | 13 |
string list list |
18756 | 14 |
-> OuterParse.token list -> |
18865 | 15 |
((string -> string option) |
16 |
* (string -> CodegenThingol.itype pretty_syntax option) |
|
20105 | 17 |
* (string -> CodegenThingol.iterm pretty_syntax option) |
19884 | 18 |
-> string list * string list option |
18756 | 19 |
-> CodegenThingol.module -> unit) |
20 |
* OuterParse.token list; |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
21 |
val parse_syntax: ('b -> int) -> (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
18702 | 22 |
('b -> 'a pretty_syntax * 'b) * OuterParse.token list; |
20401 | 23 |
val pretty_list: string -> string -> (Pretty.T list -> Pretty.T) |
24 |
-> ((string -> string) * (string -> string)) option |
|
25 |
-> int * string -> CodegenThingol.iterm pretty_syntax; |
|
26 |
val pretty_ml_string: string -> string -> (string -> string) -> (string -> string) |
|
27 |
-> string -> CodegenThingol.iterm pretty_syntax; |
|
18702 | 28 |
val serializers: { |
20183 | 29 |
ml: string * (string -> serializer), |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
30 |
haskell: string * (string * string list -> serializer) |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
31 |
}; |
19150 | 32 |
val mk_flat_ml_resolver: string list -> string -> string; |
20216 | 33 |
val eval_term: string -> string -> string list list |
20191 | 34 |
-> (string -> CodegenThingol.itype pretty_syntax option) |
35 |
* (string -> CodegenThingol.iterm pretty_syntax option) |
|
36 |
-> string list |
|
37 |
-> (string * 'a ref) * CodegenThingol.iterm -> CodegenThingol.module |
|
38 |
-> 'a; |
|
20389 | 39 |
val eval_verbose: bool ref; |
20183 | 40 |
val ml_fun_datatype: string |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
41 |
-> ((string -> CodegenThingol.itype pretty_syntax option) |
20105 | 42 |
* (string -> CodegenThingol.iterm pretty_syntax option)) |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
43 |
-> (string -> string) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
44 |
-> ((string * CodegenThingol.funn) list -> Pretty.T) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
45 |
* ((string * CodegenThingol.datatyp) list -> Pretty.T); |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
46 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
47 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
48 |
structure CodegenSerializer: CODEGEN_SERIALIZER = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
49 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
50 |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
51 |
open BasicCodegenThingol; |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
52 |
val debug_msg = CodegenThingol.debug_msg; |
18850 | 53 |
|
18216 | 54 |
(** generic serialization **) |
55 |
||
18702 | 56 |
(* precedences *) |
57 |
||
18216 | 58 |
datatype lrx = L | R | X; |
59 |
||
18516 | 60 |
datatype fixity = |
18216 | 61 |
BR |
62 |
| NOBR |
|
63 |
| INFX of (int * lrx); |
|
64 |
||
18702 | 65 |
datatype 'a mixfix = |
66 |
Arg of fixity |
|
67 |
| Ignore |
|
68 |
| Pretty of Pretty.T |
|
69 |
| Quote of 'a; |
|
18516 | 70 |
|
18865 | 71 |
type 'a pretty_syntax = (int * int) * (fixity -> (fixity -> 'a -> Pretty.T) |
72 |
-> 'a list -> Pretty.T); |
|
18516 | 73 |
|
18216 | 74 |
fun eval_lrx L L = false |
75 |
| eval_lrx R R = false |
|
76 |
| eval_lrx _ _ = true; |
|
77 |
||
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
78 |
fun eval_fxy NOBR _ = false |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
79 |
| eval_fxy _ BR = true |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
80 |
| eval_fxy _ NOBR = false |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
81 |
| eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) = |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
82 |
pr < pr_ctxt |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
83 |
orelse pr = pr_ctxt |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
84 |
andalso eval_lrx lr lr_ctxt |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
85 |
| eval_fxy _ (INFX _) = false; |
18216 | 86 |
|
18702 | 87 |
val str = setmp print_mode [] Pretty.str; |
18216 | 88 |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
89 |
fun gen_brackify _ [p] = p |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
90 |
| gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
91 |
| gen_brackify false (ps as _::_) = Pretty.block ps; |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
92 |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
93 |
fun brackify fxy_ctxt ps = |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
94 |
gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps); |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
95 |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
96 |
fun brackify_infix infx fxy_ctxt ps = |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
97 |
gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps); |
18216 | 98 |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
99 |
fun from_app mk_app from_expr const_syntax fxy (const as (c, _), es) = |
20191 | 100 |
case const_syntax c |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
101 |
of NONE => brackify fxy (mk_app c es) |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
102 |
| SOME ((i, k), pr) => |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
103 |
if i <= length es |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
104 |
then case chop k es of (es1, es2) => |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
105 |
brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2) |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
106 |
else from_expr fxy (CodegenThingol.eta_expand (const, es) i); |
18865 | 107 |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
108 |
fun fillin_mixfix fxy_this ms fxy_ctxt pr args = |
18702 | 109 |
let |
110 |
fun fillin [] [] = |
|
19008 | 111 |
[] |
18702 | 112 |
| fillin (Arg fxy :: ms) (a :: args) = |
113 |
pr fxy a :: fillin ms args |
|
114 |
| fillin (Ignore :: ms) args = |
|
115 |
fillin ms args |
|
116 |
| fillin (Pretty p :: ms) args = |
|
117 |
p :: fillin ms args |
|
118 |
| fillin (Quote q :: ms) args = |
|
19008 | 119 |
pr BR q :: fillin ms args |
120 |
| fillin [] _ = |
|
20389 | 121 |
error ("Inconsistent mixfix: too many arguments") |
19008 | 122 |
| fillin _ [] = |
20389 | 123 |
error ("Inconsistent mixfix: too less arguments"); |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
124 |
in gen_brackify (eval_fxy fxy_this fxy_ctxt) (fillin ms args) end; |
18702 | 125 |
|
126 |
||
127 |
(* user-defined syntax *) |
|
128 |
||
129 |
val (atomK, infixK, infixlK, infixrK) = |
|
18756 | 130 |
("target_atom", "infix", "infixl", "infixr"); |
131 |
val _ = OuterSyntax.add_keywords [atomK, infixK, infixlK, infixrK]; |
|
18216 | 132 |
|
18702 | 133 |
fun parse_infix (fixity as INFX (i, x)) s = |
134 |
let |
|
135 |
val l = case x of L => fixity |
|
136 |
| _ => INFX (i, X); |
|
137 |
val r = case x of R => fixity |
|
138 |
| _ => INFX (i, X); |
|
139 |
in |
|
140 |
pair [Arg l, (Pretty o Pretty.brk) 1, (Pretty o str) s, (Pretty o Pretty.brk) 1, Arg r] |
|
141 |
end; |
|
142 |
||
143 |
fun parse_mixfix reader s ctxt = |
|
18335 | 144 |
let |
18702 | 145 |
fun sym s = Scan.lift ($$ s); |
146 |
fun lift_reader ctxt s = |
|
147 |
ctxt |
|
148 |
|> reader s |
|
149 |
|-> (fn x => pair (Quote x)); |
|
150 |
val sym_any = Scan.lift (Scan.one Symbol.not_eof); |
|
151 |
val parse = Scan.repeat ( |
|
152 |
(sym "_" -- sym "_" >> K (Arg NOBR)) |
|
153 |
|| (sym "_" >> K (Arg BR)) |
|
154 |
|| (sym "?" >> K Ignore) |
|
155 |
|| (sym "/" |-- Scan.repeat (sym " ") >> (Pretty o Pretty.brk o length)) |
|
156 |
|| Scan.depend (fn ctxt => $$ "{" |-- $$ "*" |-- Scan.repeat1 |
|
157 |
( $$ "'" |-- Scan.one Symbol.not_eof |
|
158 |
|| Scan.unless ($$ "*" -- $$ "}") (Scan.one Symbol.not_eof)) --| |
|
159 |
$$ "*" --| $$ "}" >> (implode #> lift_reader ctxt #> swap)) |
|
160 |
|| (Scan.repeat1 |
|
161 |
( sym "'" |-- sym_any |
|
162 |
|| Scan.unless (sym "_" || sym "?" || sym "/" || sym "{" |-- sym "*") |
|
163 |
sym_any) >> (Pretty o str o implode))); |
|
164 |
in case Scan.finite' Symbol.stopper parse (ctxt, Symbol.explode s) |
|
165 |
of (p, (ctxt, [])) => (p, ctxt) |
|
166 |
| _ => error ("Malformed mixfix annotation: " ^ quote s) |
|
167 |
end; |
|
168 |
||
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
169 |
fun parse_nonatomic_mixfix reader s ctxt = |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
170 |
case parse_mixfix reader s ctxt |
18865 | 171 |
of ([Pretty _], _) => |
20389 | 172 |
error ("Mixfix contains just one pretty element; either declare as " |
18865 | 173 |
^ quote atomK ^ " or consider adding a break") |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
174 |
| x => x; |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
175 |
|
18702 | 176 |
fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- ( |
18865 | 177 |
OuterParse.$$$ infixK |-- OuterParse.nat |
178 |
>> (fn i => (parse_infix (INFX (i, X)), INFX (i, X))) |
|
179 |
|| OuterParse.$$$ infixlK |-- OuterParse.nat |
|
180 |
>> (fn i => (parse_infix (INFX (i, L)), INFX (i, L))) |
|
181 |
|| OuterParse.$$$ infixrK |-- OuterParse.nat |
|
182 |
>> (fn i => (parse_infix (INFX (i, R)), INFX (i, R))) |
|
18702 | 183 |
|| OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR) |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
184 |
|| pair (parse_nonatomic_mixfix reader, BR) |
18702 | 185 |
) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy)); |
18282 | 186 |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
187 |
fun parse_syntax no_args reader = |
18335 | 188 |
let |
18702 | 189 |
fun is_arg (Arg _) = true |
190 |
| is_arg Ignore = true |
|
191 |
| is_arg _ = false; |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
192 |
fun mk fixity mfx ctxt = |
18702 | 193 |
let |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
194 |
val i = (length o List.filter is_arg) mfx; |
20389 | 195 |
val _ = if i > no_args ctxt then error "Too many arguments in codegen syntax" else (); |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
196 |
in (((i, i), fillin_mixfix fixity mfx), ctxt) end; |
18702 | 197 |
in |
198 |
parse_syntax_proto reader |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
199 |
#-> (fn (mfx_reader, fixity) => |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
200 |
pair (mfx_reader #-> (fn mfx => mk fixity mfx)) |
18702 | 201 |
) |
202 |
end; |
|
203 |
||
204 |
||
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
205 |
(* generic abstract serializer *) |
18282 | 206 |
|
20191 | 207 |
type serializer = |
18702 | 208 |
string list list |
18756 | 209 |
-> OuterParse.token list -> |
18865 | 210 |
((string -> string option) |
18963 | 211 |
* (string -> itype pretty_syntax option) |
20105 | 212 |
* (string -> iterm pretty_syntax option) |
19884 | 213 |
-> string list * string list option |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
214 |
-> CodegenThingol.module -> unit) |
18756 | 215 |
* OuterParse.token list; |
18702 | 216 |
|
18919 | 217 |
fun abstract_serializer (target, nspgrp) name_root (from_defs, from_module, validator, postproc) |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
218 |
postprocess (class_syntax, tyco_syntax, const_syntax) |
19884 | 219 |
(drop: string list, select) module = |
18702 | 220 |
let |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
221 |
fun from_module' resolv imps ((name_qual, name), defs) = |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
222 |
from_module resolv imps ((name_qual, name), defs) |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
223 |
|> postprocess (resolv name_qual); |
18702 | 224 |
in |
225 |
module |
|
20191 | 226 |
|> debug_msg (fn _ => "dropping shadowed defintions...") |
227 |
|> CodegenThingol.delete_garbage drop |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
228 |
|> debug_msg (fn _ => "selecting submodule...") |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
229 |
|> (if is_some select then (CodegenThingol.project_module o the) select else I) |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
230 |
|> debug_msg (fn _ => "serializing...") |
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
231 |
|> CodegenThingol.serialize (from_defs (class_syntax : string -> string option, tyco_syntax, const_syntax)) |
18919 | 232 |
from_module' validator postproc nspgrp name_root |
18850 | 233 |
|> K () |
18702 | 234 |
end; |
235 |
||
236 |
fun abstract_validator keywords name = |
|
237 |
let |
|
20203 | 238 |
fun replace_invalid c = (* FIXME *) |
239 |
if Symbol.is_ascii_letter c orelse Symbol.is_ascii_digit c orelse c = "'" |
|
18702 | 240 |
andalso not (NameSpace.separator = c) |
241 |
then c |
|
242 |
else "_" |
|
20191 | 243 |
fun suffix_it name= |
18702 | 244 |
name |
245 |
|> member (op =) keywords ? suffix "'" |
|
246 |
|> (fn name' => if name = name' then name else suffix_it name') |
|
247 |
in |
|
248 |
name |
|
249 |
|> translate_string replace_invalid |
|
250 |
|> suffix_it |
|
251 |
|> (fn name' => if name = name' then NONE else SOME name') |
|
252 |
end; |
|
253 |
||
18850 | 254 |
fun write_file mkdir path p = ( |
255 |
if mkdir |
|
256 |
then |
|
257 |
File.mkdir (Path.dir path) |
|
258 |
else (); |
|
259 |
File.write path (Pretty.output p ^ "\n"); |
|
260 |
p |
|
261 |
); |
|
262 |
||
263 |
fun mk_module_file postprocess_module ext path name p = |
|
264 |
let |
|
265 |
val prfx = Path.dir path; |
|
266 |
val name' = case name |
|
267 |
of "" => Path.base path |
|
268 |
| _ => (Path.ext ext o Path.unpack o implode o separate "/" o NameSpace.unpack) name; |
|
269 |
in |
|
270 |
p |
|
271 |
|> write_file true (Path.append prfx name') |
|
272 |
|> postprocess_module name |
|
273 |
end; |
|
274 |
||
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
275 |
fun constructive_fun is_cons (name, (eqs, ty)) = |
19202 | 276 |
let |
277 |
fun check_eq (eq as (lhs, rhs)) = |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
278 |
if forall (CodegenThingol.is_pat is_cons) lhs |
19202 | 279 |
then SOME eq |
20389 | 280 |
else (warning ("In function " ^ quote name ^ ", throwing away one " |
19202 | 281 |
^ "non-executable function clause"); NONE) |
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
282 |
in case map_filter check_eq eqs |
20389 | 283 |
of [] => error ("In function " ^ quote name ^ ", no " |
19202 | 284 |
^ "executable function clauses found") |
285 |
| eqs => (name, (eqs, ty)) |
|
286 |
end; |
|
287 |
||
18756 | 288 |
fun parse_single_file serializer = |
18850 | 289 |
OuterParse.path |
290 |
>> (fn path => serializer |
|
291 |
(fn "" => write_file false path #> K NONE |
|
292 |
| _ => SOME)); |
|
293 |
||
294 |
fun parse_multi_file postprocess_module ext serializer = |
|
295 |
OuterParse.path |
|
296 |
>> (fn path => (serializer o mk_module_file postprocess_module ext) path); |
|
18702 | 297 |
|
18756 | 298 |
fun parse_internal serializer = |
299 |
OuterParse.name |
|
18850 | 300 |
>> (fn "-" => serializer |
301 |
(fn "" => (fn p => (use_text Context.ml_output false (Pretty.output p); NONE)) |
|
302 |
| _ => SOME) |
|
18756 | 303 |
| _ => Scan.fail ()); |
18702 | 304 |
|
20105 | 305 |
fun parse_stdout serializer = |
306 |
OuterParse.name |
|
307 |
>> (fn "_" => serializer |
|
308 |
(fn "" => (fn p => (Pretty.writeln p; NONE)) |
|
309 |
| _ => SOME) |
|
310 |
| _ => Scan.fail ()); |
|
18282 | 311 |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
312 |
|
20401 | 313 |
(* list and string serializers *) |
314 |
||
315 |
fun implode_list c_nil c_cons e = |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
316 |
let |
19202 | 317 |
fun dest_cons (IConst (c, _) `$ e1 `$ e2) = |
20401 | 318 |
if c = c_cons |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
319 |
then SOME (e1, e2) |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
320 |
else NONE |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
321 |
| dest_cons _ = NONE; |
20401 | 322 |
val (es, e') = CodegenThingol.unfoldr dest_cons e; |
323 |
in case e' |
|
324 |
of IConst (c, _) => if c = c_nil then SOME es else NONE |
|
325 |
| _ => NONE |
|
326 |
end; |
|
327 |
||
328 |
fun implode_string mk_char mk_string es = |
|
329 |
if forall (fn IChar _ => true | _ => false) es |
|
330 |
then (SOME o str o mk_string o implode o map (fn IChar (c, _) => mk_char c)) es |
|
331 |
else NONE; |
|
332 |
||
333 |
fun pretty_ml_string c_nil c_cons mk_char mk_string target_implode = |
|
334 |
let |
|
335 |
fun pretty fxy pr [e] = |
|
336 |
case implode_list c_nil c_cons e |
|
337 |
of SOME es => (case implode_string mk_char mk_string es |
|
338 |
of SOME p => p |
|
339 |
| NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e]) |
|
340 |
| NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e] |
|
341 |
in ((1, 1), pretty) end; |
|
342 |
||
343 |
fun pretty_list c_nil c_cons mk_list mk_char_string (target_fxy, target_cons) = |
|
344 |
let |
|
345 |
fun default fxy pr e1 e2 = |
|
346 |
brackify_infix (target_fxy, R) fxy [ |
|
347 |
pr (INFX (target_fxy, X)) e1, |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
348 |
str target_cons, |
20401 | 349 |
pr (INFX (target_fxy, R)) e2 |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
350 |
]; |
20401 | 351 |
fun pretty fxy pr [e1, e2] = |
352 |
case Option.map (cons e1) (implode_list c_nil c_cons e2) |
|
353 |
of SOME es => |
|
354 |
(case mk_char_string |
|
355 |
of SOME (mk_char, mk_string) => |
|
356 |
(case implode_string mk_char mk_string es |
|
357 |
of SOME p => p |
|
358 |
| NONE => mk_list (map (pr NOBR) es)) |
|
359 |
| NONE => mk_list (map (pr NOBR) es)) |
|
360 |
| NONE => default fxy pr e1 e2; |
|
361 |
in ((2, 2), pretty) end; |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
362 |
|
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
363 |
|
18216 | 364 |
|
365 |
(** ML serializer **) |
|
366 |
||
367 |
local |
|
368 |
||
19150 | 369 |
val reserved_ml = ThmDatabase.ml_reserved @ [ |
20401 | 370 |
"bool", "int", "list", "unit", "option", "true", "false", "not", "NONE", "SOME", |
371 |
"o", "string", "char", "String", "Term" |
|
372 |
]; |
|
19150 | 373 |
|
374 |
structure NameMangler = NameManglerFun ( |
|
375 |
type ctxt = string list; |
|
376 |
type src = string; |
|
377 |
val ord = string_ord; |
|
20203 | 378 |
fun mk reserved_ml (name, i) = |
379 |
(Symbol.alphanum o NameSpace.base) name ^ replicate_string i "'"; |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
380 |
fun is_valid (reserved_ml : string list) = not o member (op =) reserved_ml; |
19150 | 381 |
fun maybe_unique _ _ = NONE; |
20389 | 382 |
fun re_mangle _ dst = error ("No such definition name: " ^ quote dst); |
19150 | 383 |
); |
384 |
||
20183 | 385 |
fun ml_expr_seri is_cons (tyco_syntax, const_syntax) resolv = |
18216 | 386 |
let |
18865 | 387 |
val ml_from_label = |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
388 |
str o translate_string (fn "_" => "__" | "." => "_" | c => c) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
389 |
o NameSpace.base o resolv; |
20401 | 390 |
fun ml_from_dictvar v = |
391 |
str (Symbol.to_ascii_upper v ^ "_"); |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
392 |
fun ml_from_tyvar (v, []) = |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
393 |
str "()" |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
394 |
| ml_from_tyvar (v, sort) = |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
395 |
let |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
396 |
fun mk_class class = |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
397 |
str (prefix "'" v ^ " " ^ resolv class); |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
398 |
in |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
399 |
Pretty.block [ |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
400 |
str "(", |
20401 | 401 |
ml_from_dictvar v, |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
402 |
str ":", |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
403 |
case sort |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
404 |
of [class] => mk_class class |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
405 |
| _ => Pretty.enum " *" "" "" (map mk_class sort), |
20191 | 406 |
str ")" |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
407 |
] |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
408 |
end; |
19280
5091dc43817b
slight improvement in serializer, stub for code generator theorems added
haftmann
parents:
19253
diff
changeset
|
409 |
fun ml_from_sortlookup fxy lss = |
18885 | 410 |
let |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
411 |
fun from_label l = |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
412 |
Pretty.block [str "#", |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
413 |
if (is_some o Int.fromString) l then str l |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
414 |
else ml_from_label l |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
415 |
]; |
20401 | 416 |
fun from_lookup fxy [] p = |
417 |
p |
|
418 |
| from_lookup fxy [l] p = |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
419 |
brackify fxy [ |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
420 |
from_label l, |
20401 | 421 |
p |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
422 |
] |
20401 | 423 |
| from_lookup fxy ls p = |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
424 |
brackify fxy [ |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
425 |
Pretty.enum " o" "(" ")" (map from_label ls), |
20401 | 426 |
p |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
427 |
]; |
18885 | 428 |
fun from_classlookup fxy (Instance (inst, lss)) = |
429 |
brackify fxy ( |
|
430 |
(str o resolv) inst |
|
431 |
:: map (ml_from_sortlookup BR) lss |
|
432 |
) |
|
433 |
| from_classlookup fxy (Lookup (classes, (v, ~1))) = |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
434 |
from_lookup BR classes |
20401 | 435 |
(ml_from_dictvar v) |
18885 | 436 |
| from_classlookup fxy (Lookup (classes, (v, i))) = |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
437 |
from_lookup BR (string_of_int (i+1) :: classes) |
20401 | 438 |
(ml_from_dictvar v) |
19280
5091dc43817b
slight improvement in serializer, stub for code generator theorems added
haftmann
parents:
19253
diff
changeset
|
439 |
in case lss |
19253 | 440 |
of [] => str "()" |
19280
5091dc43817b
slight improvement in serializer, stub for code generator theorems added
haftmann
parents:
19253
diff
changeset
|
441 |
| [ls] => from_classlookup fxy ls |
5091dc43817b
slight improvement in serializer, stub for code generator theorems added
haftmann
parents:
19253
diff
changeset
|
442 |
| lss => (Pretty.list "(" ")" o map (from_classlookup NOBR)) lss |
18885 | 443 |
end; |
18963 | 444 |
fun ml_from_tycoexpr fxy (tyco, tys) = |
445 |
let |
|
446 |
val tyco' = (str o resolv) tyco |
|
447 |
in case map (ml_from_type BR) tys |
|
448 |
of [] => tyco' |
|
449 |
| [p] => Pretty.block [p, Pretty.brk 1, tyco'] |
|
450 |
| (ps as _::_) => Pretty.block [Pretty.list "(" ")" ps, Pretty.brk 1, tyco'] |
|
451 |
end |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
452 |
and ml_from_type fxy (tycoexpr as tyco `%% tys) = |
18702 | 453 |
(case tyco_syntax tyco |
18963 | 454 |
of NONE => ml_from_tycoexpr fxy (tyco, tys) |
18702 | 455 |
| SOME ((i, k), pr) => |
456 |
if not (i <= length tys andalso length tys <= k) |
|
20389 | 457 |
then error ("Number of argument mismatch in customary serialization: " |
18865 | 458 |
^ (string_of_int o length) tys ^ " given, " |
459 |
^ string_of_int i ^ " to " ^ string_of_int k |
|
18702 | 460 |
^ " expected") |
461 |
else pr fxy ml_from_type tys) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
462 |
| ml_from_type fxy (t1 `-> t2) = |
18216 | 463 |
let |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
464 |
val brackify = gen_brackify |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
465 |
(case fxy |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
466 |
of BR => false |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
467 |
| _ => eval_fxy (INFX (1, R)) fxy) o Pretty.breaks; |
18216 | 468 |
in |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
469 |
brackify [ |
18702 | 470 |
ml_from_type (INFX (1, X)) t1, |
471 |
str "->", |
|
472 |
ml_from_type (INFX (1, R)) t2 |
|
473 |
] |
|
18216 | 474 |
end |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
475 |
| ml_from_type fxy (ITyVar v) = |
18885 | 476 |
str ("'" ^ v); |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
477 |
fun ml_from_expr fxy (e as IConst x) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
478 |
ml_from_app fxy (x, []) |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
479 |
| ml_from_expr fxy (IVar v) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
480 |
str v |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
481 |
| ml_from_expr fxy (e as e1 `$ e2) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
482 |
(case CodegenThingol.unfold_const_app e |
18885 | 483 |
of SOME x => ml_from_app fxy x |
18865 | 484 |
| NONE => |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
485 |
brackify fxy [ |
18885 | 486 |
ml_from_expr NOBR e1, |
487 |
ml_from_expr BR e2 |
|
18216 | 488 |
]) |
20105 | 489 |
| ml_from_expr fxy (e as _ `|-> _) = |
490 |
let |
|
491 |
val (es, be) = CodegenThingol.unfold_abs e; |
|
492 |
fun mk_abs (e, ty) = (Pretty.block o Pretty.breaks) [ |
|
493 |
str "fn", |
|
20183 | 494 |
ml_from_expr NOBR e, |
20105 | 495 |
str "=>" |
496 |
]; |
|
497 |
in brackify BR (map mk_abs es @ [ml_from_expr NOBR be]) end |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
498 |
| ml_from_expr fxy (INum (n, _)) = |
19213 | 499 |
brackify BR [ |
19202 | 500 |
(str o IntInf.toString) n, |
19884 | 501 |
str ":", |
502 |
str "IntInf.int" |
|
19202 | 503 |
] |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
504 |
| ml_from_expr _ (IChar (c, _)) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
505 |
(str o prefix "#" o quote) |
20203 | 506 |
(let val i = ord c |
20191 | 507 |
in if i < 32 |
20105 | 508 |
then prefix "\\" (string_of_int i) |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
509 |
else c |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
510 |
end) |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
511 |
| ml_from_expr fxy (e as ICase ((_, [_]), _)) = |
18216 | 512 |
let |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
513 |
val (ves, be) = CodegenThingol.unfold_let e; |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
514 |
fun mk_val ((ve, vty), se) = Pretty.block [ |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
515 |
(Pretty.block o Pretty.breaks) [ |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
516 |
str "val", |
20191 | 517 |
ml_from_expr NOBR ve, |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
518 |
str "=", |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
519 |
ml_from_expr NOBR se |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
520 |
], |
18702 | 521 |
str ";" |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
522 |
]; |
18216 | 523 |
in Pretty.chunks [ |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
524 |
[str ("let"), Pretty.fbrk, map mk_val ves |> Pretty.chunks] |> Pretty.block, |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
525 |
[str ("in"), Pretty.fbrk, ml_from_expr NOBR be] |> Pretty.block, |
18702 | 526 |
str ("end") |
18216 | 527 |
] end |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
528 |
| ml_from_expr fxy (ICase (((de, dty), bse::bses), _)) = |
18216 | 529 |
let |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
530 |
fun mk_clause definer (se, be) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
531 |
(Pretty.block o Pretty.breaks) [ |
18702 | 532 |
str definer, |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
533 |
ml_from_expr NOBR se, |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
534 |
str "=>", |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
535 |
ml_from_expr NOBR be |
18216 | 536 |
] |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
537 |
in brackify fxy ( |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
538 |
str "(case" |
20183 | 539 |
:: ml_from_expr NOBR de |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
540 |
:: mk_clause "of" bse |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
541 |
:: map (mk_clause "|") bses |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
542 |
@ [str ")"] |
18216 | 543 |
) end |
18885 | 544 |
| ml_from_expr _ e = |
20389 | 545 |
error ("Dubious expression: " ^ (Pretty.output o CodegenThingol.pretty_iterm) e) |
18885 | 546 |
and ml_mk_app f es = |
19136 | 547 |
if is_cons f andalso length es > 1 then |
19038 | 548 |
[(str o resolv) f, Pretty.enum "," "(" ")" (map (ml_from_expr BR) es)] |
18702 | 549 |
else |
18885 | 550 |
(str o resolv) f :: map (ml_from_expr BR) es |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
551 |
and ml_from_app fxy (app_expr as ((c, (lss, ty)), es)) = |
18885 | 552 |
case map (ml_from_sortlookup BR) lss |
553 |
of [] => |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
554 |
from_app ml_mk_app ml_from_expr const_syntax fxy app_expr |
18885 | 555 |
| lss => |
556 |
brackify fxy ( |
|
557 |
(str o resolv) c |
|
558 |
:: (lss |
|
559 |
@ map (ml_from_expr BR) es) |
|
560 |
); |
|
20183 | 561 |
in (ml_from_label, ml_from_tyvar, ml_from_sortlookup, ml_from_tycoexpr, ml_from_type, ml_from_expr) end; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
562 |
|
20183 | 563 |
fun ml_fun_datatyp is_cons (tyco_syntax, const_syntax) resolv = |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
564 |
let |
20183 | 565 |
val (ml_from_label, ml_from_tyvar, ml_from_sortlookup, ml_from_tycoexpr, ml_from_type, ml_from_expr) = |
566 |
ml_expr_seri is_cons (tyco_syntax, const_syntax) resolv; |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
567 |
fun chunk_defs ps = |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
568 |
let |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
569 |
val (p_init, p_last) = split_last ps |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
570 |
in |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
571 |
Pretty.chunks (p_init @ [Pretty.block ([p_last, str ";"])]) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
572 |
end; |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
573 |
fun eta_expand_poly_fun (funn as (_, (_::_, _))) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
574 |
funn |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
575 |
| eta_expand_poly_fun (funn as (eqs, sctxt_ty as (_, ty))) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
576 |
let |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
577 |
fun no_eta (_::_, _) = I |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
578 |
| no_eta (_, _ `|-> _) = I |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
579 |
| no_eta ([], e) = K false; |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
580 |
fun has_tyvars (_ `%% tys) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
581 |
exists has_tyvars tys |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
582 |
| has_tyvars (ITyVar _) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
583 |
true |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
584 |
| has_tyvars (ty1 `-> ty2) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
585 |
has_tyvars ty1 orelse has_tyvars ty2; |
19622 | 586 |
in if (null o fst o CodegenThingol.unfold_fun) ty |
587 |
orelse (not o has_tyvars) ty |
|
588 |
orelse fold no_eta eqs true |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
589 |
then funn |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
590 |
else (map (fn ([], rhs) => ([IVar "x"], rhs `$ IVar "x")) eqs, sctxt_ty) |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
591 |
end; |
18912 | 592 |
fun ml_from_funs (defs as def::defs_tl) = |
18216 | 593 |
let |
19213 | 594 |
fun mk_definer [] [] = "val" |
595 |
| mk_definer _ _ = "fun"; |
|
596 |
fun check_args (_, ((pats, _)::_, (sortctxt, _))) NONE = |
|
597 |
SOME (mk_definer pats sortctxt) |
|
598 |
| check_args (_, ((pats, _)::_, (sortctxt, _))) (SOME definer) = |
|
599 |
if mk_definer pats sortctxt = definer |
|
18216 | 600 |
then SOME definer |
20389 | 601 |
else error ("Mixing simultaneous vals and funs not implemented"); |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
602 |
fun mk_fun definer (name, (eqs as eq::eq_tl, (sortctxt, ty))) = |
18216 | 603 |
let |
19136 | 604 |
val shift = if null eq_tl then I else |
605 |
map (Pretty.block o single o Pretty.block o single); |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
606 |
fun mk_arg e ty = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
607 |
ml_from_expr BR e |
18912 | 608 |
fun mk_eq definer (pats, expr) = |
609 |
(Pretty.block o Pretty.breaks) ( |
|
610 |
[str definer, (str o resolv) name] |
|
19213 | 611 |
@ (if null pats andalso null sortctxt |
18912 | 612 |
then [str ":", ml_from_type NOBR ty] |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
613 |
else |
19213 | 614 |
map ml_from_tyvar sortctxt |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
615 |
@ map2 mk_arg pats |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
616 |
((curry Library.take (length pats) o fst o CodegenThingol.unfold_fun) ty)) |
20191 | 617 |
@ [str "=", ml_from_expr NOBR expr] |
18912 | 618 |
) |
18216 | 619 |
in |
18912 | 620 |
(Pretty.block o Pretty.fbreaks o shift) ( |
621 |
mk_eq definer eq |
|
622 |
:: map (mk_eq "|") eq_tl |
|
623 |
) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
624 |
end; |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
625 |
val def' :: defs' = map (apsnd eta_expand_poly_fun o constructive_fun is_cons) defs |
18216 | 626 |
in |
627 |
chunk_defs ( |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
628 |
(mk_fun (the (fold check_args defs NONE))) def' |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
629 |
:: map (mk_fun "and") defs' |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
630 |
) |
18216 | 631 |
end; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
632 |
fun ml_from_datatypes (defs as (def::defs_tl)) = |
18216 | 633 |
let |
18702 | 634 |
fun mk_cons (co, []) = |
635 |
str (resolv co) |
|
636 |
| mk_cons (co, tys) = |
|
19136 | 637 |
Pretty.block [ |
638 |
str (resolv co), |
|
639 |
str " of", |
|
640 |
Pretty.brk 1, |
|
641 |
Pretty.enum " *" "" "" (map (ml_from_type NOBR) tys) |
|
642 |
] |
|
19038 | 643 |
fun mk_datatype definer (t, (vs, cs)) = |
18912 | 644 |
(Pretty.block o Pretty.breaks) ( |
18702 | 645 |
str definer |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
646 |
:: ml_from_tycoexpr NOBR (t, map (ITyVar o fst) vs) |
18912 | 647 |
:: str "=" |
648 |
:: separate (str "|") (map mk_cons cs) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
649 |
) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
650 |
in |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
651 |
chunk_defs ( |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
652 |
mk_datatype "datatype" def |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
653 |
:: map (mk_datatype "and") defs_tl |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
654 |
) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
655 |
end; |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
656 |
in (ml_from_funs, ml_from_datatypes) end; |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
657 |
|
20183 | 658 |
fun ml_from_defs is_cons |
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
659 |
(_, tyco_syntax, const_syntax) resolver prefix defs = |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
660 |
let |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
661 |
val resolv = resolver prefix; |
20183 | 662 |
val (ml_from_label, ml_from_tyvar, ml_from_sortlookup, ml_from_tycoexpr, ml_from_type, ml_from_expr) = |
663 |
ml_expr_seri is_cons (tyco_syntax, const_syntax) resolv; |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
664 |
val (ml_from_funs, ml_from_datatypes) = |
20183 | 665 |
ml_fun_datatyp is_cons (tyco_syntax, const_syntax) resolv; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
666 |
val filter_datatype = |
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
667 |
map_filter |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
668 |
(fn (name, CodegenThingol.Datatype info) => SOME (name, info) |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
669 |
| (name, CodegenThingol.Datatypecons _) => NONE |
20389 | 670 |
| (name, def) => error ("Datatype block containing illegal def: " |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
671 |
^ (Pretty.output o CodegenThingol.pretty_def) def)); |
20191 | 672 |
fun filter_class defs = |
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
673 |
case map_filter |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
674 |
(fn (name, CodegenThingol.Class info) => SOME (name, info) |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
675 |
| (name, CodegenThingol.Classmember _) => NONE |
20389 | 676 |
| (name, def) => error ("Class block containing illegal def: " |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
677 |
^ (Pretty.output o CodegenThingol.pretty_def) def)) defs |
19136 | 678 |
of [class] => class |
20389 | 679 |
| _ => error ("Class block without class: " ^ (commas o map (quote o fst)) defs) |
19136 | 680 |
fun ml_from_class (name, (supclasses, (v, membrs))) = |
681 |
let |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
682 |
val w = (Char.toString o Char.toUpper o the o Char.fromString) v; |
19136 | 683 |
fun from_supclass class = |
684 |
Pretty.block [ |
|
685 |
ml_from_label class, |
|
686 |
str ":", |
|
687 |
Pretty.brk 1, |
|
688 |
str ("'" ^ v), |
|
689 |
Pretty.brk 1, |
|
690 |
(str o resolv) class |
|
691 |
]; |
|
692 |
fun from_membr (m, (_, ty)) = |
|
693 |
Pretty.block [ |
|
694 |
ml_from_label m, |
|
695 |
str ":", |
|
696 |
Pretty.brk 1, |
|
697 |
ml_from_type NOBR ty |
|
698 |
]; |
|
699 |
fun from_membr_fun (m, _) = |
|
700 |
(Pretty.block o Pretty.breaks) [ |
|
701 |
str "fun", |
|
20191 | 702 |
(str o resolv) m, |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
703 |
Pretty.enclose "(" ")" [str (w ^ ":'" ^ v ^ " " ^ resolv name)], |
19136 | 704 |
str "=", |
705 |
Pretty.block [str "#", ml_from_label m], |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
706 |
str (w ^ ";") |
19136 | 707 |
]; |
708 |
in |
|
709 |
Pretty.chunks ( |
|
710 |
(Pretty.block o Pretty.breaks) [ |
|
711 |
str "type", |
|
712 |
str ("'" ^ v), |
|
713 |
(str o resolv) name, |
|
714 |
str "=", |
|
715 |
Pretty.enum "," "{" "};" ( |
|
716 |
map from_supclass supclasses @ map from_membr membrs |
|
717 |
) |
|
718 |
] |
|
719 |
:: map from_membr_fun membrs) |
|
720 |
end |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
721 |
fun ml_from_def (name, CodegenThingol.Typesyn (vs, ty)) = |
18865 | 722 |
(map (fn (vname, []) => () | _ => |
20389 | 723 |
error "Can't serialize sort constrained type declaration to ML") vs; |
18702 | 724 |
Pretty.block [ |
725 |
str "type ", |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
726 |
ml_from_tycoexpr NOBR (name, map (ITyVar o fst) vs), |
18702 | 727 |
str " =", |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
728 |
Pretty.brk 1, |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
729 |
ml_from_type NOBR ty, |
18702 | 730 |
str ";" |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
731 |
] |
20191 | 732 |
) |> SOME |
20389 | 733 |
| ml_from_def (name, CodegenThingol.Classinst ((class, (tyco, arity)), (suparities, memdefs))) = |
18865 | 734 |
let |
735 |
val definer = if null arity then "val" else "fun" |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
736 |
fun from_supclass (supclass, ls) = |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
737 |
(Pretty.block o Pretty.breaks) [ |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
738 |
ml_from_label supclass, |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
739 |
str "=", |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
740 |
ml_from_sortlookup NOBR ls |
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
741 |
]; |
20389 | 742 |
fun from_memdef (m, e) = |
743 |
(Pretty.block o Pretty.breaks) [ |
|
744 |
ml_from_label m, |
|
745 |
str "=", |
|
746 |
ml_from_expr NOBR e |
|
747 |
]; |
|
19253 | 748 |
fun mk_corp rhs = |
749 |
(Pretty.block o Pretty.breaks) ( |
|
750 |
str definer |
|
751 |
:: (str o resolv) name |
|
752 |
:: map ml_from_tyvar arity |
|
753 |
@ [str "=", rhs] |
|
754 |
); |
|
20389 | 755 |
fun mk_memdefs supclassexprs memdefs = |
756 |
(mk_corp o Pretty.block o Pretty.breaks) [ |
|
757 |
Pretty.enum "," "{" "}" (supclassexprs @ memdefs), |
|
758 |
str ":", |
|
759 |
ml_from_tycoexpr NOBR (class, [tyco `%% map (ITyVar o fst) arity]) |
|
760 |
]; |
|
18865 | 761 |
in |
20389 | 762 |
mk_memdefs (map from_supclass suparities) (map from_memdef memdefs) |> SOME |
19213 | 763 |
end |
20389 | 764 |
| ml_from_def (name, def) = error ("Illegal definition for " ^ quote name ^ ": " ^ |
20353 | 765 |
(Pretty.output o CodegenThingol.pretty_def) def); |
18850 | 766 |
in case defs |
20353 | 767 |
of (_, CodegenThingol.Fun _)::_ => ((*writeln "FUN";*) (SOME o ml_from_funs o map (fn (name, CodegenThingol.Fun info) => (name, info))) defs) |
768 |
| (_, CodegenThingol.Datatypecons _)::_ => ((*writeln "DTCO";*) (SOME o ml_from_datatypes o filter_datatype) defs) |
|
769 |
| (_, CodegenThingol.Datatype _)::_ => ((*writeln "DT";*) (SOME o ml_from_datatypes o filter_datatype) defs) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
770 |
| (_, CodegenThingol.Class _)::_ => (SOME o ml_from_class o filter_class) defs |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
771 |
| (_, CodegenThingol.Classmember _)::_ => (SOME o ml_from_class o filter_class) defs |
18850 | 772 |
| [def] => ml_from_def def |
20389 | 773 |
| defs => error ("Illegal mutual dependencies: " ^ (commas o map fst) defs) |
18216 | 774 |
end; |
775 |
||
20183 | 776 |
fun ml_annotators nsp_dtcon = |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
777 |
let |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
778 |
fun is_cons c = CodegenThingol.has_nsp c nsp_dtcon; |
20183 | 779 |
in is_cons end; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
780 |
|
20191 | 781 |
fun ml_serializer root_name target nsp_dtcon nspgrp = |
18216 | 782 |
let |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
783 |
fun ml_from_module resolv _ ((_, name), ps) = |
18756 | 784 |
Pretty.chunks ([ |
18702 | 785 |
str ("structure " ^ name ^ " = "), |
786 |
str "struct", |
|
787 |
str "" |
|
788 |
] @ separate (str "") ps @ [ |
|
789 |
str "", |
|
790 |
str ("end; (* struct " ^ name ^ " *)") |
|
18756 | 791 |
]); |
20183 | 792 |
val is_cons = ml_annotators nsp_dtcon; |
20401 | 793 |
fun postproc (shallow, n) = |
794 |
let |
|
795 |
fun ch_first f = String.implode o nth_map 0 f o String.explode; |
|
796 |
in if shallow = nsp_dtcon |
|
797 |
then ch_first Char.toUpper n |
|
798 |
else n |
|
799 |
end; |
|
20191 | 800 |
in abstract_serializer (target, nspgrp) |
801 |
root_name (ml_from_defs is_cons, ml_from_module, |
|
20401 | 802 |
abstract_validator reserved_ml, postproc) end; |
20191 | 803 |
|
804 |
in |
|
805 |
||
806 |
fun ml_from_thingol target nsp_dtcon nspgrp = |
|
807 |
let |
|
808 |
val serializer = ml_serializer "ROOT" target nsp_dtcon nspgrp |
|
18850 | 809 |
val parse_multi = |
810 |
OuterParse.name |
|
20191 | 811 |
#-> (fn "dir" => |
18850 | 812 |
parse_multi_file |
813 |
(K o SOME o str o suffix ";" o prefix "val _ = use " |
|
814 |
o quote o suffix ".ML" o translate_string (fn "." => "/" | s => s)) "ML" serializer |
|
815 |
| _ => Scan.fail ()); |
|
18282 | 816 |
in |
19884 | 817 |
parse_multi |
818 |
|| parse_internal serializer |
|
20105 | 819 |
|| parse_stdout serializer |
19884 | 820 |
|| parse_single_file serializer |
18216 | 821 |
end; |
822 |
||
20389 | 823 |
val eval_verbose = ref false; |
824 |
||
20216 | 825 |
fun eval_term nsp_eval nsp_dtcon nspgrp (syntax_tyco, syntax_const) hidden ((ref_name, reff), e) modl = |
20191 | 826 |
let |
20216 | 827 |
val (val_name, modl') = CodegenThingol.add_eval_def (nsp_eval, e) modl; |
20191 | 828 |
val struct_name = "EVAL"; |
20401 | 829 |
fun output p = if !eval_verbose then (Pretty.writeln p; Pretty.output p) |
830 |
else Pretty.output p; |
|
20191 | 831 |
val serializer = ml_serializer struct_name "ml" nsp_dtcon nspgrp |
20401 | 832 |
(fn "" => (fn p => (use_text Context.ml_output (!eval_verbose) (output p); NONE)) |
20216 | 833 |
| _ => SOME) (K NONE, syntax_tyco, syntax_const) (hidden, SOME [NameSpace.pack [nsp_eval, val_name]]); |
20191 | 834 |
val _ = serializer modl'; |
835 |
val val_name_struct = NameSpace.append struct_name val_name; |
|
20389 | 836 |
val _ = use_text Context.ml_output (!eval_verbose) ("val _ = (" ^ ref_name ^ " := " ^ val_name_struct ^ "())"); |
20191 | 837 |
val value = ! reff; |
838 |
in value end; |
|
839 |
||
19150 | 840 |
fun mk_flat_ml_resolver names = |
841 |
let |
|
842 |
val mangler = |
|
843 |
NameMangler.empty |
|
844 |
|> fold_map (NameMangler.declare reserved_ml) names |
|
845 |
|-> (fn _ => I) |
|
846 |
in NameMangler.get reserved_ml mangler end; |
|
847 |
||
20183 | 848 |
fun ml_fun_datatype nsp_dtcon = |
849 |
ml_fun_datatyp (ml_annotators nsp_dtcon); |
|
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
850 |
|
18216 | 851 |
end; (* local *) |
852 |
||
20191 | 853 |
|
854 |
(** haskell serializer **) |
|
855 |
||
18282 | 856 |
local |
857 |
||
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
858 |
fun hs_from_defs (is_cons, with_typs) (class_syntax, tyco_syntax, const_syntax) |
19038 | 859 |
resolver prefix defs = |
18282 | 860 |
let |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
861 |
val resolv = resolver ""; |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
862 |
val resolv_here = resolver prefix; |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
863 |
fun hs_from_sctxt vs = |
18282 | 864 |
let |
18865 | 865 |
fun from_class cls = |
18919 | 866 |
class_syntax cls |
867 |
|> the_default (resolv cls) |
|
18702 | 868 |
fun from_sctxt [] = str "" |
18282 | 869 |
| from_sctxt vs = |
870 |
vs |
|
18919 | 871 |
|> map (fn (v, cls) => str (from_class cls ^ " " ^ v)) |
18812 | 872 |
|> Pretty.enum "," "(" ")" |
18702 | 873 |
|> (fn p => Pretty.block [p, str " => "]) |
20191 | 874 |
in |
18282 | 875 |
vs |
876 |
|> map (fn (v, sort) => map (pair v) sort) |
|
19466 | 877 |
|> flat |
18282 | 878 |
|> from_sctxt |
879 |
end; |
|
18963 | 880 |
fun hs_from_tycoexpr fxy (tyco, tys) = |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
881 |
brackify fxy (str tyco :: map (hs_from_type BR) tys) |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
882 |
and hs_from_type fxy (tycoexpr as tyco `%% tys) = |
18865 | 883 |
(case tyco_syntax tyco |
18335 | 884 |
of NONE => |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
885 |
hs_from_tycoexpr fxy (resolv tyco, tys) |
18702 | 886 |
| SOME ((i, k), pr) => |
18865 | 887 |
if not (i <= length tys andalso length tys <= k) |
20389 | 888 |
then error ("Number of argument mismatch in customary serialization: " |
18865 | 889 |
^ (string_of_int o length) tys ^ " given, " |
890 |
^ string_of_int i ^ " to " ^ string_of_int k |
|
18702 | 891 |
^ " expected") |
18865 | 892 |
else pr fxy hs_from_type tys) |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
893 |
| hs_from_type fxy (t1 `-> t2) = |
18865 | 894 |
brackify_infix (1, R) fxy [ |
895 |
hs_from_type (INFX (1, X)) t1, |
|
896 |
str "->", |
|
897 |
hs_from_type (INFX (1, R)) t2 |
|
898 |
] |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
899 |
| hs_from_type fxy (ITyVar v) = |
18919 | 900 |
str v; |
18963 | 901 |
fun hs_from_sctxt_tycoexpr (sctxt, tycoexpr) = |
902 |
Pretty.block [hs_from_sctxt sctxt, hs_from_tycoexpr NOBR tycoexpr] |
|
18865 | 903 |
fun hs_from_sctxt_type (sctxt, ty) = |
904 |
Pretty.block [hs_from_sctxt sctxt, hs_from_type NOBR ty] |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
905 |
fun hs_from_expr fxy (e as IConst x) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
906 |
hs_from_app fxy (x, []) |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
907 |
| hs_from_expr fxy (e as (e1 `$ e2)) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
908 |
(case CodegenThingol.unfold_const_app e |
18865 | 909 |
of SOME x => hs_from_app fxy x |
18282 | 910 |
| _ => |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
911 |
brackify fxy [ |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
912 |
hs_from_expr NOBR e1, |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
913 |
hs_from_expr BR e2 |
18282 | 914 |
]) |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
915 |
| hs_from_expr fxy (IVar v) = |
20175 | 916 |
str v |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
917 |
| hs_from_expr fxy (e as _ `|-> _) = |
18282 | 918 |
let |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
919 |
val (es, e) = CodegenThingol.unfold_abs e |
18282 | 920 |
in |
19038 | 921 |
brackify BR ( |
18702 | 922 |
str "\\" |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
923 |
:: map (hs_from_expr BR o fst) es @ [ |
18702 | 924 |
str "->", |
19038 | 925 |
hs_from_expr NOBR e |
18282 | 926 |
]) |
927 |
end |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
928 |
| hs_from_expr fxy (INum (n, _)) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
929 |
(str o IntInf.toString) n |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
930 |
| hs_from_expr fxy (IChar (c, _)) = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
931 |
(str o enclose "'" "'") |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
932 |
(let val i = (Char.ord o the o Char.fromString) c |
20191 | 933 |
in if i < 32 |
20105 | 934 |
then Library.prefix "\\" (string_of_int i) |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
935 |
else c |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
936 |
end) |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
937 |
| hs_from_expr fxy (e as ICase ((_, [_]), _)) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
938 |
let |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
939 |
val (ps, body) = CodegenThingol.unfold_let e; |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
940 |
fun mk_bind ((p, _), e) = (Pretty.block o Pretty.breaks) [ |
18865 | 941 |
hs_from_expr BR p, |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
942 |
str "=", |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
943 |
hs_from_expr NOBR e |
18282 | 944 |
]; |
945 |
in Pretty.chunks [ |
|
18702 | 946 |
[str ("let"), Pretty.fbrk, map mk_bind ps |> Pretty.chunks] |> Pretty.block, |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
947 |
[str ("in "), hs_from_expr NOBR body] |> Pretty.block |
18282 | 948 |
] end |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
949 |
| hs_from_expr fxy (ICase (((de, _), bses), _)) = |
18282 | 950 |
let |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
951 |
fun mk_clause (se, be) = |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
952 |
(Pretty.block o Pretty.breaks) [ |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
953 |
hs_from_expr NOBR se, |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
954 |
str "->", |
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
955 |
hs_from_expr NOBR be |
18282 | 956 |
] |
18850 | 957 |
in Pretty.block [ |
958 |
str "case", |
|
959 |
Pretty.brk 1, |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
960 |
hs_from_expr NOBR de, |
18850 | 961 |
Pretty.brk 1, |
962 |
str "of", |
|
963 |
Pretty.fbrk, |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
964 |
(Pretty.chunks o map mk_clause) bses |
18850 | 965 |
] end |
18865 | 966 |
and hs_mk_app c es = |
18919 | 967 |
(str o resolv) c :: map (hs_from_expr BR) es |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
968 |
and hs_from_app fxy = |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
969 |
from_app hs_mk_app hs_from_expr const_syntax fxy |
19202 | 970 |
fun hs_from_funeqs (def as (name, _)) = |
18865 | 971 |
let |
19202 | 972 |
fun from_eq (args, rhs) = |
18865 | 973 |
Pretty.block [ |
19038 | 974 |
(str o resolv_here) name, |
18865 | 975 |
Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args), |
976 |
Pretty.brk 1, |
|
977 |
str ("="), |
|
978 |
Pretty.brk 1, |
|
979 |
hs_from_expr NOBR rhs |
|
980 |
] |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
981 |
in Pretty.chunks ((map from_eq o fst o snd o constructive_fun is_cons) def) end; |
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
982 |
fun hs_from_def (name, CodegenThingol.Fun (def as (_, (sctxt, ty)))) = |
18963 | 983 |
let |
19202 | 984 |
val body = hs_from_funeqs (name, def); |
18963 | 985 |
in if with_typs then |
986 |
Pretty.chunks [ |
|
987 |
Pretty.block [ |
|
19038 | 988 |
(str o suffix " ::" o resolv_here) name, |
18963 | 989 |
Pretty.brk 1, |
990 |
hs_from_sctxt_type (sctxt, ty) |
|
991 |
], |
|
992 |
body |
|
993 |
] |> SOME |
|
994 |
else SOME body end |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
995 |
| hs_from_def (name, CodegenThingol.Typesyn (sctxt, ty)) = |
20401 | 996 |
(Pretty.block o Pretty.breaks) [ |
997 |
str "type", |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
998 |
hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
20401 | 999 |
str "=", |
18865 | 1000 |
hs_from_sctxt_type ([], ty) |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1001 |
] |> SOME |
20401 | 1002 |
| hs_from_def (name, CodegenThingol.Datatype (sctxt, [(co, [ty])])) = |
20386 | 1003 |
(Pretty.block o Pretty.breaks) [ |
1004 |
str "newtype", |
|
1005 |
hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
|
1006 |
str "=", |
|
20401 | 1007 |
(str o resolv_here) co, |
1008 |
hs_from_type BR ty |
|
20386 | 1009 |
] |> SOME |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
1010 |
| hs_from_def (name, CodegenThingol.Datatype (sctxt, constrs)) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1011 |
let |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1012 |
fun mk_cons (co, tys) = |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1013 |
(Pretty.block o Pretty.breaks) ( |
19038 | 1014 |
(str o resolv_here) co |
19597 | 1015 |
:: map (hs_from_type BR) tys |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1016 |
) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1017 |
in |
19785 | 1018 |
(Pretty.block o Pretty.breaks) [ |
1019 |
str "data", |
|
1020 |
hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19785
diff
changeset
|
1021 |
str "=", |
19785 | 1022 |
Pretty.block (separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs)) |
1023 |
] |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1024 |
end |> SOME |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
1025 |
| hs_from_def (_, CodegenThingol.Datatypecons _) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1026 |
NONE |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
1027 |
| hs_from_def (name, CodegenThingol.Class (supclasss, (v, membrs))) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1028 |
let |
18865 | 1029 |
fun mk_member (m, (sctxt, ty)) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1030 |
Pretty.block [ |
19038 | 1031 |
str (resolv_here m ^ " ::"), |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1032 |
Pretty.brk 1, |
18865 | 1033 |
hs_from_sctxt_type (sctxt, ty) |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1034 |
] |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1035 |
in |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1036 |
Pretty.block [ |
18702 | 1037 |
str "class ", |
19213 | 1038 |
hs_from_sctxt [(v, supclasss)], |
19038 | 1039 |
str (resolv_here name ^ " " ^ v), |
18702 | 1040 |
str " where", |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1041 |
Pretty.fbrk, |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1042 |
Pretty.chunks (map mk_member membrs) |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1043 |
] |> SOME |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1044 |
end |
19213 | 1045 |
| hs_from_def (_, CodegenThingol.Classmember _) = |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1046 |
NONE |
20389 | 1047 |
| hs_from_def (_, CodegenThingol.Classinst ((clsname, (tyco, arity)), (_, memdefs))) = |
18385 | 1048 |
Pretty.block [ |
18702 | 1049 |
str "instance ", |
19213 | 1050 |
hs_from_sctxt arity, |
1051 |
str (resolv clsname ^ " "), |
|
1052 |
hs_from_type BR (tyco `%% map (ITyVar o fst) arity), |
|
18702 | 1053 |
str " where", |
18385 | 1054 |
Pretty.fbrk, |
20389 | 1055 |
Pretty.chunks (map (fn (m, e) => |
1056 |
(Pretty.block o Pretty.breaks) [ |
|
1057 |
(str o NameSpace.base o resolv) m, |
|
1058 |
str "=", |
|
1059 |
hs_from_expr NOBR e |
|
1060 |
] |
|
1061 |
) memdefs) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1062 |
] |> SOME |
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1063 |
in |
19482
9f11af8f7ef9
tuned basic list operators (flat, maps, map_filter);
wenzelm
parents:
19466
diff
changeset
|
1064 |
case map_filter (fn (name, def) => hs_from_def (name, def)) defs |
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1065 |
of [] => NONE |
18702 | 1066 |
| l => (SOME o Pretty.chunks o separate (str "")) l |
18282 | 1067 |
end; |
1068 |
||
1069 |
in |
|
1070 |
||
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
1071 |
fun hs_from_thingol target (nsp_dtcon, nsps_upper) nspgrp = |
18282 | 1072 |
let |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
1073 |
val reserved_hs = [ |
18702 | 1074 |
"hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
1075 |
"import", "default", "forall", "let", "in", "class", "qualified", "data", |
|
1076 |
"newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
|
1077 |
] @ [ |
|
20401 | 1078 |
"Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate", |
1079 |
"String", "Char" |
|
18702 | 1080 |
]; |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
1081 |
fun is_cons c = CodegenThingol.has_nsp c nsp_dtcon; |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19280
diff
changeset
|
1082 |
fun hs_from_module resolv imps ((_, name), ps) = |
19038 | 1083 |
(Pretty.chunks) ( |
1084 |
str ("module " ^ name ^ " where") |
|
1085 |
:: map (str o prefix "import qualified ") imps @ ( |
|
1086 |
str "" |
|
1087 |
:: separate (str "") ps |
|
1088 |
)); |
|
18919 | 1089 |
fun postproc (shallow, n) = |
1090 |
let |
|
1091 |
fun ch_first f = String.implode o nth_map 0 f o String.explode; |
|
1092 |
in if member (op =) nsps_upper shallow |
|
1093 |
then ch_first Char.toUpper n |
|
1094 |
else ch_first Char.toLower n |
|
1095 |
end; |
|
18963 | 1096 |
fun serializer with_typs = abstract_serializer (target, nspgrp) |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19936
diff
changeset
|
1097 |
"Main" (hs_from_defs (is_cons, with_typs), hs_from_module, abstract_validator reserved_hs, postproc); |
18282 | 1098 |
in |
18963 | 1099 |
(Scan.optional (OuterParse.name >> (fn "no_typs" => false | s => Scan.fail_with (fn _ => "illegal flag: " ^ quote s) true)) true |
1100 |
#-> (fn with_typs => parse_multi_file ((K o K) NONE) "hs" (serializer with_typs))) |
|
18282 | 1101 |
end; |
1102 |
||
1103 |
end; (* local *) |
|
1104 |
||
18702 | 1105 |
|
1106 |
(** lookup record **) |
|
1107 |
||
1108 |
val serializers = |
|
1109 |
let |
|
1110 |
fun seri s f = (s, f s); |
|
1111 |
in { |
|
1112 |
ml = seri "ml" ml_from_thingol, |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
1113 |
haskell = seri "haskell" hs_from_thingol |
18702 | 1114 |
} end; |
1115 |
||
18216 | 1116 |
end; (* struct *) |