Handle negatives in patterns correctly
This commit is contained in:
parent
5c9180efc2
commit
fa7b6ce96b
@ -157,7 +157,10 @@ pub enum Pattern {
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum PatternLiteral {
|
||||
NumPattern(ExpressionType), //TODO fix
|
||||
NumPattern {
|
||||
neg: bool,
|
||||
num: ExpressionType,
|
||||
},
|
||||
StringPattern(Rc<String>),
|
||||
BoolPattern(bool),
|
||||
VarPattern(Rc<String>)
|
||||
|
@ -235,7 +235,8 @@ digits := (DIGIT_GROUP underscore)+
|
||||
/* Pattern syntax */
|
||||
pattern := '(' (pattern, ',')* ')' | simple_pattern
|
||||
simple_pattern := pattern_literal | record_pattern | tuple_struct_pattern
|
||||
pattern_literal := 'true' | 'false' | number_literal | STR_LITERAL | IDENTIFIER
|
||||
pattern_literal := 'true' | 'false' | signed_number_literal | STR_LITERAL | IDENTIFIER
|
||||
signed_number_literal := '-'? number_literal
|
||||
record_pattern := IDENTIFIER '{' (record_pattern_entry, ',')* '}'
|
||||
record_pattern_entry := IDENTIFIER | IDENTIFIER ':' Pattern
|
||||
tuple_struct_pattern := IDENTIFIER '(' (pattern, ',')* ')'
|
||||
@ -735,14 +736,12 @@ impl Parser {
|
||||
_ => Pattern::Literal(PatternLiteral::VarPattern(id))
|
||||
}
|
||||
},
|
||||
//TODO I think these are buggy b/c they don't advance the parser
|
||||
Keyword(Kw::True) => Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
||||
Keyword(Kw::False) => Pattern::Literal(PatternLiteral::BoolPattern(false)),
|
||||
StrLiteral(s) => Pattern::Literal(PatternLiteral::StringPattern(s)),
|
||||
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => {
|
||||
//TODO handle negatives
|
||||
let Expression(expr_type, _) = self.number_literal()?;
|
||||
Pattern::Literal(PatternLiteral::NumPattern(expr_type))
|
||||
},
|
||||
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.signed_number_literal()?,
|
||||
Operator(ref op) if **op == "-" => self.signed_number_literal()?,
|
||||
Underscore => {
|
||||
self.next();
|
||||
Pattern::Ignored
|
||||
@ -751,6 +750,18 @@ impl Parser {
|
||||
})
|
||||
});
|
||||
|
||||
parse_method!(signed_number_literal(&mut self) -> ParseResult<Pattern> {
|
||||
let neg = match self.peek() {
|
||||
Operator(ref op) if **op == "-" => {
|
||||
self.next();
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
};
|
||||
let Expression(expr_type, _) = self.number_literal()?;
|
||||
Ok(Pattern::Literal(PatternLiteral::NumPattern { neg, num: expr_type }))
|
||||
});
|
||||
|
||||
parse_method!(record_pattern_entry(&mut self) -> ParseResult<(Rc<String>, Pattern)> {
|
||||
let name = self.identifier()?;
|
||||
Ok(match self.peek() {
|
||||
@ -1439,5 +1450,37 @@ fn a(x) {
|
||||
)
|
||||
])
|
||||
}
|
||||
|
||||
parse_test! {
|
||||
"if x is -1 then 1 else 2", AST(vec![
|
||||
exprstatement!(
|
||||
IfExpression {
|
||||
discriminator: bx!(Discriminator::Simple(ex!(Value(rc!(x))))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: NatLiteral(1) }),
|
||||
vec![exprstatement!(NatLiteral(1))],
|
||||
Some(vec![exprstatement!(NatLiteral(2))]),
|
||||
))
|
||||
}
|
||||
)
|
||||
])
|
||||
}
|
||||
|
||||
parse_test! {
|
||||
"if x is 1 then 1 else 2", AST(vec![
|
||||
exprstatement!(
|
||||
IfExpression {
|
||||
discriminator: bx!(Discriminator::Simple(ex!(Value(rc!(x))))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch(
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1) }),
|
||||
vec![exprstatement!(NatLiteral(1))],
|
||||
Some(vec![exprstatement!(NatLiteral(2))]),
|
||||
))
|
||||
}
|
||||
)
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
||||
item: then_clause,
|
||||
}
|
||||
},
|
||||
_ => panic!()
|
||||
e => { println!("SAW {:?}", e); panic!() }
|
||||
};
|
||||
|
||||
let alternatives = vec![
|
||||
@ -196,7 +196,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
||||
Guard::Pat(ref p) => match p {
|
||||
Pattern::Ignored => (None, vec![]),
|
||||
Pattern::Literal(lit) => match lit {
|
||||
PatternLiteral::NumPattern(_expr) => unimplemented!(),
|
||||
PatternLiteral::NumPattern { neg, num } => unimplemented!(),
|
||||
PatternLiteral::StringPattern(_s) => unimplemented!(),
|
||||
PatternLiteral::BoolPattern(_b) => unimplemented!(),
|
||||
PatternLiteral::VarPattern(_var) => unimplemented!(),
|
||||
|
Loading…
Reference in New Issue
Block a user