mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Fix some defs parsing logic
This commit is contained in:
parent
fb646a5fa7
commit
49d2faad4e
2 changed files with 28 additions and 8 deletions
|
@ -33,7 +33,7 @@ use parse::number_literal::number_literal;
|
||||||
use parse::parser::{
|
use parse::parser::{
|
||||||
and, attempt, between, char, either, loc, map, map_with_arena, one_of4, one_of5, one_of9,
|
and, attempt, between, char, either, loc, map, map_with_arena, one_of4, one_of5, one_of9,
|
||||||
one_or_more, optional, sep_by0, skip_first, skip_second, string, then, unexpected,
|
one_or_more, optional, sep_by0, skip_first, skip_second, string, then, unexpected,
|
||||||
unexpected_eof, zero_or_more, Either, ParseResult, Parser, State,
|
unexpected_eof, zero_or_more, Either, Fail, FailReason, ParseResult, Parser, State,
|
||||||
};
|
};
|
||||||
use parse::string_literal::string_literal;
|
use parse::string_literal::string_literal;
|
||||||
use region::Located;
|
use region::Located;
|
||||||
|
@ -187,6 +187,9 @@ pub fn loc_parenthetical_expr<'a>(min_indent: u16) -> impl Parser<'a, Located<Ex
|
||||||
/// * A type annotation
|
/// * A type annotation
|
||||||
/// * Both
|
/// * Both
|
||||||
pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>> {
|
pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>> {
|
||||||
|
// Indented more beyond the original indent.
|
||||||
|
let indented_more = min_indent + 1;
|
||||||
|
|
||||||
// TODO support type annotations
|
// TODO support type annotations
|
||||||
map_with_arena(
|
map_with_arena(
|
||||||
and(
|
and(
|
||||||
|
@ -195,7 +198,7 @@ pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>> {
|
||||||
char('='),
|
char('='),
|
||||||
),
|
),
|
||||||
space0_before(
|
space0_before(
|
||||||
loc(move |arena, state| parse_expr(min_indent, arena, state)),
|
loc(move |arena, state| parse_expr(indented_more, arena, state)),
|
||||||
min_indent,
|
min_indent,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -228,24 +231,41 @@ fn parse_def_expr<'a>(
|
||||||
let original_indent = state.indent_col;
|
let original_indent = state.indent_col;
|
||||||
|
|
||||||
if original_indent < min_indent {
|
if original_indent < min_indent {
|
||||||
panic!("TODO this declaration is outdented too far");
|
Err((
|
||||||
|
Fail {
|
||||||
|
attempting: state.attempting,
|
||||||
|
reason: FailReason::DefOutdentedTooFar(
|
||||||
|
original_indent,
|
||||||
|
min_indent,
|
||||||
|
loc_first_pattern.region,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
state,
|
||||||
|
))
|
||||||
// `<` because '=' should be same indent or greater
|
// `<` because '=' should be same indent or greater
|
||||||
} else if equals_sign_indent < original_indent {
|
} else if equals_sign_indent < original_indent {
|
||||||
panic!("TODO the = in this declaration seems outdented");
|
panic!("TODO the = in this declaration seems outdented");
|
||||||
} else {
|
} else {
|
||||||
|
// Indented more beyond the original indent.
|
||||||
|
let indented_more = original_indent + 1;
|
||||||
|
|
||||||
then(
|
then(
|
||||||
and(
|
and(
|
||||||
// Parse the body of the first def. It doesn't need any spaces
|
// Parse the body of the first def. It doesn't need any spaces
|
||||||
// around it parsed, because both the subsquent defs and the
|
// around it parsed, because both the subsquent defs and the
|
||||||
// final body will have space1_before on them.
|
// final body will have space1_before on them.
|
||||||
loc(move |arena, state| parse_expr(original_indent + 1, arena, state)),
|
//
|
||||||
|
// It should be indented more than the original, and it will
|
||||||
|
// end when outdented again.
|
||||||
|
loc(move |arena, state| parse_expr(indented_more, arena, state)),
|
||||||
and(
|
and(
|
||||||
// Optionally parse additional defs.
|
// Optionally parse additional defs.
|
||||||
zero_or_more(nested_def(original_indent)),
|
zero_or_more(nested_def(original_indent)),
|
||||||
// Parse the final expression that will be returned
|
// Parse the final expression that will be returned.
|
||||||
|
// It should be indented the same amount as the original.
|
||||||
space1_before(
|
space1_before(
|
||||||
loc(move |arena, state| parse_expr(original_indent + 1, arena, state)),
|
loc(move |arena, state| parse_expr(original_indent, arena, state)),
|
||||||
original_indent + 1,
|
indented_more,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -466,7 +486,6 @@ pub fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
|
||||||
// This appears to be a var, keyword, or function application.
|
// This appears to be a var, keyword, or function application.
|
||||||
match opt_extras {
|
match opt_extras {
|
||||||
Some(Either::First(loc_args)) => {
|
Some(Either::First(loc_args)) => {
|
||||||
let len = loc_ident.value.len();
|
|
||||||
let loc_expr = Located {
|
let loc_expr = Located {
|
||||||
region: loc_ident.region,
|
region: loc_ident.region,
|
||||||
value: ident_to_expr(loc_ident.value),
|
value: ident_to_expr(loc_ident.value),
|
||||||
|
|
|
@ -136,6 +136,7 @@ pub type ParseResult<'a, Output> = Result<(Output, State<'a>), (Fail, State<'a>)
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum FailReason {
|
pub enum FailReason {
|
||||||
Unexpected(char, Region),
|
Unexpected(char, Region),
|
||||||
|
DefOutdentedTooFar(u16, u16, Region),
|
||||||
ConditionFailed,
|
ConditionFailed,
|
||||||
LineTooLong(u32 /* which line was too long */),
|
LineTooLong(u32 /* which line was too long */),
|
||||||
TooManyLines,
|
TooManyLines,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue