Skip to content

Commit

Permalink
Support += and other similar operators for storage accesses (#1970)
Browse files Browse the repository at this point in the history
Allow += and similar operators for storage accesses
  • Loading branch information
mohammadfawaz authored Jun 17, 2022
1 parent 9791173 commit 3a2e719
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 6 deletions.
35 changes: 30 additions & 5 deletions sway-core/src/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2864,11 +2864,36 @@ fn assignable_to_expression(
index: Box::new(expr_to_expression(ec, *arg.into_inner())?),
span,
},
Assignable::FieldProjection { target, name, .. } => Expression::SubfieldExpression {
prefix: Box::new(assignable_to_expression(ec, *target)?),
field_to_access: name,
span,
},
Assignable::FieldProjection { target, name, .. } => {
let mut idents = vec![&name];
let mut base = &*target;
let storage_access_field_names_opt = loop {
match base {
Assignable::FieldProjection { target, name, .. } => {
idents.push(name);
base = target;
}
Assignable::Var(name) => {
if name.as_str() == "storage" {
break Some(idents);
}
break None;
}
_ => break None,
}
};
match storage_access_field_names_opt {
Some(field_names) => {
let field_names = field_names.into_iter().rev().cloned().collect();
Expression::StorageAccess { field_names, span }
}
None => Expression::SubfieldExpression {
prefix: Box::new(assignable_to_expression(ec, *target)?),
field_to_access: name,
span,
},
}
}
Assignable::TupleFieldProjection {
target,
field,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use storage_access_abi::*;
use std::{assert::assert, hash::sha256};

fn main() -> bool {
let contract_id = 0xe9f125e3327a56e071b6063f16b0d290b6ce05ff6744dea9aeced5a035a5f121;
let contract_id = 0x41b881e842026ed4f607156ddc0f98866944c4c67478ededb48932c578ddd52c;
let caller = abi(StorageAccess, contract_id);

// Test 1
Expand Down Expand Up @@ -118,6 +118,25 @@ fn main() -> bool {
assert(t.y == 12);
assert(t.z == 0x0000000000000000000000000000000000000000000000000000000000000006);

// Test operations on `s.t.x`
caller.add_to_s_dot_t_dot_x(15);
assert(caller.get_s_dot_t_dot_x() == 26); // 11 + 15

caller.subtract_from_s_dot_t_dot_x(6);
assert(caller.get_s_dot_t_dot_x() == 20); // 26 - 6

caller.multiply_by_s_dot_t_dot_x(5);
assert(caller.get_s_dot_t_dot_x() == 100); // 20 * 5

caller.divide_s_dot_t_dot_x(2);
assert(caller.get_s_dot_t_dot_x() == 50); // 100 / 2

caller.shift_left_s_dot_t_dot_x(3);
assert(caller.get_s_dot_t_dot_x() == 400); // 50 << 3

caller.shift_right_s_dot_t_dot_x(2);
assert(caller.get_s_dot_t_dot_x() == 100); // 400 >> 2

// Test 13
caller.set_e(E::A(42));
let e = caller.get_e();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,18 @@ abi StorageAccess {
fn get_e() -> E;
#[storage(read)]
fn get_string() -> str[40];

// Operations
#[storage(read, write)]
fn add_to_s_dot_t_dot_x(k: u64);
#[storage(read, write)]
fn subtract_from_s_dot_t_dot_x(k: u64);
#[storage(read, write)]
fn multiply_by_s_dot_t_dot_x(k: u64);
#[storage(read, write)]
fn divide_s_dot_t_dot_x(k: u64);
#[storage(read, write)]
fn shift_left_s_dot_t_dot_x(k: u64);
#[storage(read, write)]
fn shift_right_s_dot_t_dot_x(k: u64);
}
Original file line number Diff line number Diff line change
Expand Up @@ -878,5 +878,113 @@
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "add_to_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "subtract_from_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "multiply_by_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "divide_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "shift_left_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
},
{
"inputs": [
{
"components": null,
"name": "k",
"type": "u64"
}
],
"name": "shift_right_s_dot_t_dot_x",
"outputs": [
{
"components": [],
"name": "",
"type": "()"
}
],
"type": "function"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,30 @@ impl StorageAccess for Contract {
fn get_string() -> str[40] {
storage.string
}

// Operations
#[storage(read, write)]
fn add_to_s_dot_t_dot_x(k: u64) {
storage.s.t.x += k;
}
#[storage(read, write)]
fn subtract_from_s_dot_t_dot_x(k: u64) {
storage.s.t.x -= k;
}
#[storage(read, write)]
fn multiply_by_s_dot_t_dot_x(k: u64) {
storage.s.t.x *= k;
}
#[storage(read, write)]
fn divide_s_dot_t_dot_x(k: u64) {
storage.s.t.x /= k;
}
#[storage(read, write)]
fn shift_left_s_dot_t_dot_x(k: u64) {
storage.s.t.x <<= k;
}
#[storage(read, write)]
fn shift_right_s_dot_t_dot_x(k: u64) {
storage.s.t.x >>= k;
}
}

0 comments on commit 3a2e719

Please sign in to comment.