More tuple pattern work
This commit is contained in:
parent
48e2d9a683
commit
a03f570266
1
TODO.md
1
TODO.md
@ -3,6 +3,7 @@
|
||||
## Testing
|
||||
|
||||
* Get a test library for running many unit tests working
|
||||
* Write a human-readable display of the AST
|
||||
|
||||
## Symbols
|
||||
|
||||
|
@ -830,6 +830,55 @@ fn if_expr() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advanced_if_expr() {
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
r#"
|
||||
if (45, "panda", false, 2.2) {
|
||||
is (49, "pablo", _, 28.4) then "no"
|
||||
is (_, "panda", _, -2.2) then "yes"
|
||||
is _ then "maybe"
|
||||
}"#,
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s r#"(45, "panda", false, 2.2)"#))),
|
||||
body: bx!(IfExpressionBody::CondList(vec![
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(49) }),
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(pablo))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: FloatLiteral(28.4) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""no""#)],
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(panda))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: FloatLiteral(2.2) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""yes""#)],
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::Ignored),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""maybe""#)],
|
||||
},
|
||||
]))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modules() {
|
||||
parse_test_wrap_ast! {
|
||||
@ -890,4 +939,3 @@ fn annotations() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -311,8 +311,11 @@ impl ast::Pattern {
|
||||
ast::Pattern::Ignored => {
|
||||
Pattern::Ignored
|
||||
},
|
||||
ast::Pattern::TuplePattern(/*Vec<Pattern>*/..) => {
|
||||
unimplemented!()
|
||||
ast::Pattern::TuplePattern(subpatterns) => {
|
||||
let pats: Vec<_> = subpatterns.iter().map(|pat| pat.reduce(symbol_table)).collect();
|
||||
let pats: Result<Vec<Pattern>, PatternError> = pats.into_iter().collect();
|
||||
let pats = pats?;
|
||||
Pattern::Tuple(pats)
|
||||
},
|
||||
ast::Pattern::Literal(lit) => Pattern::Literal(match lit {
|
||||
ast::PatternLiteral::NumPattern { neg, num } => match (neg, num) {
|
||||
|
@ -125,6 +125,7 @@ pub struct Alternative {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Pattern {
|
||||
Tuple(Vec<Pattern>),
|
||||
Literal(Literal),
|
||||
Ignored,
|
||||
}
|
||||
|
@ -284,6 +284,11 @@ impl<'a> State<'a> {
|
||||
} else {
|
||||
false
|
||||
},
|
||||
Pattern::Tuple(subpatterns) => match scrut {
|
||||
Primitive::Tuple(items) if items.len() == subpatterns.len() =>
|
||||
items.iter().zip(subpatterns.iter()).all(|(item, subpat)| matches(item, subpat)),
|
||||
_ => false //TODO should be a type error
|
||||
}
|
||||
}
|
||||
}
|
||||
let cond = self.expression(cond)?;
|
||||
@ -413,6 +418,7 @@ impl<'a> State<'a> {
|
||||
(BooleanNot, Lit(Bool(false))) => Bool(true),
|
||||
(Negate, Lit(Nat(n))) => Int(-(*n as i64)),
|
||||
(Negate, Lit(Int(n))) => Int(-(*n as i64)),
|
||||
(Negate, Lit(Float(f))) => Float(-(*f as f64)),
|
||||
(Increment, Lit(Int(n))) => Int(*n),
|
||||
(Increment, Lit(Nat(n))) => Nat(*n),
|
||||
_ => return Err("No valid prefix op".into())
|
||||
|
@ -116,6 +116,21 @@ if x {
|
||||
eval_assert(&source, expected);
|
||||
}
|
||||
|
||||
#[test_case(r#"(45, "panda", false, 2.2)"#, r#""yes""#)]
|
||||
#[test_case(r#"(99, "panda", false, -2.45)"#, r#""maybe""#)]
|
||||
fn tuple_patterns(input: &str, expected: &str) {
|
||||
let mut source = format!("let x = {}", input);
|
||||
source.push_str(r#"
|
||||
if x {
|
||||
is (45, "pablo", _, 28.4) then "no"
|
||||
is (_, "panda", _, 2.2) then "yes"
|
||||
is _ then "maybe"
|
||||
}"#);
|
||||
println!("{}", source);
|
||||
|
||||
eval_assert(&source, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_is_patterns() {
|
||||
let source = r#"
|
||||
|
Loading…
Reference in New Issue
Block a user