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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Guard {
|
pub enum Guard {
|
||||||
|
None,
|
||||||
Pat(Pattern),
|
Pat(Pattern),
|
||||||
HalfExpr(HalfExpr)
|
HalfExpr(HalfExpr)
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@
|
|||||||
//! simple_pattern_match := pattern "then" conditional
|
//! simple_pattern_match := pattern "then" conditional
|
||||||
//! else_clause := ε | "else" expr_or_block
|
//! else_clause := ε | "else" expr_or_block
|
||||||
//! guard_block := "{" (guard_arm, ",")* "}"
|
//! 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
|
//! guard := "is" pattern | (operator)+ precedence_expr
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -893,11 +893,17 @@ impl Parser {
|
|||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn guard_arm(&mut self) -> ParseResult<GuardArm> {
|
fn guard_arm(&mut self) -> ParseResult<GuardArm> {
|
||||||
|
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()?;
|
let guard = self.guard()?;
|
||||||
expect!(self, Keyword(Kw::Then));
|
expect!(self, Keyword(Kw::Then));
|
||||||
let body = self.expr_or_block()?;
|
let body = self.expr_or_block()?;
|
||||||
Ok(GuardArm { guard, body })
|
Ok(GuardArm { guard, body })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[recursive_descent_method]
|
#[recursive_descent_method]
|
||||||
fn guard(&mut self) -> ParseResult<Guard> {
|
fn guard(&mut self) -> ParseResult<Guard> {
|
||||||
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use super::tokenize;
|
use super::tokenize;
|
||||||
use super::ParseResult;
|
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::Declaration::*;
|
||||||
use super::Signature;
|
use super::Signature;
|
||||||
use super::TypeIdentifier::*;
|
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![];
|
let mut alternatives = vec![];
|
||||||
for arm in guard_arms {
|
for arm in guard_arms {
|
||||||
match arm.guard {
|
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) => {
|
Guard::Pat(ref p) => {
|
||||||
let item = self.block(&arm.body);
|
let item = self.block(&arm.body);
|
||||||
let alt = p.to_alternative(item, symbol_table);
|
let alt = p.to_alternative(item, symbol_table);
|
||||||
|
Loading…
Reference in New Issue
Block a user