I have worked out the feasibility of Haskell's Hamlet style xml.

(https://hackage.haskell.org/package/hamlet)

<ixml>
<body>
  <h3> title
     $if {null item_list_expr}
        <p> Sorry, no items
     $else
        <ul>
           $for {item} <- {item_list_expr}
              <li> <b>{[item]}</b>
</ixml>

Are you interested?


I made it work.

Other logic control statements are harder to work out.

(* ----- *)

Here are some details:

Auto-closing of line-beginning tags is done on the lexer, emitting closing tags for precedent lines with same or deeper indentation.

To emit extra tokens on a specific input the rule can be re-executed by rewinding the next character pointer (yybufpos) to the precedent position:
  yybufpos := (!yybufpos) - size yytext

New lexer states:
  1.IXML state between <ixml></ixml> accepting XML state like inputs.
2.IXML_TAG similar to XMLTAG where to distinguish indented tags to close from empty tags. (pending)
  3.IXML_LOGIC where to look for logic parameters

A new stack variable of indented Tags/Logic.
  Every new indented line will emit closing tokens
  for deeper or equal indented items on the stack
  (variable ixml_indents: (int * ixml_item) list)

Prevent nesting of IXML states, with an isIXML variable.

(pending)

To distinguish indented empty tags,
a tag to close must be pushed at the first only '>' IXML_TAG state input, iif there is no precedent '/'.
  (variable ixml_candidate_tag_to_push: string option)

The STRING state finalisation must take on account an extra state where to return (INITIAL, XMLTAG, IXML_TAG).

-----

Grammar additions:

 * terminals

 | IXML_FOR  | IXML_END_FOR
 | IXML_IFTHEN | IXML_END_IFTHEN | IXML_ELSE | IXML_END_ELSE

 * extra xml production rules:

(* $if $else rule:
*)

   | IXML_IFTHEN LBRACE eexp RBRACE xml IXML_END_IFTHEN
           IXML_ELSE xmlOpt IXML_END_ELSE

        (let
                val loc = s (IXML_IFTHENleft, IXML_END_ELSEright)
        in
        (ECase (eexp, [((PCon (["Basis"], "True", NONE), loc), xml),
((PCon (["Basis"], "False", NONE), loc), xmlOpt)]), loc)

        end)

(* $for rule:

   List.foldr join <xml/> (List.mp (fn item_patt => xml) items_expr)
*)

| IXML_FOR LBRACE eargs RBRACE LARROW LBRACE eexp RBRACE xml IXML_END_FOR
        (let
        val loc = s (IXML_FORleft, IXML_END_FORright)

val fn_item_pattern_to_xml = #1 (eargs (xml, (CWild (KType, loc), loc)))
        val list_map = (EVar (["List"], "mp", Infer), loc)
        val list_foldr = (EVar (["List"], "foldr", Infer), loc)
        val basis_join = (EVar (["Basis"], "join", Infer), loc)
        val xmlEmpty = (EApp ((EVar (["Basis"], "cdata", Infer), loc),
                             (EPrim (Prim.String (Prim.Html, "")), loc))
                        , loc)
        val e = (EApp (list_map, fn_item_pattern_to_xml), loc)
        val e1 = (EApp (e, eexp), loc)

        val e = (EApp (list_foldr, basis_join), loc)
        val e = (EApp (e, xmlEmpty), loc)

        in
                (EApp (e, e1), loc)
        end
        )








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

Reply via email to