Skip to content

Commit

Permalink
Finalize implementation, add warnings for footguns
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-snezhko committed Aug 29, 2024
1 parent 845fc6b commit eac5c75
Show file tree
Hide file tree
Showing 65 changed files with 2,185 additions and 1,761 deletions.
144 changes: 71 additions & 73 deletions compiler/src/formatting/fmt.re
Original file line number Diff line number Diff line change
Expand Up @@ -181,49 +181,6 @@ let precedence = expr => {
};
};

let infixop = op => {
switch (op.[0]) {
| '+'
| '-'
| '*'
| '/'
| '%'
| '='
| '^'
| '<'
| '>'
| '&'
| '|'
| '?' => true
| _ when op == "is" => true
| _ when op == "isnt" => true
| _ when String.starts_with(~prefix="!=", op) => true
| _
| exception _ => false
};
};

let is_infix_op = expr => {
switch (expr.pexp_desc) {
| PExpId({txt: Identifier.IdentName({txt: op})}) => infixop(op)
| _ => false
};
};

let prefixop = op =>
switch (op.[0]) {
| '!' => true
| _
| exception _ => false
};

let is_prefix_op = expr => {
switch (expr.pexp_desc) {
| PExpId({txt: Identifier.IdentName({txt: op})}) => prefixop(op)
| _ => false
};
};

