10 sig |
10 sig |
11 type 'a pretty_syntax; |
11 type 'a pretty_syntax; |
12 type serializer = |
12 type serializer = |
13 string list list |
13 string list list |
14 -> OuterParse.token list -> |
14 -> OuterParse.token list -> |
15 ((string -> CodegenThingol.itype pretty_syntax option) |
15 ((string -> string option) |
|
16 * (string -> CodegenThingol.itype pretty_syntax option) |
16 * (string -> CodegenThingol.iexpr pretty_syntax option) |
17 * (string -> CodegenThingol.iexpr pretty_syntax option) |
17 -> string list option |
18 -> string list option |
18 -> CodegenThingol.module -> unit) |
19 -> CodegenThingol.module -> unit) |
19 * OuterParse.token list; |
20 * OuterParse.token list; |
20 val parse_syntax: (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
21 val parse_syntax: (string -> 'b -> 'a * 'b) -> OuterParse.token list -> |
21 ('b -> 'a pretty_syntax * 'b) * OuterParse.token list; |
22 ('b -> 'a pretty_syntax * 'b) * OuterParse.token list; |
22 val parse_targetdef: (string -> string) -> string -> string; |
23 val parse_targetdef: (string -> string) -> string -> string; |
23 val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax; |
24 val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax; |
24 val serializers: { |
25 val serializers: { |
25 ml: string * (string * string * string -> serializer), |
26 ml: string * (string * string * (string -> bool) -> serializer), |
26 haskell: string * (string -> serializer) |
27 haskell: string * (string -> serializer) |
27 } |
28 } |
28 end; |
29 end; |
29 |
30 |
30 structure CodegenSerializer: CODEGEN_SERIALIZER = |
31 structure CodegenSerializer: CODEGEN_SERIALIZER = |
82 gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps); |
84 gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps); |
83 |
85 |
84 fun brackify_infix infx fxy_ctxt ps = |
86 fun brackify_infix infx fxy_ctxt ps = |
85 gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps); |
87 gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps); |
86 |
88 |
87 fun from_app mk_app from_expr const_syntax fxy (f, es) = |
89 fun from_app mk_app from_expr const_syntax fxy (c, es) = |
88 let |
90 let |
89 fun mk NONE es = |
91 fun mk NONE es = |
90 brackify fxy (mk_app f es) |
92 brackify fxy (mk_app c es) |
91 | mk (SOME ((i, k), pr)) es = |
93 | mk (SOME ((i, k), pr)) es = |
92 let |
94 let |
93 val (es1, es2) = splitAt (i, es); |
95 val (es1, es2) = splitAt (k, es); |
94 in |
96 in |
95 brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2) |
97 brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2) |
96 end; |
98 end; |
97 in mk (const_syntax f) es end; |
99 in mk (const_syntax c) es end; |
|
100 |
|
101 val _ : (string -> iexpr list -> Pretty.T list) |
|
102 -> (fixity -> iexpr -> Pretty.T) |
|
103 -> (string |
|
104 -> ((int * int) |
|
105 * (fixity |
|
106 -> (fixity -> iexpr -> Pretty.T) |
|
107 -> iexpr list -> Pretty.T)) option) |
|
108 -> fixity -> string * iexpr list -> Pretty.T = from_app; |
98 |
109 |
99 fun fillin_mixfix fxy_this ms fxy_ctxt pr args = |
110 fun fillin_mixfix fxy_this ms fxy_ctxt pr args = |
100 let |
111 let |
101 fun fillin [] [] = |
112 fun fillin [] [] = |
102 [] |
113 [] |
153 | _ => error ("Malformed mixfix annotation: " ^ quote s) |
164 | _ => error ("Malformed mixfix annotation: " ^ quote s) |
154 end; |
165 end; |
155 |
166 |
156 fun parse_nonatomic_mixfix reader s ctxt = |
167 fun parse_nonatomic_mixfix reader s ctxt = |
157 case parse_mixfix reader s ctxt |
168 case parse_mixfix reader s ctxt |
158 of ([Pretty _], _) => error ("mixfix contains just one pretty element; either declare as " ^ quote atomK ^ " or consider adding a break") |
169 of ([Pretty _], _) => |
|
170 error ("mixfix contains just one pretty element; either declare as " |
|
171 ^ quote atomK ^ " or consider adding a break") |
159 | x => x; |
172 | x => x; |
160 |
173 |
161 fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- ( |
174 fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- ( |
162 OuterParse.$$$ infixK |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, X)), INFX (i, X))) |
175 OuterParse.$$$ infixK |-- OuterParse.nat |
163 || OuterParse.$$$ infixlK |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, L)), INFX (i, L))) |
176 >> (fn i => (parse_infix (INFX (i, X)), INFX (i, X))) |
164 || OuterParse.$$$ infixrK |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, R)), INFX (i, R))) |
177 || OuterParse.$$$ infixlK |-- OuterParse.nat |
|
178 >> (fn i => (parse_infix (INFX (i, L)), INFX (i, L))) |
|
179 || OuterParse.$$$ infixrK |-- OuterParse.nat |
|
180 >> (fn i => (parse_infix (INFX (i, R)), INFX (i, R))) |
165 || OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR) |
181 || OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR) |
166 || pair (parse_nonatomic_mixfix reader, BR) |
182 || pair (parse_nonatomic_mixfix reader, BR) |
167 ) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy)); |
183 ) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy)); |
168 |
184 |
169 fun parse_syntax reader = |
185 fun parse_syntax reader = |
377 ml_from_type (INFX (1, X)) t1, |
394 ml_from_type (INFX (1, X)) t1, |
378 str "->", |
395 str "->", |
379 ml_from_type (INFX (1, R)) t2 |
396 ml_from_type (INFX (1, R)) t2 |
380 ] |
397 ] |
381 end |
398 end |
382 | ml_from_type _ (IVarT (v, [])) = |
399 | ml_from_type _ (IVarT (v, _)) = |
383 str ("'" ^ v) |
400 str ("'" ^ v) |
384 | ml_from_type _ (IVarT (_, sort)) = |
|
385 "cannot serialize sort constrained type variable to ML: " ^ commas sort |> error |
|
386 | ml_from_type _ (IDictT fs) = |
401 | ml_from_type _ (IDictT fs) = |
387 Pretty.enum "," "{" "}" ( |
402 Pretty.enum "," "{" "}" ( |
388 map (fn (f, ty) => |
403 map (fn (f, ty) => |
389 Pretty.block [str (ml_from_label f ^ ": "), ml_from_type NOBR ty]) fs |
404 Pretty.block [ml_from_label f, str ": ", ml_from_type NOBR ty]) fs |
390 ); |
405 ); |
391 fun ml_from_pat fxy (ICons ((f, ps), ty)) = |
406 fun ml_from_expr sortctxt fxy (e as IApp (e1, e2)) = |
392 (case const_syntax f |
407 (case unfold_const_app e |
393 of NONE => if length ps <= 1 |
408 of SOME x => ml_from_app sortctxt fxy x |
394 then |
409 | NONE => |
395 ps |
|
396 |> map (ml_from_pat BR) |
|
397 |> cons ((str o resolv) f) |
|
398 |> brackify fxy |
|
399 else |
|
400 ps |
|
401 |> map (ml_from_pat BR) |
|
402 |> Pretty.enum "," "(" ")" |
|
403 |> single |
|
404 |> cons ((str o resolv) f) |
|
405 |> brackify fxy |
|
406 | SOME ((i, k), pr) => |
|
407 if not (i <= length ps andalso length ps <= k) |
|
408 then error ("number of argument mismatch in customary serialization: " |
|
409 ^ (string_of_int o length) ps ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k |
|
410 ^ " expected") |
|
411 else pr fxy ml_from_expr (map iexpr_of_ipat ps)) |
|
412 | ml_from_pat fxy (IVarP (v, ty)) = |
|
413 if needs_type ty |
|
414 then |
|
415 brackify fxy [ |
|
416 str v, |
|
417 str ":", |
|
418 ml_from_type NOBR ty |
|
419 ] |
|
420 else |
|
421 str v |
|
422 and ml_from_expr fxy (e as IApp (e1, e2)) = |
|
423 (case (unfold_app e) |
|
424 of (e as (IConst (f, _)), es) => |
|
425 ml_from_app fxy (f, es) |
|
426 | _ => |
|
427 brackify fxy [ |
410 brackify fxy [ |
428 ml_from_expr NOBR e1, |
411 ml_from_expr sortctxt NOBR e1, |
429 ml_from_expr BR e2 |
412 ml_from_expr sortctxt BR e2 |
430 ]) |
413 ]) |
431 | ml_from_expr fxy (e as IConst (f, _)) = |
414 | ml_from_expr sortctxt fxy (e as IConst x) = |
432 ml_from_app fxy (f, []) |
415 ml_from_app sortctxt fxy (x, []) |
433 | ml_from_expr fxy (IVarE (v, _)) = |
416 | ml_from_expr sortctxt fxy (IVarE (v, _)) = |
434 str v |
417 str v |
435 | ml_from_expr fxy (IAbs ((v, _), e)) = |
418 | ml_from_expr sortctxt fxy (IAbs ((v, _), e)) = |
436 brackify fxy [ |
419 brackify fxy [ |
437 str ("fn " ^ v ^ " =>"), |
420 str ("fn " ^ v ^ " =>"), |
438 ml_from_expr NOBR e |
421 ml_from_expr sortctxt NOBR e |
439 ] |
422 ] |
440 | ml_from_expr fxy (e as ICase (_, [_])) = |
423 | ml_from_expr sortctxt fxy (e as ICase (_, [_])) = |
441 let |
424 let |
442 val (ps, e) = unfold_let e; |
425 val (ps, e) = unfold_let e; |
443 fun mk_val (p, e) = Pretty.block [ |
426 fun mk_val (p, e) = Pretty.block [ |
444 str "val ", |
427 str "val ", |
445 ml_from_pat fxy p, |
428 ml_from_expr sortctxt fxy p, |
446 str " =", |
429 str " =", |
447 Pretty.brk 1, |
430 Pretty.brk 1, |
448 ml_from_expr NOBR e, |
431 ml_from_expr sortctxt NOBR e, |
449 str ";" |
432 str ";" |
450 ] |
433 ] |
451 in Pretty.chunks [ |
434 in Pretty.chunks [ |
452 [str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block, |
435 [str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block, |
453 [str ("in"), Pretty.fbrk, ml_from_expr NOBR e] |> Pretty.block, |
436 [str ("in"), Pretty.fbrk, ml_from_expr sortctxt NOBR e] |> Pretty.block, |
454 str ("end") |
437 str ("end") |
455 ] end |
438 ] end |
456 | ml_from_expr fxy (ICase (e, c::cs)) = |
439 | ml_from_expr sortctxt fxy (ICase (e, c::cs)) = |
457 let |
440 let |
458 fun mk_clause definer (p, e) = |
441 fun mk_clause definer (p, e) = |
459 Pretty.block [ |
442 Pretty.block [ |
460 str definer, |
443 str definer, |
461 ml_from_pat NOBR p, |
444 ml_from_expr sortctxt NOBR p, |
462 str " =>", |
445 str " =>", |
463 Pretty.brk 1, |
446 Pretty.brk 1, |
464 ml_from_expr NOBR e |
447 ml_from_expr sortctxt NOBR e |
465 ] |
448 ] |
466 in brackify fxy ( |
449 in brackify fxy ( |
467 str "case" |
450 str "case" |
468 :: ml_from_expr NOBR e |
451 :: ml_from_expr sortctxt NOBR e |
469 :: mk_clause "of " c |
452 :: mk_clause "of " c |
470 :: map (mk_clause "| ") cs |
453 :: map (mk_clause "| ") cs |
471 ) end |
454 ) end |
472 | ml_from_expr fxy (IInst _) = |
455 | ml_from_expr sortctxt fxy (IDictE fs) = |
473 error "cannot serialize poly instant to ML" |
|
474 | ml_from_expr fxy (IDictE fs) = |
|
475 Pretty.enum "," "{" "}" ( |
456 Pretty.enum "," "{" "}" ( |
476 map (fn (f, e) => |
457 map (fn (f, e) => |
477 Pretty.block [str (ml_from_label f ^ " = "), ml_from_expr NOBR e]) fs |
458 Pretty.block [ml_from_label f, str " = ", ml_from_expr sortctxt NOBR e]) fs |
478 ) |
459 ) |
479 | ml_from_expr fxy (ILookup ([], v)) = |
460 | ml_from_expr sortctxt fxy (ILookup ([], v)) = |
480 str v |
461 str v |
481 | ml_from_expr fxy (ILookup ([l], v)) = |
462 | ml_from_expr sortctxt fxy (ILookup ([l], v)) = |
482 brackify fxy [ |
463 brackify fxy [ |
483 str ("#" ^ (ml_from_label l)), |
464 str "#", |
|
465 ml_from_label l, |
484 str v |
466 str v |
485 ] |
467 ] |
486 | ml_from_expr fxy (ILookup (ls, v)) = |
468 (*| ml_from_expr sortctxt fxy (ILookup (ls, v)) = |
487 brackify fxy [ |
469 brackify fxy [ |
488 str ("(" |
470 str ("(" |
489 ^ (ls |> map ((fn s => "#" ^ s) o ml_from_label) |> foldr1 (fn (l, e) => l ^ " o " ^ e)) |
471 ^ (ls |> map ((fn s => "#" ^ s) o ml_from_label) |> foldr1 (fn (l, e) => l ^ " o " ^ e)) |
490 ^ ")"), |
472 ^ ")"), |
491 str v |
473 str v |
492 ] |
474 ]*) |
493 | ml_from_expr _ e = |
475 | ml_from_expr _ _ e = |
494 error ("dubious expression: " ^ (Pretty.output o pretty_iexpr) e) |
476 error ("dubious expression: " ^ (Pretty.output o pretty_iexpr) e) |
495 and ml_mk_app f es = |
477 and ml_mk_app sortctxt f es = |
496 if is_cons f andalso length es > 1 |
478 if is_cons f andalso length es > 1 |
497 then |
479 then |
498 [(str o resolv) f, Pretty.enum " *" "(" ")" (map (ml_from_expr BR) es)] |
480 [(str o resolv) f, Pretty.enum " *" "(" ")" (map (ml_from_expr sortctxt BR) es)] |
499 else |
481 else |
500 (str o resolv) f :: map (ml_from_expr BR) es |
482 (str o resolv) f :: map (ml_from_expr sortctxt BR) es |
501 and ml_from_app fxy = |
483 and ml_from_app sortctxt fxy (((f, _), ls), es) = |
502 from_app ml_mk_app ml_from_expr const_syntax fxy; |
484 let |
|
485 val _ = (); |
|
486 in |
|
487 from_app (ml_mk_app sortctxt) (ml_from_expr sortctxt) const_syntax fxy (f, es) |
|
488 end; |
503 fun ml_from_funs (ds as d::ds_tl) = |
489 fun ml_from_funs (ds as d::ds_tl) = |
504 let |
490 let |
505 fun mk_definer [] = "val" |
491 fun mk_definer [] = "val" |
506 | mk_definer _ = "fun"; |
492 | mk_definer _ = "fun"; |
507 fun check_args (_, Fun ((pats, _)::_, _)) NONE = |
493 fun check_args (_, Fun ((pats, _)::_, _)) NONE = |
511 then SOME definer |
497 then SOME definer |
512 else error ("mixing simultaneous vals and funs not implemented") |
498 else error ("mixing simultaneous vals and funs not implemented") |
513 | check_args _ _ = |
499 | check_args _ _ = |
514 error ("function definition block containing other definitions than functions") |
500 error ("function definition block containing other definitions than functions") |
515 val definer = the (fold check_args ds NONE); |
501 val definer = the (fold check_args ds NONE); |
516 fun mk_eq definer f ty (pats, expr) = |
502 fun mk_eq definer sortctxt f ty (pats, expr) = |
517 let |
503 let |
518 val lhs = [str (definer ^ " " ^ f)] |
504 val lhs = [str (definer ^ " " ^ f)] |
519 @ (if null pats |
505 @ (if null pats |
520 then [str ":", ml_from_type NOBR ty] |
506 then [str ":", ml_from_type NOBR ty] |
521 else map (ml_from_pat BR) pats) |
507 else map (ml_from_expr sortctxt BR) pats) |
522 val rhs = [str "=", ml_from_expr NOBR expr] |
508 val rhs = [str "=", ml_from_expr sortctxt NOBR expr] |
523 in |
509 in |
524 Pretty.block (separate (Pretty.brk 1) (lhs @ rhs)) |
510 Pretty.block (separate (Pretty.brk 1) (lhs @ rhs)) |
525 end |
511 end |
526 fun mk_fun definer (f, Fun (eqs as eq::eq_tl, (_, ty))) = |
512 fun mk_fun definer (f, Fun (eqs as eq::eq_tl, (sortctxt , ty))) = |
527 let |
513 let |
528 val (pats_hd::pats_tl) = (fst o split_list) eqs; |
514 val (pats_hd::pats_tl) = (fst o split_list) eqs; |
529 val shift = if null eq_tl then I else map (Pretty.block o single); |
515 val shift = if null eq_tl then I else map (Pretty.block o single); |
530 in (Pretty.block o Pretty.fbreaks o shift) ( |
516 in (Pretty.block o Pretty.fbreaks o shift) ( |
531 mk_eq definer f ty eq |
517 mk_eq definer sortctxt f ty eq |
532 :: map (mk_eq "|" f ty) eq_tl |
518 :: map (mk_eq "|" sortctxt f ty) eq_tl |
533 ) |
519 ) |
534 end; |
520 end; |
535 in |
521 in |
536 chunk_defs ( |
522 chunk_defs ( |
537 mk_fun definer d |
523 mk_fun definer d |
541 fun ml_from_datatypes defs = |
527 fun ml_from_datatypes defs = |
542 let |
528 let |
543 val defs' = List.mapPartial |
529 val defs' = List.mapPartial |
544 (fn (name, Datatype info) => SOME (name, info) |
530 (fn (name, Datatype info) => SOME (name, info) |
545 | (name, Datatypecons _) => NONE |
531 | (name, Datatypecons _) => NONE |
546 | (name, def) => error ("datatype block containing illegal def: " ^ (Pretty.output o pretty_def) def) |
532 | (name, def) => error ("datatype block containing illegal def: " |
|
533 ^ (Pretty.output o pretty_def) def) |
547 ) defs |
534 ) defs |
548 fun mk_cons (co, []) = |
535 fun mk_cons (co, []) = |
549 str (resolv co) |
536 str (resolv co) |
550 | mk_cons (co, tys) = |
537 | mk_cons (co, tys) = |
551 Pretty.block ( |
538 Pretty.block ( |
552 str (resolv co) |
539 str (resolv co) |
553 :: str " of" |
540 :: str " of" |
554 :: Pretty.brk 1 |
541 :: Pretty.brk 1 |
555 :: separate (Pretty.block [str " *", Pretty.brk 1]) (map (ml_from_type NOBR) tys) |
542 :: separate (Pretty.block [str " *", Pretty.brk 1]) |
|
543 (map (ml_from_type NOBR) tys) |
556 ) |
544 ) |
557 fun mk_datatype definer (t, ((vs, cs), _)) = |
545 fun mk_datatype definer (t, ((vs, cs), _)) = |
558 Pretty.block ( |
546 Pretty.block ( |
559 str definer |
547 str definer |
560 :: ml_from_type NOBR (t `%% map IVarT vs) |
548 :: ml_from_type NOBR (t `%% map IVarT vs) |
574 fun ml_from_def (name, Undef) = |
562 fun ml_from_def (name, Undef) = |
575 error ("empty definition during serialization: " ^ quote name) |
563 error ("empty definition during serialization: " ^ quote name) |
576 | ml_from_def (name, Prim prim) = |
564 | ml_from_def (name, Prim prim) = |
577 from_prim (name, prim) |
565 from_prim (name, prim) |
578 | ml_from_def (name, Typesyn (vs, ty)) = |
566 | ml_from_def (name, Typesyn (vs, ty)) = |
579 (map (fn (vname, []) => () | _ => error "can't serialize sort constrained type declaration to ML") vs; |
567 (map (fn (vname, []) => () | _ => |
|
568 error "can't serialize sort constrained type declaration to ML") vs; |
580 Pretty.block [ |
569 Pretty.block [ |
581 str "type ", |
570 str "type ", |
582 ml_from_type NOBR (name `%% map IVarT vs), |
571 ml_from_type NOBR (name `%% map IVarT vs), |
583 str " =", |
572 str " =", |
584 Pretty.brk 1, |
573 Pretty.brk 1, |
585 ml_from_type NOBR ty, |
574 ml_from_type NOBR ty, |
586 str ";" |
575 str ";" |
587 ] |
576 ] |
588 ) |> SOME |
577 ) |> SOME |
589 | ml_from_def (name, Class _) = |
578 | ml_from_def (name, Class ((supclasses, (v, membrs)), _)) = |
590 error ("can't serialize class declaration " ^ quote name ^ " to ML") |
579 let |
|
580 val pv = str ("'" ^ v); |
|
581 fun from_supclass class = |
|
582 Pretty.block [ |
|
583 ml_from_label class, |
|
584 str ":", |
|
585 Pretty.brk 1, |
|
586 pv, |
|
587 Pretty.brk 1, |
|
588 (str o resolv) class |
|
589 ] |
|
590 fun from_membr (m, (_, ty)) = |
|
591 Pretty.block [ |
|
592 ml_from_label m, |
|
593 str ":", |
|
594 Pretty.brk 1, |
|
595 ml_from_type NOBR ty |
|
596 ] |
|
597 in |
|
598 Pretty.block [ |
|
599 str "type", |
|
600 Pretty.brk 1, |
|
601 pv, |
|
602 Pretty.brk 1, |
|
603 (str o resolv) name, |
|
604 Pretty.brk 1, |
|
605 str "=", |
|
606 Pretty.brk 1, |
|
607 Pretty.enum "," "{" "};" ( |
|
608 map from_supclass supclasses @ map from_membr membrs |
|
609 ) |
|
610 ] |> SOME |
|
611 end |
591 | ml_from_def (_, Classmember _) = |
612 | ml_from_def (_, Classmember _) = |
592 NONE |
613 NONE |
593 | ml_from_def (name, Classinst _) = |
614 | ml_from_def (name, Classinst (((class, (tyco, arity)), suparities), memdefs)) = |
594 error ("can't serialize instance declaration " ^ quote name ^ " to ML") |
615 let |
|
616 val definer = if null arity then "val" else "fun" |
|
617 fun from_supclass (supclass, (inst, ls)) = str "<DUMMY>" |
|
618 fun from_memdef (m, def) = |
|
619 ((the o ml_from_funs) [(m, Fun def)], Pretty.block [ |
|
620 (str o resolv) m, |
|
621 Pretty.brk 1, |
|
622 str "=", |
|
623 Pretty.brk 1, |
|
624 (str o resolv) m |
|
625 ]) |
|
626 fun mk_memdefs supclassexprs [] = |
|
627 Pretty.enum "," "{" "};" ( |
|
628 supclassexprs |
|
629 ) |
|
630 | mk_memdefs supclassexprs memdefs = |
|
631 let |
|
632 val (defs, assigns) = (split_list o map from_memdef) memdefs; |
|
633 in |
|
634 Pretty.chunks [ |
|
635 [str ("let"), Pretty.fbrk, defs |> Pretty.chunks] |
|
636 |> Pretty.block, |
|
637 [str ("in "), Pretty.enum "," "{" "};" (supclassexprs @ assigns)] |
|
638 |> Pretty.block |
|
639 ] |
|
640 end; |
|
641 in |
|
642 Pretty.block [ |
|
643 (Pretty.block o Pretty.breaks) ( |
|
644 str definer |
|
645 :: str name |
|
646 :: map (str o fst) arity |
|
647 ), |
|
648 Pretty.brk 1, |
|
649 str "=", |
|
650 Pretty.brk 1, |
|
651 mk_memdefs (map from_supclass suparities) memdefs |
|
652 ] |> SOME |
|
653 end; |
595 in case defs |
654 in case defs |
596 of (_, Fun _)::_ => ml_from_funs defs |
655 of (_, Fun _)::_ => ml_from_funs defs |
597 | (_, Datatypecons _)::_ => ml_from_datatypes defs |
656 | (_, Datatypecons _)::_ => ml_from_datatypes defs |
598 | (_, Datatype _)::_ => ml_from_datatypes defs |
657 | (_, Datatype _)::_ => ml_from_datatypes defs |
599 | [def] => ml_from_def def |
658 | [def] => ml_from_def def |
600 end; |
659 end; |
601 |
660 |
602 in |
661 in |
603 |
662 |
604 fun ml_from_thingol target (nsp_dtcon, nsp_class, int_tyco) nspgrp = |
663 fun ml_from_thingol target (nsp_dtcon, nsp_class, is_int_tyco) nspgrp = |
605 let |
664 let |
606 val reserved_ml = ThmDatabase.ml_reserved @ [ |
665 val reserved_ml = ThmDatabase.ml_reserved @ [ |
607 "bool", "int", "list", "true", "false" |
666 "bool", "int", "list", "true", "false", "o" |
608 ]; |
667 ]; |
609 fun ml_from_module _ ((_, name), ps) = |
668 fun ml_from_module _ ((_, name), ps) = |
610 Pretty.chunks ([ |
669 Pretty.chunks ([ |
611 str ("structure " ^ name ^ " = "), |
670 str ("structure " ^ name ^ " = "), |
612 str "struct", |
671 str "struct", |
689 else (lower_first o resolv) f |
747 else (lower_first o resolv) f |
690 else |
748 else |
691 f; |
749 f; |
692 fun hs_from_sctxt vs = |
750 fun hs_from_sctxt vs = |
693 let |
751 let |
|
752 fun from_class cls = |
|
753 case class_syntax cls |
|
754 of NONE => (upper_first o resolv) cls |
|
755 | SOME cls => cls |
694 fun from_sctxt [] = str "" |
756 fun from_sctxt [] = str "" |
695 | from_sctxt vs = |
757 | from_sctxt vs = |
696 vs |
758 vs |
697 |> map (fn (v, cls) => str ((upper_first o resolv) cls ^ " " ^ lower_first v)) |
759 |> map (fn (v, cls) => str (from_class cls ^ " " ^ lower_first v)) |
698 |> Pretty.enum "," "(" ")" |
760 |> Pretty.enum "," "(" ")" |
699 |> (fn p => Pretty.block [p, str " => "]) |
761 |> (fn p => Pretty.block [p, str " => "]) |
700 in |
762 in |
701 vs |
763 vs |
702 |> map (fn (v, sort) => map (pair v) sort) |
764 |> map (fn (v, sort) => map (pair v) sort) |
703 |> Library.flat |
765 |> Library.flat |
704 |> from_sctxt |
766 |> from_sctxt |
705 end; |
767 end; |
706 fun hs_from_type fxy ty = |
768 fun hs_from_type fxy (IType (tyco, tys)) = |
707 let |
769 (case tyco_syntax tyco |
708 fun from_itype fxy (IType (tyco, tys)) sctxt = |
|
709 (case tyco_syntax tyco |
|
710 of NONE => |
|
711 sctxt |
|
712 |> fold_map (from_itype BR) tys |
|
713 |-> (fn tyargs => pair (brackify fxy ((str o upper_first o resolv) tyco :: tyargs))) |
|
714 | SOME ((i, k), pr) => |
|
715 if not (i <= length tys andalso length tys <= k) |
|
716 then error ("number of argument mismatch in customary serialization: " |
|
717 ^ (string_of_int o length) tys ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k |
|
718 ^ " expected") |
|
719 else (pr fxy hs_from_type tys, sctxt)) |
|
720 | from_itype fxy (IFun (t1, t2)) sctxt = |
|
721 sctxt |
|
722 |> from_itype (INFX (1, X)) t1 |
|
723 ||>> from_itype (INFX (1, R)) t2 |
|
724 |-> (fn (p1, p2) => pair ( |
|
725 brackify_infix (1, R) fxy [ |
|
726 p1, |
|
727 str "->", |
|
728 p2 |
|
729 ] |
|
730 )) |
|
731 | from_itype fxy (IVarT (v, [])) sctxt = |
|
732 sctxt |
|
733 |> pair ((str o lower_first) v) |
|
734 | from_itype fxy (IVarT (v, sort)) sctxt = |
|
735 sctxt |
|
736 |> AList.default (op =) (v, []) |
|
737 |> AList.map_entry (op =) v (fold (insert (op =)) sort) |
|
738 |> pair ((str o lower_first) v) |
|
739 | from_itype fxy (IDictT _) _ = |
|
740 error "cannot serialize dictionary type to hs" |
|
741 in |
|
742 [] |
|
743 |> from_itype fxy ty |
|
744 ||> hs_from_sctxt |
|
745 |> (fn (pty, pctxt) => Pretty.block [pctxt, pty]) |
|
746 end; |
|
747 fun hs_from_pat fxy (ICons ((f, ps), _)) = |
|
748 (case const_syntax f |
|
749 of NONE => |
770 of NONE => |
750 ps |
771 brackify fxy ((str o upper_first o resolv) tyco :: map (hs_from_type BR) tys) |
751 |> map (hs_from_pat BR) |
|
752 |> cons ((str o resolv_const) f) |
|
753 |> brackify fxy |
|
754 | SOME ((i, k), pr) => |
772 | SOME ((i, k), pr) => |
755 if not (i <= length ps andalso length ps <= k) |
773 if not (i <= length tys andalso length tys <= k) |
756 then error ("number of argument mismatch in customary serialization: " |
774 then error ("number of argument mismatch in customary serialization: " |
757 ^ (string_of_int o length) ps ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k |
775 ^ (string_of_int o length) tys ^ " given, " |
|
776 ^ string_of_int i ^ " to " ^ string_of_int k |
758 ^ " expected") |
777 ^ " expected") |
759 else pr fxy hs_from_expr (map iexpr_of_ipat ps)) |
778 else pr fxy hs_from_type tys) |
760 | hs_from_pat fxy (IVarP (v, _)) = |
779 | hs_from_type fxy (IFun (t1, t2)) = |
|
780 brackify_infix (1, R) fxy [ |
|
781 hs_from_type (INFX (1, X)) t1, |
|
782 str "->", |
|
783 hs_from_type (INFX (1, R)) t2 |
|
784 ] |
|
785 | hs_from_type fxy (IVarT (v, _)) = |
761 (str o lower_first) v |
786 (str o lower_first) v |
762 and hs_from_expr fxy (e as IApp (e1, e2)) = |
787 | hs_from_type fxy (IDictT _) = |
763 (case (unfold_app e) |
788 error "can't serialize dictionary type to hs"; |
764 of (e as (IConst (f, _)), es) => |
789 fun hs_from_sctxt_type (sctxt, ty) = |
765 hs_from_app fxy (f, es) |
790 Pretty.block [hs_from_sctxt sctxt, hs_from_type NOBR ty] |
|
791 fun hs_from_expr fxy (e as IApp (e1, e2)) = |
|
792 (case unfold_const_app e |
|
793 of SOME x => hs_from_app fxy x |
766 | _ => |
794 | _ => |
767 brackify fxy [ |
795 brackify fxy [ |
768 hs_from_expr NOBR e1, |
796 hs_from_expr NOBR e1, |
769 hs_from_expr BR e2 |
797 hs_from_expr BR e2 |
770 ]) |
798 ]) |
771 | hs_from_expr fxy (e as IConst (f, _)) = |
799 | hs_from_expr fxy (e as IConst x) = |
772 hs_from_app fxy (f, []) |
800 hs_from_app fxy (x, []) |
773 | hs_from_expr fxy (IVarE (v, _)) = |
801 | hs_from_expr fxy (IVarE (v, _)) = |
774 (str o lower_first) v |
802 (str o lower_first) v |
775 | hs_from_expr fxy (e as IAbs _) = |
803 | hs_from_expr fxy (e as IAbs _) = |
776 let |
804 let |
777 val (vs, body) = unfold_abs e |
805 val (vs, body) = unfold_abs e |
812 Pretty.brk 1, |
840 Pretty.brk 1, |
813 str "of", |
841 str "of", |
814 Pretty.fbrk, |
842 Pretty.fbrk, |
815 (Pretty.chunks o map mk_clause) cs |
843 (Pretty.chunks o map mk_clause) cs |
816 ] end |
844 ] end |
817 | hs_from_expr fxy (IInst (e, _)) = |
|
818 hs_from_expr fxy e |
|
819 | hs_from_expr fxy (IDictE _) = |
845 | hs_from_expr fxy (IDictE _) = |
820 error "cannot serialize dictionary expression to hs" |
846 error "can't serialize dictionary expression to hs" |
821 | hs_from_expr fxy (ILookup _) = |
847 | hs_from_expr fxy (ILookup _) = |
822 error "cannot serialize lookup expression to hs" |
848 error "can't serialize lookup expression to hs" |
823 and hs_mk_app f es = |
849 and hs_mk_app c es = |
824 (str o resolv_const) f :: map (hs_from_expr BR) es |
850 (str o resolv_const) c :: map (hs_from_expr BR) es |
825 and hs_from_app fxy = |
851 and hs_from_app fxy (((c, _), ls), es) = |
826 from_app hs_mk_app hs_from_expr const_syntax fxy; |
852 from_app hs_mk_app hs_from_expr const_syntax fxy (c, es); |
|
853 fun hs_from_funeqs (name, eqs) = |
|
854 let |
|
855 fun from_eq name (args, rhs) = |
|
856 Pretty.block [ |
|
857 str (lower_first name), |
|
858 Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args), |
|
859 Pretty.brk 1, |
|
860 str ("="), |
|
861 Pretty.brk 1, |
|
862 hs_from_expr NOBR rhs |
|
863 ] |
|
864 in Pretty.chunks (map (from_eq name) eqs) end; |
827 fun hs_from_def (name, Undef) = |
865 fun hs_from_def (name, Undef) = |
828 error ("empty statement during serialization: " ^ quote name) |
866 error ("empty statement during serialization: " ^ quote name) |
829 | hs_from_def (name, Prim prim) = |
867 | hs_from_def (name, Prim prim) = |
830 from_prim (name, prim) |
868 from_prim (name, prim) |
831 | hs_from_def (name, Fun (eqs, (_, ty))) = |
869 | hs_from_def (name, Fun (eqs, (sctxt, ty))) = |
832 let |
870 let |
833 fun from_eq name (args, rhs) = |
871 fun from_eq name (args, rhs) = |
834 Pretty.block [ |
872 Pretty.block [ |
835 str (lower_first name), |
873 str (lower_first name), |
836 Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_pat BR p]) args), |
874 Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args), |
837 Pretty.brk 1, |
875 Pretty.brk 1, |
838 str ("="), |
876 str ("="), |
839 Pretty.brk 1, |
877 Pretty.brk 1, |
840 hs_from_expr NOBR rhs |
878 hs_from_expr NOBR rhs |
841 ] |
879 ] |
842 in |
880 in |
843 Pretty.chunks [ |
881 Pretty.chunks [ |
844 Pretty.block [ |
882 Pretty.block [ |
845 str (lower_first name ^ " ::"), |
883 str (lower_first name ^ " ::"), |
846 Pretty.brk 1, |
884 Pretty.brk 1, |
847 hs_from_type NOBR ty |
885 hs_from_sctxt_type (sctxt, ty) |
848 ], |
886 ], |
849 Pretty.chunks (map (from_eq name) eqs) |
887 hs_from_funeqs (name, eqs) |
850 ] |> SOME |
888 ] |> SOME |
851 end |
889 end |
852 | hs_from_def (name, Typesyn (vs, ty)) = |
890 | hs_from_def (name, Typesyn (vs, ty)) = |
853 Pretty.block [ |
891 Pretty.block [ |
854 str "type ", |
892 str "type ", |
855 hs_from_sctxt vs, |
893 hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs)), |
856 str (upper_first name), |
|
857 Pretty.block (map (fn (v, _) => str (" " ^ (lower_first) v)) vs), |
|
858 str " =", |
894 str " =", |
859 Pretty.brk 1, |
895 Pretty.brk 1, |
860 hs_from_type NOBR ty |
896 hs_from_sctxt_type ([], ty) |
861 ] |> SOME |
897 ] |> SOME |
862 | hs_from_def (name, Datatype ((vars, constrs), _)) = |
898 | hs_from_def (name, Datatype ((vs, constrs), _)) = |
863 let |
899 let |
864 fun mk_cons (co, tys) = |
900 fun mk_cons (co, tys) = |
865 (Pretty.block o Pretty.breaks) ( |
901 (Pretty.block o Pretty.breaks) ( |
866 str ((upper_first o resolv) co) |
902 str ((upper_first o resolv) co) |
867 :: map (hs_from_type NOBR) tys |
903 :: map (hs_from_type NOBR) tys |
868 ) |
904 ) |
869 in |
905 in |
870 Pretty.block ( |
906 Pretty.block (( |
871 str "data " |
907 str "data " |
872 :: hs_from_sctxt vars |
908 :: hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs)) |
873 :: str (upper_first name) |
|
874 :: Pretty.block (map (fn (v, _) => str (" " ^ (lower_first) v)) vars) |
|
875 :: str " =" |
909 :: str " =" |
876 :: Pretty.brk 1 |
910 :: Pretty.brk 1 |
877 :: separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs) |
911 :: separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs) |
878 ) |
912 ) @ [ |
|
913 Pretty.brk 1, |
|
914 str "deriving Show" |
|
915 ]) |
879 end |> SOME |
916 end |> SOME |
880 | hs_from_def (_, Datatypecons _) = |
917 | hs_from_def (_, Datatypecons _) = |
881 NONE |
918 NONE |
882 | hs_from_def (name, Class ((supclasss, (v, membrs)), _)) = |
919 | hs_from_def (name, Class ((supclasss, (v, membrs)), _)) = |
883 let |
920 let |
884 fun mk_member (m, (_, ty)) = |
921 fun mk_member (m, (sctxt, ty)) = |
885 Pretty.block [ |
922 Pretty.block [ |
886 str (resolv m ^ " ::"), |
923 str (resolv m ^ " ::"), |
887 Pretty.brk 1, |
924 Pretty.brk 1, |
888 hs_from_type NOBR ty |
925 hs_from_sctxt_type (sctxt, ty) |
889 ] |
926 ] |
890 in |
927 in |
891 Pretty.block [ |
928 Pretty.block [ |
892 str "class ", |
929 str "class ", |
893 hs_from_sctxt (map (fn class => (v, [class])) supclasss), |
930 hs_from_sctxt (map (fn class => (v, [class])) supclasss), |
897 Pretty.chunks (map mk_member membrs) |
934 Pretty.chunks (map mk_member membrs) |
898 ] |> SOME |
935 ] |> SOME |
899 end |
936 end |
900 | hs_from_def (name, Classmember _) = |
937 | hs_from_def (name, Classmember _) = |
901 NONE |
938 NONE |
902 | hs_from_def (_, Classinst ((clsname, (tyco, arity)), memdefs)) = |
939 | hs_from_def (_, Classinst (((clsname, (tyco, arity)), _), memdefs)) = |
903 Pretty.block [ |
940 Pretty.block [ |
904 str "instance ", |
941 str "instance ", |
905 hs_from_sctxt arity, |
942 hs_from_sctxt_type (arity, IType ((upper_first o resolv) clsname, map (IVarT o rpair [] o fst) arity)), |
906 str ((upper_first o resolv) clsname), |
|
907 str " ", |
943 str " ", |
908 hs_from_type NOBR (IType (tyco, (map (IVarT o rpair [] o fst)) arity)), |
944 hs_from_sctxt_type (arity, IType (tyco, map (IVarT o rpair [] o fst) arity)), |
909 str " where", |
945 str " where", |
910 Pretty.fbrk, |
946 Pretty.fbrk, |
911 Pretty.chunks (map (fn (m, funn) => hs_from_def (m, Fun funn) |> the) memdefs) |
947 Pretty.chunks (map (fn (m, (eqs, _)) => hs_from_funeqs (resolv m, eqs)) memdefs) |
912 ] |> SOME |
948 ] |> SOME |
913 in |
949 in |
914 case List.mapPartial (fn (name, def) => hs_from_def (name, def)) defs |
950 case List.mapPartial (fn (name, def) => hs_from_def (name, def)) defs |
915 of [] => NONE |
951 of [] => NONE |
916 | l => (SOME o Pretty.chunks o separate (str "")) l |
952 | l => (SOME o Pretty.chunks o separate (str "")) l |