Skip to content

Commit 3acbc08

Browse files
committed
Do not erase syntax directives.
1 parent 2a39710 commit 3acbc08

File tree

17 files changed

+187
-29
lines changed

17 files changed

+187
-29
lines changed

lib/Ast.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,9 @@ module Class_type_field = struct
718718
end
719719

720720
type toplevel_item =
721-
[`Item of structure_item | `Directive of toplevel_directive]
721+
[ `Item of structure_item
722+
| `Directive of toplevel_directive
723+
| `Lexer of lexer_directive ]
722724

723725
(** Ast terms of various forms. *)
724726
module T = struct
@@ -775,6 +777,8 @@ module T = struct
775777
Format.fprintf fs "Ctf:@\n%a@\n" Printast.class_type_field ctf
776778
| Tli (`Directive d) ->
777779
Format.fprintf fs "Dir:@\n%a" Printast.top_phrase (Ptop_dir d)
780+
| Tli (`Lexer l) ->
781+
Format.fprintf fs "Lex:@\n%a" Printast.top_phrase (Ptop_lex l)
778782
| Jkd jkd ->
779783
Format.fprintf fs "Jkd:@\n%a" (Printast.jkind_annotation 0) jkd
780784
| Top -> Format.pp_print_string fs "Top"
@@ -836,6 +840,7 @@ let location = function
836840
| Ctf x -> x.pctf_loc
837841
| Tli (`Item x) -> x.pstr_loc
838842
| Tli (`Directive x) -> x.pdir_loc
843+
| Tli (`Lexer x) -> x.plex_loc
839844
| Jkd _ -> Location.none
840845
| Top -> Location.none
841846
| Rep -> Location.none

lib/Ast.mli

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ module Tyd : sig
100100
end
101101

102102
type toplevel_item =
103-
[`Item of structure_item | `Directive of toplevel_directive]
103+
[ `Item of structure_item
104+
| `Directive of toplevel_directive
105+
| `Lexer of lexer_directive ]
104106

105107
(** Ast terms of various forms. *)
106108
type t =

lib/Chunk.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ let last_loc (type a) (fg : a list item) (l : a list) =
5757
List.last l
5858
>>= function
5959
| Ptop_def x -> List.last x >>| fun x -> x.pstr_loc
60-
| Ptop_dir x -> Some x.pdir_loc )
60+
| Ptop_dir x -> Some x.pdir_loc
61+
| Ptop_lex x -> Some x.plex_loc )
6162

6263
let mk ~attr_loc ~chunk_loc state items = {attr_loc; chunk_loc; state; items}
6364

lib/Fmt_ast.ml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5428,10 +5428,22 @@ let fmt_toplevel_directive c ~semisemi dir =
54285428
in
54295429
Cmts.fmt c pdir_loc (box_semisemi c ~parent_ctx:Top semisemi (name $ args))
54305430

5431+
let fmt_lexer_directive c ~semisemi l =
5432+
let toggle_to_string = function true -> "on" | false -> "off" in
5433+
let fmt_lexer_arg l =
5434+
match l.plex_desc with
5435+
| Plex_syntax {psyn_mode; psyn_toggle} ->
5436+
str
5437+
(Printf.sprintf "#syntax %s %s" psyn_mode.txt
5438+
(toggle_to_string psyn_toggle) )
5439+
in
5440+
box_semisemi c ~parent_ctx:Top semisemi (fmt_lexer_arg l)
5441+
54315442
let flatten_ptop =
54325443
List.concat_map ~f:(function
54335444
| Ptop_def items -> List.map items ~f:(fun i -> `Item i)
5434-
| Ptop_dir d -> [`Directive d] )
5445+
| Ptop_dir d -> [`Directive d]
5446+
| Ptop_lex l -> [`Lexer l] )
54355447

54365448
let fmt_toplevel ?(force_semisemi = false) c ctx itms =
54375449
let itms = flatten_ptop itms in
@@ -5451,6 +5463,7 @@ let fmt_toplevel ?(force_semisemi = false) c ctx itms =
54515463
match itm with
54525464
| `Item i -> fmt_structure_item c ~last ~semisemi (sub_str ~ctx i)
54535465
| `Directive d -> fmt_toplevel_directive c ~semisemi d
5466+
| `Lexer l -> fmt_lexer_directive c ~semisemi l
54545467
in
54555468
let ast x = Tli x in
54565469
fmt_item_list c ctx update_config ast fmt_item itms

lib/Std_ast.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ let map (type a) (x : a t) (m : Ast_mapper.mapper) : a -> a =
5353
match m.toplevel_phrase m x with
5454
| Ptop_def [] -> None
5555
| Ptop_def _ as x -> Some x
56-
| Ptop_dir _ as x -> Some x )
56+
| Ptop_dir _ as x -> Some x
57+
| Ptop_lex _ as x -> Some x )
5758
| Core_type -> m.typ m
5859
| Module_type -> m.module_type m
5960
| Expression -> m.expr m

test/passing/tests/quotations.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#syntax quotations on
2+
13
let simple_number = <[123]>
24

35
let npower x_quoted n =

test/passing/tests/quotations.ml.js-ref

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#syntax quotations on
2+
13
let simple_number = <[123]>
24

35
let npower x_quoted n =