let is_keyword_function = expr => {
switch (expr.pexp_desc) {
| PExpId({txt: Identifier.IdentName({txt: "assert" | "throw" | "fail"})}) =>
Expand All @@ -236,13 +193,17 @@ let needs_grouping = (~parent, ~side: infix_side, expr) => {
switch (expr.pexp_desc, side) {
| (PExpIf(_), _) => ParenGrouping
| (PExpApp(fn1, _), Left)
when is_infix_op(fn1) && precedence(fn1) < precedence(parent) =>
when
Parser_utils.is_infix_op(fn1)
&& precedence(fn1) < precedence(parent) =>
ParenGrouping
| (PExpApp(fn1, _), Right)
when is_infix_op(fn1) && precedence(fn1) <= precedence(parent) =>
when
Parser_utils.is_infix_op(fn1)
&& precedence(fn1) <= precedence(parent) =>
ParenGrouping
| (PExpApp(fn1, _), _) =>
if (is_infix_op(fn1)) {
if (Parser_utils.is_infix_op(fn1)) {
if ((!is_math_op(parent) && !is_logic_op(parent))
&& !is_same_op(fn1, parent)) {
ParenGrouping;
Expand Down Expand Up @@ -871,7 +832,7 @@ let print_pattern = (fmt, {ppat_desc, ppat_loc}) => {
};

let print_ident_string = (fmt, ident) =>
if (infixop(ident) || prefixop(ident)) {
if (Parser_utils.infixop(ident) || Parser_utils.prefixop(ident)) {
parens(string(ident));
} else {
string(ident);
Expand Down Expand Up @@ -923,7 +884,7 @@ let print_grouped_access_expression = (fmt, expr) =>
| PExpBlock(_)
| PExpArray(_)
| PExpList(_) => fmt.print_expression(fmt, expr)
| PExpApp(func, _) when is_infix_op(func) =>
| PExpApp(func, _) when Parser_utils.is_infix_op(func) =>
parens(indent(break ++ fmt.print_expression(fmt, expr)) ++ break)
| PExpApp(_) => fmt.print_expression(fmt, expr)
| _ => parens(indent(break ++ fmt.print_expression(fmt, expr)) ++ break)
Expand Down Expand Up @@ -1515,7 +1476,7 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
indent(
concat_map(
~lead=
first =>
((_, first)) =>
fmt.print_comment_range(
fmt,
~none=hardline,
Expand All @@ -1525,7 +1486,7 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
first.pexp_loc,
),
~sep=
(prev, next) =>
((_, prev), (_, next)) =>
fmt.print_comment_range(
fmt,
~none=
Expand All @@ -1543,7 +1504,7 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
next.pexp_loc,
),
~trail=
last =>
((_, last)) =>
fmt.print_comment_range(
fmt,
~block_end=true,
Expand All @@ -1552,13 +1513,21 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
enclosing_end_location(expr.pexp_loc),
),
~f=
(~final, e) =>
(~final, (i, e)) =>
if (has_disable_formatting_comment(fmt.comments, e.pexp_loc)) {
fmt.print_original_code(fmt, e.pexp_loc);
} else {
fmt.print_expression(fmt, e);
let include_parens =
i != 0
&& Parser_utils.starts_with_negative_value(
~bypass_parens=false,
e,
);
let format_expr =
include_parens ? parens(~wrap=Fun.id) : Fun.id;
format_expr(fmt.print_expression(fmt, e));
},
exprs,
List.mapi((i, expr) => (i, expr.pblk_expr), exprs),
),
)
++ hardline,
Expand Down Expand Up @@ -1602,7 +1571,7 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
~f=(~final, vb) => fmt.print_value_binding(fmt, vb),
vbs,
)
| PExpApp(fn, [arg]) when is_prefix_op(fn) =>
| PExpApp(fn, [arg]) when Parser_utils.is_prefix_op(fn) =>
fmt.print_infix_prefix_op(fmt, fn)
++ fmt.print_comment_range(fmt, fn.pexp_loc, arg.paa_loc)
++ (
Expand All @@ -1617,7 +1586,7 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
| None => fmt.print_application_argument(fmt, arg)
}
)
| PExpApp(fn, [lhs, rhs]) when is_infix_op(fn) =>
| PExpApp(fn, [lhs, rhs]) when Parser_utils.is_infix_op(fn) =>
// To ensure adequate grouping/breaking of subexpressions, chains of
// binops are included in a single Doc.group, with new groups inserted
// where necessary. By default, this group indents when breaking. This
Expand Down Expand Up @@ -1647,19 +1616,18 @@ let print_expression = (fmt, ~infix_wrap=d => group(indent(d)), expr) => {
)
++ fmt.print_comment_range(
fmt,
~none=space,
~none=breakable_space,
~lead=space,
~trail=space,
~allow_breaks=false,
~trail=breakable_space,
lhs.paa_loc,
fn.pexp_loc,
)
++ fmt.print_infix_prefix_op(fmt, fn)
++ fmt.print_comment_range(
fmt,
~none=breakable_space,
~none=space,
~lead=space,
~trail=breakable_space,
~trail=space,
fn.pexp_loc,
rhs.paa_loc,
)
Expand Down Expand Up @@ -3319,6 +3287,30 @@ let print_include_declaration =
);
};

let rec exprs_with_include_parens = (stmts, prev_is_expr, acc) => {
switch (stmts) {
| [first, ...rest] =>
let wrap_in_parens =
switch (first.ptop_desc) {
| PTopExpr(expr) =>
Parser_utils.starts_with_negative_value(~bypass_parens=false, expr)
| _ => false
};
let curr_is_expr =
switch (first.ptop_desc) {
| PTopExpr(_)
| PTopLet(_) => true
| _ => false
};
exprs_with_include_parens(
rest,
curr_is_expr,
[(first, wrap_in_parens), ...acc],
);
| [] => acc
};
};

let print_module_declaration = (fmt, {pmod_name, pmod_stmts, pmod_loc}) => {
string("module")
++ fmt.print_comment_range(
Expand All @@ -3337,7 +3329,7 @@ let print_module_declaration = (fmt, {pmod_name, pmod_stmts, pmod_loc}) => {
indent(
concat_map(
~lead=
next =>
((next, _)) =>
fmt.print_comment_range(
fmt,
~none=hardline,
Expand All @@ -3347,7 +3339,7 @@ let print_module_declaration = (fmt, {pmod_name, pmod_stmts, pmod_loc}) => {
next.ptop_loc,
),
~sep=
(prev, next) =>
((prev, _), (next, _)) =>
fmt.print_comment_range(
fmt,
~none=
Expand All @@ -3365,21 +3357,23 @@ let print_module_declaration = (fmt, {pmod_name, pmod_stmts, pmod_loc}) => {
next.ptop_loc,
),
~trail=
prev =>
((prev, _)) =>
fmt.print_comment_range(
fmt,
~lead=space,
prev.ptop_loc,
enclosing_end_location(pmod_loc),
),
~f=
(~final, s) =>
(~final, (s, include_parens)) =>
if (has_disable_formatting_comment(fmt.comments, s.ptop_loc)) {
fmt.print_original_code(fmt, s.ptop_loc);
} else {
fmt.print_toplevel_stmt(fmt, s);
let format_expr =
include_parens ? parens(~wrap=Fun.id) : Fun.id;
format_expr(fmt.print_toplevel_stmt(fmt, s));
},
pmod_stmts,
List.rev(exprs_with_include_parens(pmod_stmts, false, [])),
),
)
++ hardline,
Expand Down Expand Up @@ -3999,7 +3993,7 @@ let print_program = (fmt, parsed_program) => {
| _ =>
concat_map(
~lead=
first =>
((first, _)) =>
fmt.print_comment_range(
fmt,
~none=hardline ++ hardline,
Expand All @@ -4009,7 +4003,7 @@ let print_program = (fmt, parsed_program) => {
first.ptop_loc,
),
~sep=
(prev, next) => {
((prev, _), (next, _)) => {
fmt.print_comment_range(
fmt,
~none=
Expand All @@ -4028,7 +4022,7 @@ let print_program = (fmt, parsed_program) => {
)
},
~trail=
last =>
((last, _)) =>
fmt.print_comment_range(
fmt,
~block_end=true,
Expand All @@ -4038,13 +4032,17 @@ let print_program = (fmt, parsed_program) => {
)
++ hardline,
~f=
(~final, s) =>
(~final, (s, include_parens)) =>
if (has_disable_formatting_comment(fmt.comments, s.ptop_loc)) {
fmt.print_original_code(fmt, s.ptop_loc);
} else {
fmt.print_toplevel_stmt(fmt, s);
let format_expr =
include_parens ? parens(~wrap=Fun.id) : Fun.id;
format_expr(fmt.print_toplevel_stmt(fmt, s));
},
parsed_program.statements,
List.rev(
exprs_with_include_parens(parsed_program.statements, false, []),
),
)
};

Expand Down
4 changes: 4 additions & 0 deletions compiler/src/parsing/ast_helper.re
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ module Expression = {
pexp_attributes: attributes,
pexp_loc: loc,
pexp_core_loc: core_loc,
// Placehoder; will be corrected later in parsing
pexp_in_parens: false,
};
};
let ident = (~loc, ~core_loc, ~attributes=?, a) =>
Expand Down Expand Up @@ -430,6 +432,8 @@ module Toplevel = {
ptop_attributes: attributes,
ptop_loc: loc,
ptop_core_loc: core_loc,
// Placehoder; will be corrected later in parsing
ptop_ends_semi: false,
};
};
let include_ = (~loc, ~core_loc, ~attributes=?, i) =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/parsing/ast_helper.rei
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ module Expression: {
~loc: loc,
~core_loc: loc,
~attributes: attributes=?,
list(expression)
list(block_expression)
) =>
expression;
let ignore: expression => expression;
Expand Down
7 changes: 6 additions & 1 deletion compiler/src/parsing/ast_mapper.re
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,12 @@ module E = {
},
)
| PExpBlock(el) =>
block(~loc, ~core_loc, ~attributes, List.map(sub.expr(sub), el))
block(
~loc,
~core_loc,
~attributes,
List.map(e => {...e, pblk_expr: sub.expr(sub, e.pblk_expr)}, el),
)
| PExpConstraint(e, t) =>
constraint_(
~loc,
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/parsing/lexer.re
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ let rec token = lexbuf => {
| "*" => positioned(STAR)
| "/" => positioned(SLASH)
| "|" => positioned(PIPE)
| "-" => positioned(DASH)
| ("-", blank) => positioned(DASHWHITESPACE)
| "-" => positioned(DASHNOWHITESPACE)
| "->" => positioned(ARROW)
| "=>" => positioned(THICKARROW)
| "type" => positioned(TYPE)
Expand Down
Loading

0 comments on commit eac5c75

Please sign in to comment.