From f3234e002ab8ee6c74be55c148dda5aca711ef28 Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 23 Feb 2021 20:05:58 +0100 Subject: [PATCH] change list over --- compiler/parse/src/expr.rs | 65 +++++++++++++++++++----------------- compiler/parse/src/parser.rs | 14 ++++++++ 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/compiler/parse/src/expr.rs b/compiler/parse/src/expr.rs index 1b01a08edb..aebe5044b7 100644 --- a/compiler/parse/src/expr.rs +++ b/compiler/parse/src/expr.rs @@ -11,8 +11,8 @@ 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, If, ParseResult, Parser, State, - SyntaxError, When, + then, unexpected, unexpected_eof, word1, word2, BadInputError, EExpr, Either, If, List, + ParseResult, Parser, State, SyntaxError, When, }; use crate::pattern::loc_closure_param; use crate::type_annotation; @@ -1693,37 +1693,42 @@ fn binop<'a>() -> impl Parser<'a, BinOp, SyntaxError<'a>> { map!(ascii_char(b'%'), |_| BinOp::Percent) ) } - -pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> { - let elems = collection_trailing_sep!( - ascii_char(b'['), - loc!(expr(min_indent)), - ascii_char(b','), - ascii_char(b']'), - min_indent - ); - - parser::attempt( - Attempting::List, - map_with_arena!(elems, |arena, - (parsed_elems, final_comments): ( - Vec<'a, Located>>, - &'a [CommentOrNewline<'a>] - )| { - let mut allocated = Vec::with_capacity_in(parsed_elems.len(), arena); - - for parsed_elem in parsed_elems { - allocated.push(&*arena.alloc(parsed_elem)); - } - - Expr::List { - items: allocated.into_bump_slice(), - final_comments, - } - }), +fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> { + specialize( + |e, r, c| SyntaxError::Expr(EExpr::List(e, r, c)), + list_literal_help(min_indent), ) } +fn list_literal_help<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, List<'a>> { + move |arena, state| { + let (_, (parsed_elems, final_comments), state) = collection_trailing_sep_e!( + word1(b'[', List::Open), + specialize_ref(List::Syntax, loc!(expr(min_indent))), + word1(b',', List::End), + word1(b']', List::End), + min_indent, + List::Open, + List::Space, + List::IndentEnd + ) + .parse(arena, state)?; + + let mut allocated = Vec::with_capacity_in(parsed_elems.len(), arena); + + for parsed_elem in parsed_elems { + allocated.push(&*arena.alloc(parsed_elem)); + } + + let expr = Expr::List { + items: allocated.into_bump_slice(), + final_comments, + }; + + Ok((MadeProgress, expr, state)) + } +} + // Parser<'a, Vec<'a, Located>>> fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>, SyntaxError<'a>> { then( diff --git a/compiler/parse/src/parser.rs b/compiler/parse/src/parser.rs index b1d3d3545a..1b2ea71cce 100644 --- a/compiler/parse/src/parser.rs +++ b/compiler/parse/src/parser.rs @@ -380,11 +380,25 @@ pub enum EExpr<'a> { When(When<'a>, Row, Col), If(If<'a>, Row, Col), + List(List<'a>, Row, Col), + // EInParens(PInParens<'a>, Row, Col), IndentStart(Row, Col), IndentEnd(Row, Col), } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum List<'a> { + Open(Row, Col), + End(Row, Col), + Space(BadInputError, Row, Col), + + Syntax(&'a SyntaxError<'a>, Row, Col), + + IndentStart(Row, Col), + IndentEnd(Row, Col), +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum When<'a> { Space(BadInputError, Row, Col),