El 26/06/15 a les 18:12, Adam Chlipala ha escrit:
I appreciate your ongoing efforts to improve the usability of Ur/Web.
Based on discussion here so far, I'm leaning towards not adopting your
additional syntax extensions.  Subjectively to me, they don't make the
code more readable, while they do introduce more independent notations
to be understood.

I bring here some documentation and a mercurial patch of the trial worked, for the case anyone wanted to try it.

Summary Documentation of the Indented XML, with lines' first tag autoclosing and logic

(* Example with $foldlmapx, $if/$elsif/$else alternatives *)

val testl : list int = 1 :: 2 :: 3 :: 4 :: []

fun main (): transaction page = return <ixml>
<body>
    $foldlmapx {testl} <| {x}
        $if {x = 1}
          <p>1
        $elsif {x = 2}
          <p>2
        $elsif {x = 3}
          <p>3
        $else
          <p>other
</ixml>

(* Example with $foldlmapx, $case/$of alternatives *)

val testOpts : list (option int) = Some 3 :: None :: []

fun main (): transaction page = return <ixml>
<body>
    $foldlmapx {testOpts} <| {x}
      $case {x}
      $of {Some v}
          <p>Some {[v]}
      $of {None}
          <p>None
</ixml>

(* Example derived from the web demo "Sql" with $foldrmapx *)

table t : { A : int, B : float, C : string, D : bool }
  PRIMARY KEY A

type t_qry_item = {T: { A : int, B : float, C : string, D : bool }}

fun main () =
    rows <- queryL (SELECT * FROM t) ;

    return <ixml>
<body>
    <table>
        <tr> <th>A</th> <th>B</th> <th>C</th> <th>D</th>
        $foldrmapx {rows} <| {row : t_qry_item}
             <tr>
                 <td>{[row.T.A]}
                 <td>{[row.T.B]}
                 <td>{[row.T.C]}
                 <td>{[row.T.D]}
</ixml>

(* -------------------------------------------------------------------------------------- *)

Grammar productions added (BNF):

xmlOne: ...
| IXML_FOLDRMAP LBRACE eexp RBRACE FWDAPP LBRACE eargs RBRACE xml IXML_END_FOLDRMAP

| IXML_FOLDLMAP LBRACE eexp RBRACE FWDAPP LBRACE eargs RBRACE xml IXML_END_FOLDLMAP

| IXML_IFTHEN LBRACE eexp RBRACE xml IXML_END_IFTHEN ixml_elsifs IXML_ELSE xmlOpt IXML_END_ELSE

       | IXML_CASE_EXPR LBRACE eexp RBRACE IXML_END_CASE_EXPR ixml_caseOfs

(* --- *)

ixml_elsif : IXML_ELSIF LBRACE eexp RBRACE xml IXML_END_ELSIF

ixml_elsifs : (* empty *)
            | ixml_elsifs ixml_elsif


ixml_caseOf : IXML_CASE_OF LBRACE pat RBRACE xml IXML_END_CASE_OF

ixml_caseOfs : ixml_caseOf
            | ixml_caseOfs ixml_caseOf

(* --- terminals *)

%term
 | IXML_FOLDRMAP  | IXML_END_FOLDRMAP | IXML_FOLDLMAP  | IXML_END_FOLDLMAP
| IXML_IFTHEN | IXML_END_IFTHEN | IXML_ELSE | IXML_END_ELSE | IXML_ELSIF | IXML_END_ELSIF
 | IXML_CASE_EXPR | IXML_END_CASE_EXPR | IXML_CASE_OF | IXML_END_CASE_OF

(* --- non-terminals *)

%nonterm

 | ixml_elsif of (exp * exp)
 | ixml_elsifs of (exp * exp) list
 | ixml_caseOf of pat * exp
 | ixml_caseOfs of (pat * exp) list

(* ----------------------------------------------------------------- *)

Lexer:

new lexer states: IXML IXMLTAG IXML_LOGIC

datatype xmlStringContext = SC_XMLTAG | SC_IXMLTAG

val xmlString = ref (NONE : xmlStringContext option)

val isIXML = ref false
val ixml_candidate_tag_to_push = ref (NONE: (int * string) option)

datatype ixml_logic = IXL_FoldrMap | IXL_FoldlMap
                      | IXL_IfThen | IXL_Else | IXL_Elsif
                      | IXL_CaseExpr | IXL_CaseOf

datatype ixml_item = IX_Tag of string | IX_Logic of ixml_logic

val ixml_indents = ref ([] : (int * ixml_item) list)

val ixml_pop_deeper_or_same_level_items: int -> ixml_item option = fn indent =>
   case !ixml_indents of
     [] => NONE
     | (lastIndent, item) :: _ => if lastIndent >= indent then
(ixml_indents := tl (!ixml_indents) ; SOME item)
                                  else NONE

val ixml_emit_item_closing_and_rewind: (ixml_item * int ref * string * int) -> (svalue,pos) Tokens.token =
   fn (item, yybufpos, yytext, yypos) =>
   ((* rewind yybufpos *) yybufpos := (!yybufpos) - size yytext ;
   case item of
(IX_Tag tag_to_close) => Tokens.END_TAG (tag_to_close, yypos, yypos + size yytext)
        | (IX_Logic ixl) => (case ixl of
IXL_FoldrMap => Tokens.IXML_END_FOLDRMAP (yypos, yypos + size yytext) | IXL_FoldlMap => Tokens.IXML_END_FOLDLMAP (yypos, yypos + size yytext) | IXL_IfThen => Tokens.IXML_END_IFTHEN (yypos, yypos + size yytext) | IXL_Else => Tokens.IXML_END_ELSE (yypos, yypos + size yytext) | IXL_Elsif => Tokens.IXML_END_ELSIF (yypos, yypos + size yytext) | IXL_CaseExpr => Tokens.IXML_END_CASE_EXPR (yypos, yypos + size yytext) | IXL_CaseOf => Tokens.IXML_END_CASE_OF (yypos, yypos + size yytext)
                )
   )

(* ---- definitions *)

%%
indent = \n(\ )*;
spcs = (\ )*;

...

More in the attached patch.





_______________________________________________
Ur mailing list
[email protected]
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur

Reply via email to