mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-24 02:31:44 +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.
|
||||
fn parse_expr_tuple(&mut self) -> Result<(Vec<Expression>, bool, Span)> {
|
||||
/// Parses a tuple of `Expression` AST nodes.
|
||||
pub(crate) fn parse_expr_tuple(&mut self) -> Result<(Vec<Expression>, bool, Span)> {
|
||||
self.parse_paren_comma_list(|p| p.parse_expression().map(Some))
|
||||
}
|
||||
|
||||
@ -384,7 +384,10 @@ impl ParserContext<'_> {
|
||||
if !trailing && tuple.len() == 1 {
|
||||
Ok(tuple.swap_remove(0))
|
||||
} 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)> {
|
||||
let name = self.expect_ident()?;
|
||||
self.expect(&Token::Colon)?;
|
||||
let type_ = self.parse_all_types()?.0;
|
||||
let type_ = self.parse_single_type()?.0;
|
||||
|
||||
Ok((name, type_))
|
||||
}
|
||||
@ -201,7 +201,7 @@ impl ParserContext<'_> {
|
||||
let name = self.expect_ident()?;
|
||||
|
||||
self.expect(&Token::Colon)?;
|
||||
let type_ = self.parse_all_types()?.0;
|
||||
let type_ = self.parse_single_type()?.0;
|
||||
Ok(FunctionInput::Variable(FunctionInputVariable::new(
|
||||
name, mode, type_, name.span,
|
||||
)))
|
||||
@ -229,7 +229,7 @@ impl ParserContext<'_> {
|
||||
// Parse return type.
|
||||
self.expect(&Token::Arrow)?;
|
||||
self.disallow_circuit_construction = true;
|
||||
let output = self.parse_all_types()?.0;
|
||||
let output = self.parse_any_type()?.0;
|
||||
self.disallow_circuit_construction = false;
|
||||
|
||||
// Parse the function body.
|
||||
|
@ -103,7 +103,7 @@ impl ParserContext<'_> {
|
||||
let start_span = self.expect(&Token::For)?;
|
||||
let ident = self.expect_ident()?;
|
||||
self.expect(&Token::Colon)?;
|
||||
let type_ = self.parse_all_types()?;
|
||||
let type_ = self.parse_single_type()?;
|
||||
self.expect(&Token::In)?;
|
||||
|
||||
// Parse iteration range.
|
||||
@ -222,7 +222,7 @@ impl ParserContext<'_> {
|
||||
};
|
||||
|
||||
self.expect(&Token::Colon)?;
|
||||
let type_ = self.parse_all_types()?;
|
||||
let type_ = self.parse_single_type()?;
|
||||
|
||||
self.expect(&Token::Assign)?;
|
||||
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.
|
||||
/// 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() {
|
||||
let span = ident.span;
|
||||
(Type::Identifier(ident), span)
|
||||
@ -82,4 +82,21 @@ impl ParserContext<'_> {
|
||||
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
|
||||
// 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.
|
||||
// This `sub` operation is safe, and the proof will fail
|
||||
// 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.
|
||||
let r4: Token = mint(r0.owner, r0.amount);
|
||||
|
||||
// return (r3, r4);
|
||||
return r3;
|
||||
return (r3, r4);
|
||||
}
|
||||
|
||||
function main() -> u8 {
|
||||
|
@ -131,19 +131,19 @@ create_messages!(
|
||||
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
|
||||
empty_tuple {
|
||||
args: (),
|
||||
msg: "Tuples of 0 elements are not allowed.",
|
||||
msg: "Tuples of zero elements are not allowed.",
|
||||
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
|
||||
one_element_tuple {
|
||||
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()),
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ create_messages!(
|
||||
@formatted
|
||||
incorrect_tuple_length {
|
||||
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,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user