From 1a45295372bf312647aa4ffec66b73ba64108875 Mon Sep 17 00:00:00 2001 From: collin <16715212+collinc97@users.noreply.github.com> Date: Fri, 4 Mar 2022 13:06:22 -0800 Subject: [PATCH] remove redundant array dimension struct --- compiler/ast/src/common/array_dimensions.rs | 43 +++----------------- compiler/ast/src/input/input_value.rs | 44 ++++++++++----------- compiler/parser/src/parser/type_.rs | 13 +----- 3 files changed, 28 insertions(+), 72 deletions(-) diff --git a/compiler/ast/src/common/array_dimensions.rs b/compiler/ast/src/common/array_dimensions.rs index edb624c2d2..af5f879930 100644 --- a/compiler/ast/src/common/array_dimensions.rs +++ b/compiler/ast/src/common/array_dimensions.rs @@ -20,41 +20,12 @@ use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer}; use smallvec::{smallvec, SmallVec}; use std::{fmt, ops::Deref}; -/// A single array dimension. -#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)] -pub enum Dimension { - /// The dimension was specified, e.g., `5` elements. - Number(PositiveNumber), -} - -impl fmt::Display for Dimension { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Number(num) => write!(f, "{}", num), - } - } -} - -impl Dimension { - /// } Returns `Some(n)` unless the dimension is [`Unspecified`]. - pub fn as_specified(&self) -> Option<&PositiveNumber> { - match self { - Self::Number(n) => Some(n), - } - } - - /// Returns true if the dimension is known to be zero. - fn is_zero(&self) -> bool { - self.as_specified().filter(|n| n.is_zero()).is_some() - } -} - /// Specifies array dimensions for array [`Type`]s or in array initializer [`Expression`]s. #[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)] -pub struct ArrayDimensions(pub SmallVec<[Dimension; 1]>); +pub struct ArrayDimensions(pub SmallVec<[PositiveNumber; 1]>); impl Deref for ArrayDimensions { - type Target = [Dimension]; + type Target = [PositiveNumber]; fn deref(&self) -> &Self::Target { &*self.0 @@ -63,7 +34,7 @@ impl Deref for ArrayDimensions { impl ArrayDimensions { /// Returns a single-dimensional array dimension. - pub fn single(dim: Dimension) -> Self { + pub fn single(dim: PositiveNumber) -> Self { Self(smallvec![dim]) } @@ -73,7 +44,7 @@ impl ArrayDimensions { } /// Attempts to remove the first dimension from the array, or returns `None` if it doesn't. - pub fn remove_first(&mut self) -> Option { + pub fn remove_first(&mut self) -> Option { if self.is_empty() { None } else { @@ -82,7 +53,7 @@ impl ArrayDimensions { } /// Attempts to remove the last dimension from the array, or returns `None` if it doesn't. - pub fn remove_last(&mut self) -> Option { + pub fn remove_last(&mut self) -> Option { self.0.pop() } } @@ -95,9 +66,7 @@ impl Serialize for ArrayDimensions { { let mut seq = serializer.serialize_seq(Some(self.0.len()))?; for dim in self.0.iter() { - match dim { - Dimension::Number(num) => seq.serialize_element(&num)?, - } + seq.serialize_element(&dim)?; } seq.end() } diff --git a/compiler/ast/src/input/input_value.rs b/compiler/ast/src/input/input_value.rs index c7270eb2ee..9ca0a286d0 100644 --- a/compiler/ast/src/input/input_value.rs +++ b/compiler/ast/src/input/input_value.rs @@ -88,32 +88,28 @@ impl TryFrom<(Type, Expression)> for InputValue { } if let Some(dimension) = array_init.dimensions.remove_first() { - if let Some(number) = dimension.as_specified() { - let size = number.value.parse::().unwrap(); - let mut values = Vec::with_capacity(size); + let size = dimension.value.parse::().unwrap(); + let mut values = Vec::with_capacity(size); - // For when Dimensions are specified in a canonical way: [[u8; 3], 2]; - // Else treat as math notation: [u8; (2, 3)]; - if array_init.dimensions.len() == 0 { - for _ in 0..size { - values.push(InputValue::try_from((*type_.clone(), *array_init.element.clone()))?); - } - // Faking canonical array init is relatively easy: instead of using a straightforward - // recursion, with each iteration we manually modify ArrayInitExpression cutting off - // dimension by dimension. - } else { - for _ in 0..size { - values.push(InputValue::try_from(( - Type::Array(type_.clone(), array_init.dimensions.clone()), - Expression::ArrayInit(array_init.clone()), - ))?); - } - }; - - Self::Array(values) + // For when Dimensions are specified in a canonical way: [[u8; 3], 2]; + // Else treat as math notation: [u8; (2, 3)]; + if array_init.dimensions.len() == 0 { + for _ in 0..size { + values.push(InputValue::try_from((*type_.clone(), *array_init.element.clone()))?); + } + // Faking canonical array init is relatively easy: instead of using a straightforward + // recursion, with each iteration we manually modify ArrayInitExpression cutting off + // dimension by dimension. } else { - unreachable!("dimensions must be specified"); - } + for _ in 0..size { + values.push(InputValue::try_from(( + Type::Array(type_.clone(), array_init.dimensions.clone()), + Expression::ArrayInit(array_init.clone()), + ))?); + } + }; + + Self::Array(values) } else { unreachable!("dimensions are checked for zero"); } diff --git a/compiler/parser/src/parser/type_.rs b/compiler/parser/src/parser/type_.rs index 60fd73e73a..f634fee8ed 100644 --- a/compiler/parser/src/parser/type_.rs +++ b/compiler/parser/src/parser/type_.rs @@ -59,12 +59,12 @@ impl ParserContext<'_> { /// Returns an [`ArrayDimensions`] AST node if the next tokens represent dimensions for an array type. pub fn parse_array_dimensions(&mut self) -> Result { - Ok(if let Some(dim) = self.parse_array_dimension() { + Ok(if let Some((dim, _)) = self.eat_int() { ArrayDimensions(smallvec![dim]) } else { let mut had_item_err = false; let (dims, _, span) = self.parse_paren_comma_list(|p| { - Ok(if let Some(dim) = p.parse_array_dimension() { + Ok(if let Some((dim, _)) = p.eat_int() { Some(dim) } else { let token = p.expect_any()?; @@ -80,15 +80,6 @@ impl ParserContext<'_> { }) } - /// Parses a basic array dimension, i.e., an integer or `_`. - fn parse_array_dimension(&mut self) -> Option { - if let Some((int, _)) = self.eat_int() { - Some(Dimension::Number(int)) - } else { - None - } - } - /// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type. /// Also returns the span of the parsed token. pub fn parse_type(&mut self) -> Result<(Type, Span)> {