From 283f1967431a5a6155be37bc6197c0ba204a1869 Mon Sep 17 00:00:00 2001 From: rostyslavtyshko <106978277+rostyslavtyshko@users.noreply.github.com> Date: Mon, 26 Sep 2022 18:21:24 +0200 Subject: [PATCH] Signed integers (#2340) i8, i16, i32, i64 Basic arithmetic operations and tests Closes #2422 Co-authored-by: tyshkor Co-authored-by: Joshua Batty Co-authored-by: Alex Hansen Co-authored-by: SwayStar123 <46050679+SwayStar123@users.noreply.github.com> Co-authored-by: Simon <46566889+simonr0204@users.noreply.github.com> --- sway-lib-std/src/i128.sw | 155 +++++++++++++++++ sway-lib-std/src/i16.sw | 151 +++++++++++++++++ sway-lib-std/src/i256.sw | 157 ++++++++++++++++++ sway-lib-std/src/i32.sw | 151 +++++++++++++++++ sway-lib-std/src/i64.sw | 151 +++++++++++++++++ sway-lib-std/src/i8.sw | 147 ++++++++++++++++ sway-lib-std/src/lib.sw | 6 + .../should_pass/stdlib/i128_test/.gitignore | 2 + .../should_pass/stdlib/i128_test/Forc.lock | 14 ++ .../should_pass/stdlib/i128_test/Forc.toml | 8 + .../should_pass/stdlib/i128_test/src/main.sw | 63 +++++++ .../should_pass/stdlib/i16_test/.gitignore | 2 + .../should_pass/stdlib/i16_test/Forc.lock | 14 ++ .../should_pass/stdlib/i16_test/Forc.toml | 8 + .../should_pass/stdlib/i16_test/src/main.sw | 27 +++ .../should_pass/stdlib/i256_test/.gitignore | 2 + .../should_pass/stdlib/i256_test/Forc.lock | 14 ++ .../should_pass/stdlib/i256_test/Forc.toml | 8 + .../should_pass/stdlib/i256_test/src/main.sw | 80 +++++++++ .../should_pass/stdlib/i32_test/.gitignore | 2 + .../should_pass/stdlib/i32_test/Forc.lock | 14 ++ .../should_pass/stdlib/i32_test/Forc.toml | 8 + .../should_pass/stdlib/i32_test/src/main.sw | 27 +++ .../should_pass/stdlib/i64_test/.gitignore | 2 + .../should_pass/stdlib/i64_test/Forc.lock | 14 ++ .../should_pass/stdlib/i64_test/Forc.toml | 8 + .../should_pass/stdlib/i64_test/src/main.sw | 27 +++ .../should_pass/stdlib/i8_test/.gitignore | 2 + .../should_pass/stdlib/i8_test/Forc.lock | 14 ++ .../should_pass/stdlib/i8_test/Forc.toml | 8 + .../should_pass/stdlib/i8_test/src/main.sw | 27 +++ 31 files changed, 1313 insertions(+) create mode 100644 sway-lib-std/src/i128.sw create mode 100644 sway-lib-std/src/i16.sw create mode 100644 sway-lib-std/src/i256.sw create mode 100644 sway-lib-std/src/i32.sw create mode 100644 sway-lib-std/src/i64.sw create mode 100644 sway-lib-std/src/i8.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/src/main.sw create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/.gitignore create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/src/main.sw diff --git a/sway-lib-std/src/i128.sw b/sway-lib-std/src/i128.sw new file mode 100644 index 00000000000..a23c84e790b --- /dev/null +++ b/sway-lib-std/src/i128.sw @@ -0,0 +1,155 @@ +library i128; + +use core::num::*; +use ::assert::assert; +use ::u128::U128; + +/// The 128-bit signed integer type. +/// Represented as an underlying U128 value. +/// Actual value is underlying value minus 2 ^ 127 +/// Max value is 2 ^ 127 - 1, min value is - 2 ^ 127 +pub struct I128 { + underlying: U128, +} + +pub trait From { + /// Function for creating I128 from U128 + fn from(underlying: U128) -> Self; +} + +impl From for I128 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: U128) -> Self { + Self { + underlying + } + } +} + +impl core::ops::Eq for I128 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I128 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I128 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> U128 { + U128 { + upper: 1, + lower: 0, + } + } +} + +impl I128 { + /// Initializes a new, zeroed I128. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~U128::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~U128::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 128 + } + + /// Helper function to get a negative value of unsigned number + pub fn neg_from(value: U128) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: U128) -> Self { + // as the minimal value of I128 is -~I128::indent() (1 << 63) we should add ~I128::indent() (1 << 63) + let underlying: U128 = value + ~Self::indent(); + Self { + underlying + } + } +} + +impl core::ops::Add for I128 { + /// Add a I128 to a I128. Panics on overflow. + fn add(self, other: Self) -> Self { + // subtract 1 << 63 to avoid double move + ~Self::from(self.underlying - ~Self::indent() + other.underlying) + } +} + +impl core::ops::Subtract for I128 { + /// Subtract a I128 from a I128. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + // add 1 << 63 to avoid loosing the move + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); + } else { + // subtract from 1 << 63 as we are getting a negative value + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); + } + res + } +} + +impl core::ops::Multiply for I128 { + /// Multiply a I128 with a I128. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && (other.underlying > ~Self::indent() || other.underlying == ~Self::indent()) { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && (other.underlying > ~Self::indent() || other.underlying == ~Self::indent()) { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I128 { + /// Divide a I128 by a I128. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying - ~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/i16.sw b/sway-lib-std/src/i16.sw new file mode 100644 index 00000000000..5b07345228f --- /dev/null +++ b/sway-lib-std/src/i16.sw @@ -0,0 +1,151 @@ +library i16; + +use core::num::*; +use ::assert::assert; + +/// The 16-bit signed integer type. +/// Represented as an underlying u16 value. +/// Actual value is underlying value minus 2 ^ 15 +/// Max value is 2 ^ 15 - 1, min value is - 2 ^ 15 +pub struct I16 { + underlying: u16, +} + +pub trait From { + /// Function for creating I16 from u16 + fn from(underlying: u16) -> Self; +} + +impl From for I16 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: u16) -> Self { + Self { + underlying + } + } +} + +impl core::ops::Eq for I16 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I16 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I16 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> u16 { + 32768u16 + } +} + +impl I16 { + /// Initializes a new, zeroed I16. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~u16::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~u16::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 16 + } + + /// Helper function to get a negative value of unsigned number + pub fn neg_from(value: u16) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: u16) -> Self { + // as the minimal value of I16 is -~I16::indent() (1 << 15) we should add ~I16::indent() (1 << 15) + let underlying: u16 = value + ~Self::indent(); + Self { + underlying + } + } +} + +impl core::ops::Add for I16 { + /// Add a I16 to a I16. Panics on overflow. + fn add(self, other: Self) -> Self { + // subtract 1 << 15 to avoid double move + ~Self::from(self.underlying - ~Self::indent() + other.underlying) + } +} + +impl core::ops::Subtract for I16 { + /// Subtract a I16 from a I16. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + // add 1 << 15 to avoid loosing the move + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); + } else { + // subtract from 1 << 15 as we are getting a negative value + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); + } + res + } +} + +impl core::ops::Multiply for I16 { + /// Multiply a I16 with a I16. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I16 { + /// Divide a I16 by a I16. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/i256.sw b/sway-lib-std/src/i256.sw new file mode 100644 index 00000000000..06cb74752ae --- /dev/null +++ b/sway-lib-std/src/i256.sw @@ -0,0 +1,157 @@ +library i256; + +use core::num::*; +use ::assert::assert; +use ::u256::U256; + +/// The 128-bit signed integer type. +/// Represented as an underlying U256 value. +/// Actual value is underlying value minus 2 ^ 255 +/// Max value is 2 ^ 255 - 1, min value is - 2 ^ 255 +pub struct I256 { + underlying: U256, +} + +pub trait From { + /// Function for creating I256 from U256 + fn from(underlying: U256) -> Self; +} + +impl From for I256 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: U256) -> Self { + Self { + underlying, + } + } +} + +impl core::ops::Eq for I256 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I256 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I256 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> U256 { + U256 { + a: 0, + b: 1, + c: 0, + d: 0, + } + } +} + +impl I256 { + /// Initializes a new, zeroed I256. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~U256::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~U256::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 128 + } + + /// Helper function to get a negative value of unsigned number + pub fn neg_from(value: U256) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: U256) -> Self { + // as the minimal value of I256 is -~I256::indent() (1 << 63) we should add ~I256::indent() (1 << 63) + let underlying: U256 = value + ~Self::indent(); + Self { + underlying + } + } +} + +impl core::ops::Add for I256 { + /// Add a I256 to a I256. Panics on overflow. + fn add(self, other: Self) -> Self { + // subtract 1 << 63 to avoid double move + ~Self::from(self.underlying - ~Self::indent() + other.underlying) + } +} + +impl core::ops::Subtract for I256 { + /// Subtract a I256 from a I256. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + // add 1 << 63 to avoid loosing the move + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); + } else { + // subtract from 1 << 63 as we are getting a negative value + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); + } + res + } +} + +impl core::ops::Multiply for I256 { + /// Multiply a I256 with a I256. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && (other.underlying > ~Self::indent() || other.underlying == ~Self::indent()) { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && (other.underlying > ~Self::indent() || other.underlying == ~Self::indent()) { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I256 { + /// Divide a I256 by a I256. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if (self.underlying > ~Self::indent() || self.underlying == ~Self::indent()) && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/i32.sw b/sway-lib-std/src/i32.sw new file mode 100644 index 00000000000..925ed17c4c7 --- /dev/null +++ b/sway-lib-std/src/i32.sw @@ -0,0 +1,151 @@ +library i32; + +use core::num::*; +use ::assert::assert; + +/// The 32-bit signed integer type. +/// Represented as an underlying u32 value. +/// Actual value is underlying value minus 2 ^ 31 +/// Max value is 2 ^ 31 - 1, min value is - 2 ^ 31 +pub struct I32 { + underlying: u32, +} + +pub trait From { + /// Function for creating I32 from u32 + fn from(underlying: u32) -> Self; +} + +impl From for I32 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: u32) -> Self { + Self { + underlying, + } + } +} + +impl core::ops::Eq for I32 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I32 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I32 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> u32 { + 2147483648u32 + } +} + +impl I32 { + /// Initializes a new, zeroed I32. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~u32::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~u32::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 32 + } + + /// Helper function to get a negative value of unsigned numbers + pub fn neg_from(value: u32) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: u32) -> Self { + // as the minimal value of I32 is 2147483648 (1 << 31) we should add ~I32::indent() (1 << 31) + let underlying: u32 = value + ~Self::indent(); + Self { + underlying + } + } +} + +impl core::ops::Add for I32 { + /// Add a I32 to a I32. Panics on overflow. + fn add(self, other: Self) -> Self { + // subtract 1 << 31 to avoid double move + ~Self::from(self.underlying - ~Self::indent() + other.underlying) + } +} + +impl core::ops::Subtract for I32 { + /// Subtract a I32 from a I32. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + // add 1 << 31 to avoid loosing the move + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); + } else { + // subtract from 1 << 31 as we are getting a negative value + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); + } + res + } +} + +impl core::ops::Multiply for I32 { + /// Multiply a I32 with a I32. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I32 { + /// Divide a I32 by a I32. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/i64.sw b/sway-lib-std/src/i64.sw new file mode 100644 index 00000000000..45db8449e28 --- /dev/null +++ b/sway-lib-std/src/i64.sw @@ -0,0 +1,151 @@ +library i64; + +use core::num::*; +use ::assert::assert; + +/// The 64-bit signed integer type. +/// Represented as an underlying u64 value. +/// Actual value is underlying value minus 2 ^ 63 +/// Max value is 2 ^ 63 - 1, min value is - 2 ^ 63 +pub struct I64 { + underlying: u64, +} + +pub trait From { + /// Function for creating I64 from u64 + fn from(underlying: u64) -> Self; +} + +impl From for I64 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: u64) -> Self { + Self { + underlying, + } + } +} + +impl core::ops::Eq for I64 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I64 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I64 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> u64 { + 9223372036854775808u64 + } +} + +impl I64 { + /// Initializes a new, zeroed I64. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~u64::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~u64::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 64 + } + + /// Helper function to get a negative value of unsigned number + pub fn neg_from(value: u64) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: u64) -> Self { + // as the minimal value of I64 is -~I64::indent() (1 << 63) we should add ~I64::indent() (1 << 63) + let underlying: u64 = value + ~Self::indent(); + Self { + underlying + } + } +} + +impl core::ops::Add for I64 { + /// Add a I64 to a I64. Panics on overflow. + fn add(self, other: Self) -> Self { + // subtract 1 << 63 to avoid double move + ~Self::from(self.underlying - ~Self::indent() + other.underlying) + } +} + +impl core::ops::Subtract for I64 { + /// Subtract a I64 from a I64. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + // add 1 << 63 to avoid loosing the move + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); + } else { + // subtract from 1 << 63 as we are getting a negative value + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); + } + res + } +} + +impl core::ops::Multiply for I64 { + /// Multiply a I64 with a I64. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I64 { + /// Divide a I64 by a I64. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/i8.sw b/sway-lib-std/src/i8.sw new file mode 100644 index 00000000000..adf53bcdde5 --- /dev/null +++ b/sway-lib-std/src/i8.sw @@ -0,0 +1,147 @@ +library i8; + +use core::num::*; +use ::assert::assert; + +/// The 8-bit signed integer type. +/// Represented as an underlying u8 value. +/// Actual value is underlying value minus 2 ^ 7 +/// Max value is 2 ^ 7 - 1, min value is - 2 ^ 7 +pub struct I8 { + underlying: u8, +} + +pub trait From { + /// Function for creating I8 from u8 + fn from(underlying: u8) -> Self; +} + +impl From for I8 { + /// Helper function to get a signed number from with an underlying + fn from(underlying: u8) -> Self { + Self { + underlying + } + } +} + +impl core::ops::Eq for I8 { + fn eq(self, other: Self) -> bool { + self.underlying == other.underlying + } +} + +impl core::ops::Ord for I8 { + fn gt(self, other: Self) -> bool { + self.underlying > other.underlying + } + + fn lt(self, other: Self) -> bool { + self.underlying < other.underlying + } +} + +impl I8 { + /// The underlying value that corresponds to zero signed value + pub fn indent() -> u8 { + 128u8 + } +} + +impl I8 { + /// Initializes a new, zeroed I8. + pub fn new() -> Self { + Self { + underlying: ~Self::indent(), + } + } + + /// The smallest value that can be represented by this integer type. + pub fn min() -> Self { + Self { + underlying: ~u8::min(), + } + } + + /// The largest value that can be represented by this type, + pub fn max() -> Self { + Self { + underlying: ~u8::max(), + } + } + + /// The size of this type in bits. + pub fn bits() -> u32 { + 8 + } + + /// Helper function to get a negative value of unsigned number + pub fn neg_from(value: u8) -> Self { + Self { + underlying: ~Self::indent() - value, + } + } + + /// Helper function to get a positive value from unsigned number + fn from_uint(value: u8) -> Self { + let underlying: u8 = value + ~Self::indent(); // as the minimal value of I8 is -~I8::indent() (1 << 7) we should add ~I8::indent() (1 << 7) + Self { + underlying + } + } +} + +impl core::ops::Add for I8 { + /// Add a I8 to a I8. Panics on overflow. + fn add(self, other: Self) -> Self { + ~Self::from(self.underlying - ~Self::indent() + other.underlying) // subtract 1 << 7 to avoid double move + } +} + +impl core::ops::Subtract for I8 { + /// Subtract a I8 from a I8. Panics of overflow. + fn subtract(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self > other { + res = ~Self::from(self.underlying - other.underlying + ~Self::indent()); // add 1 << 7 to avoid loosing the move + } else { + res = ~Self::from(~Self::indent() - (other.underlying - self.underlying)); // subtract from 1 << 7 as we are getting a negative value + } + res + } +} + +impl core::ops::Multiply for I8 { + /// Multiply a I8 with a I8. Panics of overflow. + fn multiply(self, other: Self) -> Self { + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) * (other.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) * (~Self::indent() - other.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && other.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) * (~Self::indent() - other.underlying)); + } else if self.underlying < ~Self::indent() && other.underlying >= ~Self::indent() { + res = ~Self::from(~Self::indent() - (other.underlying - ~Self::indent()) * (~Self::indent() - self.underlying)); + } + res + } +} + +impl core::ops::Divide for I8 { + /// Divide a I8 by a I8. Panics if divisor is zero. + fn divide(self, divisor: Self) -> Self { + assert(divisor != ~Self::new()); + let mut res = ~Self::new(); + if self.underlying >= ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from((self.underlying - ~Self::indent()) / (divisor.underlying -~Self::indent()) + ~Self::indent()); + } else if self.underlying < ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from((~Self::indent() - self.underlying) / (~Self::indent() - divisor.underlying) + ~Self::indent()); + } else if self.underlying >= ~Self::indent() && divisor.underlying < ~Self::indent() { + res = ~Self::from(~Self::indent() - (self.underlying - ~Self::indent()) / (~Self::indent() - divisor.underlying)); + } else if self.underlying < ~Self::indent() && divisor.underlying > ~Self::indent() { + res = ~Self::from(~Self::indent() - (~Self::indent() - self.underlying) / (divisor.underlying - ~Self::indent())); + } + res + } +} diff --git a/sway-lib-std/src/lib.sw b/sway-lib-std/src/lib.sw index bf177bbf91d..5f84e88bca8 100644 --- a/sway-lib-std/src/lib.sw +++ b/sway-lib-std/src/lib.sw @@ -30,6 +30,12 @@ dep flags; dep u128; dep u256; dep vec; +dep i8; +dep i16; +dep i32; +dep i64; +dep i128; +dep i256; dep prelude; use core::*; diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.lock new file mode 100644 index 00000000000..2f36026c6a9 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-5340E4F7C2F2C9E9' +dependencies = [] + +[[package]] +name = 'i128_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-5340E4F7C2F2C9E9' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.toml new file mode 100644 index 00000000000..55510d018c4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i128_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/src/main.sw new file mode 100644 index 00000000000..b041ad76e4f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i128_test/src/main.sw @@ -0,0 +1,63 @@ +script; + +use std::assert::assert; +use std::i128::I128; +use std::u128::U128; + +fn main() -> bool { + let u128_one = U128 { + upper: 0, + lower: 1, + }; + let u128_two = U128 { + upper: 0, + lower: 2, + }; + let one = ~I128::from_uint(u128_one); + let mut res = one + ~I128::from_uint(u128_one); + assert(res == ~I128::from_uint(u128_two)); + + let u128_10 = U128 { + upper: 0, + lower: 10, + }; + let u128_11 = U128 { + upper: 0, + lower: 11, + }; + res = ~I128::from_uint(u128_10) - ~I128::from_uint(u128_11); + assert(res.underlying.lower == ~u64::max()); + + res = ~I128::from_uint(u128_10) * ~I128::neg_from(u128_one); + assert(res == ~I128::neg_from(u128_10)); + + res = ~I128::from_uint(u128_10) * ~I128::from_uint(u128_10); + let u128_100 = U128 { + upper: 0, + lower: 100, + }; + assert(res == ~I128::from_uint(u128_100)); + + let u128_lower_max_u64 = U128 { + upper: 0, + lower: ~u64::max(), + }; + + res = ~I128::from_uint(u128_10) / ~I128::from(u128_lower_max_u64); + assert(res == ~I128::neg_from(u128_10)); + + let u128_5 = U128 { + upper: 0, + lower: 5, + }; + + let u128_2 = U128 { + upper: 0, + lower: 2, + }; + + res = ~I128::from_uint(u128_10) / ~I128::from_uint(u128_5); + assert(res == ~I128::from_uint(u128_2)); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.lock new file mode 100644 index 00000000000..ca36fb044bf --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-130E360D4B6E1F73' +dependencies = [] + +[[package]] +name = 'i16_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-130E360D4B6E1F73' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.toml new file mode 100644 index 00000000000..3831f378bae --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i16_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/src/main.sw new file mode 100644 index 00000000000..b3d697abe78 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i16_test/src/main.sw @@ -0,0 +1,27 @@ +script; + +use std::assert::assert; +use std::I16; + +fn main() -> bool { + let one = ~I16::from_uint(1u16); + let mut res = one + ~I16::from_uint(1u16); + assert(res == ~I16::from_uint(2u16)); + + res = ~I16::from_uint(10u16) - ~I16::from_uint(11u16); + assert(res == ~I16::from(32767u16)); + + res = ~I16::from_uint(10u16) * ~I16::neg_from(1u16); + assert(res == ~I16::neg_from(10u16)); + + res = ~I16::from_uint(10u16) * ~I16::from_uint(10u16); + assert(res == ~I16::from_uint(100u16)); + + res = ~I16::from_uint(10u16) / ~I16::neg_from(1u16); + assert(res == ~I16::neg_from(10u16)); + + res = ~I16::from_uint(10u16) / ~I16::from_uint(5u16); + assert(res == ~I16::from_uint(2u16)); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.lock new file mode 100644 index 00000000000..b7f352788bb --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-781D3A422BF1D5DF' +dependencies = [] + +[[package]] +name = 'i256_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-781D3A422BF1D5DF' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.toml new file mode 100644 index 00000000000..5931bf38dd5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i256_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/src/main.sw new file mode 100644 index 00000000000..76148b1d47c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i256_test/src/main.sw @@ -0,0 +1,80 @@ +script; + +use std::assert::assert; +use std::i256::I256; +use std::u256::U256; + +fn main() -> bool { + let u128_one = U256 { + a: 0, + b: 0, + c: 0, + d: 1, + }; + let u128_two = U256 { + a: 0, + b: 0, + c: 0, + d: 2, + }; + let one = ~I256::from_uint(u128_one); + let mut res = one + ~I256::from_uint(u128_one); + assert(res == ~I256::from_uint(u128_two)); + + let u128_10 = U256 { + a: 0, + b: 0, + c: 0, + d: 10, + }; + let u128_11 = U256 { + a: 0, + b: 0, + c: 0, + d: 11, + }; + res = ~I256::from_uint(u128_10) - ~I256::from_uint(u128_11); + assert(res.underlying.c == ~u64::max()); + assert(res.underlying.d == ~u64::max()); + + res = ~I256::from_uint(u128_10) * ~I256::neg_from(u128_one); + assert(res == ~I256::neg_from(u128_10)); + + res = ~I256::from_uint(u128_10) * ~I256::from_uint(u128_10); + let u128_100 = U256 { + a: 0, + b: 0, + c: 0, + d: 100, + }; + assert(res == ~I256::from_uint(u128_100)); + + let u128_lower_max_u64 = U256 { + a: 0, + b: 0, + c: 0, + d: ~u64::max(), + }; + + res = ~I256::from_uint(u128_10) / ~I256::from(u128_lower_max_u64); + assert(res == ~I256::neg_from(u128_10)); + + let u128_5 = U256 { + a: 0, + b: 0, + c: 0, + d: 5, + }; + + let u128_2 = U256 { + a: 0, + b: 0, + c: 0, + d: 2, + }; + + res = ~I256::from_uint(u128_10) / ~I256::from_uint(u128_5); + assert(res == ~I256::from_uint(u128_2)); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.lock new file mode 100644 index 00000000000..4e55e556d71 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-887228D59D9D7BA9' +dependencies = [] + +[[package]] +name = 'i32_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-887228D59D9D7BA9' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.toml new file mode 100644 index 00000000000..2441339a92f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i32_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/src/main.sw new file mode 100644 index 00000000000..108428f3f45 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i32_test/src/main.sw @@ -0,0 +1,27 @@ +script; + +use std::assert::assert; +use std::I32; + +fn main() -> bool { + let one = ~I32::from_uint(1u32); + let mut res = one + ~I32::from_uint(1u32); + assert(res == ~I32::from_uint(2u32)); + + res = ~I32::from_uint(10u32) - ~I32::from_uint(11u32); + assert(res == ~I32::from(2147483647u32)); + + res = ~I32::from_uint(10u32) * ~I32::neg_from(1u32); + assert(res == ~I32::neg_from(10u32)); + + res = ~I32::from_uint(10u32) * ~I32::from_uint(10u32); + assert(res == ~I32::from_uint(100u32)); + + res = ~I32::from_uint(10u32) / ~I32::neg_from(1u32); + assert(res == ~I32::neg_from(10u32)); + + res = ~I32::from_uint(10u32) / ~I32::from_uint(5u32); + assert(res == ~I32::from_uint(2u32)); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.lock new file mode 100644 index 00000000000..e5e76bee359 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-65D447ACE1F6E7E8' +dependencies = [] + +[[package]] +name = 'i64_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-65D447ACE1F6E7E8' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.toml new file mode 100644 index 00000000000..f21cc61789b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i64_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/src/main.sw new file mode 100644 index 00000000000..4daebec1cab --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i64_test/src/main.sw @@ -0,0 +1,27 @@ +script; + +use std::assert::assert; +use std::I64; + +fn main() -> bool { + let one = ~I64::from_uint(1u64); + let mut res = one + ~I64::from_uint(1u64); + assert(res == ~I64::from_uint(2u64)); + + res = ~I64::from_uint(10u64) - ~I64::from_uint(11u64); + assert(res == ~I64::from(9223372036854775807u64)); + + res = ~I64::from_uint(10u64) * ~I64::neg_from(1); + assert(res == ~I64::neg_from(10)); + + res = ~I64::from_uint(10u64) * ~I64::from_uint(10u64); + assert(res == ~I64::from_uint(100u64)); + + res = ~I64::from_uint(10u64) / ~I64::from(9223372036854775807u64); + assert(res == ~I64::neg_from(10u64)); + + res = ~I64::from_uint(10u64) / ~I64::from_uint(5u64); + assert(res == ~I64::from_uint(2u64)); + + true +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/.gitignore b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/.gitignore new file mode 100644 index 00000000000..77d3844f58c --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.lock new file mode 100644 index 00000000000..aaf9b5cab6f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'core' +source = 'path+from-root-7D40F5FAFA1A828E' +dependencies = [] + +[[package]] +name = 'i8_test' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'std' +source = 'path+from-root-7D40F5FAFA1A828E' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.toml new file mode 100644 index 00000000000..b81add92e83 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "i8_test" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/src/main.sw new file mode 100644 index 00000000000..e673e72a6ed --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/stdlib/i8_test/src/main.sw @@ -0,0 +1,27 @@ +script; + +use std::assert::assert; +use std::I8; + +fn main() -> bool { + let one = ~I8::from_uint(1u8); + let mut res = one + ~I8::from_uint(1u8); + assert(res == ~I8::from_uint(2u8)); + + res = ~I8::from_uint(10u8) - ~I8::from_uint(11u8); + assert(res == ~I8::from(127u8)); + + res = ~I8::from_uint(10u8) * ~I8::from(127u8); + assert(res == ~I8::from(118u8)); + + res = ~I8::from_uint(10u8) * ~I8::from_uint(10u8); + assert(res == ~I8::from_uint(100u8)); + + res = ~I8::from_uint(10u8) / ~I8::from(127u8); + assert(res == ~I8::from(118u8)); + + res = ~I8::from_uint(10u8) / ~I8::from_uint(5u8); + assert(res == ~I8::from_uint(2u8)); + + true +}