| author | wenzelm | 
| Sat, 04 Nov 2006 19:25:41 +0100 | |
| changeset 21174 | 4d733b76b5fa | 
| parent 21162 | f982765d71f4 | 
| child 21285 | ee8cafbcb506 | 
| 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
 | 
| 20699 | 6  | 
target languages (like SML 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  | 
| 20456 | 11  | 
include BASIC_CODEGEN_THINGOL;  | 
| 20931 | 12  | 
|
| 20699 | 13  | 
val add_pretty_list: string -> string -> string -> (Pretty.T list -> Pretty.T)  | 
14  | 
-> ((string -> string) * (string -> string)) option -> int * string  | 
|
15  | 
-> theory -> theory;  | 
|
16  | 
val add_pretty_ml_string: string -> string -> string -> string  | 
|
17  | 
-> (string -> string) -> (string -> string) -> string -> theory -> theory;  | 
|
18  | 
val add_undefined: string -> string -> string -> theory -> theory;  | 
|
| 20896 | 19  | 
|
20  | 
type serializer;  | 
|
21  | 
val add_serializer : string * serializer -> theory -> theory;  | 
|
| 21015 | 22  | 
val get_serializer: theory -> string -> Args.T list  | 
| 20931 | 23  | 
-> string list option -> CodegenThingol.code -> unit;  | 
| 21082 | 24  | 
val assert_serializer: theory -> string -> string;  | 
| 20931 | 25  | 
|
26  | 
val const_has_serialization: theory -> string list -> string -> bool;  | 
|
27  | 
val tyco_has_serialization: theory -> string list -> string -> bool;  | 
|
28  | 
||
29  | 
val eval_verbose: bool ref;  | 
|
30  | 
val eval_term: theory ->  | 
|
31  | 
(string * 'a option ref) * CodegenThingol.iterm -> CodegenThingol.code  | 
|
32  | 
-> 'a;  | 
|
| 21067 | 33  | 
val sml_code_width: int ref;  | 
| 
18169
 
45def66f86cb
added modules for code generator generation two, not operational yet
 
haftmann 
parents:  
diff
changeset
 | 
34  | 
end;  | 
| 
 
45def66f86cb
added modules for code generator generation two, not operational yet
 
haftmann 
parents:  
diff
changeset
 | 
35  | 
|
| 
 
45def66f86cb
added modules for code generator generation two, not operational yet
 
haftmann 
parents:  
diff
changeset
 | 
36  | 
structure CodegenSerializer: CODEGEN_SERIALIZER =  | 
| 
 
45def66f86cb
added modules for code generator generation two, not operational yet
 
haftmann 
parents:  
diff
changeset
 | 
37  | 
struct  | 
| 
 
45def66f86cb
added modules for code generator generation two, not operational yet
 
haftmann 
parents:  
diff
changeset
 | 
38  | 
|
| 
19167
 
f237c0cb3882
refined representation of codegen intermediate language
 
haftmann 
parents: 
19150 
diff
changeset
 | 
39  | 
open BasicCodegenThingol;  | 
| 20845 | 40  | 
val tracing = CodegenThingol.tracing;  | 
| 18850 | 41  | 
|
| 20896 | 42  | 
(** syntax **)  | 
43  | 
||
44  | 
(* basics *)  | 
|
| 18702 | 45  | 
|
| 18216 | 46  | 
datatype lrx = L | R | X;  | 
47  | 
||
| 18516 | 48  | 
datatype fixity =  | 
| 18216 | 49  | 
BR  | 
50  | 
| NOBR  | 
|
51  | 
| INFX of (int * lrx);  | 
|
52  | 
||
| 20699 | 53  | 
type 'a pretty_syntax = int * (fixity -> (fixity -> 'a -> Pretty.T)  | 
| 18865 | 54  | 
-> 'a list -> Pretty.T);  | 
| 18516 | 55  | 
|
| 18216 | 56  | 
fun eval_lrx L L = false  | 
57  | 
| eval_lrx R R = false  | 
|
58  | 
| eval_lrx _ _ = true;  | 
|
59  | 
||
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
60  | 
fun eval_fxy NOBR _ = false  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
61  | 
| eval_fxy _ BR = true  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
62  | 
| eval_fxy _ NOBR = false  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
63  | 
| eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) =  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
64  | 
pr < pr_ctxt  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
65  | 
orelse pr = pr_ctxt  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
66  | 
andalso eval_lrx lr lr_ctxt  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
67  | 
| eval_fxy _ (INFX _) = false;  | 
| 18216 | 68  | 
|
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
69  | 
fun gen_brackify _ [p] = p  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
70  | 
  | gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps
 | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
71  | 
| gen_brackify false (ps as _::_) = Pretty.block ps;  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
72  | 
|
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
73  | 
fun brackify fxy_ctxt ps =  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
74  | 
gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps);  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
75  | 
|
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
76  | 
fun brackify_infix infx fxy_ctxt ps =  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
77  | 
gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps);  | 
| 18216 | 78  | 
|
| 20976 | 79  | 
fun mk_app mk_app' from_expr const_syntax fxy (app as ((c, (_, ty)), ts)) =  | 
| 20191 | 80  | 
case const_syntax c  | 
| 20976 | 81  | 
of NONE => brackify fxy (mk_app' app)  | 
| 20699 | 82  | 
| SOME (i, pr) =>  | 
83  | 
let  | 
|
84  | 
val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i  | 
|
| 20976 | 85  | 
in if k <= length ts  | 
86  | 
then case chop i ts of (ts1, ts2) =>  | 
|
87  | 
brackify fxy (pr fxy from_expr ts1 :: map (from_expr BR) ts2)  | 
|
88  | 
else from_expr fxy (CodegenThingol.eta_expand app k)  | 
|
| 20699 | 89  | 
end;  | 
90  | 
||
| 20896 | 91  | 
val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode;  | 
| 20699 | 92  | 
|
93  | 
||
| 20896 | 94  | 
(* user-defined syntax *)  | 
| 20699 | 95  | 
|
| 20896 | 96  | 
val str = setmp print_mode [] Pretty.str;  | 
| 20699 | 97  | 
|
98  | 
datatype 'a mixfix =  | 
|
99  | 
Arg of fixity  | 
|
| 20931 | 100  | 
| Pretty of Pretty.T;  | 
| 18865 | 101  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
102  | 
fun mk_mixfix (fixity_this, mfx) =  | 
| 18702 | 103  | 
let  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
104  | 
fun is_arg (Arg _) = true  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
105  | 
| is_arg _ = false;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
106  | 
val i = (length o List.filter is_arg) mfx;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
107  | 
fun fillin _ [] [] =  | 
| 19008 | 108  | 
[]  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
109  | 
| fillin pr (Arg fxy :: mfx) (a :: args) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
110  | 
pr fxy a :: fillin pr mfx args  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
111  | 
| fillin pr (Pretty p :: mfx) args =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
112  | 
p :: fillin pr mfx args  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
113  | 
| fillin _ [] _ =  | 
| 20389 | 114  | 
          error ("Inconsistent mixfix: too many arguments")
 | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
115  | 
| fillin _ _ [] =  | 
| 20389 | 116  | 
          error ("Inconsistent mixfix: too less arguments");
 | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
117  | 
in  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
118  | 
(i, fn fixity_ctxt => fn pr => fn args =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
119  | 
gen_brackify (eval_fxy fixity_this fixity_ctxt) (fillin pr mfx args))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
120  | 
end;  | 
| 18702 | 121  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
122  | 
fun parse_infix (x, i) s =  | 
| 18702 | 123  | 
let  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
124  | 
val l = case x of L => INFX (i, L) | _ => INFX (i, X);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
125  | 
val r = case x of R => INFX (i, R) | _ => INFX (i, X);  | 
| 18702 | 126  | 
in  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
127  | 
mk_mixfix (INFX (i, x), [Arg l, (Pretty o Pretty.brk) 1, (Pretty o str) s, (Pretty o Pretty.brk) 1, Arg r])  | 
| 18702 | 128  | 
end;  | 
129  | 
||
| 20931 | 130  | 
fun parse_mixfix s =  | 
| 18335 | 131  | 
let  | 
| 20931 | 132  | 
val sym_any = Scan.one Symbol.not_eof;  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
133  | 
val parse = Scan.optional ($$ "!" >> K true) false -- Scan.repeat (  | 
| 21130 | 134  | 
         ($$ "(" -- $$ "_" -- $$ ")" >> K (Arg NOBR))
 | 
| 20931 | 135  | 
|| ($$ "_" >> K (Arg BR))  | 
136  | 
|| ($$ "/" |-- Scan.repeat ($$ " ") >> (Pretty o Pretty.brk o length))  | 
|
| 18702 | 137  | 
|| (Scan.repeat1  | 
| 20931 | 138  | 
( $$ "'" |-- sym_any  | 
| 21130 | 139  | 
            || Scan.unless ($$ "_" || $$ "/" || $$ "(" |-- $$ "_" |-- $$ ")")
 | 
| 18702 | 140  | 
sym_any) >> (Pretty o str o implode)));  | 
| 20931 | 141  | 
in case Scan.finite Symbol.stopper parse (Symbol.explode s)  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
142  | 
of ((_, p as [_]), []) => mk_mixfix (NOBR, p)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
143  | 
| ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
144  | 
    | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail ()
 | 
| 18702 | 145  | 
end;  | 
146  | 
||
| 21082 | 147  | 
fun parse_args f args =  | 
148  | 
case f args  | 
|
149  | 
of (x, []) => x  | 
|
150  | 
| (_, _) => error "bad serializer arguments";  | 
|
151  | 
||
| 18702 | 152  | 
|
| 20896 | 153  | 
(* list and string serializer *)  | 
| 20401 | 154  | 
|
155  | 
fun implode_list c_nil c_cons e =  | 
|
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
156  | 
let  | 
| 19202 | 157  | 
fun dest_cons (IConst (c, _) `$ e1 `$ e2) =  | 
| 20401 | 158  | 
if c = c_cons  | 
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
159  | 
then SOME (e1, e2)  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
160  | 
else NONE  | 
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
161  | 
| dest_cons _ = NONE;  | 
| 20401 | 162  | 
val (es, e') = CodegenThingol.unfoldr dest_cons e;  | 
163  | 
in case e'  | 
|
164  | 
of IConst (c, _) => if c = c_nil then SOME es else NONE  | 
|
165  | 
| _ => NONE  | 
|
166  | 
end;  | 
|
167  | 
||
168  | 
fun implode_string mk_char mk_string es =  | 
|
169  | 
if forall (fn IChar _ => true | _ => false) es  | 
|
| 21015 | 170  | 
then (SOME o str o mk_string o implode o map (fn IChar c => mk_char c)) es  | 
| 20401 | 171  | 
else NONE;  | 
172  | 
||
173  | 
fun pretty_ml_string c_nil c_cons mk_char mk_string target_implode =  | 
|
174  | 
let  | 
|
175  | 
fun pretty fxy pr [e] =  | 
|
176  | 
case implode_list c_nil c_cons e  | 
|
177  | 
of SOME es => (case implode_string mk_char mk_string es  | 
|
178  | 
of SOME p => p  | 
|
179  | 
| NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e])  | 
|
180  | 
| NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e]  | 
|
| 20699 | 181  | 
in (1, pretty) end;  | 
| 20401 | 182  | 
|
183  | 
fun pretty_list c_nil c_cons mk_list mk_char_string (target_fxy, target_cons) =  | 
|
184  | 
let  | 
|
185  | 
fun default fxy pr e1 e2 =  | 
|
186  | 
brackify_infix (target_fxy, R) fxy [  | 
|
187  | 
pr (INFX (target_fxy, X)) e1,  | 
|
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
188  | 
str target_cons,  | 
| 20401 | 189  | 
pr (INFX (target_fxy, R)) e2  | 
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
190  | 
];  | 
| 20401 | 191  | 
fun pretty fxy pr [e1, e2] =  | 
192  | 
case Option.map (cons e1) (implode_list c_nil c_cons e2)  | 
|
193  | 
of SOME es =>  | 
|
194  | 
(case mk_char_string  | 
|
195  | 
of SOME (mk_char, mk_string) =>  | 
|
196  | 
(case implode_string mk_char mk_string es  | 
|
197  | 
of SOME p => p  | 
|
198  | 
| NONE => mk_list (map (pr NOBR) es))  | 
|
199  | 
| NONE => mk_list (map (pr NOBR) es))  | 
|
200  | 
| NONE => default fxy pr e1 e2;  | 
|
| 20699 | 201  | 
in (2, pretty) end;  | 
| 
18704
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
202  | 
|
| 
 
2c86ced392a8
substantial improvement in serialization handling
 
haftmann 
parents: 
18702 
diff
changeset
 | 
