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
1 changed files with 36 additions and 37 deletions

View File

@ -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); match self.token_handler.peek_kind() {
loop { Comma | Semicolon | Newline => { self.token_handler.next(); continue; },
match self.token_handler.peek_kind() { _ => break,
Semicolon | Newline => { self.token_handler.next(); continue; },
_ => 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));
let body = self.expr_or_block()?; (condition, guard)
Ok(GuardArm { guard, body }) };
} let body = self.expr_or_block()?;
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
}) })
} }