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.iexpr pretty_syntax; |
23 val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax; |
24 val serializers: { |
24 val serializers: { |
25 ml: string * (string * string * (string -> bool) -> serializer), |
25 ml: string * (string * string * (string -> bool) -> serializer), |
26 haskell: string * (string list -> serializer) |
26 haskell: string * (string * string list -> serializer) |
27 }; |
27 }; |
28 val mk_flat_ml_resolver: string list -> string -> string; |
28 val mk_flat_ml_resolver: string list -> string -> string; |
29 val ml_fun_datatype: string * string * (string -> bool) |
29 val ml_fun_datatype: string * string * (string -> bool) |
30 -> ((string -> CodegenThingol.itype pretty_syntax option) |
30 -> ((string -> CodegenThingol.itype pretty_syntax option) |
31 * (string -> CodegenThingol.iexpr pretty_syntax option)) |
31 * (string -> CodegenThingol.iexpr pretty_syntax option)) |
257 p |
257 p |
258 |> write_file true (Path.append prfx name') |
258 |> write_file true (Path.append prfx name') |
259 |> postprocess_module name |
259 |> postprocess_module name |
260 end; |
260 end; |
261 |
261 |
262 fun constructive_fun (name, (eqs, ty)) = |
262 fun constructive_fun is_cons (name, (eqs, ty)) = |
263 let |
263 let |
264 fun check_eq (eq as (lhs, rhs)) = |
264 fun check_eq (eq as (lhs, rhs)) = |
265 if forall CodegenThingol.is_pat lhs |
265 if forall (CodegenThingol.is_pat is_cons) lhs |
266 then SOME eq |
266 then SOME eq |
267 else (warning ("in function " ^ quote name ^ ", throwing away one " |
267 else (warning ("in function " ^ quote name ^ ", throwing away one " |
268 ^ "non-executable function clause"); NONE) |
268 ^ "non-executable function clause"); NONE) |
269 in case map_filter check_eq eqs |
269 in case map_filter check_eq eqs |
270 of [] => error ("in function " ^ quote name ^ ", no " |
270 of [] => error ("in function " ^ quote name ^ ", no " |
340 fun ml_expr_seri (is_cons, needs_type) (tyco_syntax, const_syntax) resolv = |
340 fun ml_expr_seri (is_cons, needs_type) (tyco_syntax, const_syntax) resolv = |
341 let |
341 let |
342 val ml_from_label = |
342 val ml_from_label = |
343 str o translate_string (fn "_" => "__" | "." => "_" | c => c) |
343 str o translate_string (fn "_" => "__" | "." => "_" | c => c) |
344 o NameSpace.base o resolv; |
344 o NameSpace.base o resolv; |
345 fun ml_from_tyvar (v, sort) = |
345 fun ml_from_tyvar (v, []) = |
346 let |
346 str "()" |
347 fun mk_class v class = |
347 | ml_from_tyvar (v, sort) = |
348 str (prefix "'" v ^ " " ^ resolv class); |
348 let |
349 in |
349 val w = (Char.toString o Char.toUpper o the o Char.fromString) v; |
350 Pretty.block [ |
350 fun mk_class class = |
351 str "(", |
351 str (prefix "'" v ^ " " ^ resolv class); |
352 str v, |
352 in |
353 str ":", |
353 Pretty.block [ |
354 case sort |
354 str "(", |
355 of [] => str "unit" |
355 str w, |
356 | [class] => mk_class v class |
356 str ":", |
357 | _ => Pretty.enum " *" "" "" (map (mk_class v) sort), |
357 case sort |
358 str ")" |
358 of [class] => mk_class class |
359 ] |
359 | _ => Pretty.enum " *" "" "" (map mk_class sort), |
360 end; |
360 str ")" |
|
361 ] |
|
362 end; |
361 fun ml_from_sortlookup fxy lss = |
363 fun ml_from_sortlookup fxy lss = |
362 let |
364 let |
363 fun from_label l = |
365 fun from_label l = |
364 Pretty.block [str "#", |
366 Pretty.block [str "#", |
365 if (is_some o Int.fromString) l then str l |
367 if (is_some o Int.fromString) l then str l |
366 else ml_from_label l |
368 else ml_from_label l |
367 ]; |
369 ]; |
368 fun from_lookup fxy [] p = p |
370 fun from_lookup fxy [] v = |
369 | from_lookup fxy [l] p = |
371 v |
|
372 | from_lookup fxy [l] v = |
370 brackify fxy [ |
373 brackify fxy [ |
371 from_label l, |
374 from_label l, |
372 p |
375 v |
373 ] |
376 ] |
374 | from_lookup fxy ls p = |
377 | from_lookup fxy ls v = |
375 brackify fxy [ |
378 brackify fxy [ |
376 Pretty.enum " o" "(" ")" (map from_label ls), |
379 Pretty.enum " o" "(" ")" (map from_label ls), |
377 p |
380 v |
378 ]; |
381 ]; |
379 fun from_classlookup fxy (Instance (inst, lss)) = |
382 fun from_classlookup fxy (Instance (inst, lss)) = |
380 brackify fxy ( |
383 brackify fxy ( |
381 (str o resolv) inst |
384 (str o resolv) inst |
382 :: map (ml_from_sortlookup BR) lss |
385 :: map (ml_from_sortlookup BR) lss |
383 ) |
386 ) |
384 | from_classlookup fxy (Lookup (classes, (v, ~1))) = |
387 | from_classlookup fxy (Lookup (classes, (v, ~1))) = |
385 from_lookup BR classes (str v) |
388 from_lookup BR classes |
|
389 ((str o Char.toString o Char.toUpper o the o Char.fromString) v) |
386 | from_classlookup fxy (Lookup (classes, (v, i))) = |
390 | from_classlookup fxy (Lookup (classes, (v, i))) = |
387 from_lookup BR (string_of_int (i+1) :: classes) (str v) |
391 from_lookup BR (string_of_int (i+1) :: classes) |
|
392 ((str o Char.toString o Char.toUpper o the o Char.fromString) v) |
388 in case lss |
393 in case lss |
389 of [] => str "()" |
394 of [] => str "()" |
390 | [ls] => from_classlookup fxy ls |
395 | [ls] => from_classlookup fxy ls |
391 | lss => (Pretty.list "(" ")" o map (from_classlookup NOBR)) lss |
396 | lss => (Pretty.list "(" ")" o map (from_classlookup NOBR)) lss |
392 end; |
397 end; |
651 ^ (Pretty.output o CodegenThingol.pretty_def) def)) defs |
656 ^ (Pretty.output o CodegenThingol.pretty_def) def)) defs |
652 of [class] => class |
657 of [class] => class |
653 | _ => error ("class block without class: " ^ (commas o map (quote o fst)) defs) |
658 | _ => error ("class block without class: " ^ (commas o map (quote o fst)) defs) |
654 fun ml_from_class (name, (supclasses, (v, membrs))) = |
659 fun ml_from_class (name, (supclasses, (v, membrs))) = |
655 let |
660 let |
|
661 val w = (Char.toString o Char.toUpper o the o Char.fromString) v; |
656 fun from_supclass class = |
662 fun from_supclass class = |
657 Pretty.block [ |
663 Pretty.block [ |
658 ml_from_label class, |
664 ml_from_label class, |
659 str ":", |
665 str ":", |
660 Pretty.brk 1, |
666 Pretty.brk 1, |
671 ]; |
677 ]; |
672 fun from_membr_fun (m, _) = |
678 fun from_membr_fun (m, _) = |
673 (Pretty.block o Pretty.breaks) [ |
679 (Pretty.block o Pretty.breaks) [ |
674 str "fun", |
680 str "fun", |
675 (str o resolv) m, |
681 (str o resolv) m, |
676 Pretty.enclose "(" ")" [str (v ^ ":'" ^ v ^ " " ^ resolv name)], |
682 Pretty.enclose "(" ")" [str (w ^ ":'" ^ v ^ " " ^ resolv name)], |
677 str "=", |
683 str "=", |
678 Pretty.block [str "#", ml_from_label m], |
684 Pretty.block [str "#", ml_from_label m], |
679 str (v ^ ";") |
685 str (w ^ ";") |
680 ]; |
686 ]; |
681 in |
687 in |
682 Pretty.chunks ( |
688 Pretty.chunks ( |
683 (Pretty.block o Pretty.breaks) [ |
689 (Pretty.block o Pretty.breaks) [ |
684 str "type", |
690 str "type", |
704 ] |
710 ] |
705 ) |> SOME |
711 ) |> SOME |
706 | ml_from_def (name, CodegenThingol.Classinst (((class, (tyco, arity)), suparities), memdefs)) = |
712 | ml_from_def (name, CodegenThingol.Classinst (((class, (tyco, arity)), suparities), memdefs)) = |
707 let |
713 let |
708 val definer = if null arity then "val" else "fun" |
714 val definer = if null arity then "val" else "fun" |
709 fun from_supclass (supclass, (supinst, lss)) = |
715 fun from_supclass (supclass, ls) = |
710 (Pretty.block o Pretty.breaks) ( |
716 (Pretty.block o Pretty.breaks) [ |
711 ml_from_label supclass |
717 ml_from_label supclass, |
712 :: str "=" |
718 str "=", |
713 :: (str o resolv) supinst |
719 ml_from_sortlookup NOBR ls |
714 :: (if null lss andalso (not o null) arity |
720 ]; |
715 then [str "()"] |
|
716 else map (ml_from_sortlookup NOBR) lss) |
|
717 ); |
|
718 fun from_memdef (m, ((m', def), lss)) = |
721 fun from_memdef (m, ((m', def), lss)) = |
719 (ml_from_funs [(m', def)], (Pretty.block o Pretty.breaks) ( |
722 (ml_from_funs [(m', def)], (Pretty.block o Pretty.breaks) ( |
720 ml_from_label m |
723 ml_from_label m |
721 :: str "=" |
724 :: str "=" |
722 :: (str o resolv) m' |
725 :: (str o resolv) m' |
963 Pretty.brk 1, |
966 Pretty.brk 1, |
964 str ("="), |
967 str ("="), |
965 Pretty.brk 1, |
968 Pretty.brk 1, |
966 hs_from_expr NOBR rhs |
969 hs_from_expr NOBR rhs |
967 ] |
970 ] |
968 in Pretty.chunks ((map from_eq o fst o snd o constructive_fun) def) end; |
971 in Pretty.chunks ((map from_eq o fst o snd o constructive_fun is_cons) def) end; |
969 fun hs_from_def (name, CodegenThingol.Fun (def as (_, (sctxt, ty)))) = |
972 fun hs_from_def (name, CodegenThingol.Fun (def as (_, (sctxt, ty)))) = |
970 let |
973 let |
971 val body = hs_from_funeqs (name, def); |
974 val body = hs_from_funeqs (name, def); |
972 in if with_typs then |
975 in if with_typs then |
973 Pretty.chunks [ |
976 Pretty.chunks [ |
1042 | l => (SOME o Pretty.chunks o separate (str "")) l |
1045 | l => (SOME o Pretty.chunks o separate (str "")) l |
1043 end; |
1046 end; |
1044 |
1047 |
1045 in |
1048 in |
1046 |
1049 |
1047 fun hs_from_thingol target nsps_upper nspgrp = |
1050 fun hs_from_thingol target (nsp_dtcon, nsps_upper) nspgrp = |
1048 let |
1051 let |
1049 val reserved_hs = [ |
1052 val reserved_hs = [ |
1050 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
1053 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
1051 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
1054 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
1052 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
1055 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
1053 ] @ [ |
1056 ] @ [ |
1054 "Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate" |
1057 "Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate" |
1055 ]; |
1058 ]; |
|
1059 fun is_cons c = CodegenThingol.has_nsp c nsp_dtcon; |
1056 fun hs_from_module resolv imps ((_, name), ps) = |
1060 fun hs_from_module resolv imps ((_, name), ps) = |
1057 (Pretty.chunks) ( |
1061 (Pretty.chunks) ( |
1058 str ("module " ^ name ^ " where") |
1062 str ("module " ^ name ^ " where") |
1059 :: map (str o prefix "import qualified ") imps @ ( |
1063 :: map (str o prefix "import qualified ") imps @ ( |
1060 str "" |
1064 str "" |
1066 in if member (op =) nsps_upper shallow |
1070 in if member (op =) nsps_upper shallow |
1067 then ch_first Char.toUpper n |
1071 then ch_first Char.toUpper n |
1068 else ch_first Char.toLower n |
1072 else ch_first Char.toLower n |
1069 end; |
1073 end; |
1070 fun serializer with_typs = abstract_serializer (target, nspgrp) |
1074 fun serializer with_typs = abstract_serializer (target, nspgrp) |
1071 "Main" (hs_from_defs with_typs, hs_from_module, abstract_validator reserved_hs, postproc); |
1075 "Main" (hs_from_defs (is_cons, with_typs), hs_from_module, abstract_validator reserved_hs, postproc); |
1072 fun eta_expander const_syntax c = |
1076 fun eta_expander const_syntax c = |
1073 const_syntax c |
1077 const_syntax c |
1074 |> Option.map (fst o fst) |
1078 |> Option.map (fst o fst) |
1075 |> the_default 0; |
1079 |> the_default 0; |
1076 in |
1080 in |