From 6c43c604b84fb70953dc75861bf70cb440381319 Mon Sep 17 00:00:00 2001 From: Mark <> Date: Wed, 2 Oct 2024 02:36:15 +0200 Subject: [PATCH] improve ints in .try --- mers/Cargo.toml | 4 ++-- mers_lib/Cargo.toml | 2 +- mers_lib/src/data/int.rs | 27 ++++++++++++++++----------- mers_lib/src/data/mod.rs | 24 +++++++++++++++++------- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/mers/Cargo.toml b/mers/Cargo.toml index 35dc740..c01bad3 100644 --- a/mers/Cargo.toml +++ b/mers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers" -version = "0.9.4" +version = "0.9.5" edition = "2021" license = "MIT OR Apache-2.0" description = "dynamically typed but type-checked programming language" @@ -15,7 +15,7 @@ default = ["colored-output"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"] [dependencies] -mers_lib = "0.9.4" +mers_lib = "0.9.5" # mers_lib = { path = "../mers_lib" } clap = { version = "4.3.19", features = ["derive"] } colored = { version = "2.1.0", optional = true } diff --git a/mers_lib/Cargo.toml b/mers_lib/Cargo.toml index a672730..5e5df41 100755 --- a/mers_lib/Cargo.toml +++ b/mers_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mers_lib" -version = "0.9.4" +version = "0.9.5" edition = "2021" license = "MIT OR Apache-2.0" description = "library to use the mers language in other projects" diff --git a/mers_lib/src/data/int.rs b/mers_lib/src/data/int.rs index e908df7..b448c0e 100755 --- a/mers_lib/src/data/int.rs +++ b/mers_lib/src/data/int.rs @@ -6,11 +6,11 @@ use super::{MersData, MersType, Type}; /// The smallest representable integer. /// Depends on the system for which mers is being compiled, as mers uses pointer-sized signed integers. -/// `-2^W`, `W` is the bit-width of a pointer on the system, often `32` or `64`. +/// `-2^W`, `W` is the bit-width of a pointer on the system, often `32` or `64`, minus one. pub const INT_MIN: isize = isize::MIN; /// The largest representable integer. /// Depends on the system for which mers is being compiled, as mers uses pointer-sized signed integers. -/// `2^W-1`, `W` is the bit-width of a pointer on the system, often `32` or `64`. +/// `2^W-1`, `W` is the bit-width of a pointer on the system, often `32` or `64`, minus one. pub const INT_MAX: isize = isize::MAX; /// The smallest integer representable by mers and by a signed 32-bit number. /// `max(INT_MIN, -2^31)` @@ -97,21 +97,26 @@ impl MersType for IntT { } } fn subtypes(&self, acc: &mut Type) { - acc.add(Arc::new(self.clone())); - // INT_MIN .. INT32U_MIN .. INT32S_MIN .. 0 .. INT32S_MAX .. INT32U_MAX .. INT_MAX + // INT_MIN .. INT32U_MIN .. INT32S_MIN .. -128 .. -1 .. 0 .. 1 .. 127 .. 255 .. 65535 .. INT32S_MAX .. INT32U_MAX .. INT_MAX let mut add_range = |min, max| { // the range is non-empty, self starts before or where the range ends, and self ends after or where the range starts. - if min <= max && self.0 <= max && self.1 >= min { + if min <= max && self.0 <= max && min <= self.1 { acc.add(Arc::new(IntT(self.0.max(min), self.1.min(max)))); } }; - add_range(INT_MIN, INT32U_MIN - 1); - add_range(INT32U_MIN, INT32S_MIN - 1); - add_range(INT32S_MIN, -1); + add_range(INT_MIN, INT32U_MIN.saturating_sub(1)); + add_range(INT32U_MIN, INT32S_MIN.saturating_sub(1)); + add_range(INT32S_MIN, -129); + add_range(-128, -2); + add_range(-1, -1); add_range(0, 0); - add_range(1, INT32S_MAX); - add_range(INT32S_MAX + 1, INT32U_MAX); - add_range(INT32U_MAX + 1, INT_MAX); + add_range(1, 1); + add_range(2, 127); + add_range(128, 255); + add_range(256, 65535); + add_range(65536, INT32S_MAX); + add_range(INT32S_MAX.saturating_add(1), INT32U_MAX); + add_range(INT32U_MAX.saturating_add(1), INT_MAX); } fn as_any(&self) -> &dyn Any { self diff --git a/mers_lib/src/data/mod.rs b/mers_lib/src/data/mod.rs index 198d622..7757e40 100755 --- a/mers_lib/src/data/mod.rs +++ b/mers_lib/src/data/mod.rs @@ -340,18 +340,26 @@ pub struct Type { // TODO: Maybe make sure this is always sorted by (recursive?!?) TypeId, // that way is_same_type_as can work more efficiently (cuz good code but also branch prediction) pub types: Vec>, + pub smart_type_simplification: bool, } impl Type { pub fn new(t: T) -> Self { Self { types: vec![Arc::new(t)], + smart_type_simplification: true, } } pub fn newm(types: Vec>) -> Self { - Self { types } + Self { + types, + smart_type_simplification: true, + } } pub fn empty() -> Self { - Self { types: vec![] } + Self { + types: vec![], + smart_type_simplification: true, + } } pub fn empty_tuple() -> Self { Self::new(tuple::TupleT(vec![])) @@ -413,7 +421,11 @@ impl Type { let n = new.as_any(); if let Some(s) = n.downcast_ref::() { self.add_all(s); - } else if let Some(n) = n.downcast_ref::() { + } else if let Some(n) = self + .smart_type_simplification + .then(|| n.downcast_ref::()) + .flatten() + { let n = n.clone(); let mut newt = None; for a in &self.types { @@ -429,7 +441,6 @@ impl Type { } } } - let newt2 = newt.is_some(); // remove types that are included in `self` before adding `self` let newt = newt.unwrap_or(n); let mut rmstack = vec![]; @@ -443,9 +454,7 @@ impl Type { for i in rmstack.into_iter().rev() { self.types.remove(i); } - if !newt2 { - self.types.push(new); - } + self.types.push(Arc::new(newt)); } else { if !self.types.iter().any(|t| new.is_included_in(t.as_ref())) { self.types.push(new); @@ -500,6 +509,7 @@ impl Type { } pub fn subtypes_type(&self) -> Type { let mut acc = Type::empty(); + acc.smart_type_simplification = false; self.subtypes(&mut acc); acc }