From 53c633b53e8825cb9058fb88e86d1ca7828b83e6 Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Thu, 27 Dec 2012 15:34:11 -0500 Subject: Add some name-mangling rules to allow XML attribute 'name' and attributes with dashes --- lib/ur/list.ur | 12 ++++++++++++ lib/ur/list.urs | 3 +++ src/monoize.sml | 5 +++++ src/urweb.grm | 11 +++++++---- src/urweb.lex | 3 ++- tests/attrMangle.ur | 5 +++++ tests/attrMangle.urp | 4 ++++ tests/goofy.urs | 1 + 8 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tests/attrMangle.ur create mode 100644 tests/attrMangle.urp create mode 100644 tests/goofy.urs diff --git a/lib/ur/list.ur b/lib/ur/list.ur index bce5335e..cbb4faf2 100644 --- a/lib/ur/list.ur +++ b/lib/ur/list.ur @@ -437,3 +437,15 @@ fun mapXiM [m ::: Type -> Type] (_ : monad m) [a] [ctx ::: {Unit}] (f : int -> a in mapXiM' 0 end + +fun tabulateM [m] (_ : monad m) [a] (f : int -> m a) n = + let + fun tabulate' n acc = + if n <= 0 then + return acc + else + (v <- f (n-1); + tabulate' (n-1) (v :: acc)) + in + tabulate' n [] + end diff --git a/lib/ur/list.urs b/lib/ur/list.urs index b26c9ad9..66007a39 100644 --- a/lib/ur/list.urs +++ b/lib/ur/list.urs @@ -63,6 +63,9 @@ val all : a ::: Type -> (a -> bool) -> t a -> bool val app : m ::: (Type -> Type) -> monad m -> a ::: Type -> (a -> m unit) -> t a -> m unit +val tabulateM : m ::: (Type -> Type) -> monad m -> a ::: Type + -> (int -> m a) -> int -> m (t a) + val mapQuery : tables ::: {{Type}} -> exps ::: {Type} -> t ::: Type -> [tables ~ exps] => sql_query [] [] tables exps diff --git a/src/monoize.sml b/src/monoize.sml index 39e4853b..d324b235 100644 --- a/src/monoize.sml +++ b/src/monoize.sml @@ -3364,8 +3364,13 @@ fun monoExp (env, st, fm) (all as (e, loc)) = val x = case x of "Typ" => "Type" + | "Nam" => "Name" | "Link" => "Href" | _ => x + + val x = String.translate (fn #"_" => "-" + | ch => String.str ch) x + val xp = " " ^ lowercaseFirst x ^ "=\"" val (e, fm) = fooify env fm (e, t) diff --git a/src/urweb.grm b/src/urweb.grm index a45c7ffa..c2a48742 100644 --- a/src/urweb.grm +++ b/src/urweb.grm @@ -35,6 +35,12 @@ val dummy = ErrorMsg.dummySpan fun capitalize "" = "" | capitalize s = str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE) +fun makeAttr s = + case s of + "type" => "Typ" + | "name" => "Nam" + | _ => capitalize (String.translate (fn ch => if ch = #"-" then "_" else str ch) s) + fun entable t = case #1 t of TRecord c => c @@ -1648,10 +1654,7 @@ attr : SYMBOL EQ attrv (case SYMBOL of | "dynStyle" => DynStyle attrv | _ => let - val sym = - case SYMBOL of - "type" => "Typ" - | x => capitalize x + val sym = makeAttr SYMBOL in Normal ((CName sym, s (SYMBOLleft, SYMBOLright)), if (sym = "Href" orelse sym = "Src") diff --git a/src/urweb.lex b/src/urweb.lex index 0994ecec..293c6dc6 100644 --- a/src/urweb.lex +++ b/src/urweb.lex @@ -177,6 +177,7 @@ fun unescape loc s = %s COMMENT STRING CHAR XML XMLTAG; id = [a-z_][A-Za-z0-9_']*; +xmlid = [A-Za-z][A-Za-z0-9-_]*; cid = [A-Z][A-Za-z0-9_]*; ws = [\ \t\012\r]; intconst = [0-9]+; @@ -313,7 +314,7 @@ xint = x[0-9a-fA-F][0-9a-fA-F]; {ws}+ => (lex ()); - {id} => (Tokens.SYMBOL (yytext, yypos, yypos + size yytext)); + {xmlid} => (Tokens.SYMBOL (yytext, yypos, yypos + size yytext)); "=" => (Tokens.EQ (yypos, yypos + size yytext)); {intconst} => (case Int64.fromString yytext of diff --git a/tests/attrMangle.ur b/tests/attrMangle.ur new file mode 100644 index 00000000..6efb0513 --- /dev/null +++ b/tests/attrMangle.ur @@ -0,0 +1,5 @@ +open Goofy + +fun main () : transaction page = return + + diff --git a/tests/attrMangle.urp b/tests/attrMangle.urp new file mode 100644 index 00000000..5059998b --- /dev/null +++ b/tests/attrMangle.urp @@ -0,0 +1,4 @@ +ffi goofy +rewrite all AttrMangle/* + +attrMangle diff --git a/tests/goofy.urs b/tests/goofy.urs new file mode 100644 index 00000000..71b55f42 --- /dev/null +++ b/tests/goofy.urs @@ -0,0 +1 @@ +val goofy : bodyTag [Nam = string, Data_role = string] -- cgit v1.2.3