cleanup blankspace function usage

This commit is contained in:
Folkert 2021-03-11 16:37:42 +01:00
parent 92cff4c32a
commit e214674016
5 changed files with 51 additions and 66 deletions

View file

@ -15,7 +15,7 @@ use roc_region::all::{Located, Region};
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// If any newlines or comments were found, the Expr will be wrapped in a SpaceBefore and/or /// If any newlines or comments were found, the Expr will be wrapped in a SpaceBefore and/or
/// SpaceAfter as appropriate. /// SpaceAfter as appropriate.
pub fn space0_around<'a, P, S>( fn space0_around<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -119,7 +119,7 @@ where
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// If any newlines or comments were found, the Expr will be wrapped in a SpaceBefore and/or /// If any newlines or comments were found, the Expr will be wrapped in a SpaceBefore and/or
/// SpaceAfter as appropriate. /// SpaceAfter as appropriate.
pub fn space1_around<'a, P, S>( fn space1_around<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -160,7 +160,7 @@ where
/// Parses the given expression with 0 or more (spaces/comments/newlines) before it. /// Parses the given expression with 0 or more (spaces/comments/newlines) before it.
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// The Expr will be wrapped in a SpaceBefore if there were any newlines or comments found. /// The Expr will be wrapped in a SpaceBefore if there were any newlines or comments found.
pub fn space0_before<'a, P, S>( fn space0_before<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -241,7 +241,7 @@ where
/// Parses the given expression with 1 or more (spaces/comments/newlines) before it. /// Parses the given expression with 1 or more (spaces/comments/newlines) before it.
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// The Expr will be wrapped in a SpaceBefore if there were any newlines or comments found. /// The Expr will be wrapped in a SpaceBefore if there were any newlines or comments found.
pub fn space1_before<'a, P, S>( fn space1_before<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -268,7 +268,7 @@ where
/// Parses the given expression with 0 or more (spaces/comments/newlines) after it. /// Parses the given expression with 0 or more (spaces/comments/newlines) after it.
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// The Expr will be wrapped in a SpaceAfter if there were any newlines or comments found. /// The Expr will be wrapped in a SpaceAfter if there were any newlines or comments found.
pub fn space0_after<'a, P, S>( fn space0_after<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -295,7 +295,7 @@ where
/// Parses the given expression with 1 or more (spaces/comments/newlines) after it. /// Parses the given expression with 1 or more (spaces/comments/newlines) after it.
/// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces. /// Returns a Located<Expr> where the location is around the Expr, ignoring the spaces.
/// The Expr will be wrapped in a SpaceAfter if there were any newlines or comments found. /// The Expr will be wrapped in a SpaceAfter if there were any newlines or comments found.
pub fn space1_after<'a, P, S>( fn space1_after<'a, P, S>(
parser: P, parser: P,
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Located<S>, SyntaxError<'a>> ) -> impl Parser<'a, Located<S>, SyntaxError<'a>>
@ -320,7 +320,7 @@ where
} }
/// Zero or more (spaces/comments/newlines). /// Zero or more (spaces/comments/newlines).
pub fn space0<'a>(min_indent: u16) -> impl Parser<'a, &'a [CommentOrNewline<'a>], SyntaxError<'a>> { fn space0<'a>(min_indent: u16) -> impl Parser<'a, &'a [CommentOrNewline<'a>], SyntaxError<'a>> {
spaces(false, min_indent) spaces(false, min_indent)
} }
@ -360,7 +360,7 @@ where
} }
/// One or more (spaces/comments/newlines). /// One or more (spaces/comments/newlines).
pub fn space1<'a>(min_indent: u16) -> impl Parser<'a, &'a [CommentOrNewline<'a>], SyntaxError<'a>> { fn space1<'a>(min_indent: u16) -> impl Parser<'a, &'a [CommentOrNewline<'a>], SyntaxError<'a>> {
// TODO try benchmarking a short-circuit for the typical case: see if there is // TODO try benchmarking a short-circuit for the typical case: see if there is
// exactly one space followed by char that isn't [' ', '\n', or '#'], and // exactly one space followed by char that isn't [' ', '\n', or '#'], and
// if so, return empty slice. The case where there's exactly 1 space should // if so, return empty slice. The case where there's exactly 1 space should

View file

@ -20,6 +20,24 @@ use roc_region::all::{Located, Region};
use crate::parser::Progress::{self, *}; use crate::parser::Progress::{self, *};
pub fn test_parse_expr<'a>(
min_indent: u16,
arena: &'a bumpalo::Bump,
state: State<'a>,
) -> Result<(Located<Expr<'a>>, State<'a>), EExpr<'a>> {
let parser = space0_before_e(
loc!(|a, s| parse_expr_help(min_indent, a, s)),
min_indent,
EExpr::Space,
EExpr::IndentStart,
);
match parser.parse(arena, state) {
Ok((_, expression, state)) => Ok((expression, state)),
Err((_, fail, _)) => Err(fail),
}
}
// public for testing purposes // public for testing purposes
pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> { pub fn expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> {
// Recursive parsers must not directly invoke functions which return (impl Parser), // Recursive parsers must not directly invoke functions which return (impl Parser),
@ -718,47 +736,6 @@ fn assigned_expr_field_to_pattern_help<'a>(
}) })
} }
/// A def beginning with a parenthetical pattern, for example:
///
/// (UserId userId) = ...
///
/// Note: Parenthetical patterns are a shorthand convenience, and may not have type annotations.
/// It would be too weird to parse; imagine `(UserId userId) : ...` above `(UserId userId) = ...`
/// !!!! THIS IS NOT USED !!!!
// fn loc_parenthetical_def<'a>(min_indent: u16) -> impl Parser<'a, Located<Expr<'a>>> {
// move |arena, state| {
// let (loc_tuple, state) = loc!(and!(
// space0_after(
// between!(
// ascii_char(b'('),
// space0_around(loc_pattern(min_indent), min_indent),
// ascii_char(b')')
// ),
// min_indent,
// ),
// equals_with_indent()
// ))
// .parse(arena, state)?;
// let region = loc_tuple.region;
// let (loc_first_pattern, equals_sign_indent) = loc_tuple.value;
// // Continue parsing the expression as a Def.
// let (spaces_after_equals, state) = space0(min_indent).parse(arena, state)?;
// let (value, state) = parse_def_expr(
// region.start_col,
// min_indent,
// equals_sign_indent,
// arena,
// state,
// loc_first_pattern,
// spaces_after_equals,
// )?;
// Ok((Located { value, region }, state))
// }
// }
fn parse_defs_help<'a>( fn parse_defs_help<'a>(
min_indent: u16, min_indent: u16,
) -> impl Parser<'a, Vec<'a, &'a Located<Def<'a>>>, EExpr<'a>> { ) -> impl Parser<'a, Vec<'a, &'a Located<Def<'a>>>, EExpr<'a>> {
@ -795,7 +772,7 @@ pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, SyntaxError<'a>> {
specialize(|e, _, _| SyntaxError::Expr(e), def_help(min_indent)) specialize(|e, _, _| SyntaxError::Expr(e), def_help(min_indent))
} }
fn def_help<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, EExpr<'a>> { pub fn def_help<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>, EExpr<'a>> {
let indented_more = min_indent + 1; let indented_more = min_indent + 1;
enum DefKind { enum DefKind {

View file

@ -1,6 +1,5 @@
use crate::ast::{CommentOrNewline, Def, Module}; use crate::ast::{CommentOrNewline, Def, Module};
use crate::blankspace::{space0_around, space0_before_e, space0_e}; use crate::blankspace::{space0_before_e, space0_e};
use crate::expr::def;
use crate::header::{ use crate::header::{
package_entry, package_name, package_or_path, AppHeader, Effects, ExposesEntry, ImportsEntry, package_entry, package_name, package_or_path, AppHeader, Effects, ExposesEntry, ImportsEntry,
InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, To, TypedIdent, InterfaceHeader, ModuleName, PackageEntry, PlatformHeader, To, TypedIdent,
@ -252,8 +251,22 @@ fn platform_header<'a>() -> impl Parser<'a, PlatformHeader<'a>, EHeader<'a>> {
#[inline(always)] #[inline(always)]
pub fn module_defs<'a>() -> impl Parser<'a, Vec<'a, Located<Def<'a>>>, SyntaxError<'a>> { pub fn module_defs<'a>() -> impl Parser<'a, Vec<'a, Located<Def<'a>>>, SyntaxError<'a>> {
use crate::parser::EExpr;
// force that we pare until the end of the input // force that we pare until the end of the input
skip_second!(zero_or_more!(space0_around(loc!(def(0)), 0)), end_of_file()) let min_indent = 0;
skip_second!(
specialize(
|e, _, _| SyntaxError::Expr(e),
zero_or_more!(crate::blankspace::space0_around_ee(
loc!(crate::expr::def_help(min_indent)),
min_indent,
EExpr::Space,
EExpr::IndentStart,
EExpr::IndentEnd,
))
),
end_of_file()
)
} }
#[derive(Debug)] #[derive(Debug)]
struct ProvidesTo<'a> { struct ProvidesTo<'a> {

View file

@ -1,5 +1,4 @@
use crate::ast; use crate::ast;
use crate::blankspace::space0_before;
use crate::expr::expr; use crate::expr::expr;
use crate::module::module_defs; use crate::module::module_defs;
use crate::parser::{loc, Parser, State, SyntaxError}; use crate::parser::{loc, Parser, State, SyntaxError};
@ -32,10 +31,9 @@ pub fn parse_loc_with<'a>(
input: &'a str, input: &'a str,
) -> Result<Located<ast::Expr<'a>>, SyntaxError<'a>> { ) -> Result<Located<ast::Expr<'a>>, SyntaxError<'a>> {
let state = State::new_in(arena, input.trim().as_bytes()); let state = State::new_in(arena, input.trim().as_bytes());
let parser = space0_before(loc(expr(0)), 0);
let answer = parser.parse(&arena, state);
answer match crate::expr::test_parse_expr(0, arena, state) {
.map(|(_, loc_expr, _)| loc_expr) Ok((loc_expr, _state)) => Ok(loc_expr),
.map_err(|(_, fail, _)| fail) Err(fail) => Err(SyntaxError::Expr(fail)),
}
} }

View file

@ -18,7 +18,6 @@ use roc_module::operator::CalledVia;
use roc_module::symbol::{IdentIds, ModuleId, ModuleIds, Symbol}; use roc_module::symbol::{IdentIds, ModuleId, ModuleIds, Symbol};
use roc_parse::ast; use roc_parse::ast;
use roc_parse::ast::StrLiteral; use roc_parse::ast::StrLiteral;
use roc_parse::blankspace::space0_before;
use roc_parse::expr::expr; use roc_parse::expr::expr;
use roc_parse::parser::{loc, Parser, State, SyntaxError}; use roc_parse::parser::{loc, Parser, State, SyntaxError};
use roc_problem::can::{Problem, RuntimeError}; use roc_problem::can::{Problem, RuntimeError};
@ -236,13 +235,11 @@ pub fn str_to_expr2<'a>(
region: Region, region: Region,
) -> Result<(Expr2, self::Output), SyntaxError<'a>> { ) -> Result<(Expr2, self::Output), SyntaxError<'a>> {
let state = State::new_in(arena, input.trim().as_bytes()); let state = State::new_in(arena, input.trim().as_bytes());
let parser = space0_before(loc(expr(0)), 0);
let parse_res = parser.parse(&arena, state);
parse_res match roc_parse::expr::test_parse_expr(0, arena, state) {
.map(|(_, loc_expr, _)| arena.alloc(loc_expr.value)) Ok((loc_expr, _state)) => Ok(to_expr2(env, scope, arena.alloc(loc_expr.value), region)),
.map(|loc_expr_val_ref| to_expr2(env, scope, loc_expr_val_ref, region)) Err(fail) => Err(SyntaxError::Expr(fail)),
.map_err(|(_, fail, _)| fail) }
} }
pub fn to_expr2<'a>( pub fn to_expr2<'a>(