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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum PatternLiteral {
|
pub enum PatternLiteral {
|
||||||
NumPattern(ExpressionType), //TODO fix
|
NumPattern {
|
||||||
|
neg: bool,
|
||||||
|
num: ExpressionType,
|
||||||
|
},
|
||||||
StringPattern(Rc<String>),
|
StringPattern(Rc<String>),
|
||||||
BoolPattern(bool),
|
BoolPattern(bool),
|
||||||
VarPattern(Rc<String>)
|
VarPattern(Rc<String>)
|
||||||
|
@ -235,7 +235,8 @@ digits := (DIGIT_GROUP underscore)+
|
|||||||
/* Pattern syntax */
|
/* Pattern syntax */
|
||||||
pattern := '(' (pattern, ',')* ')' | simple_pattern
|
pattern := '(' (pattern, ',')* ')' | simple_pattern
|
||||||
simple_pattern := pattern_literal | record_pattern | tuple_struct_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 := IDENTIFIER '{' (record_pattern_entry, ',')* '}'
|
||||||
record_pattern_entry := IDENTIFIER | IDENTIFIER ':' Pattern
|
record_pattern_entry := IDENTIFIER | IDENTIFIER ':' Pattern
|
||||||
tuple_struct_pattern := IDENTIFIER '(' (pattern, ',')* ')'
|
tuple_struct_pattern := IDENTIFIER '(' (pattern, ',')* ')'
|
||||||
@ -735,14 +736,12 @@ impl Parser {
|
|||||||
_ => Pattern::Literal(PatternLiteral::VarPattern(id))
|
_ => 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::True) => Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
||||||
Keyword(Kw::False) => Pattern::Literal(PatternLiteral::BoolPattern(false)),
|
Keyword(Kw::False) => Pattern::Literal(PatternLiteral::BoolPattern(false)),
|
||||||
StrLiteral(s) => Pattern::Literal(PatternLiteral::StringPattern(s)),
|
StrLiteral(s) => Pattern::Literal(PatternLiteral::StringPattern(s)),
|
||||||
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => {
|
DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.signed_number_literal()?,
|
||||||
//TODO handle negatives
|
Operator(ref op) if **op == "-" => self.signed_number_literal()?,
|
||||||
let Expression(expr_type, _) = self.number_literal()?;
|
|
||||||
Pattern::Literal(PatternLiteral::NumPattern(expr_type))
|
|
||||||
},
|
|
||||||
Underscore => {
|
Underscore => {
|
||||||
self.next();
|
self.next();
|
||||||
Pattern::Ignored
|
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)> {
|
parse_method!(record_pattern_entry(&mut self) -> ParseResult<(Rc<String>, Pattern)> {
|
||||||
let name = self.identifier()?;
|
let name = self.identifier()?;
|
||||||
Ok(match self.peek() {
|
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,
|
item: then_clause,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => panic!()
|
e => { println!("SAW {:?}", e); panic!() }
|
||||||
};
|
};
|
||||||
|
|
||||||
let alternatives = vec![
|
let alternatives = vec![
|
||||||
@ -196,7 +196,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
|||||||
Guard::Pat(ref p) => match p {
|
Guard::Pat(ref p) => match p {
|
||||||
Pattern::Ignored => (None, vec![]),
|
Pattern::Ignored => (None, vec![]),
|
||||||
Pattern::Literal(lit) => match lit {
|
Pattern::Literal(lit) => match lit {
|
||||||
PatternLiteral::NumPattern(_expr) => unimplemented!(),
|
PatternLiteral::NumPattern { neg, num } => unimplemented!(),
|
||||||
PatternLiteral::StringPattern(_s) => unimplemented!(),
|
PatternLiteral::StringPattern(_s) => unimplemented!(),
|
||||||
PatternLiteral::BoolPattern(_b) => unimplemented!(),
|
PatternLiteral::BoolPattern(_b) => unimplemented!(),
|
||||||
PatternLiteral::VarPattern(_var) => unimplemented!(),
|
PatternLiteral::VarPattern(_var) => unimplemented!(),
|
||||||
|
Loading…
Reference in New Issue
Block a user