Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AST: represent concatenation and (dis)equality operators just like in the syntax. #7248

Merged
merged 6 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- AST cleanup: Remove `@res.partial` attribute from the internal representation, and add a flag to untyped and typed ASTs instead. https://github.com/rescript-lang/rescript/pull/7238 https://github.com/rescript-lang/rescript/pull/7240
- AST cleanup: Remove `structure_item_desc.Pstr_class`, `signature_item_desc.Psig_class`, `structure_item_desc.Pstr_class_type`, `signature_item_desc.Psig_class_type`, `structure_item_desc.Tstr_class`, `structure_item_desc.Tstr_class_type`, `signature_item_desc.Tsig_class`, `signature_item_desc.Tsig_class_type` from AST as it is unused. https://github.com/rescript-lang/rescript/pull/7242
- AST cleanup: remove "|." and rename "|." to "->" in the internal representation for the pipe operator. https://github.com/rescript-lang/rescript/pull/7244
- AST cleanup: represent concatenation (`++`) and (dis)equality operators (`==`, `===`, `!=`, `!==`) just like in the syntax. https://github.com/rescript-lang/rescript/pull/7248

# 12.0.0-alpha.7

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1236,8 +1236,8 @@ and walkExpr = (expr, t, comments) => {
":="
| "||"
| "&&"
| "="
| "=="
| "==="
| "<"
| ">"
| "!="
Expand Down
4 changes: 2 additions & 2 deletions analysis/src/Xform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ module IfThenElse = struct
{
pexp_desc =
Pexp_ident
{txt = Longident.Lident (("=" | "<>") as op)};
{txt = Longident.Lident (("==" | "!=") as op)};
};
args = [(Nolabel, arg1); (Nolabel, arg2)];
};
},
e1,
Some e2 )
when Loc.hasPos ~pos e.pexp_loc -> (
let e1, e2 = if op = "=" then (e1, e2) else (e2, e1) in
let e1, e2 = if op = "==" then (e1, e2) else (e2, e1) in
let mkMatch ~arg ~pat =
let cases =
[
Expand Down
21 changes: 21 additions & 0 deletions compiler/ml/ast_mapper_from0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,27 @@ module E = struct
| ( Pexp_ident ({txt = Longident.Lident "|."} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "->"}}
| ( Pexp_ident ({txt = Longident.Lident "^"} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "++"}}
| ( Pexp_ident ({txt = Longident.Lident "<>"} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "!="}}
| ( Pexp_ident ({txt = Longident.Lident "!="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{
e with
pexp_desc = Pexp_ident {lid with txt = Longident.Lident "!=="};
}
| ( Pexp_ident ({txt = Longident.Lident "="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "=="}}
| ( Pexp_ident ({txt = Longident.Lident "=="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{
e with
pexp_desc = Pexp_ident {lid with txt = Longident.Lident "==="};
}
| _ -> e
in
let process_partial_app_attribute attrs =
Expand Down
15 changes: 15 additions & 0 deletions compiler/ml/ast_mapper_to0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,21 @@ module E = struct
| ( Pexp_ident ({txt = Longident.Lident "->"} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "|."}}
| ( Pexp_ident ({txt = Longident.Lident "++"} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "^"}}
| ( Pexp_ident ({txt = Longident.Lident "!="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "<>"}}
| ( Pexp_ident ({txt = Longident.Lident "!=="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "!="}}
| ( Pexp_ident ({txt = Longident.Lident "==="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "=="}}
| ( Pexp_ident ({txt = Longident.Lident "=="} as lid),
[(Nolabel, _); (Nolabel, _)] ) ->
{e with pexp_desc = Pexp_ident {lid with txt = Longident.Lident "="}}
| _ -> e
in
let attrs =
Expand Down
3 changes: 2 additions & 1 deletion compiler/ml/error_message_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ let error_expected_type_text ppf type_clash_context =
operator
| Some FunctionReturn ->
fprintf ppf "But this function is expecting you to return:"
| Some StringConcat -> fprintf ppf "But string concatenation is expecting:"
| _ -> fprintf ppf "But it's expected to have type:"

let is_record_type ~extract_concrete_typedecl ~env ty =
Expand Down Expand Up @@ -204,7 +205,7 @@ let type_clash_context_from_function sexp sfunct =
in
match sfunct.Parsetree.pexp_desc with
| Pexp_ident
{txt = Lident ("=" | "==" | "<>" | "!=" | ">" | ">=" | "<" | "<=")} ->
{txt = Lident ("==" | "===" | "!=" | "!==" | ">" | ">=" | "<" | "<=")} ->
Some ComparisonOperator
| Pexp_ident {txt = Lident "++"} -> Some StringConcat
| Pexp_ident {txt = Lident (("/." | "*." | "+." | "-.") as operator)} ->
Expand Down
2 changes: 1 addition & 1 deletion compiler/syntax/src/res_comments_table.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,7 @@ and walk_expression expr t comments =
{
txt =
Longident.Lident
( ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!="
( ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!="
| "!==" | "<=" | ">=" | "|>" | "+" | "+." | "-" | "-."
| "++" | "^" | "*" | "*." | "/" | "/." | "**" | "->"
| "<>" );
Expand Down
9 changes: 2 additions & 7 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -391,16 +391,11 @@ let build_longident words =

let make_infix_operator (p : Parser.t) token start_pos end_pos =
let stringified_token =
if token = Token.PlusPlus then "^"
else if token = Token.BangEqual then "<>"
else if token = Token.BangEqualEqual then "!="
else if token = Token.Equal then (
if token = Token.Equal then (
(* TODO: could have a totally different meaning like x->fooSet(y)*)
Parser.err ~start_pos ~end_pos p
(Diagnostics.message "Did you mean `==` here?");
"=")
else if token = Token.EqualEqual then "="
else if token = Token.EqualEqualEqual then "=="
else Token.to_string token
in
let loc = mk_loc start_pos end_pos in
Expand Down Expand Up @@ -2327,7 +2322,7 @@ and parse_template_expr ?prefix p =
in

let hidden_operator =
let op = Location.mknoloc (Longident.Lident "^") in
let op = Location.mknoloc (Longident.Lident "++") in
Ast_helper.Exp.ident op
in
let concat (e1 : Parsetree.expression) (e2 : Parsetree.expression) =
Expand Down
4 changes: 2 additions & 2 deletions compiler/syntax/src/res_parens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ let rhs_binary_expr_operand parent_operator rhs =
args = [(_, _left); (_, _right)];
}
when ParsetreeViewer.is_binary_operator operator
&& not (operator_loc.loc_ghost && operator = "^") ->
&& not (operator_loc.loc_ghost && operator = "++") ->
let prec_parent = ParsetreeViewer.operator_precedence parent_operator in
let prec_child = ParsetreeViewer.operator_precedence operator in
prec_parent == prec_child
Expand All @@ -180,7 +180,7 @@ let flatten_operand_rhs parent_operator rhs =
args = [(_, _left); (_, _right)];
}
when ParsetreeViewer.is_binary_operator operator
&& not (operator_loc.loc_ghost && operator = "^") ->
&& not (operator_loc.loc_ghost && operator = "++") ->
let prec_parent = ParsetreeViewer.operator_precedence parent_operator in
let prec_child = ParsetreeViewer.operator_precedence operator in
prec_parent >= prec_child || rhs.pexp_attributes <> []
Expand Down
16 changes: 8 additions & 8 deletions compiler/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ let operator_precedence operator =
| ":=" -> 1
| "||" -> 2
| "&&" -> 3
| "=" | "==" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4
| "+" | "+." | "-" | "-." | "^" -> 5
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4
| "+" | "+." | "-" | "-." | "++" -> 5
| "*" | "*." | "/" | "/." | "%" -> 6
| "**" -> 7
| "#" | "##" | "->" -> 8
Expand All @@ -296,9 +296,9 @@ let is_unary_expression expr =
(* TODO: tweak this to check for ghost ^ as template literal *)
let is_binary_operator operator =
match operator with
| ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">="
| "|>" | "+" | "+." | "-" | "-." | "^" | "*" | "*." | "/" | "/." | "**" | "->"
| "<>" | "%" ->
| ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">="
| "|>" | "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**"
| "->" | "<>" | "%" ->
true
| _ -> false

Expand All @@ -314,14 +314,14 @@ let is_binary_expression expr =
args = [(Nolabel, _operand1); (Nolabel, _operand2)];
}
when is_binary_operator operator
&& not (operator_loc.loc_ghost && operator = "^")
&& not (operator_loc.loc_ghost && operator = "++")
(* template literal *) ->
true
| _ -> false

let is_equality_operator operator =
match operator with
| "=" | "==" | "<>" | "!=" -> true
| "==" | "===" | "!=" | "!==" -> true
| _ -> false

let is_rhs_binary_operator operator =
Expand Down Expand Up @@ -643,7 +643,7 @@ let is_template_literal expr =
match expr.pexp_desc with
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "^"}};
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "++"}};
args = [(Nolabel, _); (Nolabel, _)];
}
when has_template_literal_attr expr.pexp_attributes ->
Expand Down
15 changes: 3 additions & 12 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3557,7 +3557,7 @@ and print_template_literal ~state expr cmt_tbl =
match expr.pexp_desc with
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "^"}};
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "++"}};
args = [(Nolabel, arg1); (Nolabel, arg2)];
} ->
let lhs = walk_expr arg1 in
Expand Down Expand Up @@ -3662,15 +3662,6 @@ and print_unary_expression ~state expr cmt_tbl =

and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
let print_binary_operator ~inline_rhs operator =
let operator_txt =
match operator with
| "^" -> "++"
| "=" -> "=="
| "==" -> "==="
| "<>" -> "!="
| "!=" -> "!=="
| txt -> txt
in
let spacing_before_operator =
if operator = "->" then Doc.soft_line
else if operator = "|>" then Doc.line
Expand All @@ -3683,7 +3674,7 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
else Doc.line
in
Doc.concat
[spacing_before_operator; Doc.text operator_txt; spacing_after_operator]
[spacing_before_operator; Doc.text operator; spacing_after_operator]
in
let print_operand ~is_lhs ~is_multiline expr parent_operator =
let rec flatten ~is_lhs ~is_multiline expr parent_operator =
Expand Down Expand Up @@ -3800,7 +3791,7 @@ and print_binary_expression ~state (expr : Parsetree.expression) cmt_tbl =
match expr.pexp_desc with
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "^"; loc}};
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "++"; loc}};
args = [(Nolabel, _); (Nolabel, _)];
}
when loc.loc_ghost ->
Expand Down
10 changes: 5 additions & 5 deletions runtime/Pervasives.res
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ external mod: ('a, 'a) => 'a = "%mod"
/* Comparisons */
/* Note: Later comparisons will be converted to unified operations too */

