18 -> string list * string list option |
18 -> string list * string list option |
19 -> CodegenThingol.module -> unit) |
19 -> CodegenThingol.module -> unit) |
20 * OuterParse.token list; |
20 * OuterParse.token list; |
21 val parse_syntax: ('b -> int) -> (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
21 val parse_syntax: ('b -> int) -> (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
22 ('b -> 'a pretty_syntax * 'b) * OuterParse.token list; |
22 ('b -> 'a pretty_syntax * 'b) * OuterParse.token list; |
23 val pretty_list: string -> string -> int * string -> CodegenThingol.iterm pretty_syntax; |
23 val pretty_list: string -> string -> (Pretty.T list -> Pretty.T) |
|
24 -> ((string -> string) * (string -> string)) option |
|
25 -> int * string -> CodegenThingol.iterm pretty_syntax; |
|
26 val pretty_ml_string: string -> string -> (string -> string) -> (string -> string) |
|
27 -> string -> CodegenThingol.iterm pretty_syntax; |
24 val serializers: { |
28 val serializers: { |
25 ml: string * (string -> serializer), |
29 ml: string * (string -> serializer), |
26 haskell: string * (string * string list -> serializer) |
30 haskell: string * (string * string list -> serializer) |
27 }; |
31 }; |
28 val mk_flat_ml_resolver: string list -> string -> string; |
32 val mk_flat_ml_resolver: string list -> string -> string; |
303 >> (fn "_" => serializer |
307 >> (fn "_" => serializer |
304 (fn "" => (fn p => (Pretty.writeln p; NONE)) |
308 (fn "" => (fn p => (Pretty.writeln p; NONE)) |
305 | _ => SOME) |
309 | _ => SOME) |
306 | _ => Scan.fail ()); |
310 | _ => Scan.fail ()); |
307 |
311 |
308 (* list serializer *) |
312 |
309 |
313 (* list and string serializers *) |
310 fun pretty_list thingol_nil thingol_cons (target_pred, target_cons) = |
314 |
|
315 fun implode_list c_nil c_cons e = |
311 let |
316 let |
312 fun dest_cons (IConst (c, _) `$ e1 `$ e2) = |
317 fun dest_cons (IConst (c, _) `$ e1 `$ e2) = |
313 if c = thingol_cons |
318 if c = c_cons |
314 then SOME (e1, e2) |
319 then SOME (e1, e2) |
315 else NONE |
320 else NONE |
316 | dest_cons _ = NONE; |
321 | dest_cons _ = NONE; |
317 fun pretty_default fxy pr e1 e2 = |
322 val (es, e') = CodegenThingol.unfoldr dest_cons e; |
318 brackify_infix (target_pred, R) fxy [ |
323 in case e' |
319 pr (INFX (target_pred, X)) e1, |
324 of IConst (c, _) => if c = c_nil then SOME es else NONE |
|
325 | _ => NONE |
|
326 end; |
|
327 |
|
328 fun implode_string mk_char mk_string es = |
|
329 if forall (fn IChar _ => true | _ => false) es |
|
330 then (SOME o str o mk_string o implode o map (fn IChar (c, _) => mk_char c)) es |
|
331 else NONE; |
|
332 |
|
333 fun pretty_ml_string c_nil c_cons mk_char mk_string target_implode = |
|
334 let |
|
335 fun pretty fxy pr [e] = |
|
336 case implode_list c_nil c_cons e |
|
337 of SOME es => (case implode_string mk_char mk_string es |
|
338 of SOME p => p |
|
339 | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e]) |
|
340 | NONE => Pretty.block [str target_implode, Pretty.brk 1, pr BR e] |
|
341 in ((1, 1), pretty) end; |
|
342 |
|
343 fun pretty_list c_nil c_cons mk_list mk_char_string (target_fxy, target_cons) = |
|
344 let |
|
345 fun default fxy pr e1 e2 = |
|
346 brackify_infix (target_fxy, R) fxy [ |
|
347 pr (INFX (target_fxy, X)) e1, |
320 str target_cons, |
348 str target_cons, |
321 pr (INFX (target_pred, R)) e2 |
349 pr (INFX (target_fxy, R)) e2 |
322 ]; |
350 ]; |
323 fun pretty_compact fxy pr [e1, e2] = |
351 fun pretty fxy pr [e1, e2] = |
324 case CodegenThingol.unfoldr dest_cons e2 |
352 case Option.map (cons e1) (implode_list c_nil c_cons e2) |
325 of (es, IConst (c, _)) => |
353 of SOME es => |
326 if c = thingol_nil |
354 (case mk_char_string |
327 then Pretty.enum "," "[" "]" (map (pr NOBR) (e1::es)) |
355 of SOME (mk_char, mk_string) => |
328 else pretty_default fxy pr e1 e2 |
356 (case implode_string mk_char mk_string es |
329 | _ => pretty_default fxy pr e1 e2; |
357 of SOME p => p |
330 in ((2, 2), pretty_compact) end; |
358 | NONE => mk_list (map (pr NOBR) es)) |
|
359 | NONE => mk_list (map (pr NOBR) es)) |
|
360 | NONE => default fxy pr e1 e2; |
|
361 in ((2, 2), pretty) end; |
331 |
362 |
332 |
363 |
333 |
364 |
334 (** ML serializer **) |
365 (** ML serializer **) |
335 |
366 |
336 local |
367 local |
337 |
368 |
338 val reserved_ml = ThmDatabase.ml_reserved @ [ |
369 val reserved_ml = ThmDatabase.ml_reserved @ [ |
339 "bool", "int", "list", "unit", "option", "true", "false", "not", "None", "Some", "o" |
370 "bool", "int", "list", "unit", "option", "true", "false", "not", "NONE", "SOME", |
340 ]; (* FIXME None/Some no longer used *) |
371 "o", "string", "char", "String", "Term" |
|
372 ]; |
341 |
373 |
342 structure NameMangler = NameManglerFun ( |
374 structure NameMangler = NameManglerFun ( |
343 type ctxt = string list; |
375 type ctxt = string list; |
344 type src = string; |
376 type src = string; |
345 val ord = string_ord; |
377 val ord = string_ord; |
353 fun ml_expr_seri is_cons (tyco_syntax, const_syntax) resolv = |
385 fun ml_expr_seri is_cons (tyco_syntax, const_syntax) resolv = |
354 let |
386 let |
355 val ml_from_label = |
387 val ml_from_label = |
356 str o translate_string (fn "_" => "__" | "." => "_" | c => c) |
388 str o translate_string (fn "_" => "__" | "." => "_" | c => c) |
357 o NameSpace.base o resolv; |
389 o NameSpace.base o resolv; |
|
390 fun ml_from_dictvar v = |
|
391 str (Symbol.to_ascii_upper v ^ "_"); |
358 fun ml_from_tyvar (v, []) = |
392 fun ml_from_tyvar (v, []) = |
359 str "()" |
393 str "()" |
360 | ml_from_tyvar (v, sort) = |
394 | ml_from_tyvar (v, sort) = |
361 let |
395 let |
362 val w = Symbol.to_ascii_upper v; |
|
363 fun mk_class class = |
396 fun mk_class class = |
364 str (prefix "'" v ^ " " ^ resolv class); |
397 str (prefix "'" v ^ " " ^ resolv class); |
365 in |
398 in |
366 Pretty.block [ |
399 Pretty.block [ |
367 str "(", |
400 str "(", |
368 str w, |
401 ml_from_dictvar v, |
369 str ":", |
402 str ":", |
370 case sort |
403 case sort |
371 of [class] => mk_class class |
404 of [class] => mk_class class |
372 | _ => Pretty.enum " *" "" "" (map mk_class sort), |
405 | _ => Pretty.enum " *" "" "" (map mk_class sort), |
373 str ")" |
406 str ")" |
378 fun from_label l = |
411 fun from_label l = |
379 Pretty.block [str "#", |
412 Pretty.block [str "#", |
380 if (is_some o Int.fromString) l then str l |
413 if (is_some o Int.fromString) l then str l |
381 else ml_from_label l |
414 else ml_from_label l |
382 ]; |
415 ]; |
383 fun from_lookup fxy [] v = |
416 fun from_lookup fxy [] p = |
384 v |
417 p |
385 | from_lookup fxy [l] v = |
418 | from_lookup fxy [l] p = |
386 brackify fxy [ |
419 brackify fxy [ |
387 from_label l, |
420 from_label l, |
388 v |
421 p |
389 ] |
422 ] |
390 | from_lookup fxy ls v = |
423 | from_lookup fxy ls p = |
391 brackify fxy [ |
424 brackify fxy [ |
392 Pretty.enum " o" "(" ")" (map from_label ls), |
425 Pretty.enum " o" "(" ")" (map from_label ls), |
393 v |
426 p |
394 ]; |
427 ]; |
395 fun from_classlookup fxy (Instance (inst, lss)) = |
428 fun from_classlookup fxy (Instance (inst, lss)) = |
396 brackify fxy ( |
429 brackify fxy ( |
397 (str o resolv) inst |
430 (str o resolv) inst |
398 :: map (ml_from_sortlookup BR) lss |
431 :: map (ml_from_sortlookup BR) lss |
399 ) |
432 ) |
400 | from_classlookup fxy (Lookup (classes, (v, ~1))) = |
433 | from_classlookup fxy (Lookup (classes, (v, ~1))) = |
401 from_lookup BR classes |
434 from_lookup BR classes |
402 ((str o Symbol.to_ascii_upper) v) |
435 (ml_from_dictvar v) |
403 | from_classlookup fxy (Lookup (classes, (v, i))) = |
436 | from_classlookup fxy (Lookup (classes, (v, i))) = |
404 from_lookup BR (string_of_int (i+1) :: classes) |
437 from_lookup BR (string_of_int (i+1) :: classes) |
405 ((str o Symbol.to_ascii_upper) v) |
438 (ml_from_dictvar v) |
406 in case lss |
439 in case lss |
407 of [] => str "()" |
440 of [] => str "()" |
408 | [ls] => from_classlookup fxy ls |
441 | [ls] => from_classlookup fxy ls |
409 | lss => (Pretty.list "(" ")" o map (from_classlookup NOBR)) lss |
442 | lss => (Pretty.list "(" ")" o map (from_classlookup NOBR)) lss |
410 end; |
443 end; |
755 ] @ separate (str "") ps @ [ |
788 ] @ separate (str "") ps @ [ |
756 str "", |
789 str "", |
757 str ("end; (* struct " ^ name ^ " *)") |
790 str ("end; (* struct " ^ name ^ " *)") |
758 ]); |
791 ]); |
759 val is_cons = ml_annotators nsp_dtcon; |
792 val is_cons = ml_annotators nsp_dtcon; |
|
793 fun postproc (shallow, n) = |
|
794 let |
|
795 fun ch_first f = String.implode o nth_map 0 f o String.explode; |
|
796 in if shallow = nsp_dtcon |
|
797 then ch_first Char.toUpper n |
|
798 else n |
|
799 end; |
760 in abstract_serializer (target, nspgrp) |
800 in abstract_serializer (target, nspgrp) |
761 root_name (ml_from_defs is_cons, ml_from_module, |
801 root_name (ml_from_defs is_cons, ml_from_module, |
762 abstract_validator reserved_ml, snd) end; |
802 abstract_validator reserved_ml, postproc) end; |
763 |
803 |
764 in |
804 in |
765 |
805 |
766 fun ml_from_thingol target nsp_dtcon nspgrp = |
806 fun ml_from_thingol target nsp_dtcon nspgrp = |
767 let |
807 let |
784 |
824 |
785 fun eval_term nsp_eval nsp_dtcon nspgrp (syntax_tyco, syntax_const) hidden ((ref_name, reff), e) modl = |
825 fun eval_term nsp_eval nsp_dtcon nspgrp (syntax_tyco, syntax_const) hidden ((ref_name, reff), e) modl = |
786 let |
826 let |
787 val (val_name, modl') = CodegenThingol.add_eval_def (nsp_eval, e) modl; |
827 val (val_name, modl') = CodegenThingol.add_eval_def (nsp_eval, e) modl; |
788 val struct_name = "EVAL"; |
828 val struct_name = "EVAL"; |
|
829 fun output p = if !eval_verbose then (Pretty.writeln p; Pretty.output p) |
|
830 else Pretty.output p; |
789 val serializer = ml_serializer struct_name "ml" nsp_dtcon nspgrp |
831 val serializer = ml_serializer struct_name "ml" nsp_dtcon nspgrp |
790 (fn "" => (fn p => (use_text Context.ml_output (!eval_verbose) (Pretty.output p); NONE)) |
832 (fn "" => (fn p => (use_text Context.ml_output (!eval_verbose) (output p); NONE)) |
791 | _ => SOME) (K NONE, syntax_tyco, syntax_const) (hidden, SOME [NameSpace.pack [nsp_eval, val_name]]); |
833 | _ => SOME) (K NONE, syntax_tyco, syntax_const) (hidden, SOME [NameSpace.pack [nsp_eval, val_name]]); |
792 val _ = serializer modl'; |
834 val _ = serializer modl'; |
793 val val_name_struct = NameSpace.append struct_name val_name; |
835 val val_name_struct = NameSpace.append struct_name val_name; |
794 val _ = use_text Context.ml_output (!eval_verbose) ("val _ = (" ^ ref_name ^ " := " ^ val_name_struct ^ "())"); |
836 val _ = use_text Context.ml_output (!eval_verbose) ("val _ = (" ^ ref_name ^ " := " ^ val_name_struct ^ "())"); |
795 val value = ! reff; |
837 val value = ! reff; |
949 ], |
991 ], |
950 body |
992 body |
951 ] |> SOME |
993 ] |> SOME |
952 else SOME body end |
994 else SOME body end |
953 | hs_from_def (name, CodegenThingol.Typesyn (sctxt, ty)) = |
995 | hs_from_def (name, CodegenThingol.Typesyn (sctxt, ty)) = |
954 Pretty.block [ |
996 (Pretty.block o Pretty.breaks) [ |
955 str "type ", |
997 str "type", |
956 hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
998 hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
957 str " =", |
999 str "=", |
958 Pretty.brk 1, |
|
959 hs_from_sctxt_type ([], ty) |
1000 hs_from_sctxt_type ([], ty) |
960 ] |> SOME |
1001 ] |> SOME |
961 | hs_from_def (name, CodegenThingol.Datatype (sctxt, [(co, tys)])) = |
1002 | hs_from_def (name, CodegenThingol.Datatype (sctxt, [(co, [ty])])) = |
962 (Pretty.block o Pretty.breaks) [ |
1003 (Pretty.block o Pretty.breaks) [ |
963 str "newtype", |
1004 str "newtype", |
964 hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
1005 hs_from_sctxt_tycoexpr (sctxt, (resolv_here name, map (ITyVar o fst) sctxt)), |
965 str "=", |
1006 str "=", |
966 (Pretty.block o Pretty.breaks) ( |
1007 (str o resolv_here) co, |
967 (str o resolv_here) co |
1008 hs_from_type BR ty |
968 :: map (hs_from_type BR) tys |
|
969 ) |
|
970 ] |> SOME |
1009 ] |> SOME |
971 | hs_from_def (name, CodegenThingol.Datatype (sctxt, constrs)) = |
1010 | hs_from_def (name, CodegenThingol.Datatype (sctxt, constrs)) = |
972 let |
1011 let |
973 fun mk_cons (co, tys) = |
1012 fun mk_cons (co, tys) = |
974 (Pretty.block o Pretty.breaks) ( |
1013 (Pretty.block o Pretty.breaks) ( |
1034 val reserved_hs = [ |
1073 val reserved_hs = [ |
1035 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
1074 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
1036 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
1075 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
1037 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
1076 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
1038 ] @ [ |
1077 ] @ [ |
1039 "Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate" |
1078 "Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate", |
|
1079 "String", "Char" |
1040 ]; |
1080 ]; |
1041 fun is_cons c = CodegenThingol.has_nsp c nsp_dtcon; |
1081 fun is_cons c = CodegenThingol.has_nsp c nsp_dtcon; |
1042 fun hs_from_module resolv imps ((_, name), ps) = |
1082 fun hs_from_module resolv imps ((_, name), ps) = |
1043 (Pretty.chunks) ( |
1083 (Pretty.chunks) ( |
1044 str ("module " ^ name ^ " where") |
1084 str ("module " ^ name ^ " where") |