Skip to content

Commit

Permalink
make bitwise xor higher precedence than comparisons, like rust
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffIrwin committed Nov 10, 2024
1 parent 454d175 commit 981a236
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/consts.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module syntran__consts_m
integer, parameter :: &
not_token = 112, &
xor_token = 111, &
or_token = 110, &
or_token = 110, & ! TODO: rename (bitwise) tokens to distinguish from logical kwords
and_token = 109, &
ggreater_token = 108, &
lless_token = 107, &
Expand Down
3 changes: 2 additions & 1 deletion src/tests/test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,8 @@ subroutine unit_test_bitwise(npass, nfail)
eval_i32("1 ^ 1;") == 0, &
eval_i32("255 ^ 255;") == 0, &
eval_i32("0xff00 ^ 0x00ff;") == eval_i32("0xffff;"), &
eval("(0xff00 ^ 0x00ff) == 0xffff;") == "true", & ! TODO: prec shouldn't need parentheses?
eval("(0xff00 ^ 0x00ff) == 0xffff;") == "true", &
eval("0xff00 ^ 0x00ff == 0xffff;") == "true", & ! ^ vs == precedence matches rust, not c
eval("(0xf00f ^ 0x0ff0) == 0xffff;") == "true", &
eval("(0b1010 ^ 0b0101) == 0b1111;") == "true", &
eval("(0b1011 ^ 0b0101) == 0b1110;") == "true", &
Expand Down
37 changes: 27 additions & 10 deletions src/types.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1697,12 +1697,29 @@ integer function get_binary_op_prec(kind) result(prec)

select case (kind)

! Follow C operator precedence here, except possible for bitwise and/or
! Syntran operator precedence is closest to rust:
!
! Ref: https://en.cppreference.com/w/c/language/operator_precedence
! https://doc.rust-lang.org/reference/expressions.html
!
! The exception is that ordering comparisons <, >, <=, and >= have
! higher precedence than (in)equality comparisons == and !=. In rust,
! all comparisons have the same precedence.
!
! This is somewhat similar to C, except for bitwise and `&`, bitwise or
! `|`, and bitwise xor `^`, which have higher precedence here (and in
! rust) than comparisons. The fact that C works this way could be
! considered a poor design, but it is due to historical reasons
! predating even C, according to Dennis Ritchie:
!
! http://cm.bell-labs.co/who/dmr/chist.html
!
! C (and C++) precedence:
!
! https://en.cppreference.com/w/c/language/operator_precedence
!
! Note that here, a higher `prec` int return value means higher
! precedence, while the ref is the opposite
! precedence, while the C++ ref is the opposite numerically (but the
! same top to bottom)

!********

Expand All @@ -1717,23 +1734,23 @@ integer function get_binary_op_prec(kind) result(prec)
case (plus_token, minus_token)
prec = 9

case (lless_token, ggreater_token)
case (lless_token, ggreater_token) ! `<<`, `>>`
prec = 8

case (less_token, less_equals_token, &
greater_token, greater_equals_token)
case (and_token) ! `&` (bitwise and)
prec = 7

case (eequals_token, bang_equals_token)
case (xor_token) ! `^` (bitwise xor)
prec = 6

case (and_token) ! `&` (bitwise and)
case ( or_token) ! `|` (bitwise or)
prec = 5

case (xor_token) ! `^` (bitwise xor)
case (less_token, less_equals_token, &
greater_token, greater_equals_token)
prec = 4

case (or_token) ! `|` (bitwise or)
case (eequals_token, bang_equals_token)
prec = 3

case (and_keyword) ! `and` (logical)
Expand Down

0 comments on commit 981a236

Please sign in to comment.