203  | 
|
| 21082 | 204  | 
(* misc *)  | 
| 20896 | 205  | 
|
206  | 
fun constructive_fun (name, (eqs, ty)) =  | 
|
| 18216 | 207  | 
let  | 
| 20699 | 208  | 
val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;  | 
| 20896 | 209  | 
fun is_pat (IConst (c, _)) = is_cons c  | 
210  | 
| is_pat (IVar _) = true  | 
|
211  | 
| is_pat (t1 `$ t2) =  | 
|
212  | 
is_pat t1 andalso is_pat t2  | 
|
213  | 
| is_pat (INum _) = true  | 
|
214  | 
| is_pat (IChar _) = true  | 
|
215  | 
| is_pat _ = false;  | 
|
216  | 
fun check_eq (eq as (lhs, rhs)) =  | 
|
217  | 
if forall is_pat lhs  | 
|
218  | 
then SOME eq  | 
|
219  | 
      else (warning ("In function " ^ quote name ^ ", throwing away one "
 | 
|
220  | 
^ "non-executable function clause"); NONE)  | 
|
221  | 
in case map_filter check_eq eqs  | 
|
222  | 
   of [] => error ("In function " ^ quote name ^ ", no "
 | 
|
223  | 
^ "executable function clauses found")  | 
|
224  | 
| eqs => (name, (eqs, ty))  | 
|
225  | 
end;  | 
|
226  | 
||
| 21082 | 227  | 
fun dest_name name =  | 
228  | 
let  | 
|
229  | 
val (names, name_base) = (split_last o NameSpace.unpack) name;  | 
|
230  | 
val (names_mod, name_shallow) = split_last names;  | 
|
231  | 
in (names_mod, (name_shallow, name_base)) end;  | 
|
232  | 
||
| 20896 | 233  | 
|
| 21015 | 234  | 
|
| 20896 | 235  | 
(** SML serializer **)  | 
236  | 
||
237  | 
datatype ml_def =  | 
|
238  | 
MLFuns of (string * ((iterm list * iterm) list * typscheme)) list  | 
|
239  | 
| MLDatas of (string * ((vname * sort) list * (string * itype list) list)) list  | 
|
240  | 
| MLClass of string * (class list * (vname * (string * itype) list))  | 
|
241  | 
| MLClassinst of string * ((class * (string * (vname * sort) list))  | 
|
242  | 
* ((class * (string * inst list list)) list  | 
|
243  | 
* (string * iterm) list));  | 
|
244  | 
||
245  | 
fun pr_sml_def tyco_syntax const_syntax keyword_vars deresolv ml_def =  | 
|
246  | 
let  | 
|
247  | 
val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;  | 
|
248  | 
fun dictvar v =  | 
|
| 20699 | 249  | 
first_upper v ^ "_";  | 
| 20896 | 250  | 
val label = translate_string (fn "." => "__" | c => c)  | 
251  | 
o NameSpace.pack o op @ o apsnd single o apfst (fst o split_last) o split_last o NameSpace.unpack;  | 
|
252  | 
fun pr_tyvar (v, []) =  | 
|
| 
19953
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
253  | 
str "()"  | 
| 20896 | 254  | 
| pr_tyvar (v, sort) =  | 
| 
19953
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
255  | 
let  | 
| 20896 | 256  | 
fun pr_class class =  | 
257  | 
              str ("'" ^ v ^ " " ^ deresolv class);
 | 
|
| 
19953
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
258  | 
in  | 
| 
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
259  | 
Pretty.block [  | 
| 
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
260  | 
              str "(",
 | 
| 20896 | 261  | 
(str o dictvar) v,  | 
| 
19953
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
262  | 
str ":",  | 
| 
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
263  | 
case sort  | 
| 20896 | 264  | 
of [class] => pr_class class  | 
265  | 
| _ => Pretty.enum " *" "" "" (map pr_class sort),  | 
|
266  | 
str ")"  | 
|
| 
19953
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
267  | 
]  | 
| 
 
2f54a51f1801
class package refinements, slight code generation refinements
 
haftmann 
parents: 
19936 
diff
changeset
 | 
268  | 
end;  | 
| 20896 | 269  | 
fun pr_insts fxy iys =  | 
| 18885 | 270  | 
let  | 
| 20896 | 271  | 
        fun pr_proj s = str ("#" ^ s);
 | 
272  | 
fun pr_lookup [] p =  | 
|
| 20401 | 273  | 
p  | 
| 20896 | 274  | 
| pr_lookup [p'] p =  | 
275  | 
brackify BR [p', p]  | 
|
276  | 
| pr_lookup (ps as _ :: _) p =  | 
|
277  | 
              brackify BR [Pretty.enum " o" "(" ")" ps, p];
 | 
|
278  | 
fun pr_inst fxy (Instance (inst, iss)) =  | 
|
| 18885 | 279  | 
brackify fxy (  | 
| 20896 | 280  | 
(str o deresolv) inst  | 
281  | 
:: map (pr_insts BR) iss  | 
|
| 18885 | 282  | 
)  | 
| 20896 | 283  | 
| pr_inst fxy (Context (classes, (v, i))) =  | 
284  | 
pr_lookup (map (pr_proj o label) classes  | 
|
285  | 
@ (if i = ~1 then [] else [(pr_proj o string_of_int) (i+1)])  | 
|
286  | 
) ((str o dictvar) v);  | 
|
287  | 
in case iys  | 
|
| 19253 | 288  | 
of [] => str "()"  | 
| 20896 | 289  | 
| [iy] => pr_inst fxy iy  | 
290  | 
        | _ :: _ => (Pretty.list "(" ")" o map (pr_inst NOBR)) iys
 | 
|
| 18885 | 291  | 
end;  | 
| 20896 | 292  | 
fun pr_tycoexpr fxy (tyco, tys) =  | 
| 18963 | 293  | 
let  | 
| 20896 | 294  | 
val tyco' = (str o deresolv) tyco  | 
295  | 
in case map (pr_typ BR) tys  | 
|
| 18963 | 296  | 
of [] => tyco'  | 
297  | 
| [p] => Pretty.block [p, Pretty.brk 1, tyco']  | 
|
298  | 
        | (ps as _::_) => Pretty.block [Pretty.list "(" ")" ps, Pretty.brk 1, tyco']
 | 
|
299  | 
end  | 
|
| 20896 | 300  | 
and pr_typ fxy (tyco `%% tys) =  | 
| 18702 | 301  | 
(case tyco_syntax tyco  | 
| 20896 | 302  | 
of NONE => pr_tycoexpr fxy (tyco, tys)  | 
| 20699 | 303  | 
| SOME (i, pr) =>  | 
304  | 
if not (i = length tys)  | 
|
| 20389 | 305  | 
                then error ("Number of argument mismatch in customary serialization: "
 | 
| 18865 | 306  | 
^ (string_of_int o length) tys ^ " given, "  | 
| 20699 | 307  | 
^ string_of_int i ^ " expected")  | 
| 20896 | 308  | 
else pr fxy pr_typ tys)  | 
309  | 
| pr_typ fxy (ITyVar v) =  | 
|
| 18885 | 310  | 
          str ("'" ^ v);
 | 