external \"=": ('a, 'a) => bool = "%equal"
external \"<>": ('a, 'a) => bool = "%notequal"
external \"==": ('a, 'a) => bool = "%equal"
external \"!=": ('a, 'a) => bool = "%notequal"
external \"<": ('a, 'a) => bool = "%lessthan"
external \">": ('a, 'a) => bool = "%greaterthan"
external \"<=": ('a, 'a) => bool = "%lessequal"
external \">=": ('a, 'a) => bool = "%greaterequal"
external compare: ('a, 'a) => int = "%compare"
external min: ('a, 'a) => 'a = "%min"
external max: ('a, 'a) => 'a = "%max"
external \"==": ('a, 'a) => bool = "%eq"
external \"!=": ('a, 'a) => bool = "%noteq"
external \"===": ('a, 'a) => bool = "%eq"
external \"!==": ('a, 'a) => bool = "%noteq"

/* Boolean operations */

Expand Down Expand Up @@ -230,7 +230,7 @@ let classify_float = (x: float): fpclass =>

/* String and byte sequence operations -- more in modules String and Bytes */

external \"^": (string, string) => string = "%string_concat"
external \"++": (string, string) => string = "%string_concat"

/* Character operations -- more in module Char */

Expand Down
10 changes: 5 additions & 5 deletions runtime/Pervasives_mini.res
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ external mod: (int, int) => int = "%modint"
/* Comparisons */
/* Note: Later comparisons will be converted to unified operations too */

