impl tuple parsing

This commit is contained in:
collin 2022-07-09 12:39:50 -07:00
parent 296c62a280
commit 9e422599a0
7 changed files with 36 additions and 17 deletions

View File

@ -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
}))
}
}

View File

@ -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.

View File

@ -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()?;

View File

@ -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()
}
}
}

View File

@ -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 {

View File

@ -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()),
}

View File

@ -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,
}