More if-expr refactoring work
Think I finished all the parsing stuff, just need to fix the types everywhere else
This commit is contained in:
parent
95e278d1b5
commit
811c52c8d3
@ -126,8 +126,8 @@
|
||||
//! simple_pattern_match := pattern "then" simple_conditional
|
||||
//! else_case := "else" expr_or_block
|
||||
//!
|
||||
//! cond_block := "{" (cond_arm comma_or_delimiter)* ("else" expr_or_block) "}"
|
||||
//! cond_arm := condition guard "then" expr_or_block
|
||||
//! cond_block := "{" (cond_arm comma_or_delimiter)* "}"
|
||||
//! cond_arm := condition guard "then" expr_or_block | "else" expr_or_block
|
||||
//! condition := "is" pattern | operator precedence_expr | expression
|
||||
//! guard := "if" expression
|
||||
//! comma_or_delimiter := "," | delimiter
|
||||
@ -624,6 +624,7 @@ impl Parser {
|
||||
let next_tok = self.token_handler.next();
|
||||
let operation = match BinOp::from_sigil_token(&next_tok.kind) {
|
||||
Some(sigil) => sigil,
|
||||
//TODO I think I can fix this unreachable
|
||||
None => unreachable!()
|
||||
};
|
||||
let rhs = self.precedence_expr(new_precedence)?;
|
||||
@ -860,68 +861,66 @@ impl Parser {
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn cond_block(&mut self) -> ParseResult<IfExpressionBody> {
|
||||
//TODO - delimited! isn't sophisticated enough to do thisa
|
||||
//let guards = delimited!(self, LCurlyBrace, guard_arm, Comma, RCurlyBrace);
|
||||
expect!(self, LCurlyBrace);
|
||||
|
||||
let mut guards = vec![];
|
||||
let mut cond_arms = vec![];
|
||||
loop {
|
||||
match self.token_handler.peek_kind() {
|
||||
RCurlyBrace | EOF => break,
|
||||
Semicolon | Newline => { self.token_handler.next(); continue},
|
||||
_ => {
|
||||
let guard_arm = self.guard_arm()?;
|
||||
guards.push(guard_arm);
|
||||
loop {
|
||||
match self.token_handler.peek_kind() {
|
||||
Semicolon | Newline => { self.token_handler.next(); continue; },
|
||||
_ => break,
|
||||
}
|
||||
cond_arms.push(self.cond_arm()?);
|
||||
match self.token_handler.peek_kind() {
|
||||
Comma | Semicolon | Newline => { self.token_handler.next(); continue; },
|
||||
_ => break,
|
||||
}
|
||||
if let RCurlyBrace = self.token_handler.peek_kind() {
|
||||
break;
|
||||
}
|
||||
expect!(self, Comma);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect!(self, RCurlyBrace);
|
||||
Ok(IfExpressionBody::GuardList(guards))
|
||||
Ok(IfExpressionBody::CondList(cond_arms))
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn guard_arm(&mut self) -> ParseResult<GuardArm> {
|
||||
if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
||||
fn cond_arm(&mut self) -> ParseResult<GuardArm> {
|
||||
let (condition, guard) = if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
||||
self.token_handler.next();
|
||||
let body = self.expr_or_block()?;
|
||||
Ok(GuardArm { guard: Guard::None, body })
|
||||
(Condition:Else, None)
|
||||
} else {
|
||||
let condition = self.condition()?;
|
||||
let guard = self.guard()?;
|
||||
expect!(self, Keyword(Kw::Then));
|
||||
let body = self.expr_or_block()?;
|
||||
Ok(GuardArm { guard, body })
|
||||
}
|
||||
(condition, guard)
|
||||
};
|
||||
let body = self.expr_or_block()?;
|
||||
Ok(ConditionArm { condition, guard, body })
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn guard(&mut self) -> ParseResult<Guard> {
|
||||
fn condition(&mut self) -> ParseResult<Condition> {
|
||||
Ok(match self.token_handler.peek_kind() {
|
||||
Keyword(Kw::Is) => {
|
||||
self.token_handler.next();
|
||||
let pat = self.pattern()?;
|
||||
Guard::Pat(pat)
|
||||
Condition::Pattern(self.pattern()?)
|
||||
},
|
||||
ref tok if BinOp::from_sigil_token(tok).is_some() => {
|
||||
let op = BinOp::from_sigil_token(&self.token_handler.next().kind).unwrap();
|
||||
let precedence = op.get_precedence();
|
||||
let Expression { kind, .. } = self.precedence_expr(precedence)?;
|
||||
Guard::HalfExpr(HalfExpr { op: Some(op), expr: kind })
|
||||
Operator(ref op) if !PrefixOp::is_prefix(&*op) => {
|
||||
let op = self.token_handler.next();
|
||||
let expr = Box::new(self.expression()?);
|
||||
Condition::TruncatedOp(op, expr)
|
||||
},
|
||||
_ => {
|
||||
//TODO - I think there's a better way to do this involving the precedence of ->
|
||||
let Expression { kind, .. } = self.prefix_expr()?;
|
||||
Guard::HalfExpr(HalfExpr { op: None, expr: kind })
|
||||
}
|
||||
Condition::Expression(self.expression()?)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn guard(&mut self) -> ParseResult<Option<Expression>> {
|
||||
Ok(match self.token_handler.peek_kind() {
|
||||
Keyword(Kw::If) => {
|
||||
self.token_handler.next();
|
||||
Some(self.expression()?)
|
||||
},
|
||||
_ => None
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user