external \"=": ('a, 'a) => bool = "%equal"
external \"<>": ('a, 'a) => bool = "%notequal"
external \"==": ('a, 'a) => bool = "%equal"
external \"!=": ('a, 'a) => bool = "%notequal"
external \"<": ('a, 'a) => bool = "%lessthan"
external \">": ('a, 'a) => bool = "%greaterthan"
external \"<=": ('a, 'a) => bool = "%lessequal"
external \">=": ('a, 'a) => bool = "%greaterequal"
external compare: ('a, 'a) => int = "%compare"
external min: ('a, 'a) => 'a = "%min"
external max: ('a, 'a) => 'a = "%max"
external \"==": ('a, 'a) => bool = "%eq"
external \"!=": ('a, 'a) => bool = "%noteq"
external \"===": ('a, 'a) => bool = "%eq"
external \"!==": ('a, 'a) => bool = "%noteq"

/* Boolean operations */

Expand Down Expand Up @@ -78,7 +78,7 @@ external \"/.": (float, float) => float = "%divfloat"

/* String operations */

external \"^": (string, string) => string = "%string_concat"
external \"++": (string, string) => string = "%string_concat"

/* Unit operations */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
3 │

This has type: int
But this function argument is expecting: string
But string concatenation is expecting: string

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
3 │