| 20896 | 311  | 
fun pr_term vars fxy (IConst c) =  | 
312  | 
pr_app vars fxy (c, [])  | 
|
313  | 
| pr_term vars fxy (IVar v) =  | 
|
| 21082 | 314  | 
str (CodegenThingol.lookup_var vars v)  | 
| 20896 | 315  | 
| pr_term vars fxy (t as t1 `$ t2) =  | 
316  | 
(case CodegenThingol.unfold_const_app t  | 
|
317  | 
of SOME c_ts => pr_app vars fxy c_ts  | 
|
| 18865 | 318  | 
| NONE =>  | 
| 20976 | 319  | 
brackify fxy [pr_term vars NOBR t1, pr_term vars BR t2])  | 
| 20896 | 320  | 
| pr_term vars fxy (t as _ `|-> _) =  | 
| 20105 | 321  | 
let  | 
| 21015 | 322  | 
val (ps, t') = CodegenThingol.unfold_abs t;  | 
323  | 
fun pr ((v, NONE), _) vars =  | 
|
324  | 
let  | 
|
| 21082 | 325  | 
val vars' = CodegenThingol.intro_vars [v] vars;  | 
| 21015 | 326  | 
in  | 
| 21082 | 327  | 
((Pretty.block o Pretty.breaks) [str "fn", str (CodegenThingol.lookup_var vars' v), str "=>"], vars')  | 
| 21015 | 328  | 
end  | 
329  | 
| pr ((v, SOME p), _) vars =  | 
|
330  | 
let  | 
|
| 21093 | 331  | 
val vars' = CodegenThingol.intro_vars [v] vars;  | 
332  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
|
333  | 
val vars'' = CodegenThingol.intro_vars vs vars';  | 
|
| 21015 | 334  | 
in  | 
| 21082 | 335  | 
((Pretty.block o Pretty.breaks) [str "fn", str (CodegenThingol.lookup_var vars' v), str "as",  | 
| 21093 | 336  | 
pr_term vars'' NOBR p, str "=>"], vars'')  | 
| 21015 | 337  | 
end;  | 
338  | 
val (ps', vars') = fold_map pr ps vars;  | 
|
339  | 
in brackify BR (ps' @ [pr_term vars' NOBR t']) end  | 
|
340  | 
| pr_term vars fxy (INum n) =  | 
|
| 20896 | 341  | 
brackify BR [(str o IntInf.toString) n, str ":", str "IntInf.int"]  | 
| 21015 | 342  | 
| pr_term vars _ (IChar c) =  | 
| 
19607
 
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
 
haftmann 
parents: 
19597 
diff
changeset
 | 
343  | 
(str o prefix "#" o quote)  | 
| 20203 | 344  | 
(let val i = ord c  | 
| 20191 | 345  | 
in if i < 32  | 
| 20105 | 346  | 
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
 | 
347  | 
else c  | 
| 
 
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
 
haftmann 
parents: 
19597 
diff
changeset
 | 
348  | 
end)  | 
| 21015 | 349  | 
| pr_term vars fxy (t as ICase (_, [_])) =  | 
| 18216 | 350  | 
let  | 
| 20976 | 351  | 
val (ts, t') = CodegenThingol.unfold_let t;  | 
352  | 
fun mk ((p, _), t'') vars =  | 
|
| 20699 | 353  | 
let  | 
| 20896 | 354  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
| 21082 | 355  | 
val vars' = CodegenThingol.intro_vars vs vars;  | 
| 20699 | 356  | 
in  | 
357  | 
(Pretty.block [  | 
|
358  | 
(Pretty.block o Pretty.breaks) [  | 
|
359  | 
str "val",  | 
|
| 20896 | 360  | 
pr_term vars' NOBR p,  | 
| 20699 | 361  | 
str "=",  | 
| 20976 | 362  | 
pr_term vars NOBR t''  | 
| 20699 | 363  | 
],  | 
364  | 
str ";"  | 
|
| 20896 | 365  | 
], vars')  | 
| 20699 | 366  | 
end  | 
| 20896 | 367  | 
val (binds, vars') = fold_map mk ts vars;  | 
368  | 
in  | 
|
369  | 
Pretty.chunks [  | 
|
370  | 
              [str ("let"), Pretty.fbrk, binds |> Pretty.chunks] |> Pretty.block,
 | 
|
| 20976 | 371  | 
              [str ("in"), Pretty.fbrk, pr_term vars' NOBR t'] |> Pretty.block,
 | 
| 20896 | 372  | 
              str ("end")
 | 
373  | 
] end  | 
|
| 21015 | 374  | 
| pr_term vars fxy (ICase ((td, ty), b::bs)) =  | 
| 18216 | 375  | 
let  | 
| 20896 | 376  | 
fun pr definer (p, t) =  | 
| 20699 | 377  | 
let  | 
| 20896 | 378  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
| 21082 | 379  | 
val vars' = CodegenThingol.intro_vars vs vars;  | 
| 20699 | 380  | 
in  | 
381  | 
(Pretty.block o Pretty.breaks) [  | 
|
382  | 
str definer,  | 
|
| 20896 | 383  | 
pr_term vars' NOBR p,  | 
| 20699 | 384  | 
str "=>",  | 
| 20896 | 385  | 
pr_term vars' NOBR t  | 
| 20699 | 386  | 
]  | 
| 20896 | 387  | 
end;  | 
388  | 
in  | 
|
389  | 
            (Pretty.enclose "(" ")" o single o brackify fxy) (
 | 
|
390  | 
str "case"  | 
|
391  | 
:: pr_term vars NOBR td  | 
|
392  | 
:: pr "of" b  | 
|
393  | 
:: map (pr "|") bs  | 
|
394  | 
)  | 
|
395  | 
end  | 
|
| 20976 | 396  | 
and pr_app' vars (app as ((c, (iss, ty)), ts)) =  | 
397  | 
if is_cons c then let  | 
|
398  | 
val k = (length o fst o CodegenThingol.unfold_fun) ty  | 
|
399  | 
in if k < 2 then  | 
|
400  | 
(str o deresolv) c :: map (pr_term vars BR) ts  | 
|
401  | 
else if k = length ts then  | 
|
402  | 
        [(str o deresolv) c, Pretty.enum "," "(" ")" (map (pr_term vars NOBR) ts)]
 | 
|
403  | 
else [pr_term vars BR (CodegenThingol.eta_expand app k)] end else  | 
|
404  | 
(str o deresolv) c :: map (pr_term vars BR) ts  | 
|
| 20896 | 405  | 
and pr_app vars fxy (app as ((c, (iss, ty)), ts)) =  | 
406  | 
case if is_cons c then [] else (map (pr_insts BR) o filter_out null) iss  | 
|
| 18885 | 407  | 
of [] =>  | 
| 20896 | 408  | 
mk_app (pr_app' vars) (pr_term vars) const_syntax fxy app  | 
409  | 
| ps =>  | 
|
| 20456 | 410  | 
if (is_none o const_syntax) c then  | 
| 20896 | 411  | 
brackify fxy ((str o deresolv) c :: (ps @ map (pr_term vars BR) ts))  | 
412  | 
else  | 
|
413  | 
              error ("Cannot apply user defined serialization for function expecting dictionaries: " ^ quote c)
 | 
|
414  | 
fun eta_expand_poly_fun (funn as (_, (_::_, _))) =  | 
|
415  | 
funn  | 
|
416  | 
| eta_expand_poly_fun (funn as (_, ([_], ([], _)))) =  | 
|
417  | 
funn  | 
|
418  | 
| eta_expand_poly_fun (funn as (_, ([(_::_, _)], _))) =  | 
|
419  | 
funn  | 
|
420  | 
| eta_expand_poly_fun (funn as (_, ([(_, _ `|-> _)], _))) =  | 
|
421  | 
funn  | 
|
422  | 
| eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) =  | 
|
423  | 
if (null o fst o CodegenThingol.unfold_fun) ty  | 
|
424  | 
orelse (not o null o filter_out (null o snd)) vs  | 
|
425  | 
then funn  | 
|
426  | 
else (name, ([([IVar "x"], t `$ IVar "x")], tysm));  | 
|
427  | 
fun pr_def (MLFuns raw_funns) =  | 
|
428  | 
let  | 
|
429  | 
val funns as (funn :: funns') = map (eta_expand_poly_fun o constructive_fun) raw_funns;  | 
|
430  | 
val definer =  | 
|
431  | 
let  | 
|
432  | 
fun mk [] [] = "val"  | 
|
433  | 
| mk (_::_) _ = "fun"  | 
|
434  | 
| mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun";  | 
|
435  | 
fun chk (_, ((ts, _) :: _, (vs, _))) NONE = SOME (mk ts vs)  | 
|
436  | 
| chk (_, ((ts, _) :: _, (vs, _))) (SOME defi) =  | 
|
437  | 
if defi = mk ts vs then SOME defi  | 
|
438  | 
                      else error ("Mixing simultaneous vals and funs not implemented");
 | 
|
439  | 
in the (fold chk funns NONE) end;  | 
|
440  | 
fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) =  | 
|
441  | 
let  | 
|
442  | 
val vs = filter_out (null o snd) raw_vs;  | 
|
443  | 
val shift = if null eqs' then I else  | 
|
444  | 
map (Pretty.block o single o Pretty.block o single);  | 
|
445  | 
fun pr_eq definer (ts, t) =  | 
|
446  | 
let  | 
|
447  | 
val consts = map_filter  | 
|
448  | 
(fn c => if (is_some o const_syntax) c  | 
|
449  | 
then NONE else (SOME o NameSpace.base o deresolv) c)  | 
|
450  | 
((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);  | 
|
451  | 
val vars = keyword_vars  | 
|
| 21082 | 452  | 
|> CodegenThingol.intro_vars consts  | 
453  | 
|> CodegenThingol.intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);  | 
|
| 20896 | 454  | 
in  | 
455  | 
(Pretty.block o Pretty.breaks) (  | 
|
456  | 
[str definer, (str o deresolv) name]  | 
|
457  | 
@ (if null ts andalso null vs  | 
|
458  | 
andalso not (ty = ITyVar "_")(*for evaluation*)  | 
|
459  | 
then [str ":", pr_typ NOBR ty]  | 
|
460  | 
else  | 
|
461  | 
map pr_tyvar vs  | 
|
462  | 
@ map (pr_term vars BR) ts)  | 
|
463  | 
@ [str "=", pr_term vars NOBR t]  | 
|
464  | 
)  | 
|
465  | 
end  | 
|
466  | 
in  | 
|
467  | 
(Pretty.block o Pretty.fbreaks o shift) (  | 
|
468  | 
pr_eq definer eq  | 
|
469  | 
:: map (pr_eq "|") eqs'  | 
|
470  | 
)  | 
|
471  | 
end;  | 
|
472  | 
val (ps, p) = split_last (pr_funn definer funn :: map (pr_funn "and") funns');  | 
|
473  | 
in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end  | 
|
474  | 
| pr_def (MLDatas (datas as (data :: datas'))) =  | 
|
475  | 
let  | 
|
476  | 
fun pr_co (co, []) =  | 
|
477  | 
str (deresolv co)  | 
|
478  | 
| pr_co (co, tys) =  | 
|
479  | 
(Pretty.block o Pretty.breaks) [  | 
|
480  | 
str (deresolv co),  | 
|
481  | 
str "of",  | 
|
482  | 
Pretty.enum " *" "" "" (map (pr_typ (INFX (2, L))) tys)  | 
|
483  | 
];  | 
|
484  | 
fun pr_data definer (tyco, (vs, cos)) =  | 
|
485  | 
(Pretty.block o Pretty.breaks) (  | 
|
486  | 
str definer  | 
|
487  | 
:: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs)  | 
|
488  | 
:: str "="  | 
|
489  | 
:: separate (str "|") (map pr_co cos)  | 
|
490  | 
);  | 
|
491  | 
val (ps, p) = split_last (pr_data "datatype" data :: map (pr_data "and") datas');  | 
|
492  | 
in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end  | 
|
493  | 
| pr_def (MLClass (class, (superclasses, (v, classops)))) =  | 
|
494  | 
let  | 
|
495  | 
val w = dictvar v;  | 
|
496  | 
fun pr_superclass class =  | 
|
497  | 
(Pretty.block o Pretty.breaks o map str) [  | 
|
498  | 
label class, ":", "'" ^ v, deresolv class  | 
|
499  | 
];  | 
|
500  | 
fun pr_classop (classop, ty) =  | 
|
501  | 
(Pretty.block o Pretty.breaks) [  | 
|
502  | 
(str o suffix "_" o NameSpace.base) classop, str ":", pr_typ NOBR ty  | 
|
503  | 
];  | 
|
504  | 
fun pr_classop_fun (classop, _) =  | 
|
505  | 
(Pretty.block o Pretty.breaks) [  | 
|
506  | 
str "fun",  | 
|
507  | 
(str o deresolv) classop,  | 
|
508  | 
                Pretty.enclose "(" ")" [str (w ^ ":'" ^ v ^ " " ^ deresolv class)],
 | 
|
509  | 
str "=",  | 
|
510  | 
                str ("#" ^ (suffix "_" o NameSpace.base) classop),
 | 
|
511  | 
str (w ^ ";")  | 
|
512  | 
];  | 
|
513  | 
in  | 
|
514  | 
Pretty.chunks (  | 
|
515  | 
(Pretty.block o Pretty.breaks) [  | 
|
516  | 
                str ("type '" ^ v),
 | 
|
517  | 
(str o deresolv) class,  | 
|
518  | 
str "=",  | 
|
519  | 
                Pretty.enum "," "{" "};" (
 | 
|
520  | 
map pr_superclass superclasses @ map pr_classop classops  | 
|
521  | 
)  | 
|
522  | 
]  | 
|
523  | 
:: map pr_classop_fun classops  | 
|
524  | 
)  | 
|
525  | 
end  | 
|
526  | 
| pr_def (MLClassinst (inst, ((class, (tyco, arity)), (superarities, classop_defs)))) =  | 
|
527  | 
let  | 
|
528  | 
fun pr_superclass (superclass, superinst_iss) =  | 
|
529  | 
(Pretty.block o Pretty.breaks) [  | 
|
530  | 
(str o label) superclass,  | 
|
531  | 
str "=",  | 
|
532  | 
pr_insts NOBR [Instance superinst_iss]  | 
|
533  | 
];  | 
|
534  | 
fun pr_classop_def (classop, t) =  | 
|
535  | 
let  | 
|
536  | 
val consts = map_filter  | 
|
537  | 
(fn c => if (is_some o const_syntax) c  | 
|
538  | 
then NONE else (SOME o NameSpace.base o deresolv) c)  | 
|
539  | 
(CodegenThingol.fold_constnames (insert (op =)) t []);  | 
|
540  | 
val vars = keyword_vars  | 
|
| 21082 | 541  | 
|> CodegenThingol.intro_vars consts;  | 
| 20896 | 542  | 
in  | 
543  | 
(Pretty.block o Pretty.breaks) [  | 
|
544  | 
(str o suffix "_" o NameSpace.base) classop,  | 
|
545  | 
str "=",  | 
|
546  | 
pr_term vars NOBR t  | 
|
547  | 
]  | 
|
548  | 
end;  | 
|
549  | 
in  | 
|
550  | 
(Pretty.block o Pretty.breaks) ([  | 
|
551  | 
str (if null arity then "val" else "fun"),  | 
|
552  | 
(str o deresolv) inst ] @  | 
|
553  | 
map pr_tyvar arity @ [  | 
|
554  | 
str "=",  | 
|
555  | 
              Pretty.enum "," "{" "}" (map pr_superclass superarities @ map pr_classop_def classop_defs),
 | 
|
556  | 
str ":",  | 
|
557  | 
pr_tycoexpr NOBR (class, [tyco `%% map (ITyVar o fst) arity])  | 
|
558  | 
])  | 
|
559  | 
end;  | 
|
560  | 
in pr_def ml_def end;  | 
|
| 
19042
 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 
haftmann 
parents: 
19038 
diff
changeset
 | 
561  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
562  | 
val sml_code_width = ref 80;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
563  | 
|
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
564  | 
fun seri_sml output reserved_user module_alias module_prolog  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
565  | 
(_ : string -> (string * (string -> string option)) option) tyco_syntax const_syntax code =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
566  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
567  | 
datatype node =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
568  | 
Def of string * ml_def option  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
569  | 
| Module of string * ((Name.context * Name.context) * node Graph.T);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
570  | 
    val empty_names = Name.make_context ("nil" :: ThmDatabase.ml_reserved @ reserved_user);
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
571  | 
val empty_module = ((empty_names, empty_names), Graph.empty);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
572  | 
fun map_node [] f = f  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
573  | 
| map_node (m::ms) f =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
574  | 
Graph.default_node (m, Module (m, empty_module))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
575  | 
#> Graph.map_node m (fn (Module (dmodlname, (nsp, nodes))) => Module (dmodlname, (nsp, map_node ms f nodes)));  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
576  | 
fun map_nsp_yield [] f (nsp, nodes) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
577  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
578  | 
val (x, nsp') = f nsp  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
579  | 
in (x, (nsp', nodes)) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
580  | 
| map_nsp_yield (m::ms) f (nsp, nodes) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
581  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
582  | 
val (x, nodes') =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
583  | 
nodes  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
584  | 
|> Graph.default_node (m, Module (m, empty_module))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
585  | 
|> Graph.map_node_yield m (fn Module (dmodlname, nsp_nodes) =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
586  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
587  | 
val (x, nsp_nodes') = map_nsp_yield ms f nsp_nodes  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
588  | 
in (x, Module (dmodlname, nsp_nodes')) end)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
589  | 
in (x, (nsp, nodes')) end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
590  | 
val init_vars = CodegenThingol.make_vars (ThmDatabase.ml_reserved @ reserved_user);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
591  | 
fun name_modl modl =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
592  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
593  | 
val modlname = NameSpace.pack modl  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
594  | 
in case module_alias modlname  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
595  | 
of SOME modlname' => NameSpace.unpack modlname'  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
596  | 
| NONE => map (fn name => (the_single o fst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
597  | 
(Name.variants [name] empty_names)) modl  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
598  | 
end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
599  | 
fun name_def upper base nsp =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
600  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
601  | 
val base' = if upper then first_upper base else base;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
602  | 
val ([base''], nsp') = Name.variants [base'] nsp;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
603  | 
in (base'', nsp') end;  | 
| 21130 | 604  | 
fun map_nsp_fun f (nsp_fun, nsp_typ) =  | 
605  | 
let  | 
|
606  | 
val (x, nsp_fun') = f nsp_fun  | 
|
607  | 
in (x, (nsp_fun', nsp_typ)) end;  | 
|
608  | 
fun map_nsp_typ f (nsp_fun, nsp_typ) =  | 
|
609  | 
let  | 
|
610  | 
val (x, nsp_typ') = f nsp_typ  | 
|
611  | 
in (x, (nsp_fun, nsp_typ')) end;  | 
|
612  | 
fun mk_funs defs =  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
613  | 
fold_map  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
614  | 
(fn (name, CodegenThingol.Fun info) =>  | 
| 21130 | 615  | 
map_nsp_fun (name_def false (NameSpace.base name)) >> (fn base => (base, (name, info)))  | 
616  | 
          | (name, def) => error ("Function block containing illegal def: " ^ quote name)
 | 
|
617  | 
) defs  | 
|
618  | 
>> (split_list #> apsnd MLFuns);  | 
|
619  | 
fun mk_datatype defs =  | 
|
620  | 
fold_map  | 
|
621  | 
(fn (name, CodegenThingol.Datatype info) =>  | 
|
622  | 
map_nsp_typ (name_def false (NameSpace.base name)) >> (fn base => (base, SOME (name, info)))  | 
|
623  | 
| (name, CodegenThingol.Datatypecons _) =>  | 
|
624  | 
map_nsp_fun (name_def true (NameSpace.base name)) >> (fn base => (base, NONE))  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
625  | 
          | (name, def) => error ("Datatype block containing illegal def: " ^ quote name)
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
626  | 
) defs  | 
| 21130 | 627  | 
>> (split_list #> apsnd (map_filter I  | 
628  | 
        #> (fn [] => error ("Datatype block without data: " ^ (commas o map (quote o fst)) defs)
 | 
|
629  | 
| infos => MLDatas infos)));  | 
|
630  | 
fun mk_class defs =  | 
|
631  | 
fold_map  | 
|
632  | 
(fn (name, CodegenThingol.Class info) =>  | 
|
633  | 
map_nsp_typ (name_def false (NameSpace.base name)) >> (fn base => (base, SOME (name, info)))  | 
|
634  | 
| (name, CodegenThingol.Classop _) =>  | 
|
635  | 
map_nsp_fun (name_def true (NameSpace.base name)) >> (fn base => (base, NONE))  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
636  | 
          | (name, def) => error ("Class block containing illegal def: " ^ quote name)
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
637  | 
) defs  | 
| 21130 | 638  | 
>> (split_list #> apsnd (map_filter I  | 
639  | 
        #> (fn [] => error ("Class block without class: " ^ (commas o map (quote o fst)) defs)
 | 
|
640  | 
| [info] => MLClass info)));  | 
|
641  | 
fun mk_inst [(name, CodegenThingol.Classinst info)] =  | 
|
642  | 
map_nsp_fun (name_def false (NameSpace.base name))  | 
|
643  | 
>> (fn base => ([base], MLClassinst (name, info)));  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
644  | 
fun add_group mk defs nsp_nodes =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
645  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
646  | 
val names as (name :: names') = map fst defs;  | 
| 21130 | 647  | 
(*         val _ = writeln ("adding " ^ commas names);  *)
 | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
648  | 
val deps =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
649  | 
[]  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
650  | 
|> fold (fold (insert (op =)) o Graph.imm_succs code) names  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
651  | 
|> subtract (op =) names;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
652  | 
val (modls, defnames) = (split_list o map dest_name) names;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
653  | 
val modl = (the_single o distinct (op =)) modls  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
654  | 
handle Empty =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
655  | 
            error ("Illegal mutual dependencies: " ^ (commas o map fst) defs);
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
656  | 
val modl' = name_modl modl;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
657  | 
fun add_dep defname name'' =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
658  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
659  | 
val (modl'', defname'') = (apfst name_modl o dest_name) name'';  | 
| 21130 | 660  | 
(* val _ = writeln (uncurry NameSpace.append defname ^ " -> " ^ name''); *)  | 
| 21162 | 661  | 
(* val _ = (writeln o NameSpace.pack) modl'; *)  | 
662  | 
(* val _ = (writeln o NameSpace.pack) modl''; *)  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
663  | 
in if modl' = modl'' then  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
664  | 
map_node modl'  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
665  | 
(Graph.add_edge (NameSpace.pack (modl @ [fst defname, snd defname]), name''))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
666  | 
else let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
667  | 
val (common, (diff1::_, diff2::_)) = chop_prefix (op =) (modl', modl'');  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
668  | 
in  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
669  | 
map_node common  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
670  | 
(fn gr => Graph.add_edge_acyclic (diff1, diff2) gr  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
671  | 
                handle Graph.CYCLES _ => error ("Dependency "
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
672  | 
^ quote (NameSpace.pack (modl' @ [fst defname, snd defname]))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
673  | 
^ " -> " ^ quote name'' ^ " would result in module dependency cycle"))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
674  | 
end end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
675  | 
in  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
676  | 
nsp_nodes  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
677  | 
|> map_nsp_yield modl' (mk defs)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
678  | 
|-> (fn (base' :: bases', def') =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
679  | 
apsnd (map_node modl' (Graph.new_node (name, (Def (base', SOME def')))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
680  | 
#> fold2 (fn name' => fn base' => Graph.new_node (name', (Def (base', NONE)))) names' bases')))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
681  | 
|> apsnd (fold (fn defname => fold (add_dep defname) deps) defnames)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
682  | 
end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
683  | 
fun group_defs [(_, CodegenThingol.Bot)] =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
684  | 
I  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
685  | 
| group_defs ((defs as (_, CodegenThingol.Fun _)::_)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
686  | 
add_group mk_funs defs  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
687  | 
| group_defs ((defs as (_, CodegenThingol.Datatypecons _)::_)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
688  | 
add_group mk_datatype defs  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
689  | 
| group_defs ((defs as (_, CodegenThingol.Datatype _)::_)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
690  | 
add_group mk_datatype defs  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
691  | 
| group_defs ((defs as (_, CodegenThingol.Class _)::_)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
692  | 
add_group mk_class defs  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
693  | 
| group_defs ((defs as (_, CodegenThingol.Classop _)::_)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
694  | 
add_group mk_class defs  | 
| 21130 | 695  | 
| group_defs ((defs as [(_, CodegenThingol.Classinst _)])) =  | 
696  | 
add_group mk_inst defs  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
697  | 
      | group_defs defs = error ("Illegal mutual dependencies: " ^ (commas o map fst) defs)
 | 
| 21130 | 698  | 
val (_, nodes) =  | 
699  | 
empty_module  | 
|
700  | 
|> fold group_defs (map (AList.make (Graph.get_node code))  | 
|
701  | 
(rev (Graph.strong_conn code)))  | 
|
702  | 
fun deresolver prefix name =  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
703  | 
let  | 
| 21130 | 704  | 
(*         val _ = writeln ("resolving " ^ name)  *)
 | 
705  | 
val (modl, _) = apsnd (uncurry NameSpace.append) (dest_name name);  | 
|
706  | 
val modl' = name_modl modl;  | 
|
707  | 
val (_, (_, remainder)) = chop_prefix (op =) (prefix, modl');  | 
|
708  | 
val defname' =  | 
|
709  | 
nodes  | 
|
710  | 
|> fold (fn m => fn g => case Graph.get_node g m  | 
|
711  | 
of Module (_, (_, g)) => g) modl'  | 
|
712  | 
|> (fn g => case Graph.get_node g name of Def (defname, _) => defname);  | 
|
713  | 
in NameSpace.pack (remainder @ [defname']) end;  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
714  | 
fun the_prolog modlname = case module_prolog modlname  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
715  | 
of NONE => []  | 
| 21130 | 716  | 
| SOME p => [p, str ""];  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
717  | 
fun pr_node prefix (Def (_, NONE)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
718  | 
NONE  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
719  | 
| pr_node prefix (Def (_, SOME def)) =  | 
| 21130 | 720  | 
SOME (pr_sml_def tyco_syntax const_syntax init_vars (deresolver prefix) def)  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
721  | 
| pr_node prefix (Module (dmodlname, (_, nodes))) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
722  | 
(SOME o Pretty.chunks) ([  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
723  | 
            str ("structure " ^ dmodlname ^ " = "),
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
724  | 
str "struct",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
725  | 
str ""  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
726  | 
] @ the_prolog (NameSpace.pack (prefix @ [dmodlname]))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
727  | 
@ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
728  | 
o rev o flat o Graph.strong_conn) nodes) @ [  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
729  | 
str "",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
730  | 
            str ("end; (*struct " ^ dmodlname ^ "*)")
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
731  | 
]);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
732  | 
val p = Pretty.chunks ([  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
733  | 
        str ("structure ROOT = "),
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
734  | 
str "struct",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
735  | 
str ""  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
736  | 
] @ the_prolog ""  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
737  | 
@ separate (str "") ((map_filter (pr_node [] o Graph.get_node nodes)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
738  | 
o rev o flat o Graph.strong_conn) nodes) @ [  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
739  | 
str "",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
740  | 
        str ("end; (*struct ROOT*)")
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
741  | 
]);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
742  | 
in output p end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
743  | 
|
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
744  | 
val isar_seri_sml =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
745  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
746  | 
fun output_file file p = File.write (Path.unpack file) (Pretty.output p ^ "\n");  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
747  | 
fun output_diag p = Pretty.writeln p;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
748  | 
fun output_internal p = use_text Output.ml_output false (Pretty.output p);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
749  | 
in  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
750  | 
parse_args ((Args.$$$ "-" >> K output_diag  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
751  | 
|| Args.$$$ "*" >> K output_internal  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
752  | 
|| Args.name >> output_file)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
753  | 
>> (fn output => seri_sml output))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
754  | 
end;  | 
| 20896 | 755  | 
|
756  | 
||
| 21162 | 757  | 
|
| 20896 | 758  | 
(** Haskell serializer **)  | 
759  | 
||
| 21082 | 760  | 
fun pr_haskell class_syntax tyco_syntax const_syntax keyword_vars deresolv_here deresolv deriving_show def =  | 
| 
19042
 
630b8dd0b31a
exported some interfaces useful for other code generator approaches
 
haftmann 
parents: 
19038 
diff
changeset
 | 
761  | 
let  | 
| 20699 | 762  | 
val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;  | 
| 20896 | 763  | 
fun class_name class = case class_syntax class  | 
764  | 
of NONE => deresolv class  | 
|
765  | 
| SOME (class, _) => class;  | 
|
766  | 
fun classop_name class classop = case class_syntax class  | 
|
767  | 
of NONE => NameSpace.base classop  | 
|
768  | 
| SOME (_, classop_syntax) => case classop_syntax classop  | 
|
769  | 
of NONE => NameSpace.base classop  | 
|
770  | 
| SOME classop => classop  | 
|
771  | 
fun pr_typparms tyvars vs =  | 
|
772  | 
case maps (fn (v, sort) => map (pair v) sort) vs  | 
|
773  | 
of [] => str ""  | 
|
774  | 
| xs => Pretty.block [  | 
|
775  | 
            Pretty.enum "," "(" ")" (
 | 
|
776  | 
map (fn (v, class) => str  | 
|
| 21082 | 777  | 
(class_name class ^ " " ^ CodegenThingol.lookup_var tyvars v)) xs  | 
| 20896 | 778  | 
),  | 
779  | 
str " => "  | 
|
780  | 
];  | 
|
781  | 
fun pr_tycoexpr tyvars fxy (tyco, tys) =  | 
|
782  | 
brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)  | 
|
783  | 
and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) =  | 
|
784  | 
(case tyco_syntax tyco  | 
|
785  | 
of NONE =>  | 
|
786  | 
pr_tycoexpr tyvars fxy (deresolv tyco, tys)  | 
|
787  | 
| SOME (i, pr) =>  | 
|
788  | 
if not (i = length tys)  | 
|
789  | 
                then error ("Number of argument mismatch in customary serialization: "
 | 
|
790  | 
^ (string_of_int o length) tys ^ " given, "  | 
|
791  | 
^ string_of_int i ^ " expected")  | 
|
792  | 
else pr fxy (pr_typ tyvars) tys)  | 
|
793  | 
| pr_typ tyvars fxy (ITyVar v) =  | 
|
| 21082 | 794  | 
(str o CodegenThingol.lookup_var tyvars) v;  | 
| 20896 | 795  | 
fun pr_typscheme_expr tyvars (vs, tycoexpr) =  | 
796  | 
Pretty.block [pr_typparms tyvars vs, pr_tycoexpr tyvars NOBR tycoexpr];  | 
|
797  | 
fun pr_typscheme tyvars (vs, ty) =  | 
|
798  | 
Pretty.block [pr_typparms tyvars vs, pr_typ tyvars NOBR ty];  | 
|
799  | 
fun pr_term vars fxy (IConst c) =  | 
|
800  | 
pr_app vars fxy (c, [])  | 
|
801  | 
| pr_term vars fxy (t as (t1 `$ t2)) =  | 
|
802  | 
(case CodegenThingol.unfold_const_app t  | 
|
803  | 
of SOME app => pr_app vars fxy app  | 
|
804  | 
| _ =>  | 
|
805  | 
brackify fxy [  | 
|
806  | 
pr_term vars NOBR t1,  | 
|
807  | 
pr_term vars BR t2  | 
|
808  | 
])  | 
|
809  | 
| pr_term vars fxy (IVar v) =  | 
|
| 21082 | 810  | 
(str o CodegenThingol.lookup_var vars) v  | 
| 20896 | 811  | 
| pr_term vars fxy (t as _ `|-> _) =  | 
| 
19607
 
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
 
haftmann 
parents: 
19597 
diff
changeset
 | 
812  | 
let  | 
| 21015 | 813  | 
val (ps, t') = CodegenThingol.unfold_abs t;  | 
814  | 
fun pr ((v, SOME p), _) vars =  | 
|
815  | 
let  | 
|
| 21093 | 816  | 
val vars' = CodegenThingol.intro_vars [v] vars;  | 
817  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
|
818  | 
val vars'' = CodegenThingol.intro_vars vs vars';  | 
|
819  | 
in  | 
|
820  | 
((Pretty.block o Pretty.breaks) [str (CodegenThingol.lookup_var vars' v),  | 
|
821  | 
str "@", pr_term vars'' BR p], vars'')  | 
|
822  | 
end  | 
|
| 21015 | 823  | 
| pr ((v, NONE), _) vars =  | 
824  | 
let  | 
|
| 21082 | 825  | 
val vars' = CodegenThingol.intro_vars [v] vars;  | 
826  | 
in (str (CodegenThingol.lookup_var vars' v), vars') end;  | 
|
| 21015 | 827  | 
val (ps', vars') = fold_map pr ps vars;  | 
| 20896 | 828  | 
in  | 
829  | 
brackify BR (  | 
|
830  | 
str "\\"  | 
|
| 21015 | 831  | 
:: ps' @ [  | 
| 20896 | 832  | 
str "->",  | 
833  | 
pr_term vars' NOBR t'  | 
|
834  | 
])  | 
|
835  | 
end  | 
|
| 21015 | 836  | 
| pr_term vars fxy (INum n) =  | 
| 20896 | 837  | 
if n > 0 then  | 
838  | 
(str o IntInf.toString) n  | 
|
839  | 
else  | 
|
840  | 
brackify BR [(str o Library.prefix "-" o IntInf.toString o IntInf.~) n]  | 
|
| 21015 | 841  | 
| pr_term vars fxy (IChar c) =  | 
| 20896 | 842  | 
(str o enclose "'" "'")  | 
843  | 
(let val i = (Char.ord o the o Char.fromString) c  | 
|
844  | 
in if i < 32  | 
|
845  | 
then Library.prefix "\\" (string_of_int i)  | 
|
846  | 
else c  | 
|
847  | 
end)  | 
|
| 21015 | 848  | 
| pr_term vars fxy (t as ICase (_, [_])) =  | 
| 18216 | 849  | 
let  | 
| 20896 | 850  | 
val (ts, t) = CodegenThingol.unfold_let t;  | 
851  | 
fun pr ((p, _), t) vars =  | 
|
852  | 
let  | 
|
853  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
|
| 21082 | 854  | 
val vars' = CodegenThingol.intro_vars vs vars;  | 
| 20896 | 855  | 
in  | 
856  | 
((Pretty.block o Pretty.breaks) [  | 
|
857  | 
pr_term vars' BR p,  | 
|
858  | 
str "=",  | 
|
859  | 
pr_term vars NOBR t  | 
|
860  | 
], vars')  | 
|
861  | 
end;  | 
|
862  | 
val (binds, vars') = fold_map pr ts vars;  | 
|
863  | 
in Pretty.chunks [  | 
|
| 21162 | 864  | 
[str "(let", Pretty.fbrk, binds |> Pretty.chunks] |> Pretty.block,  | 
865  | 
[str "in ", pr_term vars' NOBR t, str ")"] |> Pretty.block  | 
|
| 20896 | 866  | 
] end  | 
| 21015 | 867  | 
| pr_term vars fxy (ICase ((td, _), bs)) =  | 
| 20896 | 868  | 
let  | 
869  | 
fun pr (p, t) =  | 
|
870  | 
let  | 
|
871  | 
val vs = CodegenThingol.fold_varnames (insert (op =)) p [];  | 
|
| 21082 | 872  | 
val vars' = CodegenThingol.intro_vars vs vars;  | 
| 20896 | 873  | 
in  | 
874  | 
(Pretty.block o Pretty.breaks) [  | 
|
875  | 
pr_term vars' NOBR p,  | 
|
876  | 
str "->",  | 
|
877  | 
pr_term vars' NOBR t  | 
|
878  | 
]  | 
|
879  | 
end  | 
|
880  | 
in  | 
|
881  | 
            (Pretty.enclose "(" ")" o Pretty.breaks) [
 | 
|
882  | 
str "case",  | 
|
883  | 
pr_term vars NOBR td,  | 
|
884  | 
str "of",  | 
|
885  | 
(Pretty.chunks o map pr) bs  | 
|
886  | 
]  | 
|
887  | 
end  | 
|
| 20976 | 888  | 
and pr_app' vars ((c, _), ts) =  | 
| 20896 | 889  | 
(str o deresolv) c :: map (pr_term vars BR) ts  | 
890  | 
and pr_app vars fxy =  | 
|
891  | 
mk_app (pr_app' vars) (pr_term vars) const_syntax fxy;  | 
|
892  | 
fun pr_def (name, CodegenThingol.Fun (funn as (eqs, (vs, ty)))) =  | 
|
893  | 
let  | 
|
| 21082 | 894  | 
val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;  | 
| 20896 | 895  | 
fun pr_eq (ts, t) =  | 
| 20699 | 896  | 
let  | 
897  | 
val consts = map_filter  | 
|
898  | 
(fn c => if (is_some o const_syntax) c  | 
|
| 20896 | 899  | 
then NONE else (SOME o NameSpace.base o deresolv) c)  | 
900  | 
((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);  | 
|
901  | 
val vars = keyword_vars  | 
|
| 21082 | 902  | 
|> CodegenThingol.intro_vars consts  | 
903  | 
|> CodegenThingol.intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);  | 
|
| 20699 | 904  | 
in  | 
905  | 
(Pretty.block o Pretty.breaks) (  | 
|
| 20896 | 906  | 
(str o deresolv_here) name  | 
907  | 
:: map (pr_term vars BR) ts  | 
|
908  | 
@ [str "=", pr_term vars NOBR t]  | 
|
| 20699 | 909  | 
)  | 
| 20896 | 910  | 
end;  | 
911  | 
in  | 
|
912  | 
Pretty.chunks (  | 
|
913  | 
Pretty.block [  | 
|
914  | 
(str o suffix " ::" o deresolv_here) name,  | 
|
915  | 
Pretty.brk 1,  | 
|
916  | 
pr_typscheme tyvars (vs, ty)  | 
|
917  | 
]  | 
|
918  | 
:: (map pr_eq o fst o snd o constructive_fun) (name, funn)  | 
|
919  | 
)  | 
|
| 21082 | 920  | 
end  | 
| 20896 | 921  | 
| pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =  | 
922  | 
let  | 
|
| 21082 | 923  | 
val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;  | 
| 18216 | 924  | 
in  | 
| 21082 | 925  | 
(Pretty.block o Pretty.breaks) ([  | 
| 20896 | 926  | 
str "newtype",  | 
927  | 
pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs)),  | 
|
928  | 
str "=",  | 
|
929  | 
(str o deresolv_here) co,  | 
|
930  | 
pr_typ tyvars BR ty  | 
|
| 21093 | 931  | 
] @ (if deriving_show name then [str "deriving (Read, Show)"] else []))  | 
| 21082 | 932  | 
end  | 
| 20896 | 933  | 
| pr_def (name, CodegenThingol.Datatype (vs, co :: cos)) =  | 
934  | 
let  | 
|
| 21082 | 935  | 
val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;  | 
| 20896 | 936  | 
fun pr_co (co, tys) =  | 
937  | 
(Pretty.block o Pretty.breaks) (  | 
|
938  | 
(str o deresolv_here) co  | 
|
939  | 
:: map (pr_typ tyvars BR) tys  | 
|
940  | 
)  | 
|
941  | 
in  | 
|
| 21082 | 942  | 
(Pretty.block o Pretty.breaks) ((  | 
| 20896 | 943  | 
str "data"  | 
944  | 
:: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))  | 
|
945  | 
:: str "="  | 
|
946  | 
:: pr_co co  | 
|
947  | 
:: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos  | 
|
| 21093 | 948  | 
) @ (if deriving_show name then [str "deriving (Read, Show)"] else []))  | 
| 21082 | 949  | 
end  | 
| 20896 | 950  | 
| pr_def (name, CodegenThingol.Class (superclasss, (v, classops))) =  | 
951  | 
let  | 
|
| 21082 | 952  | 
val tyvars = CodegenThingol.intro_vars [v] keyword_vars;  | 
| 20896 | 953  | 
fun pr_classop (classop, ty) =  | 
| 19136 | 954  | 
Pretty.block [  | 
| 20896 | 955  | 
str (deresolv_here classop ^ " ::"),  | 
| 19136 | 956  | 
Pretty.brk 1,  | 
| 20896 | 957  | 
pr_typ tyvars NOBR ty  | 
| 19136 | 958  | 
]  | 
| 20896 | 959  | 
in  | 
960  | 
Pretty.block [  | 
|
961  | 
str "class ",  | 
|
962  | 
pr_typparms tyvars [(v, superclasss)],  | 
|
| 21082 | 963  | 
str (deresolv_here name ^ " " ^ CodegenThingol.lookup_var tyvars v),  | 
| 20896 | 964  | 
str " where",  | 
965  | 
Pretty.fbrk,  | 
|
966  | 
Pretty.chunks (map pr_classop classops)  | 
|
967  | 
]  | 
|
| 21082 | 968  | 
end  | 
| 20896 | 969  | 
| pr_def (_, CodegenThingol.Classinst ((class, (tyco, vs)), (_, classop_defs))) =  | 
970  | 
let  | 
|
| 21082 | 971  | 
val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;  | 
| 20896 | 972  | 
in  | 
973  | 
Pretty.block [  | 
|
974  | 
str "instance ",  | 
|
975  | 
pr_typparms tyvars vs,  | 
|
976  | 
str (class_name class ^ " "),  | 
|
977  | 
pr_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),  | 
|
978  | 
str " where",  | 
|
979  | 
Pretty.fbrk,  | 
|
980  | 
Pretty.chunks (map (fn (classop, t) =>  | 
|
981  | 
let  | 
|
982  | 
val consts = map_filter  | 
|
983  | 
(fn c => if (is_some o const_syntax) c  | 
|
984  | 
then NONE else (SOME o NameSpace.base o deresolv) c)  | 
|
985  | 
(CodegenThingol.fold_constnames (insert (op =)) t []);  | 
|
986  | 
val vars = keyword_vars  | 
|
| 21082 | 987  | 
|> CodegenThingol.intro_vars consts;  | 
| 20896 | 988  | 
in  | 
989  | 
(Pretty.block o Pretty.breaks) [  | 
|
990  | 
(str o classop_name class) classop,  | 
|
991  | 
str "=",  | 
|
992  | 
pr_term vars NOBR t  | 
|
993  | 
]  | 
|
994  | 
end  | 
|
995  | 
) classop_defs)  | 
|
996  | 
]  | 
|
| 21082 | 997  | 
end;  | 
| 20940 | 998  | 
in pr_def def end;  | 
| 20896 | 999  | 
|
| 21015 | 1000  | 
val reserved_haskell = [  | 
1001  | 
"hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",  | 
|
1002  | 
"import", "default", "forall", "let", "in", "class", "qualified", "data",  | 
|
1003  | 
"newtype", "instance", "if", "then", "else", "type", "as", "do", "module"  | 
|
1004  | 
];  | 
|
1005  | 
||
| 21082 | 1006  | 
fun seri_haskell module_prefix destination string_classes reserved_user module_alias module_prolog  | 
| 21015 | 1007  | 
class_syntax tyco_syntax const_syntax code =  | 
1008  | 
let  | 
|
| 21082 | 1009  | 
val _ = Option.map File.assert destination;  | 
1010  | 
val empty_names = Name.make_context (reserved_haskell @ reserved_user);  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1011  | 
fun name_modl modl =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1012  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1013  | 
val modlname = NameSpace.pack modl  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1014  | 
in (modlname, case module_alias modlname  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1015  | 
of SOME modlname' => (case module_prefix  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1016  | 
of NONE => modlname'  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1017  | 
| SOME module_prefix => NameSpace.append module_prefix modlname')  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1018  | 
| NONE => NameSpace.pack (map_filter I (module_prefix :: map (fn name => (SOME o the_single o fst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1019  | 
(Name.variants [name] empty_names)) modl)))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1020  | 
end;  | 
| 21082 | 1021  | 
fun add_def (name, (def, deps)) =  | 
1022  | 
let  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1023  | 
fun name_def base nsp = nsp |> Name.variants [base] |>> the_single;  | 
| 21082 | 1024  | 
val (modl, (shallow, base)) = dest_name name;  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1025  | 
fun add_name (nsp as (nsp_fun, nsp_typ)) =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1026  | 
let  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1027  | 
val base' = if member (op =)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1028  | 
[CodegenNames.nsp_class, CodegenNames.nsp_tyco, CodegenNames.nsp_dtco] shallow  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1029  | 
then first_upper base else base;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1030  | 
in case def  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1031  | 
of CodegenThingol.Bot => (base', nsp)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1032  | 
| CodegenThingol.Fun _ => let val (base'', nsp_fun') = name_def base' nsp_fun in (base'', (nsp_fun', nsp_typ)) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1033  | 
| CodegenThingol.Datatype _ => let val (base'', nsp_typ') = name_def base' nsp_typ in (base'', (nsp_fun, nsp_typ')) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1034  | 
| CodegenThingol.Datatypecons _ => let val (base'', nsp_fun') = name_def base' nsp_fun in (base'', (nsp_fun', nsp_typ)) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1035  | 
| CodegenThingol.Class _ => let val (base'', nsp_typ') = name_def base' nsp_typ in (base'', (nsp_fun, nsp_typ')) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1036  | 
| CodegenThingol.Classop _ => let val (base'', nsp_fun') = name_def base' nsp_fun in (base'', (nsp_fun', nsp_typ)) end  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1037  | 
| CodegenThingol.Classinst _ => (base', nsp)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1038  | 
end;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1039  | 
val (modlname, modlname') = name_modl modl;  | 
| 21082 | 1040  | 
val deps' = remove (op =) modlname (map (NameSpace.qualifier o NameSpace.qualifier) deps);  | 
1041  | 
fun add_def base' =  | 
|
1042  | 
case def  | 
|
| 21093 | 1043  | 
of CodegenThingol.Bot => I  | 
1044  | 
| CodegenThingol.Datatypecons _ => I  | 
|
| 21082 | 1045  | 
cons (name, ((NameSpace.append modlname' base', base'), NONE))  | 
1046  | 
| CodegenThingol.Classop _ =>  | 
|
1047  | 
cons (name, ((NameSpace.append modlname' base', base'), NONE))  | 
|
1048  | 
| _ => cons (name, ((NameSpace.append modlname' base', base'), SOME def));  | 
|
1049  | 
in  | 
|
| 21093 | 1050  | 
Symtab.map_default (modlname, (modlname', ([], ([], (empty_names, empty_names)))))  | 
| 21082 | 1051  | 
((apsnd o apfst) (fold (insert (op =)) deps'))  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1052  | 
#> `(fn code => add_name ((snd o snd o snd o the o Symtab.lookup code) modlname))  | 
| 21082 | 1053  | 
#-> (fn (base', names) =>  | 
1054  | 
Symtab.map_entry modlname ((apsnd o apsnd) (fn (defs, _) =>  | 
|
1055  | 
(add_def base' defs, names))))  | 
|
1056  | 
end;  | 
|
1057  | 
val code' =  | 
|
1058  | 
fold add_def (AList.make (fn name => (Graph.get_node code name, Graph.imm_succs code name))  | 
|
1059  | 
(Graph.strong_conn code |> flat)) Symtab.empty;  | 
|
1060  | 
val init_vars = CodegenThingol.make_vars (reserved_haskell @ reserved_user);  | 
|
1061  | 
fun deresolv name =  | 
|
1062  | 
(fst o fst o the o AList.lookup (op =) ((fst o snd o snd o the  | 
|
1063  | 
o Symtab.lookup code') ((NameSpace.qualifier o NameSpace.qualifier) name))) name;  | 
|
1064  | 
fun deresolv_here name =  | 
|
1065  | 
(snd o fst o the o AList.lookup (op =) ((fst o snd o snd o the  | 
|
1066  | 
o Symtab.lookup code') ((NameSpace.qualifier o NameSpace.qualifier) name))) name;  | 
|
1067  | 
val deresolv_module = fst o the o Symtab.lookup code';  | 
|
1068  | 
fun deriving_show tyco =  | 
|
1069  | 
let  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1070  | 
fun deriv _ "fun" = false  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1071  | 
| deriv tycos tyco = member (op =) tycos tyco orelse  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1072  | 
case the_default CodegenThingol.Bot (try (Graph.get_node code) tyco)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1073  | 
of CodegenThingol.Bot => true  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1074  | 
| CodegenThingol.Datatype (_, cs) => forall (deriv' (tyco :: tycos))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1075  | 
(maps snd cs)  | 
| 21082 | 1076  | 
and deriv' tycos (tyco `%% tys) = deriv tycos tyco  | 
1077  | 
andalso forall (deriv' tycos) tys  | 
|
1078  | 
| deriv' _ (ITyVar _) = true  | 
|
1079  | 
in deriv [] tyco end;  | 
|
1080  | 
val seri_def = pr_haskell class_syntax tyco_syntax const_syntax init_vars  | 
|
1081  | 
deresolv_here deresolv (if string_classes then deriving_show else K false);  | 
|
1082  | 
fun write_module (SOME destination) modlname p =  | 
|
1083  | 
let  | 
|
1084  | 
val filename = case modlname  | 
|
1085  | 
of "" => Path.unpack "Main.hs"  | 
|
1086  | 
| _ => (Path.ext "hs" o Path.unpack o implode o separate "/" o NameSpace.unpack) modlname;  | 
|
1087  | 
val pathname = Path.append destination filename;  | 
|
1088  | 
val _ = File.mkdir (Path.dir pathname);  | 
|
1089  | 
in File.write pathname (Pretty.setmp_margin 999999 Pretty.output p ^ "\n") end  | 
|
1090  | 
| write_module NONE _ p =  | 
|
1091  | 
writeln (Pretty.setmp_margin 999999 Pretty.output p ^ "\n");  | 
|
1092  | 
fun seri_module (modlname, (modlname', (imports, (defs, _)))) =  | 
|
1093  | 
Pretty.chunks (  | 
|
1094  | 
        str ("module " ^ modlname' ^ " where")
 | 
|
1095  | 
:: map str (distinct (op =) (map (prefix "import qualified " o deresolv_module) imports)) @ (  | 
|
1096  | 
(case module_prolog modlname  | 
|
1097  | 
of SOME prolog => [str "", prolog, str ""]  | 
|
1098  | 
| NONE => [str ""])  | 
|
1099  | 
@ separate (str "") (map_filter  | 
|
1100  | 
(fn (name, (_, SOME def)) => SOME (seri_def (name, def))  | 
|
1101  | 
| (_, (_, NONE)) => NONE) defs))  | 
|
1102  | 
) |> write_module destination modlname';  | 
|
1103  | 
in Symtab.fold (fn modl => fn () => seri_module modl) code' () end;  | 
|
| 21015 | 1104  | 
|
| 21082 | 1105  | 
val isar_seri_haskell =  | 
1106  | 
parse_args (Scan.option (Args.$$$ "root" -- Args.colon |-- Args.name)  | 
|
1107  | 
-- Scan.optional (Args.$$$ "string_classes" >> K true) false  | 
|
1108  | 
-- (Args.$$$ "-" >> K NONE || Args.name >> SOME)  | 
|
1109  | 
>> (fn ((module_prefix, string_classes), destination) =>  | 
|
1110  | 
seri_haskell module_prefix (Option.map Path.unpack destination) string_classes));  | 
|
| 21015 | 1111  | 
|
1112  | 
||
1113  | 
(** diagnosis serializer **)  | 
|
1114  | 
||
1115  | 
fun seri_diagnosis _ _ _ _ _ code =  | 
|
1116  | 
let  | 
|
| 21082 | 1117  | 
val init_vars = CodegenThingol.make_vars reserved_haskell;  | 
1118  | 
val pr = pr_haskell (K NONE) (K NONE) (K NONE) init_vars I I (K false);  | 
|
| 21015 | 1119  | 
in  | 
1120  | 
[]  | 
|
| 21093 | 1121  | 
|> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code  | 
| 21015 | 1122  | 
|> separate (Pretty.str "")  | 
1123  | 
|> Pretty.chunks  | 
|
1124  | 
|> Pretty.writeln  | 
|
1125  | 
end;  | 
|
1126  | 
||
1127  | 
||
| 20896 | 1128  | 
|
1129  | 
(** theory data **)  | 
|
1130  | 
||
1131  | 
datatype syntax_expr = SyntaxExpr of {
 | 
|
1132  | 
class: ((string * (string -> string option)) * serial) Symtab.table,  | 
|
1133  | 
inst: unit Symtab.table,  | 
|
1134  | 
tyco: (itype pretty_syntax * serial) Symtab.table,  | 
|
1135  | 
const: (iterm pretty_syntax * serial) Symtab.table  | 
|
1136  | 
};  | 
|
| 18702 | 1137  | 
|
| 20896 | 1138  | 
fun mk_syntax_expr ((class, inst), (tyco, const)) =  | 
1139  | 
  SyntaxExpr { class = class, inst = inst, tyco = tyco, const = const };
 | 
|
1140  | 
fun map_syntax_expr f (SyntaxExpr { class, inst, tyco, const }) =
 | 
|
1141  | 
mk_syntax_expr (f ((class, inst), (tyco, const)));  | 
|
1142  | 
fun merge_syntax_expr (SyntaxExpr { class = class1, inst = inst1, tyco = tyco1, const = const1 },
 | 
|
1143  | 
    SyntaxExpr { class = class2, inst = inst2, tyco = tyco2, const = const2 }) =
 | 
|
1144  | 
mk_syntax_expr (  | 
|
1145  | 
(Symtab.merge (eq_snd (op =)) (class1, class2),  | 
|
1146  | 
Symtab.merge (op =) (inst1, inst2)),  | 
|
1147  | 
(Symtab.merge (eq_snd (op =)) (tyco1, tyco2),  | 
|
1148  | 
Symtab.merge (eq_snd (op =)) (const1, const2))  | 
|
1149  | 
);  | 
|
1150  | 
||
1151  | 
datatype syntax_modl = SyntaxModl of {
 | 
|
| 21015 | 1152  | 
alias: string Symtab.table,  | 
| 20896 | 1153  | 
prolog: Pretty.T Symtab.table  | 
1154  | 
};  | 
|
| 20699 | 1155  | 
|
| 21015 | 1156  | 
fun mk_syntax_modl (alias, prolog) =  | 
1157  | 
  SyntaxModl { alias = alias, prolog = prolog };
 | 
|
1158  | 
fun map_syntax_modl f (SyntaxModl { alias, prolog }) =
 | 
|
1159  | 
mk_syntax_modl (f (alias, prolog));  | 
|
1160  | 
fun merge_syntax_modl (SyntaxModl { alias = alias1, prolog = prolog1 },
 | 
|
1161  | 
    SyntaxModl { alias = alias2, prolog = prolog2 }) =
 | 
|
| 20896 | 1162  | 
mk_syntax_modl (  | 
| 21015 | 1163  | 
Symtab.merge (op =) (alias1, alias2),  | 
| 20896 | 1164  | 
Symtab.merge (op =) (prolog1, prolog2)  | 
1165  | 
);  | 
|
| 20699 | 1166  | 
|
| 21015 | 1167  | 
type serializer = Args.T list  | 
1168  | 
-> string list  | 
|
1169  | 
-> (string -> string option)  | 
|
1170  | 
-> (string -> Pretty.T option)  | 
|
1171  | 
-> (string -> (string * (string -> string option)) option)  | 
|
1172  | 
-> (string -> (int * (fixity -> (fixity -> itype -> Pretty.T) -> itype list -> Pretty.T)) option)  | 
|
1173  | 
-> (string -> (int * (fixity -> (fixity -> iterm -> Pretty.T) -> iterm list -> Pretty.T)) option)  | 
|
1174  | 
-> CodegenThingol.code -> unit;  | 
|
| 20896 | 1175  | 
|
1176  | 
datatype target = Target of {
 | 
|
1177  | 
serial: serial,  | 
|
1178  | 
serializer: serializer,  | 
|
1179  | 
syntax_expr: syntax_expr,  | 
|
| 21015 | 1180  | 
syntax_modl: syntax_modl,  | 
1181  | 
reserved: string list  | 
|
| 20896 | 1182  | 
};  | 
| 20699 | 1183  | 
|
| 21015 | 1184  | 
fun mk_target (serial, ((serializer, reserved), (syntax_expr, syntax_modl))) =  | 
1185  | 
  Target { serial = serial, reserved = reserved, serializer = serializer, syntax_expr = syntax_expr, syntax_modl = syntax_modl };
 | 
|
1186  | 
fun map_target f ( Target { serial, serializer, reserved, syntax_expr, syntax_modl } ) =
 | 
|
1187  | 
mk_target (f (serial, ((serializer, reserved), (syntax_expr, syntax_modl))));  | 
|
1188  | 
fun merge_target target (Target { serial = serial1, serializer = serializer, reserved = reserved1,
 | 
|
1189  | 
syntax_expr = syntax_expr1, syntax_modl = syntax_modl1 },  | 
|
1190  | 
    Target { serial = serial2, serializer = _, reserved = reserved2,
 | 
|
1191  | 
syntax_expr = syntax_expr2, syntax_modl = syntax_modl2 }) =  | 
|
| 20896 | 1192  | 
if serial1 = serial2 then  | 
| 21015 | 1193  | 
mk_target (serial1, ((serializer, merge (op =) (reserved1, reserved2)),  | 
| 20896 | 1194  | 
(merge_syntax_expr (syntax_expr1, syntax_expr2),  | 
1195  | 
merge_syntax_modl (syntax_modl1, syntax_modl2))  | 
|
1196  | 
))  | 
|
1197  | 
else  | 
|
1198  | 
    error ("Incompatible serializers: " ^ quote target);
 | 
|
1199  | 
||
1200  | 
structure CodegenSerializerData = TheoryDataFun  | 
|
1201  | 
(struct  | 
|
1202  | 
val name = "Pure/codegen_serializer";  | 
|
1203  | 
type T = target Symtab.table;  | 
|
1204  | 
val empty = Symtab.empty;  | 
|
1205  | 
val copy = I;  | 
|
1206  | 
val extend = I;  | 
|
1207  | 
fun merge _ = Symtab.join merge_target;  | 
|
1208  | 
fun print _ _ = ();  | 
|
1209  | 
end);  | 
|
1210  | 
||
1211  | 
fun the_serializer (Target { serializer, ... }) = serializer;
 | 
|
| 21015 | 1212  | 
fun the_reserved (Target { reserved, ... }) = reserved;
 | 
| 20896 | 1213  | 
fun the_syntax_expr (Target { syntax_expr = SyntaxExpr x, ... }) = x;
 | 
1214  | 
fun the_syntax_modl (Target { syntax_modl = SyntaxModl x, ... }) = x;
 | 
|
1215  | 
||
1216  | 
fun add_serializer (target, seri) thy =  | 
|
| 18702 | 1217  | 
let  | 
| 20896 | 1218  | 
val _ = case Symtab.lookup (CodegenSerializerData.get thy) target  | 
1219  | 
     of SOME _ => warning ("overwriting existing serializer " ^ quote target)
 | 
|
1220  | 
| NONE => ();  | 
|
| 20699 | 1221  | 
in  | 
| 20896 | 1222  | 
thy  | 
1223  | 
|> (CodegenSerializerData.map oo Symtab.map_default)  | 
|
| 21015 | 1224  | 
(target, mk_target (serial (), ((seri, []),  | 
| 20896 | 1225  | 
(mk_syntax_expr ((Symtab.empty, Symtab.empty), (Symtab.empty, Symtab.empty)),  | 
1226  | 
mk_syntax_modl (Symtab.empty, Symtab.empty)))))  | 
|
| 21015 | 1227  | 
(map_target (fn (serial, ((_, keywords), syntax)) => (serial, ((seri, keywords), syntax))))  | 
| 20699 | 1228  | 
end;  | 
1229  | 
||
| 21015 | 1230  | 
fun map_seri_data target f thy =  | 
1231  | 
let  | 
|
1232  | 
val _ = if is_some (Symtab.lookup (CodegenSerializerData.get thy) target)  | 
|
1233  | 
then ()  | 
|
1234  | 
      else error ("Unknown code target language: " ^ quote target);
 | 
|
1235  | 
in  | 
|
1236  | 
thy  | 
|
1237  | 
|> (CodegenSerializerData.map o Symtab.map_entry target o map_target) f  | 
|
1238  | 
end;  | 
|
1239  | 
||
1240  | 
val target_diag = "diag";  | 
|
1241  | 
||
| 20896 | 1242  | 
val _ = Context.add_setup (  | 
1243  | 
CodegenSerializerData.init  | 
|
| 21130 | 1244  | 
  #> add_serializer ("SML", isar_seri_sml)
 | 
| 21082 | 1245  | 
  #> add_serializer ("Haskell", isar_seri_haskell)
 | 
| 21015 | 1246  | 
#> add_serializer (target_diag, (fn _ => fn _ => seri_diagnosis))  | 
| 20896 | 1247  | 
);  | 
1248  | 
||
| 21015 | 1249  | 
fun get_serializer thy target args cs =  | 
| 20896 | 1250  | 
let  | 
1251  | 
val data = case Symtab.lookup (CodegenSerializerData.get thy) target  | 
|
1252  | 
of SOME data => data  | 
|
1253  | 
      | NONE => error ("Unknown code target language: " ^ quote target);
 | 
|
1254  | 
val seri = the_serializer data;  | 
|
| 21015 | 1255  | 
val reserved = the_reserved data;  | 
1256  | 
    val { alias, prolog } = the_syntax_modl data;
 | 
|
| 20896 | 1257  | 
    val { class, inst, tyco, const } = the_syntax_expr data;
 | 
1258  | 
fun fun_of sys = (Option.map fst oo Symtab.lookup) sys;  | 
|
| 21015 | 1259  | 
val project = if target = target_diag then I  | 
1260  | 
else CodegenThingol.project_code  | 
|
1261  | 
(Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const) cs;  | 
|
| 20896 | 1262  | 
in  | 
| 21015 | 1263  | 
project #> seri args reserved (Symtab.lookup alias) (Symtab.lookup prolog)  | 
1264  | 
(fun_of class) (fun_of tyco) (fun_of const)  | 
|
| 20896 | 1265  | 
end;  | 
1266  | 
||
| 21162 | 1267  | 
val eval_verbose = ref false;  | 
1268  | 
||
1269  | 
fun eval_term thy ((ref_name, reff), t) code =  | 
|
1270  | 
let  | 
|
1271  | 
val val_name = "eval.VALUE.EVAL";  | 
|
1272  | 
val val_name' = "ROOT.eval.EVAL";  | 
|
1273  | 
val data = (the o Symtab.lookup (CodegenSerializerData.get thy)) "SML"  | 
|
1274  | 
val reserved = the_reserved data;  | 
|
1275  | 
    val { alias, prolog } = the_syntax_modl data;
 | 
|
1276  | 
    val { class, inst, tyco, const } = the_syntax_expr data;
 | 
|
1277  | 
fun fun_of sys = (Option.map fst oo Symtab.lookup) sys;  | 
|
1278  | 
fun eval p = (  | 
|
1279  | 
reff := NONE;  | 
|
1280  | 
if !eval_verbose then Pretty.writeln p else ();  | 
|
1281  | 
use_text Output.ml_output (!eval_verbose)  | 
|
1282  | 
((Pretty.output o Pretty.chunks) [p,  | 
|
1283  | 
          str ("val _ = (" ^ ref_name ^ " := SOME " ^ val_name' ^ ")")
 | 
|
1284  | 
]);  | 
|
1285  | 
case !reff  | 
|
1286  | 
       of NONE => error ("Could not retrieve value of ML reference " ^ quote ref_name
 | 
|
1287  | 
^ " (reference probably has been shadowed)")  | 
|
1288  | 
| SOME value => value  | 
|
1289  | 
);  | 
|
1290  | 
in  | 
|
1291  | 
code  | 
|
1292  | 
|> CodegenThingol.add_eval_def (val_name, t)  | 
|
1293  | 
|> CodegenThingol.project_code  | 
|
1294  | 
(Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const)  | 
|
1295  | 
(SOME [val_name])  | 
|
1296  | 
|> seri_sml I reserved (Symtab.lookup alias) (Symtab.lookup prolog)  | 
|
1297  | 
(fun_of class) (fun_of tyco) (fun_of const)  | 
|
1298  | 
|> eval  | 
|
1299  | 
end;  | 
|
1300  | 
||
| 21082 | 1301  | 
fun assert_serializer thy target =  | 
1302  | 
case Symtab.lookup (CodegenSerializerData.get thy) target  | 
|
1303  | 
of SOME data => target  | 
|
1304  | 
    | NONE => error ("Unknown code target language: " ^ quote target);
 | 
|
1305  | 
||
| 20896 | 1306  | 
fun has_serialization f thy targets name =  | 
1307  | 
forall (  | 
|
1308  | 
is_some o (fn tab => Symtab.lookup tab name) o f o the_syntax_expr o the  | 
|
1309  | 
o (Symtab.lookup ((CodegenSerializerData.get) thy))  | 
|
1310  | 
) targets;  | 
|
1311  | 
||
1312  | 
val tyco_has_serialization = has_serialization #tyco;  | 
|
1313  | 
val const_has_serialization = has_serialization #const;  | 
|
1314  | 
||
1315  | 
||
| 20699 | 1316  | 
|
| 20931 | 1317  | 
(** ML and toplevel interface **)  | 
| 20699 | 1318  | 
|
1319  | 
local  | 
|
1320  | 
||
| 21015 | 1321  | 
fun map_syntax_exprs target =  | 
1322  | 
map_seri_data target o (apsnd o apsnd o apfst o map_syntax_expr);  | 
|
1323  | 
fun map_syntax_modls target =  | 
|
1324  | 
map_seri_data target o (apsnd o apsnd o apsnd o map_syntax_modl);  | 
|
1325  | 
fun map_reserveds target =  | 
|
1326  | 
map_seri_data target o (apsnd o apfst o apsnd);  | 
|
| 20896 | 1327  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1328  | 
fun gen_add_syntax_class prep_class prep_const target raw_class raw_syn thy =  | 
| 20699 | 1329  | 
let  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1330  | 
val cls = prep_class thy raw_class;  | 
| 20699 | 1331  | 
val class = CodegenNames.class thy cls;  | 
| 20896 | 1332  | 
fun mk_classop (const as (c, _)) = case AxClass.class_of_param thy c  | 
1333  | 
of SOME class' => if cls = class' then CodegenNames.const thy const  | 
|
| 20699 | 1334  | 
          else error ("Not a class operation for class " ^ quote class ^ ": " ^ quote c)
 | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1335  | 
      | NONE => error ("Not a class operation: " ^ quote c);
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1336  | 
fun mk_syntax_ops raw_ops = AList.lookup (op =)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1337  | 
((map o apfst) (mk_classop o prep_const thy) raw_ops);  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1338  | 
in case raw_syn  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1339  | 
of SOME (syntax, raw_ops) =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1340  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1341  | 
|> (map_syntax_exprs target o apfst o apfst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1342  | 
(Symtab.update (class, ((syntax, mk_syntax_ops raw_ops), serial ())))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1343  | 
| NONE =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1344  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1345  | 
|> (map_syntax_exprs target o apfst o apfst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1346  | 
(Symtab.delete_safe class)  | 
| 20699 | 1347  | 
end;  | 
1348  | 
||
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1349  | 
fun gen_add_syntax_inst prep_class prep_tyco target (raw_tyco, raw_class) add_del thy =  | 
| 20699 | 1350  | 
let  | 
1351  | 
val inst = CodegenNames.instance thy (prep_class thy raw_class, prep_tyco thy raw_tyco);  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1352  | 
in if add_del then  | 
| 20699 | 1353  | 
thy  | 
| 20896 | 1354  | 
|> (map_syntax_exprs target o apfst o apsnd)  | 
1355  | 
(Symtab.update (inst, ()))  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1356  | 
else  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1357  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1358  | 
|> (map_syntax_exprs target o apfst o apsnd)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1359  | 
(Symtab.delete_safe inst)  | 
| 20699 | 1360  | 
end;  | 
1361  | 
||
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1362  | 
fun gen_add_syntax_tyco prep_tyco target raw_tyco raw_syn thy =  | 
| 20699 | 1363  | 
let  | 
| 21015 | 1364  | 
val tyco = prep_tyco thy raw_tyco;  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1365  | 
val tyco' = if tyco = "fun" then "fun" else CodegenNames.tyco thy tyco;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1366  | 
fun check_args (syntax as (n, _)) = if n <> Sign.arity_number thy tyco  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1367  | 
      then error ("Number of arguments mismatch in syntax for type constructor " ^ quote tyco)
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1368  | 
else syntax  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1369  | 
in case raw_syn  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1370  | 
of SOME syntax =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1371  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1372  | 
|> (map_syntax_exprs target o apsnd o apfst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1373  | 
(Symtab.update (tyco', (check_args syntax, serial ())))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1374  | 
| NONE =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1375  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1376  | 
|> (map_syntax_exprs target o apsnd o apfst)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1377  | 
(Symtab.delete_safe tyco')  | 
| 20699 | 1378  | 
end;  | 
1379  | 
||
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1380  | 
fun gen_add_syntax_const prep_const target raw_c raw_syn thy =  | 
| 20699 | 1381  | 
let  | 
| 21015 | 1382  | 
val c = prep_const thy raw_c;  | 
1383  | 
val c' = CodegenNames.const thy c;  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1384  | 
fun check_args (syntax as (n, _)) = if n > (length o fst o strip_type o Sign.the_const_type thy o fst) c  | 
| 21015 | 1385  | 
      then error ("Too many arguments in syntax for constant " ^ (quote o fst) c)
 | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1386  | 
else syntax;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1387  | 
in case raw_syn  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1388  | 
of SOME syntax =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1389  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1390  | 
|> (map_syntax_exprs target o apsnd o apsnd)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1391  | 
(Symtab.update (c', (check_args syntax, serial ())))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1392  | 
| NONE =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1393  | 
thy  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1394  | 
|> (map_syntax_exprs target o apsnd o apsnd)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1395  | 
(Symtab.delete_safe c')  | 
| 20699 | 1396  | 
end;  | 
1397  | 
||
1398  | 
fun read_type thy raw_tyco =  | 
|
1399  | 
let  | 
|
1400  | 
val tyco = Sign.intern_type thy raw_tyco;  | 
|
1401  | 
val _ = if Sign.declared_tyname thy tyco then ()  | 
|
1402  | 
      else error ("No such type constructor: " ^ quote raw_tyco);
 | 
|
1403  | 
in tyco end;  | 
|
1404  | 
||
1405  | 
fun idfs_of_const_names thy cs =  | 
|
1406  | 
let  | 
|
1407  | 
val cs' = AList.make (fn c => Sign.the_const_type thy c) cs;  | 
|
1408  | 
val cs'' = map (CodegenConsts.norm_of_typ thy) cs';  | 
|
1409  | 
in AList.make (CodegenNames.const thy) cs'' end;  | 
|
1410  | 
||
| 21015 | 1411  | 
val add_syntax_class = gen_add_syntax_class ClassPackage.read_class CodegenConsts.read_const;  | 
1412  | 
val add_syntax_inst = gen_add_syntax_inst ClassPackage.read_class read_type;  | 
|
1413  | 
val add_syntax_tyco = gen_add_syntax_tyco read_type;  | 
|
1414  | 
val add_syntax_const = gen_add_syntax_const CodegenConsts.read_const;  | 
|
1415  | 
||
1416  | 
fun add_reserved target =  | 
|
1417  | 
map_reserveds target o insert (op =);  | 
|
1418  | 
||
1419  | 
fun add_modl_alias target =  | 
|
1420  | 
map_syntax_modls target o apfst o Symtab.update o apsnd CodegenNames.check_modulename;  | 
|
1421  | 
||
1422  | 
fun add_modl_prolog target =  | 
|
1423  | 
map_syntax_modls target o apsnd o  | 
|
1424  | 
(fn (modl, NONE) => Symtab.delete modl | (modl, SOME prolog) =>  | 
|
1425  | 
Symtab.update (modl, Pretty.str prolog));  | 
|
| 20931 | 1426  | 
|
1427  | 
fun zip_list (x::xs) f g =  | 
|
| 21015 | 1428  | 
f  | 
1429  | 
#-> (fn y =>  | 
|
1430  | 
fold_map (fn x => g |-- f >> pair x) xs  | 
|
| 20931 | 1431  | 
#-> (fn xys => pair ((x, y) :: xys)));  | 
| 20699 | 1432  | 
|
| 20931 | 1433  | 
structure P = OuterParse  | 
1434  | 
and K = OuterKeyword  | 
|
| 20699 | 1435  | 
|
| 20931 | 1436  | 
fun parse_multi_syntax parse_thing parse_syntax =  | 
1437  | 
P.and_list1 parse_thing  | 
|
| 21015 | 1438  | 
  #-> (fn things => Scan.repeat1 (P.$$$ "(" |-- P.name --
 | 
1439  | 
(zip_list things parse_syntax (P.$$$ "and")) --| P.$$$ ")"));  | 
|
| 20699 | 1440  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1441  | 
val (infixK, infixlK, infixrK) = ("infix", "infixl", "infixr");
 | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1442  | 
|
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1443  | 
fun parse_syntax xs =  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1444  | 
Scan.option ((  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1445  | 
((P.$$$ infixK >> K X)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1446  | 
|| (P.$$$ infixlK >> K L)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1447  | 
|| (P.$$$ infixrK >> K R))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1448  | 
-- P.nat >> parse_infix  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1449  | 
|| Scan.succeed parse_mixfix)  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1450  | 
-- P.string  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1451  | 
>> (fn (parse, s) => parse s)) xs;  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1452  | 
|
| 21015 | 1453  | 
val (code_classK, code_instanceK, code_typeK, code_constK,  | 
1454  | 
code_reservedK, code_modulenameK, code_moduleprologK) =  | 
|
1455  | 
  ("code_class", "code_instance", "code_type", "code_const",
 | 
|
1456  | 
"code_reserved", "code_modulename", "code_moduleprolog");  | 
|
| 20699 | 1457  | 
|
| 21015 | 1458  | 
in  | 
1459  | 
||
1460  | 
fun add_pretty_list target nill cons mk_list mk_char_string target_cons thy =  | 
|
| 20699 | 1461  | 
let  | 
| 21015 | 1462  | 
val [(_, nil''), (cons', cons'')] = idfs_of_const_names thy [nill, cons];  | 
1463  | 
val pr = pretty_list nil'' cons'' mk_list mk_char_string target_cons;  | 
|
| 20699 | 1464  | 
in  | 
| 21015 | 1465  | 
thy  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1466  | 
|> gen_add_syntax_const (K I) target cons' (SOME pr)  | 
| 20699 | 1467  | 
end;  | 
1468  | 
||
| 21015 | 1469  | 
fun add_pretty_ml_string target nill cons str mk_char mk_string target_implode thy =  | 
| 20699 | 1470  | 
let  | 
| 21015 | 1471  | 
val [(_, nil''), (_, cons''), (str', _)] = idfs_of_const_names thy [nill, cons, str];  | 
1472  | 
val pr = pretty_ml_string nil'' cons'' mk_char mk_string target_implode;  | 
|
| 20699 | 1473  | 
in  | 
| 21015 | 1474  | 
thy  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1475  | 
|> gen_add_syntax_const (K I) target str' (SOME pr)  | 
| 20699 | 1476  | 
end;  | 
1477  | 
||
| 21015 | 1478  | 
fun add_undefined target undef target_undefined thy =  | 
1479  | 
let  | 
|
1480  | 
val [(undef', _)] = idfs_of_const_names thy [undef];  | 
|
1481  | 
fun pretty _ _ _ = str target_undefined;  | 
|
1482  | 
in  | 
|
1483  | 
thy  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1484  | 
|> gen_add_syntax_const (K I) target undef' (SOME (~1, pretty))  | 
| 21015 | 1485  | 
end;  | 
| 20931 | 1486  | 
|
1487  | 
val code_classP =  | 
|
1488  | 
OuterSyntax.command code_classK "define code syntax for class" K.thy_decl (  | 
|
1489  | 
parse_multi_syntax P.xname  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1490  | 
(Scan.option (P.string -- Scan.optional (P.$$$ "where" |-- Scan.repeat1  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1491  | 
(P.term --| (P.$$$ "\\<equiv>" || P.$$$ "==") -- P.string)) []))  | 
| 20931 | 1492  | 
>> (Toplevel.theory oo fold) (fn (target, syns) =>  | 
1493  | 
fold (fn (raw_class, syn) => add_syntax_class target raw_class syn) syns)  | 
|
1494  | 
);  | 
|
1495  | 
||
1496  | 
val code_instanceP =  | 
|
1497  | 
OuterSyntax.command code_instanceK "define code syntax for instance" K.thy_decl (  | 
|
1498  | 
parse_multi_syntax (P.xname --| P.$$$ "::" -- P.xname)  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1499  | 
((P.minus >> K true) || Scan.succeed false)  | 
| 20931 | 1500  | 
>> (Toplevel.theory oo fold) (fn (target, syns) =>  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1501  | 
fold (fn (raw_inst, add_del) => add_syntax_inst target raw_inst add_del) syns)  | 
| 20931 | 1502  | 
);  | 
1503  | 
||
1504  | 
val code_typeP =  | 
|
1505  | 
OuterSyntax.command code_typeK "define code syntax for type constructor" K.thy_decl (  | 
|
| 21015 | 1506  | 
parse_multi_syntax P.xname parse_syntax  | 
1507  | 
>> (Toplevel.theory oo fold) (fn (target, syns) =>  | 
|
1508  | 
fold (fn (raw_tyco, syn) => add_syntax_tyco target raw_tyco syn) syns)  | 
|
| 20931 | 1509  | 
);  | 
1510  | 
||
1511  | 
val code_constP =  | 
|
1512  | 
OuterSyntax.command code_constK "define code syntax for constant" K.thy_decl (  | 
|
| 21015 | 1513  | 
parse_multi_syntax P.term parse_syntax  | 
1514  | 
>> (Toplevel.theory oo fold) (fn (target, syns) =>  | 
|
1515  | 
fold (fn (raw_const, syn) => add_syntax_const target raw_const syn) syns)  | 
|
| 20931 | 1516  | 
);  | 
1517  | 
||
| 21015 | 1518  | 
val code_reservedP =  | 
1519  | 
OuterSyntax.command code_reservedK "declare words as reserved for target language" K.thy_decl (  | 
|
1520  | 
P.name -- Scan.repeat1 P.name  | 
|
1521  | 
>> (fn (target, reserveds) => (Toplevel.theory o fold (add_reserved target)) reserveds)  | 
|
1522  | 
)  | 
|
| 20699 | 1523  | 
|
| 21015 | 1524  | 
val code_modulenameP =  | 
| 21082 | 1525  | 
OuterSyntax.command code_modulenameK "alias module to other name" K.thy_decl (  | 
| 21015 | 1526  | 
P.name -- Scan.repeat1 (P.name -- P.name)  | 
1527  | 
>> (fn (target, modlnames) => (Toplevel.theory o fold (add_modl_alias target)) modlnames)  | 
|
1528  | 
)  | 
|
| 20699 | 1529  | 
|
| 21015 | 1530  | 
val code_moduleprologP =  | 
| 21082 | 1531  | 
OuterSyntax.command code_moduleprologK "add prolog to module" K.thy_decl (  | 
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1532  | 
P.name -- Scan.repeat1 (P.name -- (P.text >> (fn "-" => NONE | s => SOME s)))  | 
| 21015 | 1533  | 
>> (fn (target, prologs) => (Toplevel.theory o fold (add_modl_prolog target)) prologs)  | 
1534  | 
)  | 
|
1535  | 
||
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1536  | 
val _ = OuterSyntax.add_keywords [infixK, infixlK, infixrK];  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1537  | 
|
| 21015 | 1538  | 
val _ = OuterSyntax.add_parsers [code_classP, code_instanceP, code_typeP, code_constP,  | 
1539  | 
code_reservedP, code_modulenameP, code_moduleprologP];  | 
|
| 20699 | 1540  | 
|
| 
21122
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1541  | 
val _ = Context.add_setup (  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1542  | 
gen_add_syntax_tyco (K I) "SML" "fun" (SOME (2, fn fxy => fn pr_typ => fn [ty1, ty2] =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1543  | 
(gen_brackify (case fxy of BR => false | _ => eval_fxy (INFX (1, R)) fxy) o Pretty.breaks) [  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1544  | 
pr_typ (INFX (1, X)) ty1,  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1545  | 
str "->",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1546  | 
pr_typ (INFX (1, R)) ty2  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1547  | 
]))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1548  | 
#> gen_add_syntax_tyco (K I) "Haskell" "fun" (SOME (2, fn fxy => fn pr_typ => fn [ty1, ty2] =>  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1549  | 
brackify_infix (1, R) fxy [  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1550  | 
pr_typ (INFX (1, X)) ty1,  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1551  | 
str "->",  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1552  | 
pr_typ (INFX (1, R)) ty2  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1553  | 
]))  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1554  | 
#> add_reserved "Haskell" "Show"  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1555  | 
#> add_reserved "Haskell" "Read"  | 
| 
 
b1fdd08e0ea3
new serialization syntax; experimental extensions
 
haftmann 
parents: 
21094 
diff
changeset
 | 
1556  | 
)  | 
| 21082 | 1557  | 
|
| 20699 | 1558  | 
end; (*local*)  | 
| 18702 | 1559  | 
|
| 21093 | 1560  | 
end; (*struct*)  |