mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 11:12:48 +03:00
remove redundant array dimension struct
This commit is contained in:
parent
1f7b1b57cc
commit
1a45295372
@ -20,41 +20,12 @@ use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
|||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::{fmt, ops::Deref};
|
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.
|
/// Specifies array dimensions for array [`Type`]s or in array initializer [`Expression`]s.
|
||||||
#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)]
|
#[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 {
|
impl Deref for ArrayDimensions {
|
||||||
type Target = [Dimension];
|
type Target = [PositiveNumber];
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&*self.0
|
&*self.0
|
||||||
@ -63,7 +34,7 @@ impl Deref for ArrayDimensions {
|
|||||||
|
|
||||||
impl ArrayDimensions {
|
impl ArrayDimensions {
|
||||||
/// Returns a single-dimensional array dimension.
|
/// Returns a single-dimensional array dimension.
|
||||||
pub fn single(dim: Dimension) -> Self {
|
pub fn single(dim: PositiveNumber) -> Self {
|
||||||
Self(smallvec![dim])
|
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.
|
/// Attempts to remove the first dimension from the array, or returns `None` if it doesn't.
|
||||||
pub fn remove_first(&mut self) -> Option<Dimension> {
|
pub fn remove_first(&mut self) -> Option<PositiveNumber> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@ -82,7 +53,7 @@ impl ArrayDimensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to remove the last dimension from the array, or returns `None` if it doesn't.
|
/// Attempts to remove the last dimension from the array, or returns `None` if it doesn't.
|
||||||
pub fn remove_last(&mut self) -> Option<Dimension> {
|
pub fn remove_last(&mut self) -> Option<PositiveNumber> {
|
||||||
self.0.pop()
|
self.0.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,9 +66,7 @@ impl Serialize for ArrayDimensions {
|
|||||||
{
|
{
|
||||||
let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
|
let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
|
||||||
for dim in self.0.iter() {
|
for dim in self.0.iter() {
|
||||||
match dim {
|
seq.serialize_element(&dim)?;
|
||||||
Dimension::Number(num) => seq.serialize_element(&num)?,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
seq.end()
|
seq.end()
|
||||||
}
|
}
|
||||||
|
@ -88,32 +88,28 @@ impl TryFrom<(Type, Expression)> for InputValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dimension) = array_init.dimensions.remove_first() {
|
if let Some(dimension) = array_init.dimensions.remove_first() {
|
||||||
if let Some(number) = dimension.as_specified() {
|
let size = dimension.value.parse::<usize>().unwrap();
|
||||||
let size = number.value.parse::<usize>().unwrap();
|
let mut values = Vec::with_capacity(size);
|
||||||
let mut values = Vec::with_capacity(size);
|
|
||||||
|
|
||||||
// For when Dimensions are specified in a canonical way: [[u8; 3], 2];
|
// For when Dimensions are specified in a canonical way: [[u8; 3], 2];
|
||||||
// Else treat as math notation: [u8; (2, 3)];
|
// Else treat as math notation: [u8; (2, 3)];
|
||||||
if array_init.dimensions.len() == 0 {
|
if array_init.dimensions.len() == 0 {
|
||||||
for _ in 0..size {
|
for _ in 0..size {
|
||||||
values.push(InputValue::try_from((*type_.clone(), *array_init.element.clone()))?);
|
values.push(InputValue::try_from((*type_.clone(), *array_init.element.clone()))?);
|
||||||
}
|
}
|
||||||
// Faking canonical array init is relatively easy: instead of using a straightforward
|
// Faking canonical array init is relatively easy: instead of using a straightforward
|
||||||
// recursion, with each iteration we manually modify ArrayInitExpression cutting off
|
// recursion, with each iteration we manually modify ArrayInitExpression cutting off
|
||||||
// dimension by dimension.
|
// 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)
|
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
unreachable!("dimensions are checked for zero");
|
unreachable!("dimensions are checked for zero");
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,12 @@ impl ParserContext<'_> {
|
|||||||
|
|
||||||
/// Returns an [`ArrayDimensions`] AST node if the next tokens represent dimensions for an array type.
|
/// Returns an [`ArrayDimensions`] AST node if the next tokens represent dimensions for an array type.
|
||||||
pub fn parse_array_dimensions(&mut self) -> Result<ArrayDimensions> {
|
pub fn parse_array_dimensions(&mut self) -> Result<ArrayDimensions> {
|
||||||
Ok(if let Some(dim) = self.parse_array_dimension() {
|
Ok(if let Some((dim, _)) = self.eat_int() {
|
||||||
ArrayDimensions(smallvec![dim])
|
ArrayDimensions(smallvec![dim])
|
||||||
} else {
|
} else {
|
||||||
let mut had_item_err = false;
|
let mut had_item_err = false;
|
||||||
let (dims, _, span) = self.parse_paren_comma_list(|p| {
|
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)
|
Some(dim)
|
||||||
} else {
|
} else {
|
||||||
let token = p.expect_any()?;
|
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<Dimension> {
|
|
||||||
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.
|
/// Returns a [`(Type, Span)`] tuple of AST nodes if the next token represents a type.
|
||||||
/// Also returns the span of the parsed token.
|
/// Also returns the span of the parsed token.
|
||||||
pub fn parse_type(&mut self) -> Result<(Type, Span)> {
|
pub fn parse_type(&mut self) -> Result<(Type, Span)> {
|
||||||
|
Loading…
Reference in New Issue
Block a user