@@ -237,12 +237,20 @@ let parse_string loc s =
237237 , Printf. sprintf " Unicode escape sequences are not supported.\n " ))
238238 | Some s -> s
239239
240+ let is_string s = String. length s > 0 && Char. equal s.[0 ] '"'
241+
240242let is_keyword s =
241243 let lexbuf = Sedlexing.Utf8. from_string s in
242244 match % sedlex lexbuf with
243245 | keyword , eof -> true
244246 | _ -> false
245247
248+ let is_id s =
249+ let lexbuf = Sedlexing.Utf8. from_string s in
250+ match % sedlex lexbuf with
251+ | id , eof -> true
252+ | _ -> false
253+
246254(* ***)
247255
248256module StringMap = Map. Make (String )
@@ -370,6 +378,14 @@ let skip st (pos' : pos) =
370378 Buffer. add_string st.buf (String. make (max 0 cols) ' ' );
371379 st.pos < - pos'
372380
381+ let insert st s =
382+ Buffer. add_string st.buf s;
383+ let n = String. length s in
384+ st.pos < -
385+ { loc = { st.pos.loc with pos_cnum = st.pos.loc.pos_cnum + n }
386+ ; byte_loc = st.pos.byte_loc - 1
387+ }
388+
373389let pred_position { loc; byte_loc } =
374390 { loc = { loc with pos_cnum = loc.pos_cnum - 1 }; byte_loc = byte_loc - 1 }
375391
@@ -456,6 +472,50 @@ and rewrite st elt =
456472 ( position_of_loc loc
457473 , Printf. sprintf " Unexpected %s clause. Maybe you forgot a parenthesis.\n " nm
458474 ))
475+ | { desc =
476+ List
477+ [ { desc = Atom " @string" ; _ }
478+ ; { desc = Atom name; loc = loc_name }
479+ ; { desc = Atom value; loc = loc_value }
480+ ]
481+ ; loc = pos, pos'
482+ } ->
483+ if not (is_id name) then raise (Error (position_of_loc loc_name, " Expecting an id" ));
484+ if not (is_string value)
485+ then raise (Error (position_of_loc loc_value, " Expecting a string" ));
486+ let s = parse_string loc_value value in
487+ write st pos;
488+ insert
489+ st
490+ (Format. asprintf
491+ " (global %s (ref eq) (array.new_fixed $string %d%a))"
492+ name
493+ (String. length s)
494+ (fun f s ->
495+ String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
496+ s);
497+ skip st pos'
498+ | { desc = List [ { desc = Atom " @string" ; _ }; { desc = Atom value; loc = loc_value } ]
499+ ; loc = pos, pos'
500+ } ->
501+ if not (is_string value)
502+ then raise (Error (position_of_loc loc_value, " Expecting a string" ));
503+ let s = parse_string loc_value value in
504+ write st pos;
505+ insert
506+ st
507+ (Format. asprintf
508+ " (array.new_fixed $string %d%a)"
509+ (String. length s)
510+ (fun f s ->
511+ String. iter ~f: (fun c -> Format. fprintf f " (i32.const %d)" (Char. code c)) s)
512+ s);
513+ skip st pos'
514+ | { desc = List [ { desc = Atom " @string" ; loc = _, pos } ]; loc = _ , pos' } ->
515+ raise (Error ((pos.loc, pos'.loc), Printf. sprintf " Expecting an id or a string.\n " ))
516+ | { desc = List ({ desc = Atom "@string" ; _ } :: _ :: _ :: { loc; _ } :: _ ); _ } ->
517+ raise
518+ (Error (position_of_loc loc, Printf. sprintf " Expecting a closing parenthesis.\n " ))
459519 | { desc = List l ; _ } -> rewrite_list st l
460520 | _ -> ()
461521
0 commit comments