-
Notifications
You must be signed in to change notification settings - Fork 2
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
For and While Loops #88
Changes from 13 commits
326883e
184da55
dd9e5ed
3328947
57e4d7f
5bc1f42
89450c6
b81f9d6
4aedc14
1b80f3e
3260cac
a9b7172
0fe1c0d
12844f6
324f966
077e603
a85fc04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
```k | ||
|
||
module RUST-LOOP-EXPRESSIONS | ||
imports RUST-REPRESENTATION | ||
|
||
syntax IteratorLoopExpression ::= "for1" Pattern "limit" PtrValue BlockExpression | ||
| "for2" Pattern "limit" PtrValue BlockExpression | ||
|
||
rule for Patt:Identifier:PatternNoTopAlt | R:PatternNoTopAlts in ptrValue(_, intRange(First, Last)) B:BlockExpression => | ||
{ | ||
.InnerAttributes | ||
let Patt = ptrValue(null, First); | ||
(for1 Patt | R limit ptrValue(null, Last) B):IteratorLoopExpression; | ||
.NonEmptyStatements | ||
}; | ||
requires checkIntOfSameType(First, Last) | ||
|
||
rule for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B:BlockExpression => | ||
if (Patt :: .PathExprSegments):PathExprSegments < Last { .InnerAttributes B; (for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B):IteratorLoopExpression; .NonEmptyStatements}; | ||
|
||
rule for2 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit ptrValue(_, LastValue) #as Last B:BlockExpression => | ||
incrementPatt(Patt, LastValue) | ||
~> for1 Patt:Identifier:PatternNoTopAlt | .PatternNoTopAlts limit Last B | ||
|
||
rule while (E:ExpressionExceptStructExpression) S:BlockExpression => if E { .InnerAttributes S; while(E)S; .NonEmptyStatements}; | ||
|
||
|
||
// Necessary for handling all possible integer types provided in the range expression of for loops | ||
syntax LetStatement ::= incrementPatt(Identifier, Value) [function] | ||
|
||
rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => | ||
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, i32(Int2MInt(1:Int))); | ||
requires checkIntOfType(ComparisonValue, i32) | ||
rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => | ||
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, u32(Int2MInt(1:Int))); | ||
requires checkIntOfType(ComparisonValue, u32) | ||
rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => | ||
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, u64(Int2MInt(1:Int))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm... This is interesting... Right now, we have defined addition only between ints of the same kind, and I think that Rust does not allow adding ints of different types, e.g.
|
||
requires checkIntOfType(ComparisonValue, u64) | ||
rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => | ||
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, i64(Int2MInt(1:Int))); | ||
requires checkIntOfType(ComparisonValue, i64) | ||
rule incrementPatt(Patt:Identifier, ComparisonValue:Value) => | ||
let Patt = (Patt :: .PathExprSegments):PathExprSegments + ptrValue(null, u128(Int2MInt(1:Int))); | ||
requires checkIntOfType(ComparisonValue, u128) | ||
|
||
|
||
endmodule | ||
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
new LoopExpressions; | ||
call LoopExpressions.iterator_evaluation |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
new LoopExpressions; | ||
call LoopExpressions.while_evaluation |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
new LoopExpressions; | ||
call LoopExpressions.iterator_with_variables |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
new LoopExpressions; | ||
call LoopExpressions.iterator_with_same_pattern |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#![no_std] | ||
|
||
#[allow(unused_imports)] | ||
use multiversx_sc::imports::*; | ||
|
||
#[multiversx_sc::contract] | ||
pub trait LoopExpressions { | ||
#[init] | ||
fn init(&self) { | ||
} | ||
|
||
#[upgrade] | ||
fn upgrade(&self) {} | ||
|
||
fn iterator_evaluation(&self){ | ||
for i in 1_u64..10_u64 { | ||
let x = i * 2_u64; | ||
}; | ||
} | ||
|
||
fn while_evaluation(&self){ | ||
while 1_u64 < 1_u64 { | ||
let x: u64 = 2_u64; | ||
}; | ||
} | ||
|
||
fn iterator_with_variables(&self) { | ||
let y = 20_u64; | ||
let z = 10_u64; | ||
|
||
for i in z..y { | ||
let x = i * 2_u64; | ||
}; | ||
} | ||
|
||
fn iterator_with_same_pattern(&self) { | ||
let i = 1_u64; | ||
for i in i..i+3_u64 { | ||
let x = i * 2_u64; | ||
}; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would split this into multiple lines.
Also, you can probably inline the "for2" rule below if you want.