mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 03:04:13 +03:00
impl tuple parsing
This commit is contained in:
parent
296c62a280
commit
9e422599a0
@ -320,8 +320,8 @@ impl ParserContext<'_> {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a tuple of expressions.
|
/// Parses a tuple of `Expression` AST nodes.
|
||||||
fn parse_expr_tuple(&mut self) -> Result<(Vec<Expression>, bool, Span)> {
|
pub(crate) fn parse_expr_tuple(&mut self) -> Result<(Vec<Expression>, bool, Span)> {
|
||||||
self.parse_paren_comma_list(|p| p.parse_expression().map(Some))
|
self.parse_paren_comma_list(|p| p.parse_expression().map(Some))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +384,10 @@ impl ParserContext<'_> {
|
|||||||
if !trailing && tuple.len() == 1 {
|
if !trailing && tuple.len() == 1 {
|
||||||
Ok(tuple.swap_remove(0))
|
Ok(tuple.swap_remove(0))
|
||||||
} else {
|
} else {
|
||||||
Err(ParserError::unexpected("A tuple expression.", "A valid expression.", span).into())
|
Ok(Expression::Tuple(TupleExpression {
|
||||||
|
elements: tuple,
|
||||||
|
span
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ impl ParserContext<'_> {
|
|||||||
fn parse_member(&mut self) -> Result<(Identifier, Type)> {
|
fn parse_member(&mut self) -> Result<(Identifier, Type)> {
|
||||||
let name = self.expect_ident()?;
|
let name = self.expect_ident()?;
|
||||||
self.expect(&Token::Colon)?;
|
self.expect(&Token::Colon)?;
|
||||||
let type_ = self.parse_all_types()?.0;
|
let type_ = self.parse_single_type()?.0;
|
||||||
|
|
||||||
Ok((name, type_))
|
Ok((name, type_))
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ impl ParserContext<'_> {
|
|||||||
let name = self.expect_ident()?;
|
let name = self.expect_ident()?;
|
||||||
|
|
||||||
self.expect(&Token::Colon)?;
|
self.expect(&Token::Colon)?;
|
||||||
let type_ = self.parse_all_types()?.0;
|
let type_ = self.parse_single_type()?.0;
|
||||||
Ok(FunctionInput::Variable(FunctionInputVariable::new(
|
Ok(FunctionInput::Variable(FunctionInputVariable::new(
|
||||||
name, mode, type_, name.span,
|
name, mode, type_, name.span,
|
||||||
)))
|
)))
|
||||||
@ -229,7 +229,7 @@ impl ParserContext<'_> {
|
|||||||
// Parse return type.
|
// Parse return type.
|
||||||
self.expect(&Token::Arrow)?;
|
self.expect(&Token::Arrow)?;
|
||||||
self.disallow_circuit_construction = true;
|
self.disallow_circuit_construction = true;
|
||||||
let output = self.parse_all_types()?.0;
|
let output = self.parse_any_type()?.0;
|
||||||
self.disallow_circuit_construction = false;
|
self.disallow_circuit_construction = false;
|
||||||
|
|
||||||
// Parse the function body.
|
// Parse the function body.
|
||||||
|
@ -103,7 +103,7 @@ impl ParserContext<'_> {
|
|||||||
let start_span = self.expect(&Token::For)?;
|
let start_span = self.expect(&Token::For)?;
|
||||||
let ident = self.expect_ident()?;
|
let ident = self.expect_ident()?;
|
||||||
self.expect(&Token::Colon)?;
|
self.expect(&Token::Colon)?;
|
||||||
let type_ = self.parse_all_types()?;
|
let type_ = self.parse_single_type()?;
|
||||||
self.expect(&Token::In)?;
|
self.expect(&Token::In)?;
|
||||||
|
|
||||||
// Parse iteration range.
|
// Parse iteration range.
|
||||||
@ -222,7 +222,7 @@ impl ParserContext<'_> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.expect(&Token::Colon)?;
|
self.expect(&Token::Colon)?;
|
||||||
let type_ = self.parse_all_types()?;
|
let type_ = self.parse_single_type()?;
|
||||||
|
|
||||||
self.expect(&Token::Assign)?;
|
self.expect(&Token::Assign)?;
|
||||||
let expr = self.parse_expression()?;
|
let expr = self.parse_expression()?;
|
||||||
|
@ -74,7 +74,7 @@ impl ParserContext<'_> {
|
|||||||
|
|
||||||
/// 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_all_types(&mut self) -> Result<(Type, Span)> {
|
pub fn parse_single_type(&mut self) -> Result<(Type, Span)> {
|
||||||
Ok(if let Some(ident) = self.eat_identifier() {
|
Ok(if let Some(ident) = self.eat_identifier() {
|
||||||
let span = ident.span;
|
let span = ident.span;
|
||||||
(Type::Identifier(ident), span)
|
(Type::Identifier(ident), span)
|
||||||
@ -82,4 +82,21 @@ impl ParserContext<'_> {
|
|||||||
self.parse_non_ident_types()?
|
self.parse_non_ident_types()?
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a [`(Type, Span)`] where `Type` is a `Type::Tuple` AST node.
|
||||||
|
pub fn parse_tuple_type(&mut self) -> Result<(Type, Span)> { // todo: catch and return error for nested tuple type.
|
||||||
|
let (types, _, span) = self.parse_paren_comma_list(|p| p.parse_single_type().map(Some))?;
|
||||||
|
let elements = types.into_iter().map(|(type_, _)| type_).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok((Tuple::new(elements, span)?, span))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a [`(Type, Span)`] where `Type` is a tuple or single type.
|
||||||
|
pub fn parse_any_type(&mut self) -> Result<(Type, Span)> {
|
||||||
|
if self.peek_is_left_par() {
|
||||||
|
self.parse_tuple_type()
|
||||||
|
} else {
|
||||||
|
self.parse_single_type()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ function mint(r0: address, r1: u64) -> Token {
|
|||||||
|
|
||||||
// The `transfer` function sends the specified number of tokens
|
// The `transfer` function sends the specified number of tokens
|
||||||
// to the receiver from the provided token record.
|
// to the receiver from the provided token record.
|
||||||
function transfer(r0: Token, r1: Receiver) -> Token {
|
function transfer(r0: Token, r1: Receiver) -> (Token, Token) {
|
||||||
// Checks the given token record has sufficient balance.
|
// Checks the given token record has sufficient balance.
|
||||||
// This `sub` operation is safe, and the proof will fail
|
// This `sub` operation is safe, and the proof will fail
|
||||||
// if an overflow occurs. The output register `r2` holds
|
// if an overflow occurs. The output register `r2` holds
|
||||||
@ -41,8 +41,7 @@ function transfer(r0: Token, r1: Receiver) -> Token {
|
|||||||
// with the change amount for the sender.
|
// with the change amount for the sender.
|
||||||
let r4: Token = mint(r0.owner, r0.amount);
|
let r4: Token = mint(r0.owner, r0.amount);
|
||||||
|
|
||||||
// return (r3, r4);
|
return (r3, r4);
|
||||||
return r3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() -> u8 {
|
function main() -> u8 {
|
||||||
|
@ -131,19 +131,19 @@ create_messages!(
|
|||||||
help: None,
|
help: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For when a user tries to define a tuple dimension of 1.
|
/// For when a user tries to define an empty tuple.
|
||||||
@formatted
|
@formatted
|
||||||
empty_tuple {
|
empty_tuple {
|
||||||
args: (),
|
args: (),
|
||||||
msg: "Tuples of 0 elements are not allowed.",
|
msg: "Tuples of zero elements are not allowed.",
|
||||||
help: None,
|
help: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For when a user tries to define a tuple dimension of 1.
|
/// For when a user tries to define a tuple dimension of one.
|
||||||
@formatted
|
@formatted
|
||||||
one_element_tuple {
|
one_element_tuple {
|
||||||
args: (),
|
args: (),
|
||||||
msg: "Tuples of 1 element are not allowed.",
|
msg: "Tuples of one element are not allowed.",
|
||||||
help: Some("Try defining a single type by removing the parenthesis `( )`".to_string()),
|
help: Some("Try defining a single type by removing the parenthesis `( )`".to_string()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ create_messages!(
|
|||||||
@formatted
|
@formatted
|
||||||
incorrect_tuple_length {
|
incorrect_tuple_length {
|
||||||
args: (expected: impl Display, actual: impl Display),
|
args: (expected: impl Display, actual: impl Display),
|
||||||
msg: format!("Expected a tuple of length `{expected}` got `{actual}`"),
|
msg: format!("Expected a tuple of length `{expected}` found length `{actual}`"),
|
||||||
help: None,
|
help: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user