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