Mercurial > urweb
comparison src/monoize.sml @ 1065:217eb87dde31
Basis.url and redirects
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 10 Dec 2009 13:32:09 -0500 |
parents | 93315ac00394 |
children | 50dd937c4cb9 |
comparison
equal
deleted
inserted
replaced
1064:b89e3d8731ed | 1065:217eb87dde31 |
---|---|
392 fun capitalize s = | 392 fun capitalize s = |
393 if s = "" then | 393 if s = "" then |
394 s | 394 s |
395 else | 395 else |
396 str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE) | 396 str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE) |
397 | |
398 val inTag = ref false | |
397 | 399 |
398 fun fooifyExp fk env = | 400 fun fooifyExp fk env = |
399 let | 401 let |
400 fun fooify fm (e, tAll as (t, loc)) = | 402 fun fooify fm (e, tAll as (t, loc)) = |
401 case #1 e of | 403 case #1 e of |
1058 | L.EFfi ("Basis", "show_int") => | 1060 | L.EFfi ("Basis", "show_int") => |
1059 ((L'.EFfi ("Basis", "intToString"), loc), fm) | 1061 ((L'.EFfi ("Basis", "intToString"), loc), fm) |
1060 | L.EFfi ("Basis", "show_float") => | 1062 | L.EFfi ("Basis", "show_float") => |
1061 ((L'.EFfi ("Basis", "floatToString"), loc), fm) | 1063 ((L'.EFfi ("Basis", "floatToString"), loc), fm) |
1062 | L.EFfi ("Basis", "show_string") => | 1064 | L.EFfi ("Basis", "show_string") => |
1065 let | |
1066 val s = (L'.TFfi ("Basis", "string"), loc) | |
1067 in | |
1068 ((L'.EAbs ("s", s, s, (L'.ERel 0, loc)), loc), fm) | |
1069 end | |
1070 | L.EFfi ("Basis", "show_url") => | |
1063 let | 1071 let |
1064 val s = (L'.TFfi ("Basis", "string"), loc) | 1072 val s = (L'.TFfi ("Basis", "string"), loc) |
1065 in | 1073 in |
1066 ((L'.EAbs ("s", s, s, (L'.ERel 0, loc)), loc), fm) | 1074 ((L'.EAbs ("s", s, s, (L'.ERel 0, loc)), loc), fm) |
1067 end | 1075 end |
2470 class), _), | 2478 class), _), |
2471 attrs), _), | 2479 attrs), _), |
2472 tag), _), | 2480 tag), _), |
2473 xml) => | 2481 xml) => |
2474 let | 2482 let |
2483 val inT = !inTag | |
2484 val () = inTag := true | |
2485 | |
2475 fun getTag' (e, _) = | 2486 fun getTag' (e, _) = |
2476 case e of | 2487 case e of |
2477 L.EFfi ("Basis", tag) => (tag, []) | 2488 L.EFfi ("Basis", tag) => (tag, []) |
2478 | L.ECApp (e, t) => let | 2489 | L.ECApp (e, t) => let |
2479 val (tag, ts) = getTag' e | 2490 val (tag, ts) = getTag' e |
2705 (L'.EStrcat ((L'.EPrim (Prim.String "exec("), loc), | 2716 (L'.EStrcat ((L'.EPrim (Prim.String "exec("), loc), |
2706 (L'.EStrcat ((L'.EJavaScript (L'.Attribute, e), loc), | 2717 (L'.EStrcat ((L'.EJavaScript (L'.Attribute, e), loc), |
2707 (L'.EPrim (Prim.String ")"), loc)), loc)), loc) | 2718 (L'.EPrim (Prim.String ")"), loc)), loc)), loc) |
2708 end | 2719 end |
2709 in | 2720 in |
2710 case tag of | 2721 (case tag of |
2711 "body" => let | 2722 "body" => let |
2712 val onload = execify onload | 2723 val onload = execify onload |
2713 val onunload = execify onunload | 2724 val onunload = execify onunload |
2714 in | 2725 in |
2715 normal ("body", | 2726 normal ("body", |
2716 SOME (L'.EStrcat ((L'.EFfiApp ("Basis", "maybe_onload", | 2727 SOME (L'.EStrcat ((L'.EFfiApp ("Basis", "maybe_onload", |
2717 [(L'.EStrcat ((L'.EFfiApp ("Basis", "get_settings", | 2728 [(L'.EStrcat ((L'.EFfiApp ("Basis", "get_settings", |
2718 [(L'.ERecord [], loc)]), loc), | 2729 [(L'.ERecord [], loc)]), loc), |
2719 onload), loc)]), | 2730 onload), loc)]), |
2720 loc), | 2731 loc), |
2721 (L'.EFfiApp ("Basis", "maybe_onunload", | 2732 (L'.EFfiApp ("Basis", "maybe_onunload", |
2722 [onunload]), | 2733 [onunload]), |
2723 loc)), loc), | 2734 loc)), loc), |
2724 SOME (L'.EFfiApp ("Basis", "get_script", [(L'.ERecord [], loc)]), loc)) | 2735 SOME (L'.EFfiApp ("Basis", "get_script", [(L'.ERecord [], loc)]), loc)) |
2725 end | 2736 end |
2726 | 2737 |
2727 | "dyn" => | 2738 | "dyn" => |
2728 let | 2739 let |
2729 fun inTag tag = case targs of | 2740 fun inTag tag = case targs of |
2730 (L.CRecord (_, ctx), _) :: _ => | 2741 (L.CRecord (_, ctx), _) :: _ => |
2731 List.exists (fn ((L.CName tag', _), _) => tag' = tag | 2742 List.exists (fn ((L.CName tag', _), _) => tag' = tag |
2732 | _ => false) ctx | 2743 | _ => false) ctx |
2733 | _ => false | 2744 | _ => false |
2734 | 2745 |
2735 val tag = if inTag "Tr" then | 2746 val tag = if inTag "Tr" then |
2736 "tr" | 2747 "tr" |
2737 else if inTag "Table" then | 2748 else if inTag "Table" then |
2738 "table" | 2749 "table" |
2739 else | 2750 else |
2740 "span" | 2751 "span" |
2741 in | 2752 in |
2742 case attrs of | 2753 case attrs of |
2743 [("Signal", e, _)] => | 2754 [("Signal", e, _)] => |
2744 ((L'.EStrcat | 2755 ((L'.EStrcat |
2745 ((L'.EPrim (Prim.String ("<script type=\"text/javascript\">dyn(\"" | 2756 ((L'.EPrim (Prim.String ("<script type=\"text/javascript\">dyn(\"" |
2746 ^ tag ^ "\", execD(")), loc), | 2757 ^ tag ^ "\", execD(")), loc), |
2747 (L'.EStrcat ((L'.EJavaScript (L'.Script, e), loc), | 2758 (L'.EStrcat ((L'.EJavaScript (L'.Script, e), loc), |
2748 (L'.EPrim (Prim.String ("))</script>")), loc)), loc)), loc), | 2759 (L'.EPrim (Prim.String ("))</script>")), loc)), loc)), loc), |
2749 fm) | |
2750 | _ => raise Fail "Monoize: Bad dyn attributes" | |
2751 end | |
2752 | |
2753 | "submit" => normal ("input type=\"submit\"", NONE, NONE) | |
2754 | "button" => normal ("input type=\"submit\"", NONE, NONE) | |
2755 | "hidden" => input "hidden" | |
2756 | |
2757 | "textbox" => | |
2758 (case targs of | |
2759 [_, (L.CName name, _)] => | |
2760 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | |
2761 NONE => | |
2762 let | |
2763 val (ts, fm) = tagStart "input" | |
2764 in | |
2765 ((L'.EStrcat (ts, | |
2766 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\" />")), | |
2767 loc)), loc), fm) | |
2768 end | |
2769 | SOME (_, src, _) => | |
2770 (strcat [str "<script type=\"text/javascript\">inp(exec(", | |
2771 (L'.EJavaScript (L'.Script, src), loc), | |
2772 str "))</script>"], | |
2773 fm)) | |
2774 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | |
2775 raise Fail "No name passed to textbox tag")) | |
2776 | "password" => input "password" | |
2777 | "textarea" => | |
2778 (case targs of | |
2779 [_, (L.CName name, _)] => | |
2780 let | |
2781 val (ts, fm) = tagStart "textarea" | |
2782 val (xml, fm) = monoExp (env, st, fm) xml | |
2783 in | |
2784 ((L'.EStrcat ((L'.EStrcat (ts, | |
2785 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), | |
2786 (L'.EStrcat (xml, | |
2787 (L'.EPrim (Prim.String "</textarea>"), | |
2788 loc)), loc)), | |
2789 loc), fm) | |
2790 end | |
2791 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | |
2792 raise Fail "No name passed to ltextarea tag")) | |
2793 | |
2794 | "checkbox" => input "checkbox" | |
2795 | "upload" => input "file" | |
2796 | |
2797 | "radio" => | |
2798 (case targs of | |
2799 [_, (L.CName name, _)] => | |
2800 monoExp (env, St.setRadioGroup (st, name), fm) xml | |
2801 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | |
2802 raise Fail "No name passed to radio tag")) | |
2803 | "radioOption" => | |
2804 (case St.radioGroup st of | |
2805 NONE => raise Fail "No name for radioGroup" | |
2806 | SOME name => | |
2807 normal ("input", | |
2808 SOME (L'.EPrim (Prim.String (" type=\"radio\" name=\"" ^ name ^ "\"")), loc), | |
2809 NONE)) | |
2810 | |
2811 | "select" => | |
2812 (case targs of | |
2813 [_, (L.CName name, _)] => | |
2814 let | |
2815 val (ts, fm) = tagStart "select" | |
2816 val (xml, fm) = monoExp (env, st, fm) xml | |
2817 in | |
2818 ((L'.EStrcat ((L'.EStrcat (ts, | |
2819 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), | |
2820 loc)), loc), | |
2821 (L'.EStrcat (xml, | |
2822 (L'.EPrim (Prim.String "</select>"), | |
2823 loc)), loc)), | |
2824 loc), | |
2825 fm) | 2760 fm) |
2826 end | 2761 | _ => raise Fail "Monoize: Bad dyn attributes" |
2827 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); | 2762 end |
2828 raise Fail "No name passed to lselect tag")) | 2763 |
2829 | 2764 | "submit" => normal ("input type=\"submit\"", NONE, NONE) |
2830 | "ctextbox" => | 2765 | "button" => normal ("input type=\"submit\"", NONE, NONE) |
2831 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | 2766 | "hidden" => input "hidden" |
2832 NONE => | 2767 |
2833 let | 2768 | "textbox" => |
2834 val (ts, fm) = tagStart "input" | 2769 (case targs of |
2835 in | 2770 [_, (L.CName name, _)] => |
2836 ((L'.EStrcat (ts, | 2771 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of |
2837 (L'.EPrim (Prim.String " />"), loc)), | 2772 NONE => |
2838 loc), fm) | 2773 let |
2839 end | 2774 val (ts, fm) = tagStart "input" |
2840 | SOME (_, src, _) => | 2775 in |
2841 let | 2776 ((L'.EStrcat (ts, |
2842 val sc = strcat [str "inp(exec(", | 2777 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\" />")), |
2843 (L'.EJavaScript (L'.Script, src), loc), | 2778 loc)), loc), fm) |
2844 str "))"] | 2779 end |
2845 val sc = setAttrs sc | 2780 | SOME (_, src, _) => |
2846 in | 2781 (strcat [str "<script type=\"text/javascript\">inp(exec(", |
2847 (strcat [str "<script type=\"text/javascript\">", | 2782 (L'.EJavaScript (L'.Script, src), loc), |
2848 sc, | 2783 str "))</script>"], |
2849 str "</script>"], | 2784 fm)) |
2850 fm) | 2785 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
2851 end) | 2786 raise Fail "No name passed to textbox tag")) |
2852 | 2787 | "password" => input "password" |
2853 | "ccheckbox" => | 2788 | "textarea" => |
2854 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | 2789 (case targs of |
2855 NONE => | 2790 [_, (L.CName name, _)] => |
2856 let | 2791 let |
2857 val (ts, fm) = tagStart "input type=\"checkbox\"" | 2792 val (ts, fm) = tagStart "textarea" |
2858 in | 2793 val (xml, fm) = monoExp (env, st, fm) xml |
2859 ((L'.EStrcat (ts, | 2794 in |
2860 (L'.EPrim (Prim.String " />"), loc)), | 2795 ((L'.EStrcat ((L'.EStrcat (ts, |
2861 loc), fm) | 2796 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), loc)), loc), |
2862 end | 2797 (L'.EStrcat (xml, |
2863 | SOME (_, src, _) => | 2798 (L'.EPrim (Prim.String "</textarea>"), |
2864 let | 2799 loc)), loc)), |
2865 val sc = strcat [str "chk(exec(", | 2800 loc), fm) |
2866 (L'.EJavaScript (L'.Script, src), loc), | 2801 end |
2867 str "))"] | 2802 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
2868 val sc = setAttrs sc | 2803 raise Fail "No name passed to ltextarea tag")) |
2869 in | 2804 |
2870 (strcat [str "<script type=\"text/javascript\">", | 2805 | "checkbox" => input "checkbox" |
2871 sc, | 2806 | "upload" => input "file" |
2872 str "</script>"], | 2807 |
2873 fm) | 2808 | "radio" => |
2874 end) | 2809 (case targs of |
2875 | 2810 [_, (L.CName name, _)] => |
2876 | "cselect" => | 2811 monoExp (env, St.setRadioGroup (st, name), fm) xml |
2877 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | 2812 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
2878 NONE => | 2813 raise Fail "No name passed to radio tag")) |
2879 let | 2814 | "radioOption" => |
2880 val (xml, fm) = monoExp (env, st, fm) xml | 2815 (case St.radioGroup st of |
2881 val (ts, fm) = tagStart "select" | 2816 NONE => raise Fail "No name for radioGroup" |
2882 in | 2817 | SOME name => |
2883 (strcat [ts, | 2818 normal ("input", |
2884 str ">", | 2819 SOME (L'.EPrim (Prim.String (" type=\"radio\" name=\"" ^ name ^ "\"")), loc), |
2885 xml, | 2820 NONE)) |
2886 str "</select>"], | 2821 |
2887 fm) | 2822 | "select" => |
2888 end | 2823 (case targs of |
2889 | SOME (_, src, _) => | 2824 [_, (L.CName name, _)] => |
2890 let | 2825 let |
2891 val (xml, fm) = monoExp (env, st, fm) xml | 2826 val (ts, fm) = tagStart "select" |
2892 | 2827 val (xml, fm) = monoExp (env, st, fm) xml |
2893 val sc = strcat [str "sel(exec(", | 2828 in |
2894 (L'.EJavaScript (L'.Script, src), loc), | 2829 ((L'.EStrcat ((L'.EStrcat (ts, |
2895 str "),exec(", | 2830 (L'.EPrim (Prim.String (" name=\"" ^ name ^ "\">")), |
2896 (L'.EJavaScript (L'.Script, xml), loc), | 2831 loc)), loc), |
2897 str "))"] | 2832 (L'.EStrcat (xml, |
2898 val sc = setAttrs sc | 2833 (L'.EPrim (Prim.String "</select>"), |
2899 in | 2834 loc)), loc)), |
2900 (strcat [str "<script type=\"text/javascript\">", | 2835 loc), |
2901 sc, | 2836 fm) |
2902 str "</script>"], | 2837 end |
2903 fm) | 2838 | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); |
2904 end) | 2839 raise Fail "No name passed to lselect tag")) |
2905 | 2840 |
2906 | "coption" => normal ("option", NONE, NONE) | 2841 | "ctextbox" => |
2907 | 2842 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of |
2908 | "tabl" => normal ("table", NONE, NONE) | 2843 NONE => |
2909 | _ => normal (tag, NONE, NONE) | 2844 let |
2845 val (ts, fm) = tagStart "input" | |
2846 in | |
2847 ((L'.EStrcat (ts, | |
2848 (L'.EPrim (Prim.String " />"), loc)), | |
2849 loc), fm) | |
2850 end | |
2851 | SOME (_, src, _) => | |
2852 let | |
2853 val sc = strcat [str "inp(exec(", | |
2854 (L'.EJavaScript (L'.Script, src), loc), | |
2855 str "))"] | |
2856 val sc = setAttrs sc | |
2857 in | |
2858 (strcat [str "<script type=\"text/javascript\">", | |
2859 sc, | |
2860 str "</script>"], | |
2861 fm) | |
2862 end) | |
2863 | |
2864 | "ccheckbox" => | |
2865 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | |
2866 NONE => | |
2867 let | |
2868 val (ts, fm) = tagStart "input type=\"checkbox\"" | |
2869 in | |
2870 ((L'.EStrcat (ts, | |
2871 (L'.EPrim (Prim.String " />"), loc)), | |
2872 loc), fm) | |
2873 end | |
2874 | SOME (_, src, _) => | |
2875 let | |
2876 val sc = strcat [str "chk(exec(", | |
2877 (L'.EJavaScript (L'.Script, src), loc), | |
2878 str "))"] | |
2879 val sc = setAttrs sc | |
2880 in | |
2881 (strcat [str "<script type=\"text/javascript\">", | |
2882 sc, | |
2883 str "</script>"], | |
2884 fm) | |
2885 end) | |
2886 | |
2887 | "cselect" => | |
2888 (case List.find (fn ("Source", _, _) => true | _ => false) attrs of | |
2889 NONE => | |
2890 let | |
2891 val (xml, fm) = monoExp (env, st, fm) xml | |
2892 val (ts, fm) = tagStart "select" | |
2893 in | |
2894 (strcat [ts, | |
2895 str ">", | |
2896 xml, | |
2897 str "</select>"], | |
2898 fm) | |
2899 end | |
2900 | SOME (_, src, _) => | |
2901 let | |
2902 val (xml, fm) = monoExp (env, st, fm) xml | |
2903 | |
2904 val sc = strcat [str "sel(exec(", | |
2905 (L'.EJavaScript (L'.Script, src), loc), | |
2906 str "),exec(", | |
2907 (L'.EJavaScript (L'.Script, xml), loc), | |
2908 str "))"] | |
2909 val sc = setAttrs sc | |
2910 in | |
2911 (strcat [str "<script type=\"text/javascript\">", | |
2912 sc, | |
2913 str "</script>"], | |
2914 fm) | |
2915 end) | |
2916 | |
2917 | "coption" => normal ("option", NONE, NONE) | |
2918 | |
2919 | "tabl" => normal ("table", NONE, NONE) | |
2920 | _ => normal (tag, NONE, NONE)) | |
2921 before inTag := inT | |
2910 end | 2922 end |
2911 | 2923 |
2912 | L.EApp ((L.ECApp ( | 2924 | L.EApp ((L.ECApp ( |
2913 (L.ECApp ((L.EFfi ("Basis", "form"), _), _), _), | 2925 (L.ECApp ((L.EFfi ("Basis", "form"), _), _), _), |
2914 (L.CRecord (_, fields), _)), _), | 2926 (L.CRecord (_, fields), _)), _), |
3119 (L'.EReturnBlob {blob = (L'.ERel 2, loc), | 3131 (L'.EReturnBlob {blob = (L'.ERel 2, loc), |
3120 mimeType = (L'.ERel 1, loc), | 3132 mimeType = (L'.ERel 1, loc), |
3121 t = t}, loc)), loc)), loc)), loc), | 3133 t = t}, loc)), loc)), loc)), loc), |
3122 fm) | 3134 fm) |
3123 end | 3135 end |
3136 | L.ECApp ((L.EFfi ("Basis", "redirect"), _), t) => | |
3137 let | |
3138 val t = monoType env t | |
3139 val un = (L'.TRecord [], loc) | |
3140 in | |
3141 ((L'.EAbs ("url", (L'.TFfi ("Basis", "string"), loc), (L'.TFun (un, t), loc), | |
3142 (L'.EAbs ("_", un, t, | |
3143 (L'.ERedirect ((L'.ERel 1, loc), t), loc)), loc)), loc), | |
3144 fm) | |
3145 end | |
3124 | 3146 |
3125 | L.EApp (e1, e2) => | 3147 | L.EApp (e1, e2) => |
3126 let | 3148 let |
3127 val (e1, fm) = monoExp (env, st, fm) e1 | 3149 val (e1, fm) = monoExp (env, st, fm) e1 |
3128 val (e2, fm) = monoExp (env, st, fm) e2 | 3150 val (e2, fm) = monoExp (env, st, fm) e2 |
3196 | 3218 |
3197 | L.EClosure (n, es) => | 3219 | L.EClosure (n, es) => |
3198 let | 3220 let |
3199 val (es, fm) = ListUtil.foldlMap (fn (e, fm) => | 3221 val (es, fm) = ListUtil.foldlMap (fn (e, fm) => |
3200 monoExp (env, st, fm) e) | 3222 monoExp (env, st, fm) e) |
3201 fm es | 3223 fm es |
3202 in | 3224 val e = (L'.EClosure (n, es), loc) |
3203 ((L'.EClosure (n, es), loc), fm) | 3225 in |
3226 if !inTag then | |
3227 (e, fm) | |
3228 else | |
3229 urlifyExp env fm (e, dummyTyp) | |
3204 end | 3230 end |
3205 | 3231 |
3206 | L.ELet (x, t, e1, e2) => | 3232 | L.ELet (x, t, e1, e2) => |
3207 let | 3233 let |
3208 val t' = monoType env t | 3234 val t' = monoType env t |