Skip to content
Open
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
25 changes: 19 additions & 6 deletions compiler/ml/unified_ops.ml
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ let entries =
};
};
{
path = builtin "~~";
path = builtin "~~~";
name = "%bitnot";
form = Unary;
specialization =
Expand All @@ -221,20 +221,20 @@ let entries =
};
};
{
path = builtin "&";
name = "%bitand";
path = builtin "|||";
name = "%bitor";
form = Binary;
specialization =
{
int = Pandint;
int = Porint;
bool = None;
float = None;
bigint = Some Pandbigint;
bigint = Some Porbigint;
string = None;
};
};
{
path = builtin "^";
path = builtin "^^^";
name = "%bitxor";
form = Binary;
specialization =
Expand All @@ -246,6 +246,19 @@ let entries =
string = None;
};
};
{
path = builtin "&&&";
name = "%bitand";
form = Binary;
specialization =
{
int = Pandint;
bool = None;
float = None;
bigint = Some Pandbigint;
string = None;
};
};
|]

let index_by_path =
Expand Down
5 changes: 3 additions & 2 deletions compiler/syntax/src/res_comments_table.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,7 @@ and walk_expression expr t comments =
{
txt =
Longident.Lident
("~+" | "~+." | "~-" | "~-." | "~~" | "not" | "!");
("~+" | "~+." | "~-" | "~-." | "~~~" | "not" | "!");
};
};
args = [(Nolabel, arg_expr)];
Expand All @@ -1517,7 +1517,8 @@ and walk_expression expr t comments =
Longident.Lident
( ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!="
| "!==" | "<=" | ">=" | "+" | "+." | "-" | "-." | "++"
| "^" | "*" | "*." | "/" | "/." | "**" | "->" | "<>" );
| "|||" | "^^^" | "&&&" | "*" | "*." | "/" | "/." | "**"
| "->" | "<>" );
};
};
args = [(Nolabel, operand1); (Nolabel, operand2)];
Expand Down
13 changes: 8 additions & 5 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,12 @@ let make_unary_expr start_pos token_end token operand =
}
| (Minus | MinusDot), Pexp_constant (Pconst_float (n, m)) ->
{operand with pexp_desc = Pexp_constant (Pconst_float (negate_string n, m))}
| (Token.Plus | PlusDot | Minus | MinusDot | Tilde), _ ->
| (Token.Plus | PlusDot | Minus | MinusDot | Bnot), _ ->
let token_loc = mk_loc start_pos token_end in
let operator = "~" ^ Token.to_string token in
let token_string = Token.to_string token in
let operator =
if token_string.[0] = '~' then token_string else "~" ^ token_string
in
Ast_helper.Exp.apply
~loc:(mk_loc start_pos operand.Parsetree.pexp_loc.loc_end)
(Ast_helper.Exp.ident ~loc:token_loc
Expand Down Expand Up @@ -2292,7 +2295,7 @@ and parse_primary_expr ~operand ?(no_call = false) p =
and parse_unary_expr p =
let start_pos = p.Parser.start_pos in
match p.Parser.token with
| (Minus | MinusDot | Plus | PlusDot | Bang | Tilde) as token ->
| (Minus | MinusDot | Plus | PlusDot | Bang | Bnot) as token ->
Parser.leave_breadcrumb p Grammar.ExprUnary;
let token_end = p.end_pos in
Parser.next p;
Expand Down Expand Up @@ -5932,15 +5935,15 @@ and parse_polymorphic_variant_type_spec_hash ~attrs ~full p :
let ident, loc = parse_hash_ident ~start_pos p in
let rec loop p =
match p.Parser.token with
| Band when full ->
| Ampersand when full ->
Parser.next p;
let row_field = parse_polymorphic_variant_type_args p in
row_field :: loop p
| _ -> []
in
let first_tuple, tag_contains_a_constant_empty_constructor =
match p.Parser.token with
| Band when full ->
| Ampersand when full ->
Parser.next p;
([parse_polymorphic_variant_type_args p], true)
| Lparen -> ([parse_polymorphic_variant_type_args p], false)
Expand Down
5 changes: 3 additions & 2 deletions compiler/syntax/src/res_grammar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ let is_atomic_typ_expr_start = function
let is_expr_start = function
| Token.Assert | At | Await | Backtick | Bang | Codepoint _ | False | Float _
| For | Hash | If | Int _ | Lbrace | Lbracket | LessThan | Lident _ | List
| Lparen | Minus | MinusDot | Module | Percent | Plus | PlusDot | Tilde
| String _ | Switch | True | Try | Uident _ | Underscore (* _ => doThings() *)
| Lparen | Minus | MinusDot | Module | Percent | Plus | PlusDot | Bnot | Bor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this was not all part of this PR, but

| BitwiseNot
| BitwiseOr
| BitwiseXor
| BitwiseAnd 

would read better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or actually, should it not be

| TildeTildeTilde
| BarBarBar
| CaretCaretCaret
| AndAndAnd

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if there is a possibility to reuse that tokens across the grammar, I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice for consistency, as we already have DotDotDot and EqualEqualEqual, too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And in this spirit, I would also keep Tilde.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know. we already have tokens like Land, Lor. Do you want to change those token names too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or leave them as is, as Christoph said it would just be nice to have.

| Bxor | Band | String _ | Switch | True | Try | Uident _
| Underscore (* _ => doThings() *)
| While | Forwardslash | ForwardslashDot | Dict ->
true
| _ -> false
Expand Down
1 change: 0 additions & 1 deletion compiler/syntax/src/res_parens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ let binary_expr_operand ~is_lhs expr =
| _ when Ast_uncurried.expr_is_uncurried_fun expr -> Parenthesized
| expr when ParsetreeViewer.is_binary_expression expr -> Parenthesized
| expr when ParsetreeViewer.is_ternary_expr expr -> Parenthesized
| expr when ParsetreeViewer.is_unary_bitnot_expression expr -> Parenthesized
| {pexp_desc = Pexp_assert _} when is_lhs -> Parenthesized
| _ when ParsetreeViewer.expr_is_await expr -> Parenthesized
| {Parsetree.pexp_attributes = attrs} ->
Expand Down
31 changes: 11 additions & 20 deletions compiler/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -267,19 +267,20 @@ let operator_precedence operator =
| ":=" -> 1
| "||" -> 2
| "&&" -> 3
| "^" -> 4
| "&" -> 5
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" -> 6
| "<<" | ">>" | ">>>" -> 7
| "+" | "+." | "-" | "-." | "++" -> 8
| "*" | "*." | "/" | "/." | "%" -> 9
| "**" -> 10
| "#" | "##" | "->" -> 11
| "|||" -> 4
| "^^^" -> 5
| "&&&" -> 6
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" -> 7
| "<<" | ">>" | ">>>" -> 8
| "+" | "+." | "-" | "-." | "++" -> 9
| "*" | "*." | "/" | "/." | "%" -> 10
| "**" -> 11
| "#" | "##" | "->" -> 12
| _ -> 0

let is_unary_operator operator =
match operator with
| "~+" | "~+." | "~-" | "~-." | "~~" | "not" -> true
| "~+" | "~+." | "~-" | "~-." | "~~~" | "not" -> true
| _ -> false

let is_unary_expression expr =
Expand All @@ -293,21 +294,11 @@ let is_unary_expression expr =
true
| _ -> false

let is_unary_bitnot_expression expr =
match expr.pexp_desc with
| Pexp_apply
{
funct = {pexp_desc = Pexp_ident {txt = Longident.Lident "~~"}};
args = [(Nolabel, _arg)];
} ->
true
| _ -> false

let is_binary_operator operator =
match operator with
| ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">="
| "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**" | "->"
| "<>" | "%" | "&" | "^" | "<<" | ">>" | ">>>" ->
| "<>" | "%" | "|||" | "^^^" | "&&&" | "<<" | ">>" | ">>>" ->
true
| _ -> false

Expand Down
1 change: 0 additions & 1 deletion compiler/syntax/src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ val operator_precedence : string -> int

val not_ghost_operator : string -> Location.t -> bool
val is_unary_expression : Parsetree.expression -> bool
val is_unary_bitnot_expression : Parsetree.expression -> bool
val is_binary_operator : string -> bool
val is_binary_expression : Parsetree.expression -> bool
val is_rhs_binary_operator : string -> bool
Expand Down
4 changes: 1 addition & 3 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3777,7 +3777,7 @@ and print_unary_expression ~state expr cmt_tbl =
| "~+." -> "+."
| "~-" -> "-"
| "~-." -> "-."
| "~~" -> "~"
| "~~~" -> "~~~"
| "not" -> "!"
| _ -> assert false)
in
Expand Down Expand Up @@ -5101,8 +5101,6 @@ and print_argument ~state (arg_lbl, arg) cmt_tbl =
match Parens.expr expr with
| Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing when ParsetreeViewer.is_unary_bitnot_expression expr ->
add_parens doc
| Nothing -> doc
in
let loc = {arg_loc with loc_end = expr.pexp_loc.loc_end} in
Expand Down
38 changes: 27 additions & 11 deletions compiler/syntax/src/res_scanner.ml
Original file line number Diff line number Diff line change
Expand Up @@ -756,9 +756,14 @@ let rec scan scanner =
| '`' ->
next scanner;
Token.Backtick
| '~' ->
next scanner;
Token.Tilde
| '~' -> (
match (peek scanner, peek2 scanner) with
| '~', '~' ->
next3 scanner;
Token.Bnot
| _ ->
next scanner;
Token.Tilde)
| '?' ->
next scanner;
Token.Question
Expand Down Expand Up @@ -830,24 +835,35 @@ let rec scan scanner =
next scanner;
Token.Percent)
| '|' -> (
match peek scanner with
| '|' ->
match (peek scanner, peek2 scanner) with
| '|', '|' ->
next3 scanner;
Token.Bor
| '|', _ ->
next2 scanner;
Token.Lor
| _ ->
next scanner;
Token.Bar)
| '&' -> (
match peek scanner with
| '&' ->
match (peek scanner, peek2 scanner) with
| '&', '&' ->
next3 scanner;
Token.Band
| '&', _ ->
next2 scanner;
Token.Land
| _ ->
next scanner;
Token.Band)
| '^' ->
next scanner;
Token.Caret
Token.Ampersand)
| '^' -> (
match (peek scanner, peek2 scanner) with
| '^', '^' ->
next3 scanner;
Token.Bxor
| _ ->
next scanner;
Token.Caret)
| ':' -> (
match peek scanner with
| '=' ->
Expand Down
31 changes: 20 additions & 11 deletions compiler/syntax/src/res_token.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type t =
| Equal
| EqualEqual
| EqualEqualEqual
| Ampersand
| Bar
| Lparen
| Rparen
Expand Down Expand Up @@ -76,7 +77,10 @@ type t =
| Of
| Land
| Lor
| Band (* Bitwise and: & *)
| Bnot (* Bitwise and: ~~~ *)
| Bor (* Bitwise and: ||| *)
| Bxor (* Bitwise and: ^^^ *)
| Band (* Bitwise and: &&& *)
| Caret
| BangEqual
| BangEqualEqual
Expand Down Expand Up @@ -104,17 +108,18 @@ let precedence = function
| HashEqual | ColonEqual -> 1
| Lor -> 2
| Land -> 3
| Caret -> 4
| Band -> 5
| Bor -> 4
| Bxor -> 5
| Band -> 6
| Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual
| BangEqualEqual | LessEqual | GreaterEqual ->
6
| LeftShift | RightShift | RightShiftUnsigned -> 7
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 8
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 9
| Exponentiation -> 10
| MinusGreater -> 11
| Dot -> 12
7
| LeftShift | RightShift | RightShiftUnsigned -> 8
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 9
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 10
| Exponentiation -> 11
| MinusGreater -> 12
| Dot -> 13
| _ -> 0

let to_string = function
Expand Down Expand Up @@ -143,6 +148,7 @@ let to_string = function
| EqualEqual -> "=="
| EqualEqualEqual -> "==="
| Eof -> "eof"
| Ampersand -> "&"
| Bar -> "|"
| As -> "as"
| Lparen -> "("
Expand Down Expand Up @@ -193,7 +199,10 @@ let to_string = function
| Module -> "module"
| Of -> "of"
| Lor -> "||"
| Band -> "&"
| Bnot -> "~~~"
| Bor -> "|||"
| Bxor -> "^^^"
| Band -> "&&&"
| Caret -> "^"
| Land -> "&&"
| BangEqual -> "!="
Expand Down
4 changes: 4 additions & 0 deletions compiler/syntax/src/res_token_debugger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ let dump_tokens filename =
| Res_token.Equal -> "Equal"
| Res_token.EqualEqual -> "EqualEqual"
| Res_token.EqualEqualEqual -> "EqualEqualEqual"
| Res_token.Ampersand -> "Ampersand"
| Res_token.Bar -> "Bar"
| Res_token.Lparen -> "Lparen"
| Res_token.Rparen -> "Rparen"
Expand Down Expand Up @@ -93,7 +94,10 @@ let dump_tokens filename =
| Res_token.Of -> "Of"
| Res_token.Land -> "Land"
| Res_token.Lor -> "Lor"
| Res_token.Bnot -> "Bnot"
| Res_token.Bor -> "Bor"
| Res_token.Band -> "Band"
| Res_token.Bxor -> "Bxor"
| Res_token.Caret -> "Caret"
| Res_token.BangEqual -> "BangEqual"
| Res_token.BangEqualEqual -> "BangEqualEqual"
Expand Down
9 changes: 6 additions & 3 deletions packages/@rescript/runtime/Pervasives.res
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,12 @@ external \"%": ('a, 'a) => 'a = "%mod"
external \"<<": ('a, 'a) => 'a = "%lsl"
external mod: ('a, 'a) => 'a = "%mod"
external \"**": ('a, 'a) => 'a = "%pow"
external \"~~": 'a => 'a = "%bitnot"
external \"&": ('a, 'a) => 'a = "%bitand"
external \"^": ('a, 'a) => 'a = "%bitxor"

external \"~~~": 'a => 'a = "%bitnot"
external \"|||": ('a, 'a) => 'a = "%bitor"
external \"^^^": ('a, 'a) => 'a = "%bitxor"
external \"&&&": ('a, 'a) => 'a = "%bitand"

external \">>": ('a, 'a) => 'a = "%asr"
external \">>>": ('a, 'a) => 'a = "%lsr"

Expand Down
Loading
Loading