0.5.0 -- tuples and more optimizations #12
@@ -1086,17 +1086,43 @@ impl<'a> Parser<'a> {
|
|||||||
end_col: right.span.end_col,
|
end_col: right.span.end_col,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Check if the left side is a tuple, and if so, create a TupleAssignment
|
||||||
|
let node = if let Expression::Tuple(tuple_expr) = &left.node {
|
||||||
|
// Extract variable names from the tuple, handling underscores
|
||||||
|
let mut names = Vec::new();
|
||||||
|
for item in &tuple_expr.node {
|
||||||
|
if let Expression::Variable(var) = &item.node {
|
||||||
|
names.push(var.clone());
|
||||||
|
} else {
|
||||||
|
return Err(Error::InvalidSyntax(
|
||||||
|
item.span,
|
||||||
|
String::from("Tuple assignment can only contain variable names"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::TupleAssignment(Spanned {
|
||||||
|
span,
|
||||||
|
node: TupleAssignmentExpression {
|
||||||
|
names,
|
||||||
|
value: boxed!(right),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Expression::Assignment(Spanned {
|
||||||
|
span,
|
||||||
|
node: AssignmentExpression {
|
||||||
|
assignee: boxed!(left),
|
||||||
|
expression: boxed!(right),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
expressions.insert(
|
expressions.insert(
|
||||||
i,
|
i,
|
||||||
Spanned {
|
Spanned {
|
||||||
span,
|
span,
|
||||||
node: Expression::Assignment(Spanned {
|
node,
|
||||||
span,
|
|
||||||
node: AssignmentExpression {
|
|
||||||
assignee: boxed!(left),
|
|
||||||
expression: boxed!(right),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,3 +200,56 @@ fn test_tuple_declaration() -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_assignment() -> Result<()> {
|
||||||
|
let expr = parser!("(x, y) = (1, 2);").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("((x, y) = (1, 2))", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_assignment_with_underscore() -> Result<()> {
|
||||||
|
let expr = parser!("(x, _) = (1, 2);").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("((x, _) = (1, 2))", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_declaration_with_function_call() -> Result<()> {
|
||||||
|
let expr = parser!("let (x, y) = doSomething();").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("(let (x, y) = doSomething())", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_declaration_with_function_call_with_underscore() -> Result<()> {
|
||||||
|
let expr = parser!("let (x, _) = doSomething();").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("(let (x, _) = doSomething())", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_assignment_with_function_call() -> Result<()> {
|
||||||
|
let expr = parser!("(x, y) = doSomething();").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("((x, y) = doSomething())", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_assignment_with_function_call_with_underscore() -> Result<()> {
|
||||||
|
let expr = parser!("(x, _) = doSomething();").parse()?.unwrap();
|
||||||
|
|
||||||
|
assert_eq!("((x, _) = doSomething())", expr.to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -263,6 +263,24 @@ impl<'a> std::fmt::Display for TupleDeclarationExpression<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct TupleAssignmentExpression<'a> {
|
||||||
|
pub names: Vec<Spanned<Cow<'a, str>>>,
|
||||||
|
pub value: Box<Spanned<Expression<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Display for TupleAssignmentExpression<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let names = self
|
||||||
|
.names
|
||||||
|
.iter()
|
||||||
|
.map(|n| n.node.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ");
|
||||||
|
write!(f, "(({}) = {})", names, self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct IfExpression<'a> {
|
pub struct IfExpression<'a> {
|
||||||
pub condition: Box<Spanned<Expression<'a>>>,
|
pub condition: Box<Spanned<Expression<'a>>>,
|
||||||
@@ -367,6 +385,7 @@ pub enum Expression<'a> {
|
|||||||
Syscall(Spanned<SysCall<'a>>),
|
Syscall(Spanned<SysCall<'a>>),
|
||||||
Ternary(Spanned<TernaryExpression<'a>>),
|
Ternary(Spanned<TernaryExpression<'a>>),
|
||||||
Tuple(Spanned<Vec<Spanned<Expression<'a>>>>),
|
Tuple(Spanned<Vec<Spanned<Expression<'a>>>>),
|
||||||
|
TupleAssignment(Spanned<TupleAssignmentExpression<'a>>),
|
||||||
TupleDeclaration(Spanned<TupleDeclarationExpression<'a>>),
|
TupleDeclaration(Spanned<TupleDeclarationExpression<'a>>),
|
||||||
Variable(Spanned<Cow<'a, str>>),
|
Variable(Spanned<Cow<'a, str>>),
|
||||||
While(Spanned<WhileExpression<'a>>),
|
While(Spanned<WhileExpression<'a>>),
|
||||||
@@ -413,6 +432,7 @@ impl<'a> std::fmt::Display for Expression<'a> {
|
|||||||
.join(", ");
|
.join(", ");
|
||||||
write!(f, "({})", items)
|
write!(f, "({})", items)
|
||||||
}
|
}
|
||||||
|
Expression::TupleAssignment(e) => write!(f, "{}", e),
|
||||||
Expression::TupleDeclaration(e) => write!(f, "{}", e),
|
Expression::TupleDeclaration(e) => write!(f, "{}", e),
|
||||||
Expression::Variable(id) => write!(f, "{}", id),
|
Expression::Variable(id) => write!(f, "{}", id),
|
||||||
Expression::While(e) => write!(f, "{}", e),
|
Expression::While(e) => write!(f, "{}", e),
|
||||||
|
|||||||
Reference in New Issue
Block a user