mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
use new parser for If
This commit is contained in:
parent
30ecd378a0
commit
5d8944fc6a
2 changed files with 76 additions and 34 deletions
|
@ -11,7 +11,7 @@ use crate::number_literal::number_literal;
|
|||
use crate::parser::{
|
||||
self, allocated, and_then_with_indent_level, ascii_char, ascii_string, attempt, backtrackable,
|
||||
fail, map, newline_char, not, not_followed_by, optional, sep_by1, specialize, specialize_ref,
|
||||
then, unexpected, unexpected_eof, word1, word2, EExpr, Either, ParseResult, Parser, State,
|
||||
then, unexpected, unexpected_eof, word1, word2, EExpr, Either, If, ParseResult, Parser, State,
|
||||
SyntaxError, When,
|
||||
};
|
||||
use crate::pattern::loc_closure_param;
|
||||
|
@ -1234,40 +1234,62 @@ mod when {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
skip_first!(
|
||||
parser::keyword(keyword::IF, min_indent),
|
||||
space1_around(
|
||||
pub fn if_expr_help<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, If<'a>> {
|
||||
move |arena: &'a Bump, state| {
|
||||
let (_, _, state) = parser::keyword_e(keyword::IF, If::If).parse(arena, state)?;
|
||||
|
||||
let mut branches = Vec::with_capacity_in(1, arena);
|
||||
|
||||
let (_, cond, state) = space0_around_e(
|
||||
specialize_ref(
|
||||
If::Syntax,
|
||||
loc!(move |arena, state| parse_expr(min_indent, arena, state)),
|
||||
min_indent,
|
||||
)
|
||||
),
|
||||
and!(
|
||||
skip_first!(
|
||||
parser::keyword(keyword::THEN, min_indent),
|
||||
space1_around(
|
||||
min_indent,
|
||||
If::Space,
|
||||
If::IndentCondition,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let (_, _, state) = parser::keyword_e(keyword::THEN, If::Then).parse(arena, state)?;
|
||||
|
||||
let (_, then_branch, state) = space0_around_e(
|
||||
specialize_ref(
|
||||
If::Syntax,
|
||||
loc!(move |arena, state| parse_expr(min_indent, arena, state)),
|
||||
min_indent,
|
||||
)
|
||||
),
|
||||
skip_first!(
|
||||
parser::keyword(keyword::ELSE, min_indent),
|
||||
// NOTE changed this from space1_around to space1_before
|
||||
space1_before(
|
||||
min_indent,
|
||||
If::Space,
|
||||
If::IndentThen,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
|
||||
let (_, _, state) = parser::keyword_e(keyword::ELSE, If::Else).parse(arena, state)?;
|
||||
|
||||
branches.push((cond, then_branch));
|
||||
|
||||
let (_, else_branch, state) = space0_before_e(
|
||||
specialize_ref(
|
||||
If::Syntax,
|
||||
loc!(move |arena, state| parse_expr(min_indent, arena, state)),
|
||||
min_indent,
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|arena: &'a Bump, (condition, (then_branch, else_branch))| {
|
||||
Expr::If(
|
||||
arena.alloc([(condition, then_branch)]),
|
||||
&*arena.alloc(else_branch),
|
||||
min_indent,
|
||||
If::Space,
|
||||
If::IndentElse,
|
||||
)
|
||||
.parse(arena, state)?;
|
||||
|
||||
// parse the final else
|
||||
let expr = Expr::If(branches.into_bump_slice(), arena.alloc(else_branch));
|
||||
|
||||
Ok((MadeProgress, expr, state))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn if_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
|
||||
specialize(
|
||||
|e, r, c| SyntaxError::Expr(EExpr::If(e, r, c)),
|
||||
if_expr_help(min_indent),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -378,6 +378,7 @@ pub enum EExpr<'a> {
|
|||
Space(BadInputError, Row, Col),
|
||||
|
||||
When(When<'a>, Row, Col),
|
||||
If(If<'a>, Row, Col),
|
||||
|
||||
// EInParens(PInParens<'a>, Row, Col),
|
||||
IndentStart(Row, Col),
|
||||
|
@ -408,6 +409,25 @@ pub enum When<'a> {
|
|||
PatternAlignment(u16, Row, Col),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum If<'a> {
|
||||
Space(BadInputError, Row, Col),
|
||||
If(Row, Col),
|
||||
Then(Row, Col),
|
||||
Else(Row, Col),
|
||||
// TODO make EEXpr
|
||||
Condition(&'a EExpr<'a>, Row, Col),
|
||||
ThenBranch(&'a EExpr<'a>, Row, Col),
|
||||
ElseBranch(&'a EExpr<'a>, Row, Col),
|
||||
Syntax(&'a SyntaxError<'a>, Row, Col),
|
||||
|
||||
IndentCondition(Row, Col),
|
||||
IndentThen(Row, Col),
|
||||
IndentElse(Row, Col),
|
||||
|
||||
PatternAlignment(u16, Row, Col),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EPattern<'a> {
|
||||
Record(PRecord<'a>, Row, Col),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue