Skip to content

Commit

Permalink
typed expressions support for u256
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj committed Jul 14, 2023
1 parent a5c4df4 commit dbdcc9d
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 130 deletions.
4 changes: 4 additions & 0 deletions sway-core/src/abi_generation/evm_json_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ pub fn json_abi_str(
IntegerBits::Sixteen => "uint16",
IntegerBits::ThirtyTwo => "uint32",
IntegerBits::SixtyFour => "uint64",
IntegerBits::V128 => todo!(),
IntegerBits::V256 => todo!(),
}
.into(),
Boolean => "bool".into(),
Expand Down Expand Up @@ -159,6 +161,8 @@ pub fn json_abi_param_type(
IntegerBits::Sixteen => ethabi::ParamType::Uint(16),
IntegerBits::ThirtyTwo => ethabi::ParamType::Uint(32),
IntegerBits::SixtyFour => ethabi::ParamType::Uint(64),
IntegerBits::V128 => todo!(),
IntegerBits::V256 => todo!(),
},
Boolean => ethabi::ParamType::Bool,
B256 => ethabi::ParamType::Uint(256),
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/abi_generation/fuel_json_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,8 @@ impl TypeInfo {
IntegerBits::Sixteen => "u16",
IntegerBits::ThirtyTwo => "u32",
IntegerBits::SixtyFour => "u64",
IntegerBits::V128 => todo!(),
IntegerBits::V256 => todo!(),
}
.into(),
Boolean => "bool".into(),
Expand Down
12 changes: 10 additions & 2 deletions sway-core/src/ir_generation/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ pub(super) fn convert_literal_to_value(context: &mut Context, ast_literal: &Lite
Literal::U64(n) => Constant::get_uint(context, 64, *n),
Literal::U128(_) => todo!(),
Literal::U256(_) => todo!(),
Literal::Numeric(n) => Constant::get_uint(context, 64, *n),
//TODO remove unwrap()
Literal::Numeric(n) => {
let n = n.try_into().unwrap();
Constant::get_uint(context, 64, n)
}
Literal::String(s) => Constant::get_string(context, s.as_str().as_bytes().to_vec()),
Literal::Boolean(b) => Constant::get_bool(context, *b),
Literal::B256(bs) => Constant::get_b256(context, *bs),
Expand All @@ -46,7 +50,11 @@ pub(super) fn convert_literal_to_constant(
Literal::U64(n) => Constant::new_uint(context, 64, *n),
Literal::U128(_) => todo!(),
Literal::U256(_) => todo!(),
Literal::Numeric(n) => Constant::new_uint(context, 64, *n),
//TODO remove unwrap()
Literal::Numeric(n) => {
let n = n.try_into().unwrap();
Constant::new_uint(context, 64, n)
}
Literal::String(s) => Constant::new_string(context, s.as_str().as_bytes().to_vec()),
Literal::Boolean(b) => Constant::new_bool(context, *b),
Literal::B256(bs) => Constant::new_b256(context, *bs),
Expand Down
59 changes: 52 additions & 7 deletions sway-core/src/language/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,64 @@ use sway_types::{integer_bits::IntegerBits, span};
use std::{
fmt,
hash::{Hash, Hasher},
num::{IntErrorKind, ParseIntError},
num::IntErrorKind,
};

#[derive(Debug, Clone, Eq)]
pub struct U256 {
value: BigUint,
}

impl PartialEq for U256 {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}

impl U256 {
pub fn min() -> U256 {
let value = BigUint::from_bytes_le(&[0]);
U256 { value }
}

pub fn max() -> U256 {
let value = BigUint::from_bytes_le(&[255; 32]);
U256 { value }
}
}

impl TryFrom<BigUint> for U256 {
type Error = IntErrorKind;

fn try_from(value: BigUint) -> Result<Self, Self::Error> {
let mut bytes = value.to_bytes_le();

// Normalize removing zeros from the most signicants positions
if let Some(&0) = bytes.last() {
let len = bytes.iter().rposition(|&d| d != 0).map_or(0, |i| i + 1);
bytes.truncate(len);
}

if bytes.len() <= 32 {
Ok(U256 {
value: BigUint::from_bytes_le(&bytes),
})
} else {
Err(IntErrorKind::PosOverflow)
}
}
}

#[derive(Debug, Clone, Eq)]
pub enum Literal {
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
U256(BigUint),
U256(U256),
String(span::Span),
Numeric(u64),
Numeric(BigUint),
Boolean(bool),
B256([u8; 32]),
}
Expand Down Expand Up @@ -110,11 +155,11 @@ impl Literal {
#[allow(clippy::wildcard_in_or_patterns)]
pub(crate) fn handle_parse_int_error(
engines: &Engines,
e: ParseIntError,
e: &IntErrorKind,
ty: TypeInfo,
span: sway_types::Span,
) -> CompileError {
match e.kind() {
match e {
IntErrorKind::PosOverflow => CompileError::IntegerTooLarge {
ty: engines.help_out(ty).to_string(),
span,
Expand All @@ -141,8 +186,8 @@ impl Literal {
Literal::U16(_) => TypeInfo::UnsignedInteger(IntegerBits::Sixteen),
Literal::U32(_) => TypeInfo::UnsignedInteger(IntegerBits::ThirtyTwo),
Literal::U64(_) => TypeInfo::UnsignedInteger(IntegerBits::SixtyFour),
Literal::U128(_) => todo!(),
Literal::U256(_) => todo!(),
Literal::U128(_) => TypeInfo::UnsignedInteger(IntegerBits::V128),
Literal::U256(_) => TypeInfo::UnsignedInteger(IntegerBits::V256),
Literal::Boolean(_) => TypeInfo::Boolean,
Literal::B256(_) => TypeInfo::B256,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub(crate) enum Pattern {
U64(Range<u64>),
B256([u8; 32]),
Boolean(bool),
//TODO needs to support u256
Numeric(Range<u64>),
String(String),
Struct(StructPattern),
Expand Down Expand Up @@ -198,7 +199,12 @@ impl Pattern {
Literal::U256(_) => todo!(),
Literal::B256(x) => Pattern::B256(x),
Literal::Boolean(b) => Pattern::Boolean(b),
Literal::Numeric(x) => Pattern::Numeric(Range::from_single(x)),
//TODO needs to support u256
//TODO remove unwrap()
Literal::Numeric(x) => {
let num = x.try_into().unwrap();
Pattern::Numeric(Range::from_single(num))
}
Literal::String(s) => Pattern::String(s.as_str().to_string()),
}
}
Expand Down
Loading

0 comments on commit dbdcc9d

Please sign in to comment.