vendor/parser-extended/ast_mapper.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ type mapper = {
8585
with_constraint: mapper -> with_constraint -> with_constraint;
8686
directive_argument: mapper -> directive_argument -> directive_argument;
8787
toplevel_directive: mapper -> toplevel_directive -> toplevel_directive;
88+
lexer_directive: mapper -> lexer_directive -> lexer_directive;
8889
toplevel_phrase: mapper -> toplevel_phrase -> toplevel_phrase;
8990
repl_phrase: mapper -> repl_phrase -> repl_phrase;
9091
}
@@ -1105,10 +1106,19 @@ let default_mapper =
11051106
; pdir_arg= map_opt (this.directive_argument this) d.pdir_arg
11061107
; pdir_loc= this.location this d.pdir_loc } );
11071108

1109+
lexer_directive =
1110+
(fun this l ->
1111+
match l.plex_desc with
1112+
| Plex_syntax s ->
1113+
{plex_desc= Plex_syntax { psyn_mode = map_loc this s.psyn_mode
1114+
; psyn_toggle = s.psyn_toggle };
1115+
plex_loc= this.location this l.plex_loc });
1116+
11081117
toplevel_phrase =
11091118
(fun this -> function
11101119
| Ptop_def s -> Ptop_def (this.structure this s)
1111-
| Ptop_dir d -> Ptop_dir (this.toplevel_directive this d) );
1120+
| Ptop_dir d -> Ptop_dir (this.toplevel_directive this d)
1121+
| Ptop_lex l -> Ptop_lex (this.lexer_directive this l) );
11121122

11131123
repl_phrase =
11141124
(fun this p ->

vendor/parser-extended/lexer.mll

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -895,12 +895,26 @@ and directive already_consumed = parse
895895
let explanation = "line directives are not supported" in
896896
directive_error lexbuf explanation ~already_consumed ~directive
897897
}
898-
| "syntax" [' ' '\t']+ (lowercase identchar*) [' ' '\t']+
899-
(lowercase identchar*) [^ '\010' '\013']*
900-
{
901-
(* Syntax directives are not preserved by the lexer so we error out. *)
902-
let explanation = "syntax directives are not supported" in
903-
directive_error lexbuf explanation ~already_consumed ~directive:"syntax"
898+
| "syntax" [' ' '\t']+ (lowercase identchar* as mode) [' ' '\t']+
899+
(lowercase identchar* as toggle) [^ '\010' '\013']*
900+
{ let toggle =
901+
match toggle with
902+
| "on" -> true
903+
| "off" -> false
904+
| _ ->
905+
directive_error lexbuf
906+
("syntax directive can only be toggled on or off; "
907+
^ toggle ^ " not recognized")
908+
~already_consumed ~directive:"syntax"
909+
in (
910+
match mode with
911+
| "quotations" ->
912+
Syntax_mode.quotations := toggle;
913+
| _ ->
914+
directive_error lexbuf ("unknown syntax mode " ^ mode)
915+
~already_consumed ~directive:"syntax"
916+
);
917+
HASH_SYNTAX(mode, toggle)
904918
}
905919
(* End Jane Street modification *)
906920

vendor/parser-extended/parser.mly

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,8 @@ let erase_toplevel_phrases phrases =
402402
List.map
403403
(function
404404
| Ptop_def str -> Ptop_def (erase_str_items str)
405-
| Ptop_dir _ as phrase -> phrase)
405+
| Ptop_dir _ as phrase -> phrase
406+
| Ptop_lex lex -> Ptop_lex lex)
406407
phrases
407408

408409
(*
@@ -774,6 +775,16 @@ let package_type_of_module_type pmty =
774775
| _ ->
775776
err pmty.pmty_loc Neither_identifier_nor_with_type
776777

778+
let mk_hashsyntax ~loc mode toggle =
779+
Ptop_lex {
780+
plex_desc =
781+
Plex_syntax {
782+
psyn_mode = mode;
783+
psyn_toggle = toggle;
784+
};
785+
plex_loc = make_loc loc;
786+
}
787+
777788
let mk_directive_arg ~loc k =
778789
{ pdira_desc = k;
779790
pdira_loc = make_loc loc;
@@ -990,6 +1001,7 @@ let erase_call_pos_type ~arg_label ~arg_type ~loc =
9901001
%token LESSLBRACKET "<["
9911002
%token RBRACKETGREATER "]>"
9921003
%token DOLLAR "$"
1004+
%token <string * bool> HASH_SYNTAX "#syntax foo on" (* just an example *)
9931005
(* End Jane Street extension *)
9941006

9951007
/* Precedences and associativities.
@@ -4949,9 +4961,12 @@ any_longident:
49494961
/* Toplevel directives */
49504962
49514963
toplevel_directive:
4952-
hash dir = mkrhs(ident)
4953-
arg = ioption(mk_directive_arg(toplevel_directive_argument))
4954-
{ mk_directive ~loc:$sloc dir arg }
4964+
| HASH_SYNTAX
4965+
{ let mode, toggle = $1 in
4966+
mk_hashsyntax ~loc:$sloc (mkloc mode (make_loc $sloc)) toggle }
4967+
| hash dir = mkrhs(ident)
4968+
arg = ioption(mk_directive_arg(toplevel_directive_argument))
4969+
{ mk_directive ~loc:$sloc dir arg }
49554970
;
49564971
49574972
%inline toplevel_directive_argument:

0 commit comments

Comments
 (0)