pa_dollars.ml

   1: let expr_list loc l =
   2:   List.fold_right 
   3:     (fun head tail -> <:expr< [ $head$ :: $tail$ ] >>)
   4:     l
   5:     <:expr< [] >>
   6: 
   7: RE lident = [lower '_'][alnum '_']*
   8: 
   9: let subst_string loc s =
  10:   (* we find the identifiers written as $id or ${id} using a micmatch macro *)
  11:   let map =
  12:     MAP "$" ( ("$" as x)
  13:             | (lident as x)
  14:             | "{" space* (lident as x) space* "}") ->
  15:       if x = "$" then `Text x
  16:       else `Ident x in
  17:   let pieces = map ~full:false s in
  18:   let rec compact = function
  19:       `Ident _ as head :: tail -> head :: compact tail
  20:     | `Text "" :: tail -> compact tail
  21:     | `Text a :: `Text b :: tail -> compact (`Text (a ^ b) :: tail)
  22:     | head :: tail -> head :: compact tail
  23:     | [] -> [] in
  24:   let make_expr = function
  25:       `Ident s -> <:expr< $lid:s$ >>
  26:     | `Text s -> <:expr< $str: String.escaped s$ >> in
  27:   match compact pieces with
  28:       [] -> <:expr< "" >>
  29:     | [a] -> make_expr a
  30:     | [a; b] -> <:expr< $make_expr a$ ^ $make_expr b$ >>
  31:     | l -> 
  32:         <:expr< String.concat "" $expr_list loc (List.map make_expr l)$ >>
  33: 
  34: let _ = 
  35:   (* the try-with around DELETE_RULE is important if other versions of Camlp5
  36:      do not have the same exact rule in the same entry *)
  37:   (try DELETE_RULE Pcaml.expr: STRING END with Not_found -> ());
  38: 
  39:   EXTEND
  40:     Pcaml.expr: LEVEL "simple" [
  41:       [ s = STRING -> subst_string loc (Token.eval_string loc s) ]
  42:     ];
  43:   END

This document was generated using caml2html