improve ints in .try

This commit is contained in:
Mark 2024-10-02 02:36:15 +02:00
parent 754dd5df40
commit 6c43c604b8
4 changed files with 36 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "mers" name = "mers"
version = "0.9.4" version = "0.9.5"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "dynamically typed but type-checked programming language" 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"] colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"]
[dependencies] [dependencies]
mers_lib = "0.9.4" mers_lib = "0.9.5"
# mers_lib = { path = "../mers_lib" } # mers_lib = { path = "../mers_lib" }
clap = { version = "4.3.19", features = ["derive"] } clap = { version = "4.3.19", features = ["derive"] }
colored = { version = "2.1.0", optional = true } colored = { version = "2.1.0", optional = true }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "mers_lib" name = "mers_lib"
version = "0.9.4" version = "0.9.5"
edition = "2021" edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
description = "library to use the mers language in other projects" description = "library to use the mers language in other projects"

View File

@ -6,11 +6,11 @@ use super::{MersData, MersType, Type};
/// The smallest representable integer. /// The smallest representable integer.
/// Depends on the system for which mers is being compiled, as mers uses pointer-sized signed integers. /// 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; pub const INT_MIN: isize = isize::MIN;
/// The largest representable integer. /// The largest representable integer.
/// Depends on the system for which mers is being compiled, as mers uses pointer-sized signed integers. /// 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; pub const INT_MAX: isize = isize::MAX;
/// The smallest integer representable by mers and by a signed 32-bit number. /// The smallest integer representable by mers and by a signed 32-bit number.
/// `max(INT_MIN, -2^31)` /// `max(INT_MIN, -2^31)`
@ -97,21 +97,26 @@ impl MersType for IntT {
} }
} }
fn subtypes(&self, acc: &mut Type) { fn subtypes(&self, acc: &mut Type) {
acc.add(Arc::new(self.clone())); // INT_MIN .. INT32U_MIN .. INT32S_MIN .. -128 .. -1 .. 0 .. 1 .. 127 .. 255 .. 65535 .. INT32S_MAX .. INT32U_MAX .. INT_MAX
// INT_MIN .. INT32U_MIN .. INT32S_MIN .. 0 .. INT32S_MAX .. INT32U_MAX .. INT_MAX
let mut add_range = |min, 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. // 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)))); acc.add(Arc::new(IntT(self.0.max(min), self.1.min(max))));
} }
}; };
add_range(INT_MIN, INT32U_MIN - 1); add_range(INT_MIN, INT32U_MIN.saturating_sub(1));
add_range(INT32U_MIN, INT32S_MIN - 1); add_range(INT32U_MIN, INT32S_MIN.saturating_sub(1));
add_range(INT32S_MIN, -1); add_range(INT32S_MIN, -129);
add_range(-128, -2);
add_range(-1, -1);
add_range(0, 0); add_range(0, 0);
add_range(1, INT32S_MAX); add_range(1, 1);
add_range(INT32S_MAX + 1, INT32U_MAX); add_range(2, 127);
add_range(INT32U_MAX + 1, INT_MAX); 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 { fn as_any(&self) -> &dyn Any {
self self

View File

@ -340,18 +340,26 @@ pub struct Type {
// TODO: Maybe make sure this is always sorted by (recursive?!?) TypeId, // 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) // that way is_same_type_as can work more efficiently (cuz good code but also branch prediction)
pub types: Vec<Arc<dyn MersType>>, pub types: Vec<Arc<dyn MersType>>,
pub smart_type_simplification: bool,
} }
impl Type { impl Type {
pub fn new<T: MersType>(t: T) -> Self { pub fn new<T: MersType>(t: T) -> Self {
Self { Self {
types: vec![Arc::new(t)], types: vec![Arc::new(t)],
smart_type_simplification: true,
} }
} }
pub fn newm(types: Vec<Arc<dyn MersType>>) -> Self { pub fn newm(types: Vec<Arc<dyn MersType>>) -> Self {
Self { types } Self {
types,
smart_type_simplification: true,
}
} }
pub fn empty() -> Self { pub fn empty() -> Self {
Self { types: vec![] } Self {
types: vec![],
smart_type_simplification: true,
}
} }
pub fn empty_tuple() -> Self { pub fn empty_tuple() -> Self {
Self::new(tuple::TupleT(vec![])) Self::new(tuple::TupleT(vec![]))
@ -413,7 +421,11 @@ impl Type {
let n = new.as_any(); let n = new.as_any();
if let Some(s) = n.downcast_ref::<Self>() { if let Some(s) = n.downcast_ref::<Self>() {
self.add_all(s); self.add_all(s);
} else if let Some(n) = n.downcast_ref::<crate::data::int::IntT>() { } else if let Some(n) = self
.smart_type_simplification
.then(|| n.downcast_ref::<crate::data::int::IntT>())
.flatten()
{
let n = n.clone(); let n = n.clone();
let mut newt = None; let mut newt = None;
for a in &self.types { 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` // remove types that are included in `self` before adding `self`
let newt = newt.unwrap_or(n); let newt = newt.unwrap_or(n);
let mut rmstack = vec![]; let mut rmstack = vec![];
@ -443,9 +454,7 @@ impl Type {
for i in rmstack.into_iter().rev() { for i in rmstack.into_iter().rev() {
self.types.remove(i); self.types.remove(i);
} }
if !newt2 { self.types.push(Arc::new(newt));
self.types.push(new);
}
} else { } else {
if !self.types.iter().any(|t| new.is_included_in(t.as_ref())) { if !self.types.iter().any(|t| new.is_included_in(t.as_ref())) {
self.types.push(new); self.types.push(new);
@ -500,6 +509,7 @@ impl Type {
} }
pub fn subtypes_type(&self) -> Type { pub fn subtypes_type(&self) -> Type {
let mut acc = Type::empty(); let mut acc = Type::empty();
acc.smart_type_simplification = false;
self.subtypes(&mut acc); self.subtypes(&mut acc);
acc acc
} }