mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-19 15:41:36 +03:00
Merge branch 'asg-asg' of github.com:AleoHQ/leo into asg-clippy
This commit is contained in:
commit
899d237ea3
@ -178,6 +178,10 @@ impl ConstInt {
|
|||||||
|
|
||||||
const_int_map!(value_negate, x, x.checked_neg()?);
|
const_int_map!(value_negate, x, x.checked_neg()?);
|
||||||
|
|
||||||
|
const_int_op!(to_usize, Option<usize>, x, (*x).try_into().ok());
|
||||||
|
|
||||||
|
const_int_op!(to_string, String, x, (*x).to_string());
|
||||||
|
|
||||||
const_int_bimap!(value_add, x, y, x.checked_add(*y)?);
|
const_int_bimap!(value_add, x, y, x.checked_add(*y)?);
|
||||||
|
|
||||||
const_int_bimap!(value_sub, x, y, x.checked_sub(*y)?);
|
const_int_bimap!(value_sub, x, y, x.checked_sub(*y)?);
|
||||||
|
@ -148,6 +148,23 @@ impl AsgConvertError {
|
|||||||
Self::new_from_span(format!("failed to index into non-array '{}'", name), span)
|
Self::new_from_span(format!("failed to index into non-array '{}'", name), span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invalid_assign_index(name: &str, num: &str, span: &Span) -> Self {
|
||||||
|
Self::new_from_span(
|
||||||
|
format!("failed to index array with invalid integer '{}'[{}]", name, num),
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invalid_backwards_assignment(name: &str, left: usize, right: usize, span: &Span) -> Self {
|
||||||
|
Self::new_from_span(
|
||||||
|
format!(
|
||||||
|
"failed to index array range for assignment with left > right '{}'[{}..{}]",
|
||||||
|
name, left, right
|
||||||
|
),
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn index_into_non_tuple(name: &str, span: &Span) -> Self {
|
pub fn index_into_non_tuple(name: &str, span: &Span) -> Self {
|
||||||
Self::new_from_span(format!("failed to index into non-tuple '{}'", name), span)
|
Self::new_from_span(format!("failed to index into non-tuple '{}'", name), span)
|
||||||
}
|
}
|
||||||
@ -186,6 +203,10 @@ impl AsgConvertError {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unexpected_nonconst(span: &Span) -> Self {
|
||||||
|
Self::new_from_span("expected const, found non-const value".to_string(), span)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unresolved_reference(name: &str, span: &Span) -> Self {
|
pub fn unresolved_reference(name: &str, span: &Span) -> Self {
|
||||||
Self::new_from_span(format!("failed to resolve variable reference '{}'", name), span)
|
Self::new_from_span(format!("failed to resolve variable reference '{}'", name), span)
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,9 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{
|
use leo_ast::IntegerType;
|
||||||
AsgConvertError,
|
|
||||||
ConstInt,
|
use crate::{AsgConvertError, ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Span, Type};
|
||||||
ConstValue,
|
|
||||||
Expression,
|
|
||||||
ExpressionNode,
|
|
||||||
FromAst,
|
|
||||||
Node,
|
|
||||||
PartialType,
|
|
||||||
Scope,
|
|
||||||
Span,
|
|
||||||
Type,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
sync::{Arc, Weak},
|
sync::{Arc, Weak},
|
||||||
@ -76,13 +66,13 @@ impl ExpressionNode for ArrayAccessExpression {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let const_index = match self.index.const_value()? {
|
let const_index = match self.index.const_value()? {
|
||||||
ConstValue::Int(ConstInt::U32(x)) => x,
|
ConstValue::Int(x) => x.to_usize()?,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if const_index as usize >= array.len() {
|
if const_index >= array.len() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(array.remove(const_index as usize))
|
Some(array.remove(const_index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +105,7 @@ impl FromAst<leo_ast::ArrayAccessExpression> for ArrayAccessExpression {
|
|||||||
index: Arc::<Expression>::from_ast(
|
index: Arc::<Expression>::from_ast(
|
||||||
scope,
|
scope,
|
||||||
&*value.index,
|
&*value.index,
|
||||||
Some(Type::Integer(leo_ast::IntegerType::U32).partial()),
|
Some(PartialType::Integer(None, Some(IntegerType::U32))),
|
||||||
)?,
|
)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{
|
use crate::{AsgConvertError, ConstValue, Expression, ExpressionNode, FromAst, Node, PartialType, Scope, Span, Type};
|
||||||
AsgConvertError,
|
|
||||||
ConstInt,
|
|
||||||
ConstValue,
|
|
||||||
Expression,
|
|
||||||
ExpressionNode,
|
|
||||||
FromAst,
|
|
||||||
Node,
|
|
||||||
PartialType,
|
|
||||||
Scope,
|
|
||||||
Span,
|
|
||||||
Type,
|
|
||||||
};
|
|
||||||
use leo_ast::IntegerType;
|
use leo_ast::IntegerType;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
@ -73,20 +61,20 @@ impl ExpressionNode for ArrayRangeAccessExpression {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let const_left = match self.left.as_ref().map(|x| x.const_value()) {
|
let const_left = match self.left.as_ref().map(|x| x.const_value()) {
|
||||||
Some(Some(ConstValue::Int(ConstInt::U32(x)))) => x,
|
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||||
None => 0,
|
None => 0,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let const_right = match self.right.as_ref().map(|x| x.const_value()) {
|
let const_right = match self.right.as_ref().map(|x| x.const_value()) {
|
||||||
Some(Some(ConstValue::Int(ConstInt::U32(x)))) => x,
|
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||||
None => array_len as u32,
|
None => array_len,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if const_left > const_right || const_right as usize > array_len {
|
if const_left > const_right || const_right > array_len {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Type::Array(element, (const_right - const_left) as usize))
|
Some(Type::Array(element, const_right - const_left))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_mut_ref(&self) -> bool {
|
fn is_mut_ref(&self) -> bool {
|
||||||
@ -99,22 +87,20 @@ impl ExpressionNode for ArrayRangeAccessExpression {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let const_left = match self.left.as_ref().map(|x| x.const_value()) {
|
let const_left = match self.left.as_ref().map(|x| x.const_value()) {
|
||||||
Some(Some(ConstValue::Int(ConstInt::U32(x)))) => x,
|
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||||
None => 0,
|
None => 0,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let const_right = match self.right.as_ref().map(|x| x.const_value()) {
|
let const_right = match self.right.as_ref().map(|x| x.const_value()) {
|
||||||
Some(Some(ConstValue::Int(ConstInt::U32(x)))) => x,
|
Some(Some(ConstValue::Int(x))) => x.to_usize()?,
|
||||||
None => array.len() as u32,
|
None => array.len(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if const_left > const_right || const_right as usize > array.len() {
|
if const_left > const_right || const_right as usize > array.len() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(ConstValue::Array(
|
Some(ConstValue::Array(array.drain(const_left..const_right).collect()))
|
||||||
array.drain(const_left as usize..const_right as usize).collect(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,20 +133,41 @@ impl FromAst<leo_ast::ArrayRangeAccessExpression> for ArrayRangeAccessExpression
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let left = value
|
||||||
|
.left
|
||||||
|
.as_deref()
|
||||||
|
.map(|left| {
|
||||||
|
Arc::<Expression>::from_ast(scope, left, Some(PartialType::Integer(None, Some(IntegerType::U32))))
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
let right = value
|
||||||
|
.right
|
||||||
|
.as_deref()
|
||||||
|
.map(|right| {
|
||||||
|
Arc::<Expression>::from_ast(scope, right, Some(PartialType::Integer(None, Some(IntegerType::U32))))
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
|
if let Some(left) = left.as_ref() {
|
||||||
|
if left.const_value().is_none() {
|
||||||
|
return Err(AsgConvertError::unexpected_nonconst(
|
||||||
|
&left.span().cloned().unwrap_or_default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(right) = right.as_ref() {
|
||||||
|
if right.const_value().is_none() {
|
||||||
|
return Err(AsgConvertError::unexpected_nonconst(
|
||||||
|
&right.span().cloned().unwrap_or_default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(ArrayRangeAccessExpression {
|
Ok(ArrayRangeAccessExpression {
|
||||||
parent: RefCell::new(None),
|
parent: RefCell::new(None),
|
||||||
span: Some(value.span.clone()),
|
span: Some(value.span.clone()),
|
||||||
array,
|
array,
|
||||||
left: value
|
left,
|
||||||
.left
|
right,
|
||||||
.as_deref()
|
|
||||||
.map(|left| Arc::<Expression>::from_ast(scope, left, Some(Type::Integer(IntegerType::U32).partial())))
|
|
||||||
.transpose()?,
|
|
||||||
right: value
|
|
||||||
.right
|
|
||||||
.as_deref()
|
|
||||||
.map(|right| Arc::<Expression>::from_ast(scope, right, Some(Type::Integer(IntegerType::U32).partial())))
|
|
||||||
.transpose()?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ impl FromAst<leo_ast::BinaryExpression> for BinaryExpression {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
BinaryOperationClass::Numeric => match expected_type {
|
BinaryOperationClass::Numeric => match expected_type {
|
||||||
Some(PartialType::Type(x @ Type::Integer(_))) => Some(x),
|
Some(x @ PartialType::Integer(_, _)) => Some(x),
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
return Err(AsgConvertError::unexpected_type(
|
return Err(AsgConvertError::unexpected_type(
|
||||||
&x.to_string(),
|
&x.to_string(),
|
||||||
@ -137,8 +137,7 @@ impl FromAst<leo_ast::BinaryExpression> for BinaryExpression {
|
|||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
.map(Type::partial);
|
|
||||||
|
|
||||||
// left
|
// left
|
||||||
let (left, right) = match Arc::<Expression>::from_ast(scope, &*value.left, expected_type.clone()) {
|
let (left, right) = match Arc::<Expression>::from_ast(scope, &*value.left, expected_type.clone()) {
|
||||||
@ -172,6 +171,7 @@ impl FromAst<leo_ast::BinaryExpression> for BinaryExpression {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let left_type = left.get_type();
|
let left_type = left.get_type();
|
||||||
|
#[allow(clippy::unused_unit)]
|
||||||
match class {
|
match class {
|
||||||
BinaryOperationClass::Numeric => match left_type {
|
BinaryOperationClass::Numeric => match left_type {
|
||||||
Some(Type::Integer(_)) => (),
|
Some(Type::Integer(_)) => (),
|
||||||
|
@ -154,19 +154,21 @@ impl FromAst<leo_ast::ValueExpression> for Constant {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Implicit(value, span) => match expected_type.map(PartialType::full).flatten() {
|
Implicit(value, span) => match expected_type {
|
||||||
None => return Err(AsgConvertError::unresolved_type("unknown", span)),
|
None => return Err(AsgConvertError::unresolved_type("unknown", span)),
|
||||||
Some(Type::Integer(int_type)) => Constant {
|
Some(PartialType::Integer(Some(sub_type), _)) | Some(PartialType::Integer(None, Some(sub_type))) => {
|
||||||
parent: RefCell::new(None),
|
Constant {
|
||||||
span: Some(span.clone()),
|
parent: RefCell::new(None),
|
||||||
value: ConstValue::Int(ConstInt::parse(&int_type, value, span)?),
|
span: Some(span.clone()),
|
||||||
},
|
value: ConstValue::Int(ConstInt::parse(&sub_type, value, span)?),
|
||||||
Some(Type::Field) => Constant {
|
}
|
||||||
|
}
|
||||||
|
Some(PartialType::Type(Type::Field)) => Constant {
|
||||||
parent: RefCell::new(None),
|
parent: RefCell::new(None),
|
||||||
span: Some(span.clone()),
|
span: Some(span.clone()),
|
||||||
value: ConstValue::Field(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
|
value: ConstValue::Field(value.parse().map_err(|_| AsgConvertError::invalid_int(&value, span))?),
|
||||||
},
|
},
|
||||||
Some(Type::Address) => Constant {
|
Some(PartialType::Type(Type::Address)) => Constant {
|
||||||
parent: RefCell::new(None),
|
parent: RefCell::new(None),
|
||||||
span: Some(span.clone()),
|
span: Some(span.clone()),
|
||||||
value: ConstValue::Address(value.to_string()),
|
value: ConstValue::Address(value.to_string()),
|
||||||
@ -174,8 +176,9 @@ impl FromAst<leo_ast::ValueExpression> for Constant {
|
|||||||
Some(x) => return Err(AsgConvertError::unexpected_type(&x.to_string(), Some("unknown"), span)),
|
Some(x) => return Err(AsgConvertError::unexpected_type(&x.to_string(), Some("unknown"), span)),
|
||||||
},
|
},
|
||||||
Integer(int_type, value, span) => {
|
Integer(int_type, value, span) => {
|
||||||
match expected_type.map(PartialType::full).flatten() {
|
match expected_type {
|
||||||
Some(Type::Integer(sub_type)) if &sub_type == int_type => (),
|
Some(PartialType::Integer(Some(sub_type), _)) if &sub_type == int_type => (),
|
||||||
|
Some(PartialType::Integer(None, Some(_))) => (),
|
||||||
None => (),
|
None => (),
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
return Err(AsgConvertError::unexpected_type(
|
return Err(AsgConvertError::unexpected_type(
|
||||||
|
@ -97,7 +97,7 @@ impl FromAst<leo_ast::AssignStatement> for Arc<Statement> {
|
|||||||
for access in statement.assignee.accesses.iter() {
|
for access in statement.assignee.accesses.iter() {
|
||||||
target_accesses.push(match access {
|
target_accesses.push(match access {
|
||||||
AstAssigneeAccess::ArrayRange(left, right) => {
|
AstAssigneeAccess::ArrayRange(left, right) => {
|
||||||
let index_type = Some(Type::Integer(IntegerType::U32).into());
|
let index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
|
||||||
let left = left
|
let left = left
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(
|
.map(
|
||||||
@ -127,15 +127,26 @@ impl FromAst<leo_ast::AssignStatement> for Arc<Statement> {
|
|||||||
.unwrap_or_else(|| Some(ConstValue::Int(ConstInt::U32(len.map(|x| x as u32)?)))),
|
.unwrap_or_else(|| Some(ConstValue::Int(ConstInt::U32(len.map(|x| x as u32)?)))),
|
||||||
) {
|
) {
|
||||||
let left = match left {
|
let left = match left {
|
||||||
ConstValue::Int(ConstInt::U32(x)) => x,
|
ConstValue::Int(x) => x.to_usize().ok_or_else(|| {
|
||||||
|
AsgConvertError::invalid_assign_index(&name, &x.to_string(), &statement.span)
|
||||||
|
})?,
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
let right = match right {
|
let right = match right {
|
||||||
ConstValue::Int(ConstInt::U32(x)) => x,
|
ConstValue::Int(x) => x.to_usize().ok_or_else(|| {
|
||||||
|
AsgConvertError::invalid_assign_index(&name, &x.to_string(), &statement.span)
|
||||||
|
})?,
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
if right > left {
|
if right >= left {
|
||||||
target_type = Some(PartialType::Array(item.clone(), Some((right - left) as usize)))
|
target_type = Some(PartialType::Array(item.clone(), Some((right - left) as usize)))
|
||||||
|
} else {
|
||||||
|
return Err(AsgConvertError::invalid_backwards_assignment(
|
||||||
|
&name,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
&statement.span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +163,7 @@ impl FromAst<leo_ast::AssignStatement> for Arc<Statement> {
|
|||||||
AssignAccess::ArrayIndex(Arc::<Expression>::from_ast(
|
AssignAccess::ArrayIndex(Arc::<Expression>::from_ast(
|
||||||
scope,
|
scope,
|
||||||
index,
|
index,
|
||||||
Some(Type::Integer(IntegerType::U32).into()),
|
Some(PartialType::Integer(None, Some(IntegerType::U32))),
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
AstAssigneeAccess::Tuple(index, _) => {
|
AstAssigneeAccess::Tuple(index, _) => {
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use leo_ast::IntegerType;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AsgConvertError,
|
AsgConvertError,
|
||||||
Expression,
|
Expression,
|
||||||
@ -25,7 +27,6 @@ use crate::{
|
|||||||
Scope,
|
Scope,
|
||||||
Span,
|
Span,
|
||||||
Statement,
|
Statement,
|
||||||
Type,
|
|
||||||
Variable,
|
Variable,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
@ -54,7 +55,7 @@ impl FromAst<leo_ast::IterationStatement> for Arc<Statement> {
|
|||||||
statement: &leo_ast::IterationStatement,
|
statement: &leo_ast::IterationStatement,
|
||||||
_expected_type: Option<PartialType>,
|
_expected_type: Option<PartialType>,
|
||||||
) -> Result<Arc<Statement>, AsgConvertError> {
|
) -> Result<Arc<Statement>, AsgConvertError> {
|
||||||
let expected_index_type = Some(Type::Integer(leo_ast::IntegerType::U32).into());
|
let expected_index_type = Some(PartialType::Integer(None, Some(IntegerType::U32)));
|
||||||
let start = Arc::<Expression>::from_ast(scope, &statement.start, expected_index_type.clone())?;
|
let start = Arc::<Expression>::from_ast(scope, &statement.start, expected_index_type.clone())?;
|
||||||
let stop = Arc::<Expression>::from_ast(scope, &statement.stop, expected_index_type)?;
|
let stop = Arc::<Expression>::from_ast(scope, &statement.stop, expected_index_type)?;
|
||||||
let variable = Arc::new(RefCell::new(InnerVariable {
|
let variable = Arc::new(RefCell::new(InnerVariable {
|
||||||
|
@ -44,7 +44,8 @@ pub enum WeakType {
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum PartialType {
|
pub enum PartialType {
|
||||||
Type(Type), // non-array or tuple
|
Type(Type), // non-array or tuple
|
||||||
|
Integer(Option<IntegerType>, Option<IntegerType>), // specific, context-specific
|
||||||
Array(Option<Box<PartialType>>, Option<usize>),
|
Array(Option<Box<PartialType>>, Option<usize>),
|
||||||
Tuple(Vec<Option<PartialType>>),
|
Tuple(Vec<Option<PartialType>>),
|
||||||
}
|
}
|
||||||
@ -81,6 +82,7 @@ impl Into<Option<Type>> for PartialType {
|
|||||||
fn into(self) -> Option<Type> {
|
fn into(self) -> Option<Type> {
|
||||||
match self {
|
match self {
|
||||||
PartialType::Type(t) => Some(t),
|
PartialType::Type(t) => Some(t),
|
||||||
|
PartialType::Integer(sub_type, contextual_type) => Some(Type::Integer(sub_type.or(contextual_type)?)),
|
||||||
PartialType::Array(element, len) => Some(Type::Array(Box::new((*element?).full()?), len?)),
|
PartialType::Array(element, len) => Some(Type::Array(Box::new((*element?).full()?), len?)),
|
||||||
PartialType::Tuple(sub_types) => Some(Type::Tuple(
|
PartialType::Tuple(sub_types) => Some(Type::Tuple(
|
||||||
sub_types
|
sub_types
|
||||||
@ -100,6 +102,9 @@ impl PartialType {
|
|||||||
pub fn matches(&self, other: &Type) -> bool {
|
pub fn matches(&self, other: &Type) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(PartialType::Type(t), other) => t.is_assignable_from(other),
|
(PartialType::Type(t), other) => t.is_assignable_from(other),
|
||||||
|
(PartialType::Integer(self_sub_type, _), Type::Integer(sub_type)) => {
|
||||||
|
self_sub_type.as_ref().map(|x| x == sub_type).unwrap_or(true)
|
||||||
|
}
|
||||||
(PartialType::Array(element, len), Type::Array(other_element, other_len)) => {
|
(PartialType::Array(element, len), Type::Array(other_element, other_len)) => {
|
||||||
if let Some(element) = element {
|
if let Some(element) = element {
|
||||||
if !element.matches(&*other_element) {
|
if !element.matches(&*other_element) {
|
||||||
@ -133,6 +138,7 @@ impl PartialType {
|
|||||||
impl Into<PartialType> for Type {
|
impl Into<PartialType> for Type {
|
||||||
fn into(self) -> PartialType {
|
fn into(self) -> PartialType {
|
||||||
match self {
|
match self {
|
||||||
|
Type::Integer(sub_type) => PartialType::Integer(Some(sub_type), None),
|
||||||
Type::Array(element, len) => PartialType::Array(Some(Box::new((*element).into())), Some(len)),
|
Type::Array(element, len) => PartialType::Array(Some(Box::new((*element).into())), Some(len)),
|
||||||
Type::Tuple(sub_types) => PartialType::Tuple(sub_types.into_iter().map(Into::into).map(Some).collect()),
|
Type::Tuple(sub_types) => PartialType::Tuple(sub_types.into_iter().map(Into::into).map(Some).collect()),
|
||||||
x => PartialType::Type(x),
|
x => PartialType::Type(x),
|
||||||
@ -158,11 +164,11 @@ impl fmt::Display for Type {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Type::Address => write!(f, "address"),
|
Type::Address => write!(f, "address"),
|
||||||
Type::Boolean => write!(f, "boolean"),
|
Type::Boolean => write!(f, "bool"),
|
||||||
Type::Field => write!(f, "field"),
|
Type::Field => write!(f, "field"),
|
||||||
Type::Group => write!(f, "group"),
|
Type::Group => write!(f, "group"),
|
||||||
Type::Integer(sub_type) => sub_type.fmt(f),
|
Type::Integer(sub_type) => sub_type.fmt(f),
|
||||||
Type::Array(sub_type, len) => write!(f, "{}[{}]", sub_type, len),
|
Type::Array(sub_type, len) => write!(f, "[{}; {}]", sub_type, len),
|
||||||
Type::Tuple(sub_types) => {
|
Type::Tuple(sub_types) => {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
for (i, sub_type) in sub_types.iter().enumerate() {
|
for (i, sub_type) in sub_types.iter().enumerate() {
|
||||||
@ -182,13 +188,17 @@ impl fmt::Display for PartialType {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
PartialType::Type(t) => t.fmt(f),
|
PartialType::Type(t) => t.fmt(f),
|
||||||
|
PartialType::Integer(Some(sub_type), _) => write!(f, "{}", sub_type),
|
||||||
|
PartialType::Integer(_, Some(sub_type)) => write!(f, "<{}>", sub_type),
|
||||||
|
PartialType::Integer(_, _) => write!(f, "integer"),
|
||||||
PartialType::Array(sub_type, len) => {
|
PartialType::Array(sub_type, len) => {
|
||||||
|
write!(f, "[")?;
|
||||||
if let Some(sub_type) = sub_type {
|
if let Some(sub_type) = sub_type {
|
||||||
write!(f, "{}", *sub_type)?;
|
write!(f, "{}", *sub_type)?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "?")?;
|
write!(f, "?")?;
|
||||||
}
|
}
|
||||||
write!(f, "[")?;
|
write!(f, "; ")?;
|
||||||
if let Some(len) = len {
|
if let Some(len) = len {
|
||||||
write!(f, "{}", len)?;
|
write!(f, "{}", len)?;
|
||||||
} else {
|
} else {
|
||||||
|
5
asg/tests/pass/array/index_u8.leo
Normal file
5
asg/tests/pass/array/index_u8.leo
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
function main() {
|
||||||
|
let x = 0u8;
|
||||||
|
let a = [0u8; 4];
|
||||||
|
console.assert(a[x] == 0);
|
||||||
|
}
|
@ -102,6 +102,18 @@ fn test_slice() {
|
|||||||
load_asg(program_string).unwrap();
|
load_asg(program_string).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_index_u8() {
|
||||||
|
let program_string = include_str!("index_u8.leo");
|
||||||
|
load_asg(program_string).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_slice_i8() {
|
||||||
|
let program_string = include_str!("slice_i8.leo");
|
||||||
|
load_asg(program_string).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_lower() {
|
fn test_slice_lower() {
|
||||||
let program_string = include_str!("slice_lower.leo");
|
let program_string = include_str!("slice_lower.leo");
|
||||||
|
6
asg/tests/pass/array/slice_i8.leo
Normal file
6
asg/tests/pass/array/slice_i8.leo
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// `{from}..{to}` copies the elements of one array into another exclusively
|
||||||
|
function main(a: [u8; 3]) {
|
||||||
|
let b = [1u8; 4];
|
||||||
|
|
||||||
|
console.assert(a == b[0u8..3i8]);
|
||||||
|
}
|
@ -22,7 +22,7 @@ fn test_basic() {
|
|||||||
let asg = load_asg(program_string).unwrap();
|
let asg = load_asg(program_string).unwrap();
|
||||||
let reformed_ast = leo_asg::reform_ast(&asg);
|
let reformed_ast = leo_asg::reform_ast(&asg);
|
||||||
println!("{}", reformed_ast);
|
println!("{}", reformed_ast);
|
||||||
panic!();
|
// panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -47,7 +47,7 @@ fn test_function_rename() {
|
|||||||
let asg = load_asg(program_string).unwrap();
|
let asg = load_asg(program_string).unwrap();
|
||||||
let reformed_ast = leo_asg::reform_ast(&asg);
|
let reformed_ast = leo_asg::reform_ast(&asg);
|
||||||
println!("{}", reformed_ast);
|
println!("{}", reformed_ast);
|
||||||
panic!();
|
// panic!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -84,5 +84,5 @@ fn test_imports() {
|
|||||||
let asg = crate::load_asg_imports(program_string, &mut imports).unwrap();
|
let asg = crate::load_asg_imports(program_string, &mut imports).unwrap();
|
||||||
let reformed_ast = leo_asg::reform_ast(&asg);
|
let reformed_ast = leo_asg::reform_ast(&asg);
|
||||||
println!("{}", serde_json::to_string(&reformed_ast).unwrap());
|
println!("{}", serde_json::to_string(&reformed_ast).unwrap());
|
||||||
panic!();
|
// panic!();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user