This has type: int
But this function argument is expecting: string
But string concatenation is expecting: string

You can convert int to string with Belt.Int.toString.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ let findThreadByIdLinearScan [arity:2]~threads:((threads)[@res.namedArgLoc ])
| Group { id } -> id
| Unknown { id } ->
(unknown.id -> Js.String.make) -> FBID.ofStringUnsafe in
thisId == id)
thisId === id)
[@res.braces ])))
[@res.braces ])
let x = ((loop 0 (Nil -> (push doc)))[@res.braces ])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ let wss = Server.make { port = 82 }
let address = wss -> Server.address
let log [arity:1]msg =
Js.log
(((((({js|> Server: |js})[@res.template ]) ^ msg)[@res.template ]) ^
(((((({js|> Server: |js})[@res.template ]) ++ msg)[@res.template ]) ++
(({js||js})[@res.template ]))[@res.template ])
;;log
(((((((((((((({js|Running on: |js})[@res.template ]) ^ address.address)
[@res.template ]) ^ (({js|:|js})[@res.template ]))
[@res.template ]) ^ (address.port -> string_of_int))
[@res.template ]) ^ (({js| (|js})[@res.template ]))
[@res.template ]) ^ address.family)
[@res.template ]) ^ (({js|)|js})[@res.template ]))[@res.template ])
(((((((((((((({js|Running on: |js})[@res.template ]) ++ address.address)
[@res.template ]) ++ (({js|:|js})[@res.template ]))
[@res.template ]) ++ (address.port -> string_of_int))
[@res.template ]) ++ (({js| (|js})[@res.template ]))
[@res.template ]) ++ address.family)
[@res.template ]) ++ (({js|)|js})[@res.template ]))[@res.template ])
module ClientSet =
struct
module T =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@

let rightResource =
(ur.resources).find
(fun [arity:1]r -> r.account_id == ((connection.left).account).id)
(fun [arity:1]r -> r.account_id === ((connection.left).account).id)
let x = ((let field = p -> parseFieldDeclaration in field)[@res.braces ])
let t = ((let (_, _, token) = scanner -> scan in token)[@res.braces ])
let (keyTable : int Belt.Map.String.t) = [%rescript.exprhole ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ let f [arity:4]~a:((a)[@res.namedArgLoc ][@attr ]) ((b)[@attrOnB ])
let f [arity:1]list = list ()
;;match colour with
| Red when
(l = l') ||
(l == l') ||
(Clflags.classic.contents &&
((l = Nolabel) && (not (is_optional l'))))
((l == Nolabel) && (not (is_optional l'))))
-> (t1, t2)
| _ -> ()
let arr =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let greetUser async [arity:1]userId =
((let name = ((getUserName userId)[@res.await ]) in
({js|Hello |js} ^ name) ^ {js|!|js})
({js|Hello |js} ++ name) ++ {js|!|js})
[@res.braces ])
;;async fun [arity:1]() -> 123
let fetch = ((async fun [arity:1]url -> browserFetch url)[@res.braces ])
Expand Down
Loading
Loading