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
|
//! simple_pattern_match := pattern "then" simple_conditional
|
||||||
//! else_case := "else" expr_or_block
|
//! else_case := "else" expr_or_block
|
||||||
//!
|
//!
|
||||||
//! cond_block := "{" (cond_arm comma_or_delimiter)* ("else" expr_or_block) "}"
|
//! cond_block := "{" (cond_arm comma_or_delimiter)* "}"
|
||||||
//! cond_arm := condition guard "then" expr_or_block
|
//! cond_arm := condition guard "then" expr_or_block | "else" expr_or_block
|
||||||
//! condition := "is" pattern | operator precedence_expr | expression
|
//! condition := "is" pattern | operator precedence_expr | expression
|
||||||
//! guard := "if" expression
|
//! guard := "if" expression
|
||||||
//! comma_or_delimiter := "," | delimiter
|
//! comma_or_delimiter := "," | delimiter
|
||||||
@ -624,6 +624,7 @@ impl Parser {
|
|||||||
let next_tok = self.token_handler.next();
|
let next_tok = self.token_handler.next();
|
||||||
let operation = match BinOp::from_sigil_token(&next_tok.kind) {
|
let operation = match BinOp::from_sigil_token(&next_tok.kind) {
|
||||||
Some(sigil) => sigil,
|
Some(sigil) => sigil,
|
||||||
|
//TODO I think I can fix this unreachable
|
||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
};
|
};
|
||||||
let rhs = self.precedence_expr(new_precedence)?;
|
let rhs = self.precedence_expr(new_precedence)?;
|
||||||
@ -860,68 +861,66 @@ impl Parser {
|
|||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn cond_block(&mut self) -> ParseResult<IfExpressionBody> {
|
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);
|
expect!(self, LCurlyBrace);
|
||||||
|
let mut cond_arms = vec![];
|
||||||
let mut guards = vec![];
|
|
||||||
loop {
|
loop {
|
||||||
match self.token_handler.peek_kind() {
|
match self.token_handler.peek_kind() {
|
||||||
RCurlyBrace | EOF => break,
|
RCurlyBrace | EOF => break,
|
||||||
Semicolon | Newline => { self.token_handler.next(); continue},
|
Semicolon | Newline => { self.token_handler.next(); continue},
|
||||||
_ => {
|
_ => {
|
||||||
let guard_arm = self.guard_arm()?;
|
cond_arms.push(self.cond_arm()?);
|
||||||
guards.push(guard_arm);
|
|
||||||
loop {
|
|
||||||
match self.token_handler.peek_kind() {
|
match self.token_handler.peek_kind() {
|
||||||
Semicolon | Newline => { self.token_handler.next(); continue; },
|
Comma | Semicolon | Newline => { self.token_handler.next(); continue; },
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let RCurlyBrace = self.token_handler.peek_kind() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
expect!(self, Comma);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect!(self, RCurlyBrace);
|
expect!(self, RCurlyBrace);
|
||||||
Ok(IfExpressionBody::GuardList(guards))
|
Ok(IfExpressionBody::CondList(cond_arms))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn guard_arm(&mut self) -> ParseResult<GuardArm> {
|
fn cond_arm(&mut self) -> ParseResult<GuardArm> {
|
||||||
if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
let (condition, guard) = if let Keyword(Kw::Else) = self.token_handler.peek_kind() {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
let body = self.expr_or_block()?;
|
(Condition:Else, None)
|
||||||
Ok(GuardArm { guard: Guard::None, body })
|
|
||||||
} else {
|
} else {
|
||||||
|
let condition = self.condition()?;
|
||||||
let guard = self.guard()?;
|
let guard = self.guard()?;
|
||||||
expect!(self, Keyword(Kw::Then));
|
expect!(self, Keyword(Kw::Then));
|
||||||
|
(condition, guard)
|
||||||
|
};
|
||||||
let body = self.expr_or_block()?;
|
let body = self.expr_or_block()?;
|
||||||
Ok(GuardArm { guard, body })
|
Ok(ConditionArm { condition, guard, body })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn guard(&mut self) -> ParseResult<Guard> {
|
fn condition(&mut self) -> ParseResult<Condition> {
|
||||||
Ok(match self.token_handler.peek_kind() {
|
Ok(match self.token_handler.peek_kind() {
|
||||||
Keyword(Kw::Is) => {
|
Keyword(Kw::Is) => {
|
||||||
self.token_handler.next();
|
self.token_handler.next();
|
||||||
let pat = self.pattern()?;
|
Condition::Pattern(self.pattern()?)
|
||||||
Guard::Pat(pat)
|
|
||||||
},
|
},
|
||||||
ref tok if BinOp::from_sigil_token(tok).is_some() => {
|
Operator(ref op) if !PrefixOp::is_prefix(&*op) => {
|
||||||
let op = BinOp::from_sigil_token(&self.token_handler.next().kind).unwrap();
|
let op = self.token_handler.next();
|
||||||
let precedence = op.get_precedence();
|
let expr = Box::new(self.expression()?);
|
||||||
let Expression { kind, .. } = self.precedence_expr(precedence)?;
|
Condition::TruncatedOp(op, expr)
|
||||||
Guard::HalfExpr(HalfExpr { op: Some(op), expr: kind })
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
//TODO - I think there's a better way to do this involving the precedence of ->
|
Condition::Expression(self.expression()?)
|
||||||
let Expression { kind, .. } = self.prefix_expr()?;
|
},
|
||||||
Guard::HalfExpr(HalfExpr { op: None, expr: kind })
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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