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:
greg 2019-10-10 03:56:35 -07:00
parent 95e278d1b5
commit 811c52c8d3

View File

@ -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
})
}