Introduce bare else clause in if exprs
With a non-passing test
This commit is contained in:
parent
22efd39114
commit
2ed84de641
@ -239,6 +239,7 @@ pub struct GuardArm {
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Guard {
|
||||
None,
|
||||
Pat(Pattern),
|
||||
HalfExpr(HalfExpr)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@
|
||||
//! simple_pattern_match := pattern "then" conditional
|
||||
//! else_clause := ε | "else" expr_or_block
|
||||
//! guard_block := "{" (guard_arm, ",")* "}"
|
||||
//! guard_arm := guard "then" expr_or_block
|
||||
//! guard_arm := guard "then" expr_or_block | "else" expr_or_block
|
||||
//! guard := "is" pattern | (operator)+ precedence_expr
|
||||
//! ```
|
||||
//!
|
||||
@ -893,10 +893,16 @@ impl Parser {
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn guard_arm(&mut self) -> ParseResult<GuardArm> {
|
||||
let guard = self.guard()?;
|
||||
expect!(self, Keyword(Kw::Then));
|
||||
let body = self.expr_or_block()?;
|
||||
Ok(GuardArm { guard, body })
|
||||
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 })
|
||||
} else {
|
||||
let guard = self.guard()?;
|
||||
expect!(self, Keyword(Kw::Then));
|
||||
let body = self.expr_or_block()?;
|
||||
Ok(GuardArm { guard, body })
|
||||
}
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
||||
|
||||
use super::tokenize;
|
||||
use super::ParseResult;
|
||||
use crate::ast::{ItemIdStore, AST, Expression, Statement, StatementKind, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName, ImportSpecifier, ImportedNames};
|
||||
use crate::ast::{ItemIdStore, AST, Expression, Statement, StatementKind, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName, ImportSpecifier, ImportedNames, GuardArm, Guard};
|
||||
use super::Declaration::*;
|
||||
use super::Signature;
|
||||
use super::TypeIdentifier::*;
|
||||
@ -761,3 +761,27 @@ fn imports_4() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn if_expr() {
|
||||
parse_test_wrap_ast! {
|
||||
"if x { 1 then 5, else 20 }",
|
||||
exst! {
|
||||
IfExpression {
|
||||
discriminator: bx!(Discriminator::Simple(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::GuardList(
|
||||
vec![
|
||||
GuardArm {
|
||||
guard: Guard::Pat(Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1)})),
|
||||
body: vec![exst!(s "5")],
|
||||
},
|
||||
GuardArm {
|
||||
guard: Guard::None,
|
||||
body: vec![exst!(s "20")],
|
||||
},
|
||||
]
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +276,16 @@ impl<'a> Reducer<'a> {
|
||||
let mut alternatives = vec![];
|
||||
for arm in guard_arms {
|
||||
match arm.guard {
|
||||
Guard::None => {
|
||||
let item = self.block(&arm.body);
|
||||
let alt = Alternative {
|
||||
item, matchable: Subpattern {
|
||||
tag: None, subpatterns: vec![],
|
||||
bound_vars: vec![], guard: None,
|
||||
}
|
||||
};
|
||||
alternatives.push(alt);
|
||||
},
|
||||
Guard::Pat(ref p) => {
|
||||
let item = self.block(&arm.body);
|
||||
let alt = p.to_alternative(item, symbol_table);
|
||||
|
Loading…
Reference in New Issue
Block a user