Skip to content

Commit afed94e

Browse files
committed
Parsing new mode syntax
1 parent 9693d69 commit afed94e

File tree

8 files changed

+100212
-36326
lines changed

8 files changed

+100212
-36326
lines changed

ocaml/boot/menhir/parser.ml

Lines changed: 99941 additions & 36288 deletions
Large diffs are not rendered by default.

ocaml/boot/menhir/parser.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ type token =
129129
| BAR
130130
| BANG
131131
| BACKQUOTE
132+
| AT
132133
| ASSERT
133134
| AS
134135
| ANDOP of (string)

ocaml/parsing/jane_syntax.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,10 @@ module Mode_expr = struct
406406

407407
let singleton mode loc = Location.mkloc [Location.mkloc mode loc] loc
408408

409+
let concat mode0 mode1 =
410+
let txt = mode0.txt @ mode1.txt in
411+
Location.mknoloc txt
412+
409413
let is_empty { txt; _ } = match txt with [] -> true | _ -> false
410414

411415
let embedded_name = Embedded_name.of_feature (Language_extension Mode) []

ocaml/parsing/jane_syntax.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ module Mode_expr : sig
124124

125125
val singleton : string -> Location.t -> t
126126

127+
val concat : t -> t -> t
128+
127129
val embedded_name_str : string
128130

129131
val is_empty : t -> bool

ocaml/parsing/lexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ rule token = parse
752752
{ PREFIXOP op }
753753
| ['=' '<' '>' '|' '&' '$'] symbolchar * as op
754754
{ INFIXOP0 op }
755+
| "@" { AT }
755756
| ['@' '^'] symbolchar * as op
756757
{ INFIXOP1 op }
757758
| ['+' '-'] symbolchar * as op

ocaml/parsing/parser.mly

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,8 @@ let unboxed_type sloc lident tys =
986986
%token IN "in"
987987
%token INCLUDE "include"
988988
%token <string> INFIXOP0 "!=" (* just an example *)
989-
%token <string> INFIXOP1 "@" (* just an example *)
989+
%token AT "@"
990+
%token <string> INFIXOP1 "^" (* just an example *)
990991
%token <string> INFIXOP2 "+!" (* chosen with care; see above *)
991992
%token <string> INFIXOP3 "land" (* just an example *)
992993
%token <string> INFIXOP4 "**" (* just an example *)
@@ -1123,6 +1124,7 @@ The precedences must be listed from low to high.
11231124
%right AMPERSAND AMPERAMPER /* expr (e && e && e) */
11241125
%nonassoc below_EQUAL
11251126
%left INFIXOP0 EQUAL LESS GREATER /* expr (e OP e OP e) */
1127+
%right AT
11261128
%right INFIXOP1 /* expr (e OP e OP e) */
11271129
%nonassoc below_LBRACKETAT
11281130
%nonassoc LBRACKETAT
@@ -2588,31 +2590,39 @@ seq_expr:
25882590
| or_function(fun_seq_expr) { $1 }
25892591
;
25902592
labeled_simple_pattern:
2591-
QUESTION LPAREN mode_expr_legacy label_let_pattern opt_default RPAREN
2592-
{ (Optional (fst $4), $5, mkpat_with_modes $3 (snd $4) ) }
2593+
QUESTION LPAREN mode_expr_legacy label_let_pattern mode_expr opt_default RPAREN
2594+
{ (Optional (fst $4), $6,
2595+
mkpat_with_modes (Mode.concat $3 $5) (snd $4) ) }
25932596
| QUESTION label_var
25942597
{ (Optional (fst $2), None, snd $2) }
2595-
| OPTLABEL LPAREN mode_expr_legacy let_pattern opt_default RPAREN
2596-
{ (Optional $1, $5, mkpat_with_modes $3 $4) }
2598+
| OPTLABEL LPAREN mode_expr_legacy let_pattern mode_expr opt_default RPAREN
2599+
{ (Optional $1, $6,
2600+
mkpat_with_modes (Mode.concat $3 $5) $4) }
25972601
| OPTLABEL pattern_var
25982602
{ (Optional $1, None, $2) }
2599-
| TILDE LPAREN mode_expr_legacy label_let_pattern RPAREN
2603+
| TILDE LPAREN mode_expr_legacy label_let_pattern mode_expr RPAREN
26002604
{ (Labelled (fst $4), None,
2601-
mkpat_with_modes $3 (snd $4) ) }
2605+
mkpat_with_modes (Mode.concat $3 $5) (snd $4) ) }
26022606
| TILDE label_var
26032607
{ (Labelled (fst $2), None, snd $2) }
26042608
| LABEL simple_pattern
26052609
{ (Labelled $1, None, $2) }
2606-
| LABEL LPAREN mode_expr_legacy_nonempty pattern RPAREN
2607-
{ (Labelled $1, None, mkpat_with_modes $3 $4 ) }
2610+
| LABEL LPAREN mode_expr_legacy_nonempty pattern mode_expr RPAREN
2611+
{ (Labelled $1, None, mkpat_with_modes (Mode.concat $3 $5) $4 ) }
2612+
| LABEL LPAREN pattern mode_expr_nonempty RPAREN
2613+
{ (Labelled $1, None, mkpat_with_modes $4 $3 ) }
26082614
| simple_pattern
26092615
{ (Nolabel, None, $1) }
2610-
| LPAREN mode_expr_legacy_nonempty let_pattern RPAREN
2611-
{ (Nolabel, None, mkpat_with_modes $2 $3 ) }
2616+
| LPAREN mode_expr_legacy_nonempty let_pattern mode_expr RPAREN
2617+
{ (Nolabel, None, mkpat_with_modes (Mode.concat $2 $4) $3 ) }
2618+
| LPAREN let_pattern mode_expr_nonempty RPAREN
2619+
{ (Nolabel, None, mkpat_with_modes $3 $2 ) }
26122620
| LABEL LPAREN poly_pattern RPAREN
26132621
{ (Labelled $1, None, $3) }
2614-
| LABEL LPAREN mode_expr_legacy_nonempty poly_pattern RPAREN
2615-
{ (Labelled $1, None, mkpat_with_modes $3 $4) }
2622+
| LABEL LPAREN mode_expr_legacy_nonempty poly_pattern mode_expr RPAREN
2623+
{ (Labelled $1, None, mkpat_with_modes (Mode.concat $3 $5) $4) }
2624+
| LABEL LPAREN poly_pattern mode_expr_nonempty RPAREN
2625+
{ (Labelled $1, None, mkpat_with_modes $4 $3) }
26162626
| LPAREN poly_pattern RPAREN
26172627
{ (Nolabel, None, $2) }
26182628
;
@@ -2737,6 +2747,8 @@ fun_expr:
27372747
| mode_legacy seq_expr
27382748
{ let {txt; loc} = $1 in
27392749
mkexp_with_modes $sloc (Mode.singleton txt loc) $2 }
2750+
| mode_expr_nonempty seq_expr
2751+
{ mkexp_with_modes $sloc $1 $2}
27402752
| EXCLAVE seq_expr
27412753
{ mkexp_exclave ~loc:$sloc ~kwd_loc:($loc($1)) $2 }
27422754
;
@@ -3048,27 +3060,29 @@ labeled_simple_expr:
30483060
let_binding_body_no_punning:
30493061
let_ident strict_binding
30503062
{ ($1, $2, None, []) }
3051-
| mode_expr_legacy let_ident type_constraint EQUAL seq_expr
3063+
| mode_expr_legacy let_ident mode_expr type_constraint EQUAL seq_expr
30523064
{ let v = $2 in (* PR#7344 *)
30533065
let t =
3054-
match $3 with
3066+
match $4 with
30553067
| N_ary.Pconstraint t ->
30563068
Pvc_constraint { locally_abstract_univars = []; typ=t }
30573069
| N_ary.Pcoerce (ground, coercion) -> Pvc_coercion { ground; coercion}
30583070
in
3059-
let exp = mkexp_with_modes $sloc $1 $5 in
3060-
(v, exp, Some t, let_binding_mode_attrs $1)
3071+
let modes = Mode.concat $1 $3 in
3072+
let exp = mkexp_with_modes $sloc modes $6 in
3073+
(v, exp, Some t, let_binding_mode_attrs modes)
30613074
}
3062-
| mode_expr_legacy let_ident COLON poly(core_type) EQUAL seq_expr
3063-
{ let bound_vars, inner_type = $4 in
3075+
| mode_expr_legacy let_ident mode_expr COLON poly(core_type) EQUAL seq_expr
3076+
{ let bound_vars, inner_type = $5 in
30643077
let ltyp = Jane_syntax.Layouts.Ltyp_poly { bound_vars; inner_type } in
3065-
let typ_loc = Location.ghostify (make_loc $loc($4)) in
3078+
let typ_loc = Location.ghostify (make_loc $loc($5)) in
30663079
let typ =
30673080
Jane_syntax.Layouts.type_of ~loc:typ_loc ltyp
30683081
in
3069-
let exp = mkexp_with_modes $sloc $1 $6 in
3082+
let modes = Mode.concat $1 $3 in
3083+
let exp = mkexp_with_modes $sloc modes $7 in
30703084
($2, exp, Some (Pvc_constraint { locally_abstract_univars = []; typ }),
3071-
let_binding_mode_attrs $1)
3085+
let_binding_mode_attrs modes)
30723086
}
30733087
| let_ident COLON TYPE newtypes DOT core_type EQUAL seq_expr
30743088
(* The code upstream looks like:
@@ -3097,9 +3111,13 @@ let_binding_body_no_punning:
30973111
{ ($1, $3, None, []) }
30983112
| simple_pattern_not_ident COLON core_type EQUAL seq_expr
30993113
{ ($1, $5, Some(Pvc_constraint { locally_abstract_univars=[]; typ=$3 }), []) }
3100-
| mode_expr_legacy_nonempty let_ident strict_binding_modes
3101-
{ ($2, mkexp_with_modes $sloc $1 ($3 $1), None,
3102-
let_binding_mode_attrs $1) }
3114+
| mode_expr_legacy_nonempty let_ident mode_expr strict_binding_modes
3115+
{ let modes = Mode.concat $1 $3 in
3116+
($2, mkexp_with_modes $sloc modes ($4 modes), None,
3117+
let_binding_mode_attrs modes) }
3118+
| let_ident mode_expr_nonempty strict_binding_modes
3119+
{ ($1, mkexp_with_modes $sloc $2 ($3 $2), None,
3120+
let_binding_mode_attrs $2) }
31033121
;
31043122
let_binding_body:
31053123
| let_binding_body_no_punning
@@ -3945,7 +3963,8 @@ generalized_constructor_arguments:
39453963
;
39463964

39473965
%inline atomic_type_gbl:
3948-
gbl = global_flag cty = atomic_type {
3966+
gbl = global_flag cty = atomic_type gbl_ = mode_expr {
3967+
let gbl = Mode.concat gbl gbl_ in
39493968
mkcty_modality gbl cty
39503969
}
39513970
;
@@ -3963,23 +3982,25 @@ label_declarations:
39633982
| label_declaration_semi label_declarations { $1 :: $2 }
39643983
;
39653984
label_declaration:
3966-
mutable_or_global_flag mkrhs(label) COLON poly_type_no_attr attributes
3985+
mutable_or_global_flag mkrhs(label) gbl_=mode_expr COLON poly_type_no_attr attributes
39673986
{ let info = symbol_info $endpos in
39683987
let mut, gbl = $1 in
3988+
let gbl = Mode.concat gbl gbl_ in
39693989
mkld_modality gbl
3970-
(Type.field $2 $4 ~mut ~attrs:$5 ~loc:(make_loc $sloc) ~info)}
3990+
(Type.field $2 $5 ~mut ~attrs:$6 ~loc:(make_loc $sloc) ~info)}
39713991
;
39723992
label_declaration_semi:
3973-
mutable_or_global_flag mkrhs(label) COLON poly_type_no_attr attributes
3993+
mutable_or_global_flag mkrhs(label) gbl_=mode_expr COLON poly_type_no_attr attributes
39743994
SEMI attributes
39753995
{ let info =
39763996
match rhs_info $endpos($5) with
39773997
| Some _ as info_before_semi -> info_before_semi
39783998
| None -> symbol_info $endpos
39793999
in
39804000
let mut, gbl = $1 in
4001+
let gbl = Mode.concat gbl gbl_ in
39814002
mkld_modality gbl
3982-
(Type.field $2 $4 ~mut ~attrs:($5 @ $7) ~loc:(make_loc $sloc) ~info)}
4003+
(Type.field $2 $5 ~mut ~attrs:($6 @ $8) ~loc:(make_loc $sloc) ~info)}
39834004
;
39844005

39854006
/* Type Extensions */
@@ -4168,20 +4189,26 @@ strict_function_or_labeled_tuple_type:
41684189
label = arg_label
41694190
arg_modes = mode_expr_legacy
41704191
domain = extra_rhs(param_type)
4192+
arg_modes_ = mode_expr
41714193
MINUSGREATER
41724194
codomain = strict_function_or_labeled_tuple_type
4173-
{ Ptyp_arrow(label, mktyp_with_modes arg_modes domain , codomain) }
4195+
{ let arg_modes = Mode.concat arg_modes arg_modes_ in
4196+
Ptyp_arrow(label, mktyp_with_modes arg_modes domain , codomain) }
41744197
)
41754198
{ $1 }
41764199
| mktyp(
41774200
label = arg_label
41784201
arg_modes = mode_expr_legacy
41794202
domain = extra_rhs(param_type)
4203+
arg_modes_ = mode_expr
41804204
MINUSGREATER
41814205
ret_modes = mode_expr_legacy
41824206
codomain = tuple_type
4207+
ret_modes_ = mode_expr
41834208
%prec MINUSGREATER
4184-
{ Ptyp_arrow(label,
4209+
{ let arg_modes = Mode.concat arg_modes arg_modes_ in
4210+
let ret_modes = Mode.concat ret_modes ret_modes_ in
4211+
Ptyp_arrow(label,
41854212
mktyp_with_modes arg_modes domain ,
41864213
mktyp_with_modes ret_modes (maybe_curry_typ codomain $loc(codomain))) }
41874214
)
@@ -4202,9 +4229,11 @@ strict_function_or_labeled_tuple_type:
42024229
label = LIDENT COLON
42034230
arg_modes = mode_expr_legacy
42044231
tuple = proper_tuple_type
4232+
arg_modes_ = mode_expr
42054233
MINUSGREATER
42064234
codomain = strict_function_or_labeled_tuple_type
42074235
{
4236+
let arg_modes = Mode.concat arg_modes arg_modes_ in
42084237
let ty, ltys = tuple in
42094238
let label = Labelled label in
42104239
let domain = ptyp_ltuple $loc(tuple) ((None, ty) :: ltys) in
@@ -4216,10 +4245,15 @@ strict_function_or_labeled_tuple_type:
42164245
label = LIDENT COLON
42174246
arg_modes = mode_expr_legacy
42184247
tuple = proper_tuple_type
4248+
arg_modes_ = mode_expr
42194249
MINUSGREATER
42204250
ret_modes = mode_expr_legacy
42214251
codomain = tuple_type
4222-
{ let ty, ltys = tuple in
4252+
ret_modes_ = mode_expr
4253+
%prec MINUSGREATER
4254+
{ let arg_modes = Mode.concat arg_modes arg_modes_ in
4255+
let ret_modes = Mode.concat ret_modes ret_modes_ in
4256+
let ty, ltys = tuple in
42234257
let label = Labelled label in
42244258
let domain = ptyp_ltuple $loc(tuple) ((None, ty) :: ltys) in
42254259
let domain = extra_rhs_core_type domain ~pos:$endpos(tuple) in
@@ -4248,6 +4282,7 @@ strict_function_or_labeled_tuple_type:
42484282
| /* empty */
42494283
{ Nolabel }
42504284
;
4285+
/* Legacy mode annotations */
42514286
%inline mode_legacy:
42524287
| LOCAL
42534288
{ mkloc "local" (make_loc $sloc) }
@@ -4264,6 +4299,18 @@ strict_function_or_labeled_tuple_type:
42644299
%inline mode_expr_legacy:
42654300
| { Mode.empty }
42664301
| mode_expr_legacy_nonempty {$1}
4302+
4303+
/* Mode expression followed by an "@" symbol and thus enjoying a whole namespace */
4304+
%inline mode_expr_nonempty:
4305+
| AT mkloc(LIDENT)
4306+
{let modes = [$2] in
4307+
mkloc modes (make_loc $loc($2))}
4308+
| AT LPAREN modes=mkloc(LIDENT)+ RPAREN
4309+
{ mkloc modes (make_loc $loc(modes))}
4310+
;
4311+
%inline mode_expr:
4312+
{ Mode.empty }
4313+
| mode_expr_nonempty {$1}
42674314
;
42684315
%inline param_type:
42694316
| mktyp_jane_syntax_ltyp(
@@ -4529,6 +4576,7 @@ operator:
45294576
;
45304577
%inline infix_operator:
45314578
| op = INFIXOP0 { op }
4579+
| AT {"@"}
45324580
| op = INFIXOP1 { op }
45334581
| op = INFIXOP2 { op }
45344582
| op = INFIXOP3 { op }

0 commit comments

Comments
 (0)