# HG changeset patch # User Adam Chlipala # Date 1239560355 14400 # Node ID 9864b64b17009500855d8fb7a74971084f26b31b # Parent acb8537f58f0df1f595f212261003cfc98ab58c0 Classes as optional arguments to Basis.tag diff -r acb8537f58f0 -r 9864b64b1700 include/types.h --- a/include/types.h Sun Apr 12 12:31:54 2009 -0400 +++ b/include/types.h Sun Apr 12 14:19:15 2009 -0400 @@ -17,6 +17,7 @@ typedef uw_Basis_string uw_Basis_xhtml; typedef uw_Basis_string uw_Basis_page; +typedef uw_Basis_string uw_Basis_css_class; typedef unsigned uw_Basis_client; typedef struct { diff -r acb8537f58f0 -r 9864b64b1700 include/urweb.h --- a/include/urweb.h Sun Apr 12 12:31:54 2009 -0400 +++ b/include/urweb.h Sun Apr 12 14:19:15 2009 -0400 @@ -74,6 +74,7 @@ char *uw_Basis_attrifyTime(uw_context, uw_Basis_time); char *uw_Basis_attrifyChannel(uw_context, uw_Basis_channel); char *uw_Basis_attrifyClient(uw_context, uw_Basis_client); +char *uw_Basis_attrifyCss_class(uw_context, uw_Basis_css_class); uw_unit uw_Basis_attrifyInt_w(uw_context, uw_Basis_int); uw_unit uw_Basis_attrifyFloat_w(uw_context, uw_Basis_float); diff -r acb8537f58f0 -r 9864b64b1700 lib/ur/basis.urs --- a/lib/ur/basis.urs Sun Apr 12 12:31:54 2009 -0400 +++ b/lib/ur/basis.urs Sun Apr 12 14:19:15 2009 -0400 @@ -405,12 +405,10 @@ (** XML *) -con css_class :: {Unit} -> Type -(* The argument lists categories of properties that this class could set usefully. *) +type css_class con tag :: {Type} -> {Unit} -> {Unit} -> {Type} -> {Type} -> Type - con xml :: {Unit} -> {Type} -> {Type} -> Type val cdata : ctx ::: {Unit} -> use ::: {Type} -> string -> xml ctx use [] val tag : attrsGiven ::: {Type} -> attrsAbsent ::: {Type} @@ -420,7 +418,8 @@ -> [attrsGiven ~ attrsAbsent] => [useOuter ~ useInner] => [bindOuter ~ bindInner] => - $attrsGiven + option css_class + -> $attrsGiven -> tag (attrsGiven ++ attrsAbsent) ctxOuter ctxInner useOuter bindOuter -> xml ctxInner useInner bindInner diff -r acb8537f58f0 -r 9864b64b1700 src/c/urweb.c --- a/src/c/urweb.c Sun Apr 12 12:31:54 2009 -0400 +++ b/src/c/urweb.c Sun Apr 12 14:19:15 2009 -0400 @@ -922,6 +922,10 @@ return result; } +char *uw_Basis_attrifyCss_class(uw_context ctx, uw_Basis_css_class s) { + return s; +} + static void uw_Basis_attrifyInt_w_unsafe(uw_context ctx, uw_Basis_int n) { int len; diff -r acb8537f58f0 -r 9864b64b1700 src/corify.sml --- a/src/corify.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/corify.sml Sun Apr 12 14:19:15 2009 -0400 @@ -1005,7 +1005,7 @@ | L.DStyle (_, x, n) => let val (st, n) = St.bindVal st x n - val s = doRestify (mods, x) + val s = relify (doRestify (mods, x)) in ([(L'.DStyle (x, n, s), loc)], st) end diff -r acb8537f58f0 -r 9864b64b1700 src/elab_env.sml --- a/src/elab_env.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/elab_env.sml Sun Apr 12 14:19:15 2009 -0400 @@ -899,19 +899,19 @@ end) | _ => c -fun sgnS_con' (arg as (m1, ms', (sgns, strs, cons))) c = - case c of - CModProj (m1, ms, x) => - (case IM.find (strs, m1) of - NONE => c - | SOME m1x => CModProj (m1, ms' @ m1x :: ms, x)) - | CNamed n => - (case IM.find (cons, n) of - NONE => c - | SOME nx => CModProj (m1, ms', nx)) - | CApp (c1, c2) => CApp ((sgnS_con' arg (#1 c1), #2 c1), - (sgnS_con' arg (#1 c2), #2 c2)) - | _ => c +fun sgnS_con' (m1, ms', (sgns, strs, cons)) = + U.Con.map {kind = fn x => x, + con = fn c => + case c of + CModProj (m1, ms, x) => + (case IM.find (strs, m1) of + NONE => c + | SOME m1x => CModProj (m1, ms' @ m1x :: ms, x)) + | CNamed n => + (case IM.find (cons, n) of + NONE => c + | SOME nx => CModProj (m1, ms', nx)) + | _ => c} fun sgnS_sgn (str, (sgns, strs, cons)) sgn = case sgn of @@ -1026,7 +1026,7 @@ | SOME (cn, nvs, cs, c) => let val loc = #2 c - fun globalize (c, loc) = (sgnS_con' (m1, ms, fmap) c, loc) + val globalize = sgnS_con' (m1, ms, fmap) val nc = case cn of diff -r acb8537f58f0 -r 9864b64b1700 src/elaborate.sml --- a/src/elaborate.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/elaborate.sml Sun Apr 12 14:19:15 2009 -0400 @@ -1493,26 +1493,28 @@ end | _ => (c, loc) -fun normClassKey envs c = +fun normClassKey env c = let - val c = hnormCon envs c + val c = hnormCon env c in case #1 c of L'.CApp (c1, c2) => let - val c1 = normClassKey envs c1 - val c2 = normClassKey envs c2 + val c1 = normClassKey env c1 + val c2 = normClassKey env c2 in (L'.CApp (c1, c2), #2 c) end - | _ => c + | L'.CRecord (k, xcs) => (L'.CRecord (k, map (fn (x, c) => (normClassKey env x, + normClassKey env c)) xcs), #2 c) + | _ => unmodCon env c end fun normClassConstraint env (c, loc) = case c of L'.CApp (f, x) => let - val f = unmodCon env f + val f = normClassKey env f val x = normClassKey env x in (L'.CApp (f, x), loc) @@ -1526,7 +1528,7 @@ end | L'.TCFun (expl, x, k, c1) => (L'.TCFun (expl, x, k, normClassConstraint env c1), loc) | L'.CUnif (_, _, _, ref (SOME c)) => normClassConstraint env c - | _ => (c, loc) + | _ => unmodCon env (c, loc) fun elabExp (env, denv) (eAll as (e, loc)) = let @@ -2047,6 +2049,7 @@ let val (c', ck, gs') = elabCon (env, denv) c + val old = c' val c' = normClassConstraint env c' val (env', n) = E.pushENamed env x c' in diff -r acb8537f58f0 -r 9864b64b1700 src/especialize.sml --- a/src/especialize.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/especialize.sml Sun Apr 12 14:19:15 2009 -0400 @@ -114,35 +114,6 @@ fun specialize' file = let - fun default' (_, fs) = fs - - fun actionableExp (e, fs) = - case e of - ERecord xes => - foldl (fn (((CName s, _), e, _), fs) => - if s = "Action" orelse s = "Link" then - let - fun findHead (e, _) = - case e of - ENamed n => IS.add (fs, n) - | EApp (e, _) => findHead e - | _ => fs - in - findHead e - end - else - fs - | (_, fs) => fs) - fs xes - | _ => fs - - val actionable = - U.File.fold {kind = default', - con = default', - exp = actionableExp, - decl = default'} - IS.empty file - fun bind (env, b) = case b of U.Decl.RelE xt => xt :: env @@ -150,6 +121,9 @@ fun exp (env, e, st : state) = let + (*val () = Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty + (e, ErrorMsg.dummySpan))]*) + fun getApp e = case e of ENamed f => SOME (f, []) @@ -160,12 +134,17 @@ | _ => NONE in case getApp e of - NONE => (e, st) + NONE => ((*Print.prefaces "No" [("e", CorePrint.p_exp CoreEnv.empty + (e, ErrorMsg.dummySpan))];*) + (e, st)) | SOME (f, xs) => case IM.find (#funcs st, f) of NONE => (e, st) | SOME {name, args, body, typ, tag} => let + (*val () = Print.prefaces "Consider" [("e", CorePrint.p_exp CoreEnv.empty + (e, ErrorMsg.dummySpan))]*) + val functionInside = U.Con.exists {kind = fn _ => false, con = fn TFun _ => true | CFfi ("Basis", "transaction") => true @@ -208,7 +187,7 @@ e xs in (*Print.prefaces "Brand new (reuse)" - [("e'", CorePrint.p_exp env e)];*) + [("e'", CorePrint.p_exp CoreEnv.empty e)];*) (#1 e, st) end | NONE => @@ -267,9 +246,9 @@ val e' = foldl (fn (arg, e) => (EApp (e, arg), loc)) e' xs (*val () = Print.prefaces "Brand new" - [("e'", CorePrint.p_exp env e'), - ("e", CorePrint.p_exp env (e, loc)), - ("body'", CorePrint.p_exp env body')]*) + [("e'", CorePrint.p_exp CoreEnv.empty e'), + ("e", CorePrint.p_exp CoreEnv.empty (e, loc)), + ("body'", CorePrint.p_exp CoreEnv.empty body')]*) in (#1 e', {maxName = #maxName st, @@ -358,7 +337,8 @@ fun specialize file = let - (*val () = Print.prefaces "Intermediate" [("file", CorePrint.p_file CoreEnv.empty file)];*) + val file = ReduceLocal.reduce file + (*val () = Print.prefaces "Intermediate" [("file", CorePrint.p_file CoreEnv.empty file)]*) (*val file = ReduceLocal.reduce file*) val (changed, file) = specialize' file (*val file = ReduceLocal.reduce file @@ -368,7 +348,7 @@ (*print "Round over\n";*) if changed then let - val file = ReduceLocal.reduce file + (*val file = ReduceLocal.reduce file*) val file = CoreUntangle.untangle file val file = Shake.shake file in diff -r acb8537f58f0 -r 9864b64b1700 src/mono_opt.sml --- a/src/mono_opt.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/mono_opt.sml Sun Apr 12 14:19:15 2009 -0400 @@ -242,6 +242,13 @@ | EWrite (EFfiApp ("Basis", "attrifyString", [e]), _) => EFfiApp ("Basis", "attrifyString_w", [e]) + | EFfiApp ("Basis", "attrifyCss_class", [(EPrim (Prim.String s), _)]) => + EPrim (Prim.String s) + | EWrite (EFfiApp ("Basis", "attrifyCss_class", [(EPrim (Prim.String s), _)]), loc) => + EWrite (EPrim (Prim.String s), loc) + | EWrite (EFfiApp ("Basis", "attrifyCss_class", [e]), _) => + EFfiApp ("Basis", "attrifyString_w", [e]) + | EFfiApp ("Basis", "urlifyInt", [(EPrim (Prim.Int n), _)]) => EPrim (Prim.String (urlifyInt n)) | EWrite (EFfiApp ("Basis", "urlifyInt", [(EPrim (Prim.Int n), _)]), loc) => diff -r acb8537f58f0 -r 9864b64b1700 src/monoize.sml --- a/src/monoize.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/monoize.sml Sun Apr 12 14:19:15 2009 -0400 @@ -131,6 +131,7 @@ (L'.TFfi ("Basis", "string"), loc) | L.CApp ((L.CApp ((L.CFfi ("Basis", "xhtml"), _), _), _), _) => (L'.TFfi ("Basis", "string"), loc) + | L.CFfi ("Basis", "css_class") => (L'.TFfi ("Basis", "string"), loc) | L.CApp ((L.CFfi ("Basis", "transaction"), _), t) => (L'.TFun ((L'.TRecord [], loc), mt env dtmap t), loc) @@ -2035,7 +2036,7 @@ | L.EApp ( (L.EApp ( (L.EApp ( - (L.ECApp ( + (L.EApp ( (L.ECApp ( (L.ECApp ( (L.ECApp ( @@ -2043,8 +2044,10 @@ (L.ECApp ( (L.ECApp ( (L.ECApp ( - (L.EFfi ("Basis", "tag"), - _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), + (L.ECApp ( + (L.EFfi ("Basis", "tag"), + _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), _), + class), _), attrs), _), tag), _), xml) => @@ -2096,9 +2099,24 @@ | lowercaseFirst s = String.str (Char.toLower (String.sub (s, 0))) ^ String.extract (s, 1, NONE) + val (class, fm) = monoExp (env, st, fm) class + fun tagStart tag = let + val t = (L'.TFfi ("Basis", "string"), loc) val s = (L'.EPrim (Prim.String (String.concat ["<", tag])), loc) + + val s = (L'.ECase (class, + [((L'.PNone t, loc), + s), + ((L'.PSome (t, (L'.PVar ("x", t), loc)), loc), + (L'.EStrcat (s, + (L'.EStrcat ((L'.EPrim (Prim.String " class=\""), loc), + (L'.EStrcat ((L'.ERel 0, loc), + (L'.EPrim (Prim.String "\""), loc)), + loc)), loc)), loc))], + {disc = (L'.TOption t, loc), + result = t}), loc) in foldl (fn (("Action", _, _), acc) => acc | (("Source", _, _), acc) => acc diff -r acb8537f58f0 -r 9864b64b1700 src/reduce_local.sml --- a/src/reduce_local.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/reduce_local.sml Sun Apr 12 14:19:15 2009 -0400 @@ -72,6 +72,11 @@ | EFfi _ => all | EFfiApp (m, f, es) => (EFfiApp (m, f, map (exp env) es), loc) + | EApp ((ECApp ((ECAbs (_, _, (EAbs (_, (CRel 0, _), _, + (ECon (dk, pc, [(CRel 0, loc)], SOME (ERel 0, _)), _)), _)), _), + t), _), e) => + (ECon (dk, pc, [t], SOME (exp env e)), loc) + | EApp (e1, e2) => let val e1 = exp env e1 @@ -84,6 +89,9 @@ | EAbs (x, dom, ran, e) => (EAbs (x, dom, ran, exp (Unknown :: env) e), loc) + | ECApp ((ECAbs (_, _, (ECon (dk, pc, [(CRel 0, loc)], NONE), _)), _), t) => + (ECon (dk, pc, [t], NONE), loc) + | ECApp (e, c) => (ECApp (exp env e, c), loc) | ECAbs (x, k, e) => (ECAbs (x, k, exp env e), loc) diff -r acb8537f58f0 -r 9864b64b1700 src/tag.sml --- a/src/tag.sml Sun Apr 12 12:31:54 2009 -0400 +++ b/src/tag.sml Sun Apr 12 14:19:15 2009 -0400 @@ -46,7 +46,7 @@ EApp ( (EApp ( (EApp ( - (ECApp ( + (EApp ( (ECApp ( (ECApp ( (ECApp ( @@ -54,9 +54,11 @@ (ECApp ( (ECApp ( (ECApp ( - (EFfi ("Basis", "tag"), - loc), given), _), absent), _), outer), _), inner), _), - useOuter), _), useInner), _), bindOuter), _), bindInner), _), + (ECApp ( + (EFfi ("Basis", "tag"), + loc), given), _), absent), _), outer), _), inner), _), + useOuter), _), useInner), _), bindOuter), _), bindInner), _), + class), _), attrs), _), tag), _), xml) => @@ -124,7 +126,7 @@ (EApp ( (EApp ( (EApp ( - (ECApp ( + (EApp ( (ECApp ( (ECApp ( (ECApp ( @@ -132,9 +134,11 @@ (ECApp ( (ECApp ( (ECApp ( - (EFfi ("Basis", "tag"), - loc), given), loc), absent), loc), outer), loc), inner), loc), - useOuter), loc), useInner), loc), bindOuter), loc), bindInner), loc), + (ECApp ( + (EFfi ("Basis", "tag"), + loc), given), loc), absent), loc), outer), loc), inner), loc), + useOuter), loc), useInner), loc), bindOuter), loc), bindInner), loc), + class), loc), (ERecord xets, loc)), loc), tag), loc), xml), s) diff -r acb8537f58f0 -r 9864b64b1700 src/urweb.grm --- a/src/urweb.grm Sun Apr 12 12:31:54 2009 -0400 +++ b/src/urweb.grm Sun Apr 12 14:19:15 2009 -0400 @@ -176,6 +176,8 @@ datatype prop_kind = Delete | Update +datatype attr = Class of exp | Normal of con * exp + %% %header (functor UrwebLrValsFn(structure Token : TOKEN)) @@ -296,8 +298,8 @@ | rpat of (string * pat) list * bool | ptuple of pat list - | attrs of (con * exp) list - | attr of con * exp + | attrs of exp option * (con * exp) list + | attr of attr | attrv of exp | query of exp @@ -1266,13 +1268,18 @@ tag : tagHead attrs (let val pos = s (tagHeadleft, attrsright) + + val e = (EVar (["Basis"], "tag", Infer), pos) + val eo = case #1 attrs of + NONE => (EVar (["Basis"], "None", Infer), pos) + | SOME e => (EApp ((EVar (["Basis"], "Some", Infer), pos), + e), pos) + val e = (EApp (e, eo), pos) + val e = (EApp (e, (ERecord (#2 attrs), pos)), pos) + val e = (EApp (e, (EApp (#2 tagHead, + (ERecord [], pos)), pos)), pos) in - (#1 tagHead, - (EApp ((EApp ((EVar (["Basis"], "tag", Infer), pos), - (ERecord attrs, pos)), pos), - (EApp (#2 tagHead, - (ERecord [], pos)), pos)), - pos)) + (#1 tagHead, e) end) tagHead: BEGIN_TAG (let @@ -1284,22 +1291,36 @@ end) | tagHead LBRACE cexp RBRACE (#1 tagHead, (ECApp (#2 tagHead, cexp), s (tagHeadleft, RBRACEright))) -attrs : ([]) - | attr attrs (attr :: attrs) +attrs : (NONE, []) + | attr attrs (let + val loc = s (attrleft, attrsright) + in + case attr of + Class e => + (case #1 attrs of + NONE => () + | SOME _ => ErrorMsg.errorAt loc "Multiple classes specified for tag"; + (SOME e, #2 attrs)) + | Normal xe => + (#1 attrs, xe :: #2 attrs) + end) -attr : SYMBOL EQ attrv ((CName (capitalize SYMBOL), s (SYMBOLleft, SYMBOLright)), - if (SYMBOL = "href" orelse SYMBOL = "src") - andalso (case #1 attrv of - EPrim _ => true - | _ => false) then - let - val loc = s (attrvleft, attrvright) - in - (EApp ((EVar (["Basis"], "bless", Infer), loc), - attrv), loc) - end +attr : SYMBOL EQ attrv (if SYMBOL = "class" then + Class attrv else - attrv) + Normal ((CName (capitalize SYMBOL), s (SYMBOLleft, SYMBOLright)), + if (SYMBOL = "href" orelse SYMBOL = "src") + andalso (case #1 attrv of + EPrim _ => true + | _ => false) then + let + val loc = s (attrvleft, attrvright) + in + (EApp ((EVar (["Basis"], "bless", Infer), loc), + attrv), loc) + end + else + attrv)) attrv : INT (EPrim (Prim.Int INT), s (INTleft, INTright)) | FLOAT (EPrim (Prim.Float FLOAT), s (FLOATleft, FLOATright)) diff -r acb8537f58f0 -r 9864b64b1700 tests/style.ur --- a/tests/style.ur Sun Apr 12 12:31:54 2009 -0400 +++ b/tests/style.ur Sun Apr 12 14:19:15 2009 -0400 @@ -2,5 +2,5 @@ style r fun main () : transaction page = return - Hi. + Hi. And hi again!