You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Compared to C, bedrock2 is missing quite a few operators:
Unary operators:
unary minus -
logical not !
bitwise not ~
Binary operators:
unsigned division / and modulo %: unsigned variants are already in AST bopname, but no notations
unsigned <=, >, >=
not equal !=
lazy boolean &&/||
More missing operators that I'd postpone for later:
ternary conditional _ ? _ : _
signed <=, >, >=
signed division and modulo
pre and post ++ and -- (won't add because we don't want expressions with side-effects, maybe as a statement, though)
record access . and ->
array access []
compound assignment
This absence of operators can lead to more bugs, defeating the point of using bedrock2: When transcribing C to bedrock2, one has to work around missing operators, trying to emulate them with existing ones, and (based on experience), bugs can be introduced in this process. (Hopefully, they will be found during verification, but if one only verifies memory safety, they could be missed).
Most of these operators could be implemented as notations in terms of other operators:
Unary operators:
"- x" := (0 - x)
"! x" := (1 - (x != 0)), or "! x" := (x ? 0 : 1), or a primitive?
"~ x" := x ^ (-1)
Binary operators:
"/" := (expr.op divu)
"%" := (expr.op remu)
"x <= y" := (!(y < x))
"x > y" := (y < x)
"x >= y" := (!(x < y))
"x != y" := (! (x == y))
&& and ||: as primitives, added to bopname, or maybe using a ternary if?
However, the above definitions are circular: ! is defined in terms of !=, and != is defined in terms of !.
A disadvantage of using notations is also that the C pretty printer won't print them (unless we add extra logic that detects the patterns), and that if the compiler wants to treat them specially, it also has to detect the pattern rather than just writing a case of an inductive constructor.
Overall, it seems that in order to support these operators, the at least some additions to the expr AST need to be made, while others can be implemented as notations, and that there is some flexibility as to what's a notation and what goes into the AST.
I'm a bit undecided regarding what should be notation vs in the expr AST. Opinions by @andres-erbsen or @jadephilipoom or others welcome 😉
The text was updated successfully, but these errors were encountered:
I don't see any real reasons to prefer notations to new bopnames as long as the operation is generally useful. If giving semantics directly would result in nicer proof obligations, I'd say let's prefer adding bopnames.
I think you could do "! x" := (x == 0) if you wanted, though?
&& and ||: as primitives, added to bopname, or maybe using a ternary if?
I think we should only add them if we are going to match the semantics of C and its predecessors (and at that point we could indeed add conditional expressions as well). In particular 0 && *0 should be a safe expression. We could totally do this (heck, with the confidence we now have about postcondition-style semantics I'd feel fine even going to everything-is-an-expression land), but my hunch is that it's not the most impactful thing to work on right now.
Compared to C, bedrock2 is missing quite a few operators:
Unary operators:
-
!
~
Binary operators:
/
and modulo%
: unsigned variants are already in ASTbopname
, but no notations<=
,>
,>=
!=
&&
/||
More missing operators that I'd postpone for later:
_ ? _ : _
<=
,>
,>=
++
and--
(won't add because we don't want expressions with side-effects, maybe as a statement, though).
and->
[]
This absence of operators can lead to more bugs, defeating the point of using bedrock2: When transcribing C to bedrock2, one has to work around missing operators, trying to emulate them with existing ones, and (based on experience), bugs can be introduced in this process. (Hopefully, they will be found during verification, but if one only verifies memory safety, they could be missed).
Most of these operators could be implemented as notations in terms of other operators:
Unary operators:
"- x" := (0 - x)
"! x" := (1 - (x != 0))
, or"! x" := (x ? 0 : 1)
, or a primitive?"~ x" := x ^ (-1)
Binary operators:
"/" := (expr.op divu)
"%" := (expr.op remu)
"x <= y" := (!(y < x))
"x > y" := (y < x)
"x >= y" := (!(x < y))
"x != y" := (! (x == y))
&&
and||
: as primitives, added tobopname
, or maybe using a ternary if?However, the above definitions are circular:
!
is defined in terms of!=
, and!=
is defined in terms of!
.A disadvantage of using notations is also that the C pretty printer won't print them (unless we add extra logic that detects the patterns), and that if the compiler wants to treat them specially, it also has to detect the pattern rather than just writing a case of an inductive constructor.
Overall, it seems that in order to support these operators, the at least some additions to the
expr
AST need to be made, while others can be implemented as notations, and that there is some flexibility as to what's a notation and what goes into the AST.I'm a bit undecided regarding what should be notation vs in the
expr
AST. Opinions by @andres-erbsen or @jadephilipoom or others welcome 😉The text was updated successfully, but these errors were encountered: