Skip to content

Commit

Permalink
If statements and boolean operators (#16)
Browse files Browse the repository at this point in the history
* boolean and/or

* if statements

* blocks

* add test

* update tests

* update test to have better coverage
  • Loading branch information
dwightguth authored Aug 26, 2024
1 parent d0de1dc commit 5585171
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/expression.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ module SOLIDITY-EXPRESSION
rule v(true, bool) ? X : _ => X
rule v(false, bool) ? _ : X => X
// boolean and/or
rule v(true, bool) && E => E
rule v(false, bool) && _ => v(false, bool)
rule v(true, bool) || _ => v(true, bool)
rule v(false, bool) || E => E
// helpers
syntax Int ::= Number2Int(NumberLiteral) [function]
rule Number2Int(X:HexNumber) => HexNumberString2Int(HexNumber2String(X))
Expand Down
4 changes: 2 additions & 2 deletions src/solidity-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ Following is a list of supported statements.
| VariableDeclaration "=" Expression ";" [strict(2)]
| "(" VariableDeclaration "," ")" "=" Expression ";" [strict(2)]
syntax IfStatement ::= "if" "(" Expression ")" Statement
| "if" "(" Expression ")" Statement "else" Statement
syntax IfStatement ::= "if" "(" Expression ")" Statement [strict(1)]
| "if" "(" Expression ")" Statement "else" Statement [avoid, strict(1)]
syntax ForStatement ::= "for" "(" InitStatement ConditionStatement PostLoopStatement ")" Statement
syntax InitStatement ::= VariableDeclarationStatement | ExpressionStatement | ";"
Expand Down
14 changes: 14 additions & 0 deletions src/statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,18 @@ module SOLIDITY-STATEMENT
<events>... .List => ListItem(event(X, ARGS)) </events>
requires isKResult(ARGS)
// if statement
rule if ( v(true, bool ) ) S => S
rule if ( v(false, bool ) ) _ => .K
rule if ( v(true, bool ) ) S else _ => S
rule if ( v(false, bool ) ) _ else S => S
// blocks
rule <k> { S } => S ~> restoreEnv(E) ...</k>
<env> E </env>
syntax KItem ::= restoreEnv(Map)
rule <k> restoreEnv(E) => .K ...</k>
<env> _ => E </env>
endmodule
98 changes: 98 additions & 0 deletions test/regression/block.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<solidity>
<k>
.K
</k>
<current-body>
BlockTest
</current-body>
<ifaces>
.IfaceCellMap
</ifaces>
<contracts>
<contract>
<contract-id>
BlockTest
</contract-id>
<contract-state>
.Map
</contract-state>
<contract-init>
.List
</contract-init>
<contract-fns>
<contract-fn>
<contract-fn-id>
constructor
</contract-fn-id>
<contract-fn-visibility>
public
</contract-fn-visibility>
<contract-fn-arg-types>
.List
</contract-fn-arg-types>
<contract-fn-param-names>
.List
</contract-fn-param-names>
<contract-fn-return-types>
.List
</contract-fn-return-types>
<contract-fn-return-names>
.List
</contract-fn-return-names>
<contract-fn-body>
bool x = false ; { bool x = true ; require ( x , "" , .TypedVals ) ; .Statements } if ( x ) { require ( false , "" , .TypedVals ) ; .Statements } .Statements
</contract-fn-body>
</contract-fn>
</contract-fns>
<contract-events>
.ContractEventCellMap
</contract-events>
</contract>
</contracts>
<exec>
<msg-sender>
1p160
</msg-sender>
<msg-value>
0p256
</msg-value>
<tx-origin>
1p160
</tx-origin>
<this>
2p160
</this>
<this-type>
BlockTest
</this-type>
<env>
x |-> var ( 0 , bool )
</env>
<store>
0 |-> false
1 |-> true
</store>
<call-stack>
.List
</call-stack>
<live-contracts>
<live-contract>
<contract-address>
2p160
</contract-address>
<contract-type>
BlockTest
</contract-type>
<contract-storage>
.Map
</contract-storage>
</live-contract>
</live-contracts>
<events>
.List
</events>
<next-address>
3p160
</next-address>
</exec>
</solidity>
15 changes: 15 additions & 0 deletions test/regression/block.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity ^0.8.24;

contract BlockTest {

constructor() {
bool x = false;
{
bool x = true;
require(x, "");
}
if (x) {
require(false, "");
}
}
}
1 change: 1 addition & 0 deletions test/regression/block.txn
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create(1, 0, BlockTest, )
119 changes: 119 additions & 0 deletions test/regression/boolean.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<solidity>
<k>
.K
</k>
<current-body>
BoolTest
</current-body>
<ifaces>
.IfaceCellMap
</ifaces>
<contracts>
<contract>
<contract-id>
BoolTest
</contract-id>
<contract-state>
.Map
</contract-state>
<contract-init>
.List
</contract-init>
<contract-fns>
<contract-fn>
<contract-fn-id>
constructor
</contract-fn-id>
<contract-fn-visibility>
public
</contract-fn-visibility>
<contract-fn-arg-types>
.List
</contract-fn-arg-types>
<contract-fn-param-names>
.List
</contract-fn-param-names>
<contract-fn-return-types>
.List
</contract-fn-return-types>
<contract-fn-return-names>
.List
</contract-fn-return-names>
<contract-fn-body>
bool x = true ; if ( x || fail ( .TypedVals ) ) { .Statements } else { require ( false , "" , .TypedVals ) ; .Statements } if ( x && true ) { .Statements } else { require ( false , "" , .TypedVals ) ; .Statements } x = false ; if ( x && fail ( .TypedVals ) ) { require ( false , "" , .TypedVals ) ; .Statements } if ( x || true ) { .Statements } else { require ( false , "" , .TypedVals ) ; .Statements } .Statements
</contract-fn-body>
</contract-fn> <contract-fn>
<contract-fn-id>
fail
</contract-fn-id>
<contract-fn-visibility>
private
</contract-fn-visibility>
<contract-fn-arg-types>
.List
</contract-fn-arg-types>
<contract-fn-param-names>
.List
</contract-fn-param-names>
<contract-fn-return-types>
.List
</contract-fn-return-types>
<contract-fn-return-names>
.List
</contract-fn-return-names>
<contract-fn-body>
require ( false , "" , .TypedVals ) ; .Statements
</contract-fn-body>
</contract-fn>
</contract-fns>
<contract-events>
.ContractEventCellMap
</contract-events>
</contract>
</contracts>
<exec>
<msg-sender>
1p160
</msg-sender>
<msg-value>
0p256
</msg-value>
<tx-origin>
1p160
</tx-origin>
<this>
2p160
</this>
<this-type>
BoolTest
</this-type>
<env>
x |-> var ( 0 , bool )
</env>
<store>
0 |-> false
</store>
<call-stack>
.List
</call-stack>
<live-contracts>
<live-contract>
<contract-address>
2p160
</contract-address>
<contract-type>
BoolTest
</contract-type>
<contract-storage>
.Map
</contract-storage>
</live-contract>
</live-contracts>
<events>
.List
</events>
<next-address>
3p160
</next-address>
</exec>
</solidity>
28 changes: 28 additions & 0 deletions test/regression/boolean.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
pragma solidity ^0.8.24;

contract BoolTest {

function fail() private {
require(false, "");
}

constructor() {
bool x = true;
if (x || fail()) {
} else {
require(false, "");
}
if (x && true) {
} else {
require(false, "");
}
x = false;
if (x && fail()) {
require(false, "");
}
if (x || true) {
} else {
require(false, "");
}
}
}
1 change: 1 addition & 0 deletions test/regression/boolean.txn
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create(1, 0, BoolTest, )
Loading

0 comments on commit 5585171

Please sign in to comment.