Skip to content

Commit 923625d

Browse files
authored
feat(compiler)!: Changed comma to and in recursive types and bindings (#1827)
feat(compiler)!: Changed comma to `and` in mutually rec types
1 parent e10d612 commit 923625d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+336
-295
lines changed

compiler/src/formatting/format.re

Lines changed: 129 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4198,119 +4198,145 @@ and print_value_bind =
41984198
| Mutable => Doc.text("mut ")
41994199
};
42004200

4201-
let formatted_items =
4201+
let value_bindings =
42024202
switch (vbs) {
4203-
| [] => []
4203+
| [] => Doc.nil
42044204
| [first, ...rem] =>
4205-
let get_loc = (vb: Parsetree.value_binding) => vb.pvb_loc;
4206-
let print_item = (~comments, vb: Parsetree.value_binding) => {
4207-
let after_let_comments =
4208-
Comment_utils.get_comments_enclosed_and_before_location(
4209-
~loc1=get_loc(vb),
4210-
~loc2=vb.pvb_pat.ppat_loc,
4211-
comments,
4212-
);
4205+
let leading_comments =
4206+
Comment_utils.get_comments_before_location(
4207+
~location=first.pvb_loc,
4208+
comments,
4209+
);
4210+
let leading_comments_docs =
4211+
switch (leading_comments) {
4212+
| [] => Doc.nil
4213+
| _ =>
4214+
Doc.group(
4215+
Doc.concat([
4216+
Comment_utils.new_comments_to_docs(leading_comments),
4217+
Doc.ifBreaks(Doc.nil, Doc.space),
4218+
]),
4219+
)
4220+
};
42134221

4214-
let after_let_comments_docs =
4215-
switch (after_let_comments) {
4216-
| [] => Doc.nil
4217-
| _ =>
4218-
Comment_utils.inbetween_comments_to_docs(
4219-
~offset=false,
4220-
after_let_comments,
4221-
)
4222-
};
4222+
let previous_bind: ref(option(Parsetree.value_binding)) = ref(None);
4223+
let docs =
4224+
Doc.join(
4225+
~sep=Doc.concat([Doc.hardLine]),
4226+
List.mapi(
4227+
(i, vb: Parsetree.value_binding) => {
4228+
let leading_comments =
4229+
switch (previous_bind^) {
4230+
| None => []
4231+
| Some(prev) =>
4232+
Comment_utils.get_comments_between_locations(
4233+
~loc1=prev.pvb_loc,
4234+
~loc2=vb.pvb_loc,
4235+
comments,
4236+
)
4237+
};
42234238

4224-
let expr_comments =
4225-
Comment_utils.get_comments_inside_location(
4226-
~location=vb.pvb_expr.pexp_loc,
4227-
comments,
4228-
);
4229-
let printed =
4230-
print_expression(
4231-
~expression_parent=GenericExpression,
4232-
~original_source,
4233-
~comments=expr_comments,
4234-
vb.pvb_expr,
4235-
);
4239+
let leading_comment_docs =
4240+
switch (leading_comments) {
4241+
| [] => Doc.nil
4242+
| _ =>
4243+
Doc.group(
4244+
Doc.concat([
4245+
Comment_utils.new_comments_to_docs(leading_comments),
4246+
Doc.ifBreaks(Doc.nil, Doc.space),
4247+
]),
4248+
)
4249+
};
42364250

4237-
let expression =
4238-
switch (vb.pvb_expr.pexp_desc) {
4239-
| PExpIf(_) =>
4240-
if (Doc.willBreak(printed)) {
4241-
Doc.concat([Doc.space, printed]);
4242-
} else {
4243-
Doc.indent(Doc.concat([Doc.line, printed]));
4244-
}
4245-
| _ => Doc.concat([Doc.space, printed])
4246-
};
4251+
let after_let_comments =
4252+
Comment_utils.get_comments_enclosed_and_before_location(
4253+
~loc1=vb.pvb_loc,
4254+
~loc2=vb.pvb_pat.ppat_loc,
4255+
comments,
4256+
);
42474257

4248-
let pattern_comments =
4249-
Comment_utils.get_comments_enclosed_and_before_location(
4250-
~loc1=vb.pvb_loc,
4251-
~loc2=vb.pvb_expr.pexp_loc,
4252-
comments,
4253-
);
4258+
let after_let_comments_docs =
4259+
switch (after_let_comments) {
4260+
| [] => Doc.nil
4261+
| _ =>
4262+
Comment_utils.inbetween_comments_to_docs(
4263+
~offset=false,
4264+
after_let_comments,
4265+
)
4266+
};
42544267

4255-
Doc.concat([
4256-
Doc.group(
4257-
print_pattern(
4258-
~original_source,
4259-
~comments=pattern_comments,
4260-
~next_loc=vb.pvb_loc,
4261-
vb.pvb_pat,
4262-
),
4268+
let expr_comments =
4269+
Comment_utils.get_comments_inside_location(
4270+
~location=vb.pvb_expr.pexp_loc,
4271+
comments,
4272+
);
4273+
let printed =
4274+
print_expression(
4275+
~expression_parent=GenericExpression,
4276+
~original_source,
4277+
~comments=expr_comments,
4278+
vb.pvb_expr,
4279+
);
4280+
4281+
let expression =
4282+
switch (vb.pvb_expr.pexp_desc) {
4283+
| PExpIf(_) =>
4284+
if (Doc.willBreak(printed)) {
4285+
Doc.concat([Doc.space, printed]);
4286+
} else {
4287+
Doc.indent(Doc.concat([Doc.line, printed]));
4288+
}
4289+
| _ => Doc.concat([Doc.space, printed])
4290+
};
4291+
4292+
let pattern_comments =
4293+
Comment_utils.get_comments_enclosed_and_before_location(
4294+
~loc1=vb.pvb_loc,
4295+
~loc2=vb.pvb_expr.pexp_loc,
4296+
comments,
4297+
);
4298+
4299+
previous_bind := Some(vb);
4300+
4301+
Doc.concat([
4302+
leading_comment_docs,
4303+
if (i != 0) {
4304+
Doc.text("and ");
4305+
} else {
4306+
Doc.nil;
4307+
},
4308+
Doc.group(
4309+
print_pattern(
4310+
~original_source,
4311+
~comments=pattern_comments,
4312+
~next_loc=vb.pvb_loc,
4313+
vb.pvb_pat,
4314+
),
4315+
),
4316+
after_let_comments_docs,
4317+
switch (after_let_comments) {
4318+
| [] => Doc.space
4319+
| _ => Doc.nil
4320+
},
4321+
Doc.equal,
4322+
expression,
4323+
]);
4324+
},
4325+
vbs,
42634326
),
4264-
after_let_comments_docs,
4265-
switch (after_let_comments) {
4266-
| [] => Doc.space
4267-
| _ => Doc.nil
4268-
},
4269-
Doc.equal,
4270-
expression,
4271-
]);
4272-
};
4327+
);
42734328

4274-
item_iterator(
4275-
~get_loc,
4276-
~print_item,
4277-
~comments,
4278-
~iterated_item=IteratedValueBindings,
4279-
vbs,
4280-
);
4329+
Doc.concat([leading_comments_docs, docs]);
42814330
};
42824331

4283-
let value_bindings =
4284-
List.mapi(
4285-
(index, doc) => {
4286-
let item =
4287-
if (index > 0) {
4288-
Doc.concat([Doc.line, doc]);
4289-
} else {
4290-
doc;
4291-
};
4292-
let vb = List.nth(vbs, index);
4293-
switch (vb.pvb_expr.pexp_desc) {
4294-
| PExpLambda(fn, _) => item
4295-
| _ =>
4296-
if (index > 0) {
4297-
Doc.indent(item);
4298-
} else {
4299-
item;
4300-
}
4301-
};
4302-
},
4303-
formatted_items,
4304-
);
4305-
43064332
Doc.group(
43074333
Doc.concat([
43084334
exported,
43094335
Doc.text("let"),
43104336
Doc.space,
43114337
recursive,
43124338
mutble,
4313-
Doc.concat(value_bindings),
4339+
value_bindings,
43144340
]),
43154341
);
43164342
};
@@ -4768,9 +4794,9 @@ let data_print =
47684794
) => {
47694795
let previous_data: ref(option(Parsetree.data_declaration)) = ref(None);
47704796
Doc.join(
4771-
~sep=Doc.concat([Doc.comma, Doc.hardLine]),
4772-
List.map(
4773-
data => {
4797+
~sep=Doc.concat([Doc.hardLine]),
4798+
List.mapi(
4799+
(i, data) => {
47744800
let (expt, decl: Parsetree.data_declaration) = data;
47754801

47764802
let leading_comments =
@@ -4797,6 +4823,11 @@ let data_print =
47974823

47984824
Doc.concat([
47994825
leading_comment_docs,
4826+
if (i != 0) {
4827+
Doc.text("and ");
4828+
} else {
4829+
Doc.nil;
4830+
},
48004831
switch ((expt: Asttypes.provide_flag)) {
48014832
| NotProvided => Doc.nil
48024833
| Provided => Doc.text("provide ")

compiler/src/parsing/lexer.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ let rec token = lexbuf => {
337337
| "," => positioned(COMMA)
338338
| ";" => positioned(SEMI)
339339
| "as" => positioned(AS)
340+
| "and" => positioned(AND)
340341
| "(" => positioned(LPAREN)
341342
| ")" => positioned(RPAREN)
342343
| "{" => positioned(LBRACE)

compiler/src/parsing/parser.messages

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -790,34 +790,26 @@ program: MODULE UIDENT EOL ENUM UIDENT LBRACE UIDENT LPAREN WHILE
790790

791791
Expected one or more types to complete the variant definition.
792792

793-
program: MODULE UIDENT EOL ENUM UIDENT LBRACE UIDENT RBRACE COMMA EOL WHILE
793+
program: MODULE UIDENT EOL TYPE UIDENT EQUAL UIDENT AND YIELD
794794
##
795-
## Ends in an error in state: 986.
795+
## Ends in an error in state: 860.
796796
##
797-
## separated_nonempty_list(comma,data_declaration_stmt) -> data_declaration_stmt comma . separated_nonempty_list(comma,data_declaration_stmt) [ SEMI EOL EOF ]
797+
## separated_nonempty_list(AND,data_declaration_stmt) -> data_declaration_stmt AND . separated_nonempty_list(AND,data_declaration_stmt) [ SEMI RBRACE EOL EOF ]
798798
##
799799
## The known suffix of the stack is as follows:
800-
## data_declaration_stmt comma
800+
## data_declaration_stmt AND
801801
##
802-
## WARNING: This example involves spurious reductions.
803-
## This implies that, although the LR(1) items shown above provide an
804-
## accurate view of the past (what has been recognized so far), they
805-
## may provide an INCOMPLETE view of the future (what was expected next).
806-
## In state 3, spurious reduction of production nonempty_list(eol) -> EOL
807-
## In state 5, spurious reduction of production eols -> nonempty_list(eol)
808-
## In state 96, spurious reduction of production comma -> COMMA eols
802+
program: MODULE UIDENT EOL TYPE UIDENT EQUAL UIDENT AND PROVIDE YIELD
809803
##
810-
program: MODULE UIDENT EOL ENUM UIDENT LBRACE UIDENT RBRACE COMMA PROVIDE WHILE
804+
## Ends in an error in state: 861.
811805
##
812-
## Ends in an error in state: 987.
813-
##
814-
## data_declaration_stmt -> PROVIDE . data_declaration [ SEMI EOL EOF COMMA ]
806+
## data_declaration_stmt -> PROVIDE . data_declaration [ SEMI RBRACE EOL EOF AND ]
815807
##
816808
## The known suffix of the stack is as follows:
817809
## PROVIDE
818810
##
819811

820-
Mutually recursive type declarations are separated by commas, but cannot be mixed with other kinds of expressions.
812+
Mutually recursive type declarations are separated by `and`, but cannot be mixed with other kinds of expressions.
821813

822814
program: MODULE UIDENT EOL ENUM UIDENT LBRACE UIDENT WHILE
823815
##
@@ -861,7 +853,7 @@ program: MODULE UIDENT EOL ENUM UIDENT LBRACE UIDENT RBRACE WHILE
861853
## data_declaration_stmt
862854
##
863855

864-
Expected a comma followed by more mutually-recursive type declarations or a newline character to complete the current one.
856+
Expected `and` followed by more mutually-recursive type declarations or a newline character to complete the current one.
865857

866858
program: MODULE UIDENT EOL ENUM UIDENT LCARET LIDENT RCARET INFIX_80
867859
##
@@ -4449,22 +4441,14 @@ program: MODULE UIDENT EOL LET UIDENT LPAREN WHILE
44494441

44504442
Expected a comma-separated list of patterns.
44514443

4452-
program: MODULE UIDENT EOL LET WASMI64 EQUAL WASMI64 COMMA EOL WHILE
4444+
program: MODULE UIDENT EOL LET NUMBER_INT EQUAL UIDENT AND YIELD
44534445
##
4454-
## Ends in an error in state: 433.
4446+
## Ends in an error in state: 423.
44554447
##
4456-
## lseparated_nonempty_list_inner(comma,value_bind) -> lseparated_nonempty_list_inner(comma,value_bind) comma . value_bind [ SEMI RBRACE EOL EOF COMMA ]
4448+
## lseparated_nonempty_list_inner(AND,value_bind) -> lseparated_nonempty_list_inner(AND,value_bind) AND . value_bind [ SEMI RBRACE EOL EOF AND ]
44574449
##
44584450
## The known suffix of the stack is as follows:
4459-
## lseparated_nonempty_list_inner(comma,value_bind) comma
4460-
##
4461-
## WARNING: This example involves spurious reductions.
4462-
## This implies that, although the LR(1) items shown above provide an
4463-
## accurate view of the past (what has been recognized so far), they
4464-
## may provide an INCOMPLETE view of the future (what was expected next).
4465-
## In state 3, spurious reduction of production nonempty_list(eol) -> EOL
4466-
## In state 5, spurious reduction of production eols -> nonempty_list(eol)
4467-
## In state 96, spurious reduction of production comma -> COMMA eols
4451+
## lseparated_nonempty_list_inner(AND,value_bind) AND
44684452
##
44694453

44704454
Expected a binding, e.g. `foo = 5`.

compiler/src/parsing/parser.mly

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module Grain_parsing = struct end
3838
%token <string> INFIX_ASSIGNMENT_10
3939

4040
%token ENUM RECORD TYPE MODULE INCLUDE USE PROVIDE ABSTRACT FOREIGN WASM PRIMITIVE
41+
%token AND
4142
%token EXCEPT FROM STAR
4243
%token SLASH DASH PIPE
4344
%token EOL EOF
@@ -327,7 +328,7 @@ value_bind:
327328
| pattern equal expr { ValueBinding.mk ~loc:(to_loc $loc) $1 $3 }
328329

329330
value_binds:
330-
| lseparated_nonempty_list(comma, value_bind) { $1 }
331+
| lseparated_nonempty_list(AND, value_bind) { $1 }
331332

332333
as_prefix(X):
333334
| AS opt_eols X {$3}
@@ -362,7 +363,7 @@ data_declaration_stmt:
362363
| data_declaration { (NotProvided, $1) }
363364

364365
data_declaration_stmts:
365-
| separated_nonempty_list(comma, data_declaration_stmt) { $1 }
366+
| separated_nonempty_list(AND, data_declaration_stmt) { $1 }
366367

367368
provide_item:
368369
| TYPE aliasable(uid) { PProvideType { name=fst $2; alias = snd $2; loc=to_loc $loc} }

compiler/src/parsing/wrapped_lexer.re

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ let token = state => {
316316
};
317317

318318
let token = state => {
319-
// if-else and or-patterns hack
319+
// if-else, or-patterns, and `and` hack
320320
let (tok, _, _) as triple = token(state);
321321
if (tok == EOL) {
322322
let fst = ((a, _, _)) => a;
@@ -328,6 +328,7 @@ let token = state => {
328328
};
329329

330330
switch (fst(next_triple^)) {
331+
| AND
331332
| ELSE
332333
| PIPE => next_triple^
333334
| _ =>

0 commit comments

Comments
 (0)