From e03d5c23b8ec3c97053703aba6ad2c57fa16c37c Mon Sep 17 00:00:00 2001 From: damirka Date: Tue, 31 Aug 2021 20:18:21 +0300 Subject: [PATCH] includes ast and asg changes --- asg/src/scope.rs | 19 ++++++--- asg/src/type_.rs | 4 +- .../src/canonicalization/canonicalizer.rs | 37 +++++++++------- ast/src/types/type_.rs | 27 +++++++++--- compiler/src/phases/reducing_director.rs | 4 +- errors/src/parser/parser_errors.rs | 42 +++++++++++-------- 6 files changed, 85 insertions(+), 48 deletions(-) diff --git a/asg/src/scope.rs b/asg/src/scope.rs index 26687a495d..781afb6557 100644 --- a/asg/src/scope.rs +++ b/asg/src/scope.rs @@ -183,13 +183,20 @@ impl<'a> Scope<'a> { IntegerType(int_type) => Type::Integer(int_type.clone()), Array(sub_type, dimensions) => { let mut item = Box::new(self.resolve_ast_type(&*sub_type, span)?); - for dimension in dimensions.0.iter().rev() { - let dimension = dimension - .value - .parse::() - .map_err(|_| AsgError::parse_index_error(span))?; - item = Box::new(Type::Array(item, dimension)); + + if let Some(dimensions) = dimensions { + for dimension in dimensions.0.iter().rev() { + let dimension = dimension + .value + .parse::() + .map_err(|_| AsgError::parse_index_error(span))?; + item = Box::new(Type::Array(item, dimension)); + } } + // } else { + // return AsgError::parse_index_error(span); + // } + *item } Tuple(sub_types) => Type::Tuple( diff --git a/asg/src/type_.rs b/asg/src/type_.rs index 74543b2555..e4947fd38d 100644 --- a/asg/src/type_.rs +++ b/asg/src/type_.rs @@ -207,9 +207,9 @@ impl<'a> Into for &Type<'a> { Integer(int_type) => leo_ast::Type::IntegerType(int_type.clone()), Array(type_, len) => leo_ast::Type::Array( Box::new(type_.as_ref().into()), - leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber { + Some(leo_ast::ArrayDimensions(vec![leo_ast::PositiveNumber { value: len.to_string().into(), - }]), + }])), ), Tuple(subtypes) => leo_ast::Type::Tuple(subtypes.iter().map(Into::into).collect()), Circuit(circuit) => leo_ast::Type::CircuitOrAlias(circuit.name.borrow().clone()), diff --git a/ast-passes/src/canonicalization/canonicalizer.rs b/ast-passes/src/canonicalization/canonicalizer.rs index 353e284584..410b2610e6 100644 --- a/ast-passes/src/canonicalization/canonicalizer.rs +++ b/ast-passes/src/canonicalization/canonicalizer.rs @@ -481,24 +481,31 @@ impl ReconstructingReducer for Canonicalizer { fn reduce_type(&mut self, _type_: &Type, new: Type, span: &Span) -> Result { match new { - Type::Array(type_, mut dimensions) => { - if dimensions.is_zero() { - return Err(AstError::invalid_array_dimension_size(span).into()); - } - - let mut next = Type::Array(type_, ArrayDimensions(vec![dimensions.remove_last().unwrap()])); - let mut array = next.clone(); - - loop { - if dimensions.is_empty() { - break; + Type::Array(type_, dimensions) => { + if let Some(mut dimensions) = dimensions { + if dimensions.is_zero() { + return Err(AstError::invalid_array_dimension_size(span).into()); } - array = Type::Array(Box::new(next), ArrayDimensions(vec![dimensions.remove_last().unwrap()])); - next = array.clone(); - } + let mut next = Type::Array(type_, Some(ArrayDimensions(vec![dimensions.remove_last().unwrap()]))); + let mut array = next.clone(); - Ok(array) + loop { + if dimensions.is_empty() { + break; + } + + array = Type::Array( + Box::new(next), + Some(ArrayDimensions(vec![dimensions.remove_last().unwrap()])), + ); + next = array.clone(); + } + + Ok(array) + } else { + Ok(Type::Array(type_, None)) + } } Type::SelfType if !self.in_circuit => Err(AstError::big_self_outside_of_circuit(span).into()), _ => Ok(new.clone()), diff --git a/ast/src/types/type_.rs b/ast/src/types/type_.rs index b26e09c644..1b060514f6 100644 --- a/ast/src/types/type_.rs +++ b/ast/src/types/type_.rs @@ -34,7 +34,7 @@ pub enum Type { IntegerType(IntegerType), // Data type wrappers - Array(Box, ArrayDimensions), + Array(Box, Option), Tuple(Vec), CircuitOrAlias(Identifier), SelfType, @@ -72,8 +72,17 @@ impl Type { (Type::SelfType, Type::SelfType) => true, (Type::Array(left_type, left_dim), Type::Array(right_type, right_dim)) => { // Convert array dimensions to owned. - let mut left_dim_owned = left_dim.to_owned(); - let mut right_dim_owned = right_dim.to_owned(); + let left_dim_owned = left_dim.to_owned(); + let right_dim_owned = right_dim.to_owned(); + + // Unable to compare arrays with unspecified sizes. + if left_dim_owned.is_none() || right_dim_owned.is_none() { + return false; + } + + // We know that values are Some, safe to unwrap. + let mut left_dim_owned = left_dim_owned.unwrap(); + let mut right_dim_owned = right_dim_owned.unwrap(); // Remove the first element from both dimensions. let left_first = left_dim_owned.remove_first(); @@ -120,7 +129,7 @@ impl<'ast> From> for Type { let element_type = Box::new(Type::from(*array_type.type_)); let dimensions = ArrayDimensions::from(array_type.dimensions); - Type::Array(element_type, dimensions) + Type::Array(element_type, Some(dimensions)) } } @@ -153,7 +162,13 @@ impl fmt::Display for Type { Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type), Type::CircuitOrAlias(ref variable) => write!(f, "circuit {}", variable), Type::SelfType => write!(f, "SelfType"), - Type::Array(ref array, ref dimensions) => write!(f, "[{}; {}]", *array, dimensions), + Type::Array(ref array, ref dimensions) => { + if let Some(dimensions) = dimensions { + write!(f, "[{}; {}]", *array, dimensions) + } else { + write!(f, "[{}; _]", *array) + } + } Type::Tuple(ref tuple) => { let types = tuple.iter().map(|x| x.to_string()).collect::>().join(", "); @@ -179,6 +194,6 @@ pub fn inner_array_type(element_type: Type, dimensions: ArrayDimensions) -> Type element_type } else { // The array has multiple dimensions. - Type::Array(Box::new(element_type), dimensions) + Type::Array(Box::new(element_type), Some(dimensions)) } } diff --git a/compiler/src/phases/reducing_director.rs b/compiler/src/phases/reducing_director.rs index 56e7ba565b..9071635b6d 100644 --- a/compiler/src/phases/reducing_director.rs +++ b/compiler/src/phases/reducing_director.rs @@ -76,9 +76,9 @@ impl CombineAstAsgDirector { if self.options.type_inference_enabled() { AstType::Array( Box::new(self.reduce_type(ast_type, asg_type, span)?), - ArrayDimensions(vec![PositiveNumber { + Some(ArrayDimensions(vec![PositiveNumber { value: StrTendril::from(format!("{}", asg_dimensions)), - }]), + }])), ) } else { AstType::Array( diff --git a/errors/src/parser/parser_errors.rs b/errors/src/parser/parser_errors.rs index 7728a65750..5a4a4db54d 100644 --- a/errors/src/parser/parser_errors.rs +++ b/errors/src/parser/parser_errors.rs @@ -32,7 +32,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an invalid address literal. + /// For when the parser encountered an invalid address literal. @formatted invalid_address_lit { args: (token: impl Display), @@ -40,7 +40,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an empty import list. + /// For when the parser encountered an empty import list. @formatted invalid_import_list { args: (), @@ -48,7 +48,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected End of File. + /// For when the parser encountered an unexpected End of File. @formatted unexpected_eof { args: (), @@ -56,7 +56,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected whitespace. + /// For when the parser encountered an unexpected whitespace. @formatted unexpected_whitespace { args: (left: impl Display, right: impl Display), @@ -64,7 +64,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected list of tokens. + /// For when the parser encountered an unexpected list of tokens. @formatted unexpected { args: (got: impl Display, expected: impl Display), @@ -72,7 +72,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered a mix of commas and semi-colons in circuit member variables. + /// For when the parser encountered a mix of commas and semi-colons in circuit member variables. @formatted mixed_commas_and_semicolons { args: (), @@ -80,7 +80,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected identifier. + /// For when the parser encountered an unexpected identifier. @formatted unexpected_ident { args: (got: impl Display, expected: &[impl Display]), @@ -96,7 +96,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected statement. + /// For when the parser encountered an unexpected statement. @formatted unexpected_statement { args: (got: impl Display, expected: impl Display), @@ -104,7 +104,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected string. + /// For when the parser encountered an unexpected string. @formatted unexpected_str { args: (got: impl Display, expected: impl Display), @@ -112,7 +112,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an unexpected spread in an array init expression. + /// For when the parser encountered an unexpected spread in an array init expression. @formatted spread_in_array_init { args: (), @@ -120,7 +120,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an invalid assignment target. + /// For when the parser encountered an invalid assignment target. @formatted invalid_assignment_target { args: (), @@ -128,7 +128,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an invalid package name. + /// For when the parser encountered an invalid package name. @formatted invalid_package_name { args: (), @@ -136,7 +136,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered an illegal `const self` argument. + /// For when the parser encountered an illegal `const self` argument. @formatted illegal_self_const { args: (), @@ -144,7 +144,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered a deprecated `mut` argument in a function. + /// For when the parser encountered a deprecated `mut` argument in a function. @formatted mut_function_input { args: (), @@ -152,7 +152,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered a deprecated `mut` argument in a let statement. + /// For when the parser encountered a deprecated `mut` argument in a let statement. @formatted let_mut_statement { args: (), @@ -160,7 +160,7 @@ create_errors!( help: None, } - /// For when the parser encoutnered a deprecated `test function`. + /// For when the parser encountered a deprecated `test function`. @formatted test_function { args: (), @@ -168,11 +168,19 @@ create_errors!( help: None, } - /// For when the parser encoutnered a deprecated `@context(...)` annotation. + /// For when the parser encountered a deprecated `@context(...)` annotation. @formatted context_annotation { args: (), msg: "\"@context(...)\" is deprecated. Did you mean @test annotation?", help: None, } + + /// For when the parser failed to parse array dimensions. + @formatted + unable_to_parse_array_dimensions { + args: (), + msg: "unable to parse array dimensions", + help: None, + } );