mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-18 23:02:35 +03:00
migrate latest ast changes
This commit is contained in:
parent
7b54423b41
commit
f0b312604d
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -1365,6 +1365,7 @@ dependencies = [
|
||||
"pest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
"tendril",
|
||||
]
|
||||
|
||||
@ -2655,6 +2656,9 @@ name = "smallvec"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snarkvm-algorithms"
|
||||
|
@ -18,6 +18,9 @@ license = "GPL-3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.56"
|
||||
|
||||
[dependencies]
|
||||
smallvec = { version = "1.8.0", features = ["serde"] }
|
||||
|
||||
[dependencies.leo-input]
|
||||
path = "../input"
|
||||
version = "1.5.3"
|
||||
|
@ -21,10 +21,14 @@ use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An array element access expression `array[index]`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayAccess {
|
||||
/// The expression, evaluating to an array, that is being indexed.
|
||||
pub array: Box<Expression>,
|
||||
/// The index in `array` that is being accessed.
|
||||
pub index: Box<Expression>,
|
||||
/// The span of the entire expression `array[index]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,18 @@ use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An access to a certain range of elements in an `array`.
|
||||
///
|
||||
/// Examples include `array[0..3]`, `array[3..]`, `array[..3]`, and `array[..]`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ArrayRangeAccess {
|
||||
/// The array to extract a range of elements from.
|
||||
pub array: Box<Expression>,
|
||||
/// The lower bound of the index-range, or the start of the array when `None`.
|
||||
pub left: Option<Box<Expression>>,
|
||||
/// The higher bound of the index-range, or the end of the array when `None`.
|
||||
pub right: Option<Box<Expression>>,
|
||||
/// A span for the entire expression `array[<range>]`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,19 @@ use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A field access expression `inner.name` to some structure with *named fields*.
|
||||
///
|
||||
/// For accesses to a positional fields in e.g., a tuple, see `TupleAccess`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct MemberAccess {
|
||||
/// The structure that the field `name` is being extracted from.
|
||||
pub inner: Box<Expression>,
|
||||
/// The name of the field to extract in `inner`.
|
||||
pub name: Identifier,
|
||||
/// The span covering all of `inner.name`.
|
||||
pub span: Span,
|
||||
// FIXME(Centril): Type information shouldn't be injected into an AST,
|
||||
// so this field should eventually be removed.
|
||||
pub type_: Option<crate::Type>,
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,19 @@ use leo_span::Span;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// An access expression to a static member, e.g., a constant in a circuit.
|
||||
/// An example would be `Foo::Const` or `Foo::function` in `Foo::function()`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct StaticAccess {
|
||||
/// Represents the container for the static member to access.
|
||||
/// Usually this is a circuit.
|
||||
pub inner: Box<Expression>,
|
||||
/// The static member in `inner` that is being accessed.
|
||||
pub name: Identifier,
|
||||
/// An optional type initially None, it is later assigned during type inference snapshot if necessary.
|
||||
// FIXME(Centril): Shouldn't be in an AST. Remove it as part of an architectural revamp.
|
||||
pub type_: Option<Type>,
|
||||
/// The span for the entire expression `inner::name`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,14 @@ use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An tuple access expression, e.g., `tuple.index`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct TupleAccess {
|
||||
/// An expression evaluating to some tuple type, e.g., `(5, 2)`.
|
||||
pub tuple: Box<Expression>,
|
||||
/// The index to access in the tuple expression. E.g., `0` for `(5, 2)` would yield `5`.
|
||||
pub index: PositiveNumber,
|
||||
/// The span for the entire expression `tuple.index`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,17 @@ use std::fmt;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A type alias `type name = represents;`.
|
||||
///
|
||||
/// That is, `name` will become another name for `represents`.
|
||||
/// This does not create a new type, that is, `name` is the same type as `represents`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Alias {
|
||||
/// The new name for `represents`.
|
||||
pub name: Identifier,
|
||||
/// A span for the entire `type name = represents;`.
|
||||
pub span: Span,
|
||||
/// The type that `name` will evaluate and is equal to.
|
||||
pub represents: Type,
|
||||
}
|
||||
|
||||
|
@ -19,9 +19,17 @@ use crate::{CircuitMember, Identifier};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
/// A record type definition, e.g., `circuit Foo { my_field: Bar }`.
|
||||
/// In some languages these are called `struct`s.
|
||||
///
|
||||
/// Type identity is decided by the full path including `circuit_name`,
|
||||
/// as the record is nominal, not structural.
|
||||
/// The fields are named so `circuit Foo(u8, u16)` is not allowed.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Circuit {
|
||||
/// The name of the type in the type system in this module.
|
||||
pub circuit_name: Identifier,
|
||||
/// The fields, constant variables, and functions of this structure.
|
||||
pub members: Vec<CircuitMember>,
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
/// A member of a circuit definition.
|
||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CircuitMember {
|
||||
/// A static constant in a circuit.
|
||||
|
@ -17,11 +17,5 @@
|
||||
pub mod circuit;
|
||||
pub use circuit::*;
|
||||
|
||||
pub mod circuit_variable_definition;
|
||||
pub use circuit_variable_definition::*;
|
||||
|
||||
pub mod circuit_implied_variable_definition;
|
||||
pub use circuit_implied_variable_definition::*;
|
||||
|
||||
pub mod circuit_member;
|
||||
pub use circuit_member::*;
|
||||
|
@ -18,81 +18,81 @@ use crate::PositiveNumber;
|
||||
use leo_input::types::ArrayDimensions as InputArrayDimensions;
|
||||
|
||||
use serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
|
||||
use std::fmt;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
/// Type for handling different definitions of ArrayDimensions.
|
||||
/// Can be used in an array [`Type`] or an array initializer [`Expression`].
|
||||
/// A single array dimension.
|
||||
#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ArrayDimensions {
|
||||
pub enum Dimension {
|
||||
/// The dimension is `_`, that is unspecified and syntactically unknown.
|
||||
Unspecified,
|
||||
/// The dimension was specified, e.g., `5` elements.
|
||||
Number(PositiveNumber),
|
||||
Multi(Vec<ArrayDimensions>),
|
||||
}
|
||||
|
||||
impl fmt::Display for Dimension {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Unspecified => write!(f, "_"),
|
||||
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::Unspecified => None,
|
||||
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]>);
|
||||
|
||||
impl Deref for ArrayDimensions {
|
||||
type Target = [Dimension];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ArrayDimensions {
|
||||
/// Returns `true` if the all array dimensions have been removed.
|
||||
///
|
||||
/// This method is called after repeated calls to `remove_first`.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
Self::Multi(dimensions) => dimensions.len() != 0,
|
||||
Self::Number(_) | Self::Unspecified => false,
|
||||
}
|
||||
pub fn single(dim: Dimension) -> Self {
|
||||
Self(smallvec![dim])
|
||||
}
|
||||
|
||||
/// Returns true if the dimensions are not [`Unspecified`].
|
||||
pub fn is_specified(&self) -> bool {
|
||||
match self {
|
||||
Self::Multi(_) | Self::Number(_) => true,
|
||||
Self::Unspecified => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flatten(&self) -> Vec<ArrayDimensions> {
|
||||
match self {
|
||||
dimension @ (ArrayDimensions::Number(_) | ArrayDimensions::Unspecified) => vec![dimension.clone()],
|
||||
ArrayDimensions::Multi(dimensions) => dimensions.iter().flat_map(|dim| dim.flatten()).collect(),
|
||||
}
|
||||
!self.contains(&Dimension::Unspecified)
|
||||
}
|
||||
|
||||
/// Returns `true` if there is an array dimension equal to zero.
|
||||
pub fn is_zero(&self) -> bool {
|
||||
match self {
|
||||
ArrayDimensions::Multi(dimensions) => dimensions.iter().any(|a| a.is_zero()),
|
||||
ArrayDimensions::Number(num) => num.is_zero(),
|
||||
ArrayDimensions::Unspecified => false,
|
||||
self.iter().any(|d| d.is_zero())
|
||||
}
|
||||
|
||||
/// Attempts to remove the first dimension from the array, or returns `None` if it doesn't.
|
||||
pub fn remove_first(&mut self) -> Option<Dimension> {
|
||||
if self.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.0.remove(0))
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to remove the first dimension from the array.
|
||||
///
|
||||
/// If the first dimension exists, then remove and return `Some(PositiveNumber)`.
|
||||
/// If the first dimension does not exist, then return `None`.
|
||||
pub fn remove_first(&mut self) -> Option<ArrayDimensions> {
|
||||
match self {
|
||||
Self::Multi(dims) => Some(dims.remove(0)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to remove the last dimension from the array.
|
||||
///
|
||||
/// If the last dimension exists, then remove and return `Some(PositiveNumber)`.
|
||||
/// If the last dimension does not exist, then return `None`.
|
||||
pub fn remove_last(&mut self) -> Option<ArrayDimensions> {
|
||||
match self {
|
||||
Self::Multi(dims) => dims.pop(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ArrayDimensions {
|
||||
/// Returns `PositiveNumber` if `Dimension` is specified, returns `None` otherwise.
|
||||
pub fn number(&self) -> Option<&PositiveNumber> {
|
||||
match self {
|
||||
ArrayDimensions::Number(num) => Some(num),
|
||||
ArrayDimensions::Unspecified | ArrayDimensions::Multi(_) => None,
|
||||
}
|
||||
/// Attempts to remove the last dimension from the array, or returns `None` if it doesn't.
|
||||
pub fn remove_last(&mut self) -> Option<Dimension> {
|
||||
self.0.pop()
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,13 +102,11 @@ impl Serialize for ArrayDimensions {
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let dimensions = self.flatten();
|
||||
let mut seq = serializer.serialize_seq(Some(dimensions.len()))?;
|
||||
for dimension in dimensions.iter() {
|
||||
match dimension {
|
||||
ArrayDimensions::Number(num) => seq.serialize_element(&num)?,
|
||||
ArrayDimensions::Unspecified => seq.serialize_element(&PositiveNumber { value: "0".into() })?,
|
||||
ArrayDimensions::Multi(_) => unimplemented!("there are no multi dimensions after flattening"),
|
||||
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)?,
|
||||
Dimension::Unspecified => seq.serialize_element(&PositiveNumber { value: "0".into() })?,
|
||||
}
|
||||
}
|
||||
seq.end()
|
||||
@ -119,12 +117,14 @@ impl Serialize for ArrayDimensions {
|
||||
impl<'ast> From<InputArrayDimensions<'ast>> for ArrayDimensions {
|
||||
fn from(dimensions: InputArrayDimensions<'ast>) -> Self {
|
||||
match dimensions {
|
||||
InputArrayDimensions::Single(single) => ArrayDimensions::Number(PositiveNumber::from(single.number)),
|
||||
InputArrayDimensions::Multiple(multiple) => ArrayDimensions::Multi(
|
||||
InputArrayDimensions::Single(single) => {
|
||||
Self(smallvec![Dimension::Number(PositiveNumber::from(single.number))])
|
||||
}
|
||||
InputArrayDimensions::Multiple(multiple) => Self(
|
||||
multiple
|
||||
.numbers
|
||||
.into_iter()
|
||||
.map(|num| ArrayDimensions::Number(PositiveNumber::from(num)))
|
||||
.map(|num| Dimension::Number(PositiveNumber::from(num)))
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
@ -133,16 +133,13 @@ impl<'ast> From<InputArrayDimensions<'ast>> for ArrayDimensions {
|
||||
|
||||
impl fmt::Display for ArrayDimensions {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ArrayDimensions::Unspecified => write!(f, "_"),
|
||||
ArrayDimensions::Number(num) => write!(f, "{}", num),
|
||||
ArrayDimensions::Multi(dimensions) => {
|
||||
write!(
|
||||
f,
|
||||
"({})",
|
||||
dimensions.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ")
|
||||
)
|
||||
}
|
||||
match &*self.0 {
|
||||
[dim] => write!(f, "{}", dim),
|
||||
dimensions => write!(
|
||||
f,
|
||||
"({})",
|
||||
dimensions.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(", ")
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,26 +16,47 @@
|
||||
|
||||
use super::*;
|
||||
|
||||
/// An initializer for a single field / variable of a circuit initializer expression.
|
||||
/// That is, in `Foo { bar: 42, baz }`, this is either `bar: 42`, or `baz`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CircuitVariableInitializer {
|
||||
/// The name of the field / variable to be initialized.
|
||||
pub identifier: Identifier,
|
||||
/// The expression to initialize the field with.
|
||||
/// When `None`, a binding, in scope, with the name will be used instead.
|
||||
pub expression: Option<Expression>,
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitVariableInitializer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(expr) = &self.expression {
|
||||
write!(f, "{}: {}", self.identifier, expr)
|
||||
} else {
|
||||
write!(f, "{}", self.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A circuit initialization expression, e.g., `Foo { bar: 42, baz }`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct CircuitInitExpression {
|
||||
/// The name of the structure type to initialize.
|
||||
pub name: Identifier,
|
||||
pub members: Vec<CircuitImpliedVariableDefinition>,
|
||||
/// Initializer expressions for each of the fields in the circuit.
|
||||
///
|
||||
/// N.B. Any functions or member constants in the circuit definition
|
||||
/// are excluded from this list.
|
||||
pub members: Vec<CircuitVariableInitializer>,
|
||||
/// A span from `name` to `}`.
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl fmt::Display for CircuitInitExpression {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} {{", self.name)?;
|
||||
for (i, member) in self.members.iter().enumerate() {
|
||||
if let Some(expression) = &member.expression {
|
||||
write!(f, "{}: {}", member.identifier, expression)?;
|
||||
} else {
|
||||
write!(f, "{}", member.identifier)?;
|
||||
}
|
||||
|
||||
if i < self.members.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
for member in self.members.iter() {
|
||||
write!(f, "{}", member)?;
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
}
|
||||
|
@ -14,9 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{
|
||||
ArrayDimensions, CircuitImpliedVariableDefinition, GroupValue, Identifier, IntegerType, Node, SpreadOrExpression,
|
||||
};
|
||||
use crate::{ArrayDimensions, GroupValue, Identifier, IntegerType, Node, SpreadOrExpression};
|
||||
|
||||
use leo_span::Span;
|
||||
|
||||
|
@ -341,20 +341,16 @@ impl InputValue {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns a new vector of usize values from an [`ArrayDimensions`] type.
|
||||
///
|
||||
/// Attempts to parse each dimension in the array from a `String` to a `usize` value. If parsing
|
||||
/// is successful, the `usize` value is appended to the return vector. If parsing fails, an error
|
||||
/// is returned.
|
||||
///
|
||||
fn parse_array_dimensions(array_dimensions_type: ArrayDimensions, span: &Span) -> Result<Vec<usize>, InputParserError> {
|
||||
let dimensions = array_dimensions_type.flatten();
|
||||
|
||||
fn parse_array_dimensions(dimensions: ArrayDimensions, span: &Span) -> Result<Vec<usize>, InputParserError> {
|
||||
// Convert the array dimensions to usize.
|
||||
let mut result_array_dimensions = Vec::with_capacity(dimensions.len());
|
||||
|
||||
for dimension in dimensions {
|
||||
for dimension in dimensions.iter() {
|
||||
// Convert the dimension to a string.
|
||||
let dimension_string = dimension.to_string();
|
||||
|
||||
|
@ -238,10 +238,10 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
self.reducer.reduce_tuple_init(tuple_init, elements)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_implied_variable_definition(
|
||||
pub fn reduce_circuit_variable_initializer(
|
||||
&mut self,
|
||||
variable: &CircuitImpliedVariableDefinition,
|
||||
) -> Result<CircuitImpliedVariableDefinition> {
|
||||
variable: &CircuitVariableInitializer,
|
||||
) -> Result<CircuitVariableInitializer> {
|
||||
let identifier = self.reduce_identifier(&variable.identifier)?;
|
||||
let expression = variable
|
||||
.expression
|
||||
@ -250,7 +250,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
.transpose()?;
|
||||
|
||||
self.reducer
|
||||
.reduce_circuit_implied_variable_definition(variable, identifier, expression)
|
||||
.reduce_circuit_variable_initializer(variable, identifier, expression)
|
||||
}
|
||||
|
||||
pub fn reduce_circuit_init(&mut self, circuit_init: &CircuitInitExpression) -> Result<CircuitInitExpression> {
|
||||
@ -258,7 +258,7 @@ impl<R: ReconstructingReducer> ReconstructingDirector<R> {
|
||||
|
||||
let mut members = vec![];
|
||||
for member in circuit_init.members.iter() {
|
||||
members.push(self.reduce_circuit_implied_variable_definition(member)?);
|
||||
members.push(self.reduce_circuit_variable_initializer(member)?);
|
||||
}
|
||||
|
||||
self.reducer.reduce_circuit_init(circuit_init, name, members)
|
||||
|
@ -217,20 +217,20 @@ pub trait ReconstructingReducer {
|
||||
})
|
||||
}
|
||||
|
||||
fn reduce_circuit_implied_variable_definition(
|
||||
fn reduce_circuit_variable_initializer(
|
||||
&mut self,
|
||||
_variable: &CircuitImpliedVariableDefinition,
|
||||
_variable: &CircuitVariableInitializer,
|
||||
identifier: Identifier,
|
||||
expression: Option<Expression>,
|
||||
) -> Result<CircuitImpliedVariableDefinition> {
|
||||
Ok(CircuitImpliedVariableDefinition { identifier, expression })
|
||||
) -> Result<CircuitVariableInitializer> {
|
||||
Ok(CircuitVariableInitializer { identifier, expression })
|
||||
}
|
||||
|
||||
fn reduce_circuit_init(
|
||||
&mut self,
|
||||
circuit_init: &CircuitInitExpression,
|
||||
name: Identifier,
|
||||
members: Vec<CircuitImpliedVariableDefinition>,
|
||||
members: Vec<CircuitVariableInitializer>,
|
||||
) -> Result<CircuitInitExpression> {
|
||||
Ok(CircuitInitExpression {
|
||||
name,
|
||||
|
@ -74,23 +74,19 @@ impl Type {
|
||||
(Type::IntegerType(left), Type::IntegerType(right)) => left.eq(right),
|
||||
(Type::Identifier(left), Type::Identifier(right)) => left.eq(right),
|
||||
(Type::SelfType, Type::SelfType) => true,
|
||||
(Type::Array(left_type, left_dim), Type::Array(right_type, right_dim)) => {
|
||||
(Type::Array(left_type, left_dims), Type::Array(right_type, right_dims)) => {
|
||||
// Convert array dimensions to owned.
|
||||
let left_dim_owned = left_dim.to_owned();
|
||||
let right_dim_owned = right_dim.to_owned();
|
||||
let mut left_dims = left_dims.to_owned();
|
||||
let mut right_dims = right_dims.to_owned();
|
||||
|
||||
// Unable to compare arrays with unspecified sizes.
|
||||
if !left_dim_owned.is_specified() || !right_dim_owned.is_specified() {
|
||||
if !left_dims.is_specified() || !right_dims.is_specified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We know that values are Some, safe to unwrap.
|
||||
let mut left_dim_owned = left_dim_owned;
|
||||
let mut right_dim_owned = right_dim_owned;
|
||||
|
||||
// Remove the first element from both dimensions.
|
||||
let left_first = left_dim_owned.remove_first();
|
||||
let right_first = right_dim_owned.remove_first();
|
||||
let left_first = left_dims.remove_first();
|
||||
let right_first = right_dims.remove_first();
|
||||
|
||||
// Compare the first dimensions.
|
||||
if left_first.ne(&right_first) {
|
||||
@ -98,8 +94,8 @@ impl Type {
|
||||
}
|
||||
|
||||
// Create a new array type from the remaining array dimensions.
|
||||
let left_new_type = inner_array_type(*left_type.to_owned(), left_dim_owned);
|
||||
let right_new_type = inner_array_type(*right_type.to_owned(), right_dim_owned);
|
||||
let left_new_type = inner_array_type(*left_type.to_owned(), left_dims);
|
||||
let right_new_type = inner_array_type(*right_type.to_owned(), right_dims);
|
||||
|
||||
// Call eq_flat() on the new left and right types.
|
||||
left_new_type.eq_flat(&right_new_type)
|
||||
|
Loading…
Reference in New Issue
Block a user