56 |
56 |
57 fun eval_lrx L L = false |
57 fun eval_lrx L L = false |
58 | eval_lrx R R = false |
58 | eval_lrx R R = false |
59 | eval_lrx _ _ = true; |
59 | eval_lrx _ _ = true; |
60 |
60 |
61 fun eval_fxy NOBR _ = false |
61 fun eval_fxy NOBR NOBR = false |
62 | eval_fxy _ BR = true |
62 | eval_fxy BR NOBR = false |
63 | eval_fxy _ NOBR = false |
63 | eval_fxy NOBR BR = false |
64 | eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) = |
64 | eval_fxy (INFX (pr, lr)) (INFX (pr_ctxt, lr_ctxt)) = |
65 pr < pr_ctxt |
65 pr < pr_ctxt |
66 orelse pr = pr_ctxt |
66 orelse pr = pr_ctxt |
67 andalso eval_lrx lr lr_ctxt |
67 andalso eval_lrx lr lr_ctxt |
68 | eval_fxy _ (INFX _) = false; |
68 | eval_fxy _ (INFX _) = false |
|
69 | eval_fxy _ _ = true; |
69 |
70 |
70 fun gen_brackify _ [p] = p |
71 fun gen_brackify _ [p] = p |
71 | gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps |
72 | gen_brackify true (ps as _::_) = Pretty.enclose "(" ")" ps |
72 | gen_brackify false (ps as _::_) = Pretty.block ps; |
73 | gen_brackify false (ps as _::_) = Pretty.block ps; |
73 |
74 |
81 case const_syntax c |
82 case const_syntax c |
82 of NONE => brackify fxy (mk_app' app) |
83 of NONE => brackify fxy (mk_app' app) |
83 | SOME (i, pr) => |
84 | SOME (i, pr) => |
84 let |
85 let |
85 val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i |
86 val k = if i < 0 then (length o fst o CodegenThingol.unfold_fun) ty else i |
86 in if k <= length ts |
87 in if k = length ts |
87 then case chop i ts of (ts1, ts2) => |
88 then |
88 brackify fxy (pr fxy from_expr ts1 :: map (from_expr BR) ts2) |
89 pr fxy from_expr ts |
|
90 else if k < length ts |
|
91 then case chop k ts of (ts1, ts2) => |
|
92 brackify fxy (pr NOBR from_expr ts1 :: map (from_expr BR) ts2) |
89 else from_expr fxy (CodegenThingol.eta_expand app k) |
93 else from_expr fxy (CodegenThingol.eta_expand app k) |
90 end; |
94 end; |
91 |
95 |
92 val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode; |
96 val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode; |
93 |
97 |
102 |
106 |
103 fun mk_mixfix (fixity_this, mfx) = |
107 fun mk_mixfix (fixity_this, mfx) = |
104 let |
108 let |
105 fun is_arg (Arg _) = true |
109 fun is_arg (Arg _) = true |
106 | is_arg _ = false; |
110 | is_arg _ = false; |
107 val i = (length o List.filter is_arg) mfx; |
111 val i = (length o filter is_arg) mfx; |
108 fun fillin _ [] [] = |
112 fun fillin _ [] [] = |
109 [] |
113 [] |
110 | fillin pr (Arg fxy :: mfx) (a :: args) = |
114 | fillin pr (Arg fxy :: mfx) (a :: args) = |
111 pr fxy a :: fillin pr mfx args |
115 pr fxy a :: fillin pr mfx args |
112 | fillin pr (Pretty p :: mfx) args = |
116 | fillin pr (Pretty p :: mfx) args = |
143 of ((_, p as [_]), []) => mk_mixfix (NOBR, p) |
147 of ((_, p as [_]), []) => mk_mixfix (NOBR, p) |
144 | ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p) |
148 | ((b, p as _ :: _ :: _), []) => mk_mixfix (if b then NOBR else BR, p) |
145 | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail () |
149 | _ => Scan.!! (the_default ("malformed mixfix annotation: " ^ quote s) o snd) Scan.fail () |
146 end; |
150 end; |
147 |
151 |
148 (*FIXME: use Args.syntax ???*) |
|
149 fun parse_args f args = |
152 fun parse_args f args = |
150 case f args |
153 case f args |
151 of (x, []) => x |
154 of (x, []) => x |
152 | (_, _) => error "bad serializer arguments"; |
155 | (_, _) => error "bad serializer arguments"; |
153 |
156 |
209 | pretty _ _ _ = error "bad arguments for imperative monad bind"; |
212 | pretty _ _ _ = error "bad arguments for imperative monad bind"; |
210 in (2, pretty) end; |
213 in (2, pretty) end; |
211 |
214 |
212 |
215 |
213 (* misc *) |
216 (* misc *) |
214 |
|
215 fun constructive_fun (name, (eqs, ty)) = |
|
216 let |
|
217 val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco; |
|
218 fun is_pat (IConst (c, _)) = is_cons c |
|
219 | is_pat (IVar _) = true |
|
220 | is_pat (t1 `$ t2) = |
|
221 is_pat t1 andalso is_pat t2 |
|
222 | is_pat (INum _) = true |
|
223 | is_pat (IChar _) = true |
|
224 | is_pat _ = false; |
|
225 fun check_eq (eq as (lhs, rhs)) = |
|
226 if forall is_pat lhs |
|
227 then SOME eq |
|
228 else (warning ("In function " ^ quote name ^ ", throwing away one " |
|
229 ^ "non-executable function clause"); NONE) |
|
230 in case map_filter check_eq eqs |
|
231 of [] => error ("In function " ^ quote name ^ ", no " |
|
232 ^ "executable function clauses found") |
|
233 | eqs => (name, (eqs, ty)) |
|
234 end; |
|
235 |
217 |
236 fun dest_name name = |
218 fun dest_name name = |
237 let |
219 let |
238 val (names, name_base) = (split_last o NameSpace.explode) name; |
220 val (names, name_base) = (split_last o NameSpace.explode) name; |
239 val (names_mod, name_shallow) = split_last names; |
221 val (names_mod, name_shallow) = split_last names; |
418 | ps => |
400 | ps => |
419 if (is_none o const_syntax) c then |
401 if (is_none o const_syntax) c then |
420 brackify fxy ((str o deresolv) c :: (ps @ map (pr_term vars BR) ts)) |
402 brackify fxy ((str o deresolv) c :: (ps @ map (pr_term vars BR) ts)) |
421 else |
403 else |
422 error ("Cannot apply user defined serialization for function expecting dictionaries: " ^ quote c) |
404 error ("Cannot apply user defined serialization for function expecting dictionaries: " ^ quote c) |
423 fun eta_expand_poly_fun (funn as (_, (_::_, _))) = |
405 fun pr_def (MLFuns (funns as (funn :: funns'))) = |
424 funn |
406 let |
425 | eta_expand_poly_fun (funn as (_, ([_], ([], _)))) = |
|
426 funn |
|
427 | eta_expand_poly_fun (funn as (_, ([(_::_, _)], _))) = |
|
428 funn |
|
429 | eta_expand_poly_fun (funn as (_, ([(_, _ `|-> _)], _))) = |
|
430 funn |
|
431 | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) = |
|
432 if (null o fst o CodegenThingol.unfold_fun) ty |
|
433 orelse (not o null o filter_out (null o snd)) vs |
|
434 then funn |
|
435 else (name, ([([IVar "x"], t `$ IVar "x")], tysm)); |
|
436 fun pr_def (MLFuns raw_funns) = |
|
437 let |
|
438 val funns as (funn :: funns') = map (eta_expand_poly_fun o constructive_fun) raw_funns; |
|
439 val definer = |
407 val definer = |
440 let |
408 let |
441 fun mk [] [] = "val" |
409 fun mk [] [] = "val" |
442 | mk (_::_) _ = "fun" |
410 | mk (_::_) _ = "fun" |
443 | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun"; |
411 | mk [] vs = if (null o filter_out (null o snd)) vs then "val" else "fun"; |
486 str (deresolv co) |
454 str (deresolv co) |
487 | pr_co (co, tys) = |
455 | pr_co (co, tys) = |
488 (Pretty.block o Pretty.breaks) [ |
456 (Pretty.block o Pretty.breaks) [ |
489 str (deresolv co), |
457 str (deresolv co), |
490 str "of", |
458 str "of", |
491 Pretty.enum " *" "" "" (map (pr_typ (INFX (2, L))) tys) |
459 Pretty.enum " *" "" "" (map (pr_typ (INFX (2, X))) tys) |
492 ]; |
460 ]; |
493 fun pr_data definer (tyco, (vs, cos)) = |
461 fun pr_data definer (tyco, (vs, cos)) = |
494 (Pretty.block o Pretty.breaks) ( |
462 (Pretty.block o Pretty.breaks) ( |
495 str definer |
463 str definer |
496 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs) |
464 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs) |
757 | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) = |
725 | eta_expand_poly_fun (funn as (name, ([([], t)], tysm as (vs, ty)))) = |
758 if (null o fst o CodegenThingol.unfold_fun) ty |
726 if (null o fst o CodegenThingol.unfold_fun) ty |
759 orelse (not o null o filter_out (null o snd)) vs |
727 orelse (not o null o filter_out (null o snd)) vs |
760 then funn |
728 then funn |
761 else (name, ([([IVar "x"], t `$ IVar "x")], tysm)); |
729 else (name, ([([IVar "x"], t `$ IVar "x")], tysm)); |
762 fun pr_def (MLFuns raw_funns) = |
730 fun pr_def (MLFuns (funns as (funn :: funns'))) = |
763 let |
731 let |
764 val funns as (funn :: funns') = map (eta_expand_poly_fun o constructive_fun) raw_funns; |
|
765 fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) = |
732 fun pr_funn definer (name, (eqs as eq::eqs', (raw_vs, ty))) = |
766 let |
733 let |
767 val vs = filter_out (null o snd) raw_vs; |
734 val vs = filter_out (null o snd) raw_vs; |
768 val dummy_args = map_index (fn (i, _) => str ("x" ^ string_of_int i)) (fst eq); |
735 val dummy_args = map_index (fn (i, _) => str ("x" ^ string_of_int i)) (fst eq); |
769 fun pr_eq definer (ts, t) = |
736 fun pr_eq definer (ts, t) = |
801 str (deresolv co) |
768 str (deresolv co) |
802 | pr_co (co, tys) = |
769 | pr_co (co, tys) = |
803 (Pretty.block o Pretty.breaks) [ |
770 (Pretty.block o Pretty.breaks) [ |
804 str (deresolv co), |
771 str (deresolv co), |
805 str "of", |
772 str "of", |
806 Pretty.enum " *" "" "" (map (pr_typ (INFX (2, L))) tys) |
773 Pretty.enum " *" "" "" (map (pr_typ (INFX (2, X))) tys) |
807 ]; |
774 ]; |
808 fun pr_data definer (tyco, (vs, cos)) = |
775 fun pr_data definer (tyco, (vs, cos)) = |
809 (Pretty.block o Pretty.breaks) ( |
776 (Pretty.block o Pretty.breaks) ( |
810 str definer |
777 str definer |
811 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs) |
778 :: pr_tycoexpr NOBR (tyco, map (ITyVar o fst) vs) |
1007 |> map_nsp_yield modl' (mk defs) |
974 |> map_nsp_yield modl' (mk defs) |
1008 |-> (fn (base' :: bases', def') => |
975 |-> (fn (base' :: bases', def') => |
1009 apsnd (map_node modl' (Graph.new_node (name, (Def (base', SOME def'))) |
976 apsnd (map_node modl' (Graph.new_node (name, (Def (base', SOME def'))) |
1010 #> fold2 (fn name' => fn base' => Graph.new_node (name', (Def (base', NONE)))) names' bases'))) |
977 #> fold2 (fn name' => fn base' => Graph.new_node (name', (Def (base', NONE)))) names' bases'))) |
1011 |> apsnd (fold (fn defname => fold (add_dep defname) deps) defnames) |
978 |> apsnd (fold (fn defname => fold (add_dep defname) deps) defnames) |
|
979 |> apsnd (fold (map_node modl' o Graph.add_edge) (product names names)) |
1012 end; |
980 end; |
1013 fun group_defs [(_, CodegenThingol.Bot)] = |
981 fun group_defs [(_, CodegenThingol.Bot)] = |
1014 I |
982 I |
1015 | group_defs ((defs as (_, CodegenThingol.Fun _)::_)) = |
983 | group_defs ((defs as (_, CodegenThingol.Fun _)::_)) = |
1016 add_group mk_funs defs |
984 add_group mk_funs defs |
1211 end |
1179 end |
1212 and pr_app' vars ((c, _), ts) = |
1180 and pr_app' vars ((c, _), ts) = |
1213 (str o deresolv) c :: map (pr_term vars BR) ts |
1181 (str o deresolv) c :: map (pr_term vars BR) ts |
1214 and pr_app vars fxy = |
1182 and pr_app vars fxy = |
1215 mk_app (pr_app' vars) (pr_term vars) const_syntax fxy; |
1183 mk_app (pr_app' vars) (pr_term vars) const_syntax fxy; |
1216 fun pr_def (name, CodegenThingol.Fun (funn as (eqs, (vs, ty)))) = |
1184 fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) = |
1217 let |
1185 let |
1218 val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars; |
1186 val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars; |
1219 fun pr_eq (ts, t) = |
1187 fun pr_eq (ts, t) = |
1220 let |
1188 let |
1221 val consts = map_filter |
1189 val consts = map_filter |
1237 Pretty.block [ |
1205 Pretty.block [ |
1238 (str o suffix " ::" o deresolv_here) name, |
1206 (str o suffix " ::" o deresolv_here) name, |
1239 Pretty.brk 1, |
1207 Pretty.brk 1, |
1240 pr_typscheme tyvars (vs, ty) |
1208 pr_typscheme tyvars (vs, ty) |
1241 ] |
1209 ] |
1242 :: (map pr_eq o fst o snd o constructive_fun) (name, funn) |
1210 :: map pr_eq eqs |
1243 ) |
1211 ) |
1244 end |
1212 end |
1245 | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) = |
1213 | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) = |
1246 let |
1214 let |
1247 val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars; |
1215 val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars; |