From 158b08b9d3f86d6a8962e67ea0606a6d3c89d0e1 Mon Sep 17 00:00:00 2001 From: maxrdz Date: Wed, 6 Mar 2024 00:02:05 -0700 Subject: [PATCH] dcparser: Apply explicit cast when building DCNumericType struct --- libdonet/src/dcnumeric.rs | 19 +++++++++++++++++++ libdonet/src/dcparser.rs | 18 +++++++++++++++--- libdonet/src/dctype.rs | 15 +++++++++++++-- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/libdonet/src/dcnumeric.rs b/libdonet/src/dcnumeric.rs index 966bc69..2d4dec9 100644 --- a/libdonet/src/dcnumeric.rs +++ b/libdonet/src/dcnumeric.rs @@ -110,6 +110,8 @@ pub struct DCNumericType { // These are the range and modulus values after scaling by the divisor. modulus: DCNumber, range: DCNumericRange, + // Specific to Donet's DC language + explicit_cast: Option, } pub trait DCNumericTypeInterface { @@ -122,10 +124,12 @@ pub trait DCNumericTypeInterface { fn get_divisor(&self) -> u16; fn get_modulus(&self) -> f64; fn get_range(&self) -> DCNumericRange; + fn get_explicit_cast(&self) -> Option; fn set_divisor(&mut self, divisor: u16) -> Result<(), String>; fn set_modulus(&mut self, modulus: f64) -> Result<(), String>; fn set_range(&mut self, range: DCNumericRange) -> Result<(), String>; + fn set_explicit_cast(&mut self, dtype: DCTypeDefinition) -> Result<(), String>; fn within_range(&self, data: Vec, length: u64) -> Result<(), String>; } @@ -200,6 +204,7 @@ impl DCNumericTypeInterface for DCNumericType { orig_range: DCNumericRange::new(), modulus: DCNumber::new(), range: DCNumericRange::new(), + explicit_cast: None, } } @@ -221,21 +226,30 @@ impl DCNumericTypeInterface for DCNumericType { } } + #[inline] fn has_modulus(&self) -> bool { self.orig_modulus != 0.0 } + #[inline] fn has_range(&self) -> bool { self.orig_range.is_empty() } + #[inline] fn get_divisor(&self) -> u16 { self.divisor } + #[inline] fn get_modulus(&self) -> f64 { self.orig_modulus } + #[inline] fn get_range(&self) -> DCNumericRange { self.orig_range.clone() } + #[inline] + fn get_explicit_cast(&self) -> Option { + self.explicit_cast.clone() + } fn set_divisor(&mut self, divisor: u16) -> Result<(), String> { if divisor == 0 { @@ -265,6 +279,11 @@ impl DCNumericTypeInterface for DCNumericType { Ok(()) } + fn set_explicit_cast(&mut self, dtype: DCTypeDefinition) -> Result<(), String> { + self.explicit_cast = Some(dtype); + Ok(()) // TODO: do some sort of type check + } + fn within_range(&self, data: Vec, length: u64) -> Result<(), String> { todo!(); } diff --git a/libdonet/src/dcparser.rs b/libdonet/src/dcparser.rs index ada2329..b2579c0 100644 --- a/libdonet/src/dcparser.rs +++ b/libdonet/src/dcparser.rs @@ -668,9 +668,21 @@ parser! { // this is used for types that have arithmetic operations applied, such as division. // // Also because it is 2:27 AM and its giving me a shift-reduce conflict again. - numeric_type_token[nt] OpenParenthesis signed_integer_type[_] CloseParenthesis => nt, - numeric_type_token[nt] OpenParenthesis unsigned_integer_type[_] CloseParenthesis => nt, - numeric_type_token[nt] OpenParenthesis floating_point_type[_] CloseParenthesis => nt, + numeric_type_token[mut nt] + OpenParenthesis signed_integer_type[(_, dct)] CloseParenthesis => { + let _ = nt.set_explicit_cast(DCTypeDefinition::new_with_type(dct)); + nt + }, + numeric_type_token[mut nt] + OpenParenthesis unsigned_integer_type[(_, dct)] CloseParenthesis => { + let _ = nt.set_explicit_cast(DCTypeDefinition::new_with_type(dct)); + nt + }, + numeric_type_token[mut nt] + OpenParenthesis floating_point_type[(_, dct)] CloseParenthesis => { + let _ = nt.set_explicit_cast(DCTypeDefinition::new_with_type(dct)); + nt + }, } numeric_range: Option { diff --git a/libdonet/src/dctype.rs b/libdonet/src/dctype.rs index bd6afdf..b8cc2e6 100644 --- a/libdonet/src/dctype.rs +++ b/libdonet/src/dctype.rs @@ -25,7 +25,7 @@ use strum_macros::EnumIs; /// The DCTypeEnum variants have assigned u8 values /// to keep compatibility with Astron's DC hash inputs. #[repr(u8)] // 8-bit alignment, unsigned -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] #[rustfmt::skip] pub enum DCTypeEnum { // Numeric Types @@ -45,7 +45,7 @@ pub enum DCTypeEnum { TInvalid = 21, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DCTypeDefinition { alias: Option, pub data_type: DCTypeEnum, @@ -54,6 +54,7 @@ pub struct DCTypeDefinition { pub trait DCTypeDefinitionInterface { fn new() -> Self; + fn new_with_type(dt: DCTypeEnum) -> Self; fn generate_hash(&self, hashgen: &mut DCHashGenerator); fn get_dc_type(&self) -> DCTypeEnum; @@ -66,6 +67,7 @@ pub trait DCTypeDefinitionInterface { } impl DCTypeDefinitionInterface for DCTypeDefinition { + /// Creates a new empty DCTypeDefinition struct. fn new() -> Self { Self { alias: None, @@ -74,6 +76,15 @@ impl DCTypeDefinitionInterface for DCTypeDefinition { } } + /// Creates a new DCTypeDefinition struct with a DC type set. + fn new_with_type(dt: DCTypeEnum) -> Self { + Self { + alias: None, + data_type: dt, + size: 0_u16, + } + } + /// Generates the hash for this DC Type element. fn generate_hash(&self, hashgen: &mut DCHashGenerator) { hashgen.add_int(i32::from(self.data_type.clone() as u8));