Have ascii_char take a u8

This commit is contained in:
Richard Feldman 2020-11-07 12:13:46 -05:00
parent 7ba95a0bd0
commit 61edcc7d03
6 changed files with 92 additions and 91 deletions

View file

@ -30,7 +30,7 @@ macro_rules! loc_parenthetical_expr {
then( then(
loc!(and!( loc!(and!(
between!( between!(
ascii_char('(' ), ascii_char(b'(' ),
map_with_arena!( map_with_arena!(
space0_around( space0_around(
loc!(move |arena, state| parse_expr($min_indent, arena, state)), loc!(move |arena, state| parse_expr($min_indent, arena, state)),
@ -43,7 +43,7 @@ macro_rules! loc_parenthetical_expr {
} }
} }
), ),
ascii_char(')' ) ascii_char(b')' )
), ),
optional(either!( optional(either!(
// There may optionally be function args after the ')' // There may optionally be function args after the ')'
@ -59,7 +59,7 @@ macro_rules! loc_parenthetical_expr {
// as if there were any args they'd have consumed it anyway // as if there were any args they'd have consumed it anyway
// e.g. in `((foo bar) baz.blah)` the `.blah` will be consumed by the `baz` parser // e.g. in `((foo bar) baz.blah)` the `.blah` will be consumed by the `baz` parser
either!( either!(
one_or_more!(skip_first!(ascii_char('.' ), lowercase_ident())), one_or_more!(skip_first!(ascii_char(b'.' ), lowercase_ident())),
and!(space0($min_indent), equals_with_indent()) and!(space0($min_indent), equals_with_indent())
) )
)) ))
@ -170,7 +170,7 @@ pub fn unary_op<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
one_of!( one_of!(
map_with_arena!( map_with_arena!(
and!( and!(
loc!(ascii_char('!')), loc!(ascii_char(b'!')),
loc!(move |arena, state| parse_expr(min_indent, arena, state)) loc!(move |arena, state| parse_expr(min_indent, arena, state))
), ),
|arena: &'a Bump, (loc_op, loc_expr): (Located<()>, Located<Expr<'a>>)| { |arena: &'a Bump, (loc_op, loc_expr): (Located<()>, Located<Expr<'a>>)| {
@ -179,7 +179,7 @@ pub fn unary_op<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
), ),
map_with_arena!( map_with_arena!(
and!( and!(
loc!(ascii_char('-')), loc!(ascii_char(b'-')),
loc!(move |arena, state| parse_expr(min_indent, arena, state)) loc!(move |arena, state| parse_expr(min_indent, arena, state))
), ),
|arena: &'a Bump, (loc_op, loc_expr): (Located<()>, Located<Expr<'a>>)| { |arena: &'a Bump, (loc_op, loc_expr): (Located<()>, Located<Expr<'a>>)| {
@ -449,9 +449,9 @@ pub fn loc_parenthetical_def<'a>(min_indent: u16) -> impl Parser<'a, Located<Exp
let (loc_tuple, state) = loc!(and!( let (loc_tuple, state) = loc!(and!(
space0_after( space0_after(
between!( between!(
ascii_char('('), ascii_char(b'('),
space0_around(loc_pattern(min_indent), min_indent), space0_around(loc_pattern(min_indent), min_indent),
ascii_char(')') ascii_char(b')')
), ),
min_indent, min_indent,
), ),
@ -481,7 +481,10 @@ pub fn loc_parenthetical_def<'a>(min_indent: u16) -> impl Parser<'a, Located<Exp
/// The '=' used in a def can't be followed by another '=' (or else it's actually /// The '=' used in a def can't be followed by another '=' (or else it's actually
/// an "==") and also it can't be followed by '>' (or else it's actually an "=>") /// an "==") and also it can't be followed by '>' (or else it's actually an "=>")
fn equals_for_def<'a>() -> impl Parser<'a, ()> { fn equals_for_def<'a>() -> impl Parser<'a, ()> {
not_followed_by(ascii_char('='), one_of!(ascii_char('='), ascii_char('>'))) not_followed_by(
ascii_char(b'='),
one_of!(ascii_char(b'='), ascii_char(b'>')),
)
} }
/// A definition, consisting of one of these: /// A definition, consisting of one of these:
@ -512,7 +515,7 @@ pub fn def<'a>(min_indent: u16) -> impl Parser<'a, Def<'a>> {
), ),
// Annotation // Annotation
skip_first!( skip_first!(
ascii_char(':'), ascii_char(b':'),
// Spaces after the ':' (at a normal indentation level) and then the type. // Spaces after the ':' (at a normal indentation level) and then the type.
// The type itself must be indented more than the pattern and ':' // The type itself must be indented more than the pattern and ':'
space0_before(type_annotation::located(indented_more), indented_more) space0_before(type_annotation::located(indented_more), indented_more)
@ -838,7 +841,7 @@ fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
map_with_arena!( map_with_arena!(
skip_first!( skip_first!(
// All closures start with a '\' - e.g. (\x -> x + 1) // All closures start with a '\' - e.g. (\x -> x + 1)
ascii_char('\\'), ascii_char(b'\\'),
// Once we see the '\', we're committed to parsing this as a closure. // Once we see the '\', we're committed to parsing this as a closure.
// It may turn out to be malformed, but it is definitely a closure. // It may turn out to be malformed, but it is definitely a closure.
optional(and!( optional(and!(
@ -847,7 +850,7 @@ fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
Attempting::ClosureParams, Attempting::ClosureParams,
// Params are comma-separated // Params are comma-separated
sep_by1( sep_by1(
ascii_char(','), ascii_char(b','),
space0_around(loc_closure_param(min_indent), min_indent) space0_around(loc_closure_param(min_indent), min_indent)
) )
), ),
@ -896,9 +899,9 @@ fn parse_closure_param<'a>(
// If you wrap it in parens, you can match any arbitrary pattern at all. // If you wrap it in parens, you can match any arbitrary pattern at all.
// e.g. \User.UserId userId -> ... // e.g. \User.UserId userId -> ...
between!( between!(
ascii_char('('), ascii_char(b'('),
space0_around(loc_pattern(min_indent), min_indent), space0_around(loc_pattern(min_indent), min_indent),
ascii_char(')') ascii_char(b')')
) )
) )
.parse(arena, state) .parse(arena, state)
@ -922,9 +925,9 @@ fn loc_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
fn loc_parenthetical_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> { fn loc_parenthetical_pattern<'a>(min_indent: u16) -> impl Parser<'a, Located<Pattern<'a>>> {
between!( between!(
ascii_char('('), ascii_char(b'('),
move |arena, state| loc_pattern(min_indent).parse(arena, state), move |arena, state| loc_pattern(min_indent).parse(arena, state),
ascii_char(')') ascii_char(b')')
) )
} }
@ -939,13 +942,13 @@ fn string_pattern<'a>() -> impl Parser<'a, Pattern<'a>> {
} }
fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>> { fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>> {
map!(ascii_char('_'), |_| Pattern::Underscore) map!(ascii_char(b'_'), |_| Pattern::Underscore)
} }
fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> { fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
then( then(
collection!( collection!(
ascii_char('{'), ascii_char(b'{'),
move |arena: &'a bumpalo::Bump, move |arena: &'a bumpalo::Bump,
state: crate::parser::State<'a>| state: crate::parser::State<'a>|
-> crate::parser::ParseResult<'a, Located<crate::ast::Pattern<'a>>> { -> crate::parser::ParseResult<'a, Located<crate::ast::Pattern<'a>>> {
@ -963,11 +966,11 @@ fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
// (This is true in both literals and types.) // (This is true in both literals and types.)
let (opt_loc_val, state) = crate::parser::optional(either!( let (opt_loc_val, state) = crate::parser::optional(either!(
skip_first!( skip_first!(
ascii_char(':'), ascii_char(b':'),
space0_before(loc_pattern(min_indent), min_indent) space0_before(loc_pattern(min_indent), min_indent)
), ),
skip_first!( skip_first!(
ascii_char('?'), ascii_char(b'?'),
space0_before(loc!(expr(min_indent)), min_indent) space0_before(loc!(expr(min_indent)), min_indent)
) )
)) ))
@ -1006,8 +1009,8 @@ fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> {
Ok((answer, state)) Ok((answer, state))
}, },
ascii_char(','), ascii_char(b','),
ascii_char('}'), ascii_char(b'}'),
min_indent min_indent
), ),
move |_arena, state, loc_patterns| { move |_arena, state, loc_patterns| {
@ -1250,7 +1253,7 @@ mod when {
) -> impl Parser<'a, (Vec<'a, Located<Pattern<'a>>>, Option<Located<Expr<'a>>>)> { ) -> impl Parser<'a, (Vec<'a, Located<Pattern<'a>>>, Option<Located<Expr<'a>>>)> {
and!( and!(
sep_by1( sep_by1(
ascii_char('|'), ascii_char(b'|'),
space0_around(loc_pattern(min_indent), min_indent), space0_around(loc_pattern(min_indent), min_indent),
), ),
optional(skip_first!( optional(skip_first!(
@ -1350,14 +1353,14 @@ fn unary_negate_function_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<Exp
// Try to parse a number literal *before* trying to parse unary negate, // Try to parse a number literal *before* trying to parse unary negate,
// because otherwise (foo -1) will parse as (foo (Num.neg 1)) // because otherwise (foo -1) will parse as (foo (Num.neg 1))
loc!(number_literal()), loc!(number_literal()),
loc!(ascii_char('-')) loc!(ascii_char(b'-'))
) )
), ),
one_of!( one_of!(
ascii_char(' '), ascii_char(b' '),
ascii_char('#'), ascii_char(b'#'),
ascii_char('\n'), ascii_char(b'\n'),
ascii_char('>') ascii_char(b'>')
), ),
), ),
move |arena, state, (spaces, num_or_minus_char)| { move |arena, state, (spaces, num_or_minus_char)| {
@ -1660,27 +1663,27 @@ fn binop<'a>() -> impl Parser<'a, BinOp> {
map!(ascii_string("!="), |_| BinOp::NotEquals), map!(ascii_string("!="), |_| BinOp::NotEquals),
map!(ascii_string("&&"), |_| BinOp::And), map!(ascii_string("&&"), |_| BinOp::And),
map!(ascii_string("||"), |_| BinOp::Or), map!(ascii_string("||"), |_| BinOp::Or),
map!(ascii_char('+'), |_| BinOp::Plus), map!(ascii_char(b'+'), |_| BinOp::Plus),
map!(ascii_char('*'), |_| BinOp::Star), map!(ascii_char(b'*'), |_| BinOp::Star),
map!(ascii_char('-'), |_| BinOp::Minus), map!(ascii_char(b'-'), |_| BinOp::Minus),
map!(ascii_string("//"), |_| BinOp::DoubleSlash), map!(ascii_string("//"), |_| BinOp::DoubleSlash),
map!(ascii_char('/'), |_| BinOp::Slash), map!(ascii_char(b'/'), |_| BinOp::Slash),
map!(ascii_string("<="), |_| BinOp::LessThanOrEq), map!(ascii_string("<="), |_| BinOp::LessThanOrEq),
map!(ascii_char('<'), |_| BinOp::LessThan), map!(ascii_char(b'<'), |_| BinOp::LessThan),
map!(ascii_string(">="), |_| BinOp::GreaterThanOrEq), map!(ascii_string(">="), |_| BinOp::GreaterThanOrEq),
map!(ascii_char('>'), |_| BinOp::GreaterThan), map!(ascii_char(b'>'), |_| BinOp::GreaterThan),
map!(ascii_char('^'), |_| BinOp::Caret), map!(ascii_char(b'^'), |_| BinOp::Caret),
map!(ascii_string("%%"), |_| BinOp::DoublePercent), map!(ascii_string("%%"), |_| BinOp::DoublePercent),
map!(ascii_char('%'), |_| BinOp::Percent) map!(ascii_char(b'%'), |_| BinOp::Percent)
) )
} }
pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> { pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
let elems = collection!( let elems = collection!(
ascii_char('['), ascii_char(b'['),
loc!(expr(min_indent)), loc!(expr(min_indent)),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
min_indent min_indent
); );
@ -1723,7 +1726,7 @@ pub fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
// there can be field access, e.g. `{ x : 4 }.x` // there can be field access, e.g. `{ x : 4 }.x`
let (accesses, state) = optional(one_or_more!(skip_first!( let (accesses, state) = optional(one_or_more!(skip_first!(
ascii_char('.'), ascii_char(b'.'),
lowercase_ident() lowercase_ident()
))) )))
.parse(arena, state)?; .parse(arena, state)?;
@ -1819,7 +1822,7 @@ pub fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
/// This is mainly for matching tags in closure params, e.g. \@Foo -> ... /// This is mainly for matching tags in closure params, e.g. \@Foo -> ...
pub fn private_tag<'a>() -> impl Parser<'a, &'a str> { pub fn private_tag<'a>() -> impl Parser<'a, &'a str> {
map_with_arena!( map_with_arena!(
skip_first!(ascii_char('@'), global_tag()), skip_first!(ascii_char(b'@'), global_tag()),
|arena: &'a Bump, name: &'a str| { |arena: &'a Bump, name: &'a str| {
let mut buf = String::with_capacity_in(1 + name.len(), arena); let mut buf = String::with_capacity_in(1 + name.len(), arena);

View file

@ -78,7 +78,7 @@ pub fn package_name<'a>() -> impl Parser<'a, PackageName<'a>> {
map!( map!(
and!( and!(
parse_package_part, parse_package_part,
skip_first!(ascii_char('/'), parse_package_part) skip_first!(ascii_char(b'/'), parse_package_part)
), ),
|(account, pkg)| { PackageName { account, pkg } } |(account, pkg)| { PackageName { account, pkg } }
) )
@ -254,10 +254,10 @@ fn provides<'a>() -> impl Parser<
and!( and!(
and!(skip_second!(space1(1), ascii_string("provides")), space1(1)), and!(skip_second!(space1(1), ascii_string("provides")), space1(1)),
collection!( collection!(
ascii_char('['), ascii_char(b'['),
loc!(exposes_entry()), loc!(exposes_entry()),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
1 1
) )
) )
@ -274,10 +274,10 @@ fn requires<'a>() -> impl Parser<
and!( and!(
and!(skip_second!(space1(1), ascii_string("requires")), space1(1)), and!(skip_second!(space1(1), ascii_string("requires")), space1(1)),
collection!( collection!(
ascii_char('['), ascii_char(b'['),
loc!(exposes_entry()), loc!(exposes_entry()),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
1 1
) )
) )
@ -294,10 +294,10 @@ fn exposes<'a>() -> impl Parser<
and!( and!(
and!(skip_second!(space1(1), ascii_string("exposes")), space1(1)), and!(skip_second!(space1(1), ascii_string("exposes")), space1(1)),
collection!( collection!(
ascii_char('['), ascii_char(b'['),
loc!(exposes_entry()), loc!(exposes_entry()),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
1 1
) )
) )
@ -314,10 +314,10 @@ fn imports<'a>() -> impl Parser<
and!( and!(
and!(skip_second!(space1(1), ascii_string("imports")), space1(1)), and!(skip_second!(space1(1), ascii_string("imports")), space1(1)),
collection!( collection!(
ascii_char('['), ascii_char(b'['),
loc!(imports_entry()), loc!(imports_entry()),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
1 1
) )
) )
@ -332,10 +332,10 @@ fn effects<'a>() -> impl Parser<'a, Effects<'a>> {
let ((type_name, spaces_after_type_name), state) = let ((type_name, spaces_after_type_name), state) =
and!(uppercase_ident(), space1(0)).parse(arena, state)?; and!(uppercase_ident(), space1(0)).parse(arena, state)?;
let (entries, state) = collection!( let (entries, state) = collection!(
ascii_char('{'), ascii_char(b'{'),
loc!(effects_entry()), loc!(effects_entry()),
ascii_char(','), ascii_char(b','),
ascii_char('}'), ascii_char(b'}'),
1 1
) )
.parse(arena, state)?; .parse(arena, state)?;
@ -362,7 +362,7 @@ fn effects_entry<'a>() -> impl Parser<'a, EffectsEntry<'a>> {
let (spaces_before_colon, state) = space0(0).parse(arena, state)?; let (spaces_before_colon, state) = space0(0).parse(arena, state)?;
let (ann, state) = skip_first!( let (ann, state) = skip_first!(
ascii_char(':'), ascii_char(b':'),
space0_before(type_annotation::located(0), 0) space0_before(type_annotation::located(0), 0)
) )
.parse(arena, state)?; .parse(arena, state)?;
@ -395,12 +395,12 @@ fn imports_entry<'a>() -> impl Parser<'a, ImportsEntry<'a>> {
module_name(), module_name(),
// e.g. `.{ Task, after}` // e.g. `.{ Task, after}`
optional(skip_first!( optional(skip_first!(
ascii_char('.'), ascii_char(b'.'),
collection!( collection!(
ascii_char('{'), ascii_char(b'{'),
loc!(exposes_entry()), loc!(exposes_entry()),
ascii_char(','), ascii_char(b','),
ascii_char('}'), ascii_char(b'}'),
1 1
) )
)) ))

View file

@ -433,14 +433,9 @@ fn line_too_long(attempting: Attempting, state: State<'_>) -> (Fail, State<'_>)
} }
/// A single ASCII char. /// A single ASCII char.
pub fn ascii_char<'a>(expected: char) -> impl Parser<'a, ()> { pub fn ascii_char<'a>(expected: u8) -> impl Parser<'a, ()> {
// Make sure this really is an ASCII char!
debug_assert!(expected.len_utf8() == 1);
move |_arena, state: State<'a>| match state.bytes.first() { move |_arena, state: State<'a>| match state.bytes.first() {
Some(&actual) if expected == actual as char => { Some(&actual) if expected == actual => Ok(((), state.advance_without_indenting(1)?)),
Ok(((), state.advance_without_indenting(1)?))
}
Some(_) => Err(unexpected(0, state, Attempting::Keyword)), Some(_) => Err(unexpected(0, state, Attempting::Keyword)),
_ => Err(unexpected_eof(0, Attempting::Keyword, state)), _ => Err(unexpected_eof(0, Attempting::Keyword, state)),
} }
@ -788,7 +783,7 @@ macro_rules! collection {
// We could change the AST to add extra storage specifically to // We could change the AST to add extra storage specifically to
// support empty literals containing newlines or comments, but this // support empty literals containing newlines or comments, but this
// does not seem worth even the tiniest regression in compiler performance. // does not seem worth even the tiniest regression in compiler performance.
zero_or_more!($crate::parser::ascii_char(' ')), zero_or_more!($crate::parser::ascii_char(b' ')),
skip_second!( skip_second!(
$crate::parser::sep_by0( $crate::parser::sep_by0(
$delimiter, $delimiter,
@ -1025,8 +1020,8 @@ macro_rules! record_field {
// Having a value is optional; both `{ email }` and `{ email: blah }` work. // Having a value is optional; both `{ email }` and `{ email: blah }` work.
// (This is true in both literals and types.) // (This is true in both literals and types.)
let (opt_loc_val, state) = $crate::parser::optional(either!( let (opt_loc_val, state) = $crate::parser::optional(either!(
skip_first!(ascii_char(':'), space0_before($val_parser, $min_indent)), skip_first!(ascii_char(b':'), space0_before($val_parser, $min_indent)),
skip_first!(ascii_char('?'), space0_before($val_parser, $min_indent)) skip_first!(ascii_char(b'?'), space0_before($val_parser, $min_indent))
)) ))
.parse(arena, state)?; .parse(arena, state)?;
@ -1055,10 +1050,10 @@ macro_rules! record_field {
macro_rules! record_without_update { macro_rules! record_without_update {
($val_parser:expr, $min_indent:expr) => { ($val_parser:expr, $min_indent:expr) => {
collection!( collection!(
ascii_char('{'), ascii_char(b'{'),
loc!(record_field!($val_parser, $min_indent)), loc!(record_field!($val_parser, $min_indent)),
ascii_char(','), ascii_char(b','),
ascii_char('}'), ascii_char(b'}'),
$min_indent $min_indent
) )
}; };
@ -1068,7 +1063,7 @@ macro_rules! record_without_update {
macro_rules! record { macro_rules! record {
($val_parser:expr, $min_indent:expr) => { ($val_parser:expr, $min_indent:expr) => {
skip_first!( skip_first!(
$crate::parser::ascii_char('{'), $crate::parser::ascii_char(b'{'),
and!( and!(
// You can optionally have an identifier followed by an '&' to // You can optionally have an identifier followed by an '&' to
// make this a record update, e.g. { Foo.user & username: "blah" }. // make this a record update, e.g. { Foo.user & username: "blah" }.
@ -1084,7 +1079,7 @@ macro_rules! record {
)), )),
$min_indent $min_indent
), ),
$crate::parser::ascii_char('&') $crate::parser::ascii_char(b'&')
)), )),
loc!(skip_first!( loc!(skip_first!(
// We specifically allow space characters inside here, so that // We specifically allow space characters inside here, so that
@ -1098,16 +1093,16 @@ macro_rules! record {
// We could change the AST to add extra storage specifically to // We could change the AST to add extra storage specifically to
// support empty literals containing newlines or comments, but this // support empty literals containing newlines or comments, but this
// does not seem worth even the tiniest regression in compiler performance. // does not seem worth even the tiniest regression in compiler performance.
zero_or_more!($crate::parser::ascii_char(' ')), zero_or_more!($crate::parser::ascii_char(b' ')),
skip_second!( skip_second!(
$crate::parser::sep_by0( $crate::parser::sep_by0(
$crate::parser::ascii_char(','), $crate::parser::ascii_char(b','),
$crate::blankspace::space0_around( $crate::blankspace::space0_around(
loc!(record_field!($val_parser, $min_indent)), loc!(record_field!($val_parser, $min_indent)),
$min_indent $min_indent
) )
), ),
$crate::parser::ascii_char('}') $crate::parser::ascii_char(b'}')
) )
)) ))
) )

View file

@ -162,7 +162,7 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>> {
// canonicalization error if that expression variant // canonicalization error if that expression variant
// is not allowed inside a string interpolation. // is not allowed inside a string interpolation.
let (loc_expr, new_state) = let (loc_expr, new_state) =
skip_second!(loc(allocated(expr::expr(0))), ascii_char(')')) skip_second!(loc(allocated(expr::expr(0))), ascii_char(b')'))
.parse(arena, state)?; .parse(arena, state)?;
// Advance the iterator past the expr we just parsed. // Advance the iterator past the expr we just parsed.
@ -185,8 +185,11 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>> {
// Parse the hex digits, surrounded by parens, then // Parse the hex digits, surrounded by parens, then
// give a canonicalization error if the digits form // give a canonicalization error if the digits form
// an invalid unicode code point. // an invalid unicode code point.
let (loc_digits, new_state) = let (loc_digits, new_state) = between!(
between!(ascii_char('('), loc(ascii_hex_digits()), ascii_char(')')) ascii_char(b'('),
loc(ascii_hex_digits()),
ascii_char(b')')
)
.parse(arena, state)?; .parse(arena, state)?;
// Advance the iterator past the expr we just parsed. // Advance the iterator past the expr we just parsed.

View file

@ -22,10 +22,10 @@ macro_rules! tag_union {
map!( map!(
and!( and!(
collection!( collection!(
ascii_char('['), ascii_char(b'['),
loc!(tag_type($min_indent)), loc!(tag_type($min_indent)),
ascii_char(','), ascii_char(b','),
ascii_char(']'), ascii_char(b']'),
$min_indent $min_indent
), ),
optional( optional(
@ -89,7 +89,7 @@ pub fn term<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>>
/// The `*` type variable, e.g. in (List *) Wildcard, /// The `*` type variable, e.g. in (List *) Wildcard,
fn loc_wildcard<'a>() -> impl Parser<'a, Located<TypeAnnotation<'a>>> { fn loc_wildcard<'a>() -> impl Parser<'a, Located<TypeAnnotation<'a>>> {
map!(loc!(ascii_char('*')), |loc_val: Located<()>| { map!(loc!(ascii_char(b'*')), |loc_val: Located<()>| {
loc_val.map(|_| TypeAnnotation::Wildcard) loc_val.map(|_| TypeAnnotation::Wildcard)
}) })
} }
@ -112,12 +112,12 @@ pub fn loc_applied_arg<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnot
#[inline(always)] #[inline(always)]
fn loc_parenthetical_type<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>> { fn loc_parenthetical_type<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>>> {
between!( between!(
ascii_char('('), ascii_char(b'('),
space0_around( space0_around(
move |arena, state| expression(min_indent).parse(arena, state), move |arena, state| expression(min_indent).parse(arena, state),
min_indent, min_indent,
), ),
ascii_char(')') ascii_char(b')')
) )
} }
@ -208,7 +208,7 @@ fn expression<'a>(min_indent: u16) -> impl Parser<'a, Located<TypeAnnotation<'a>
move |arena, state: State<'a>| { move |arena, state: State<'a>| {
let (first, state) = space0_before(term(min_indent), min_indent).parse(arena, state)?; let (first, state) = space0_before(term(min_indent), min_indent).parse(arena, state)?;
let (rest, state) = zero_or_more!(skip_first!( let (rest, state) = zero_or_more!(skip_first!(
ascii_char(','), ascii_char(b','),
space0_around(term(min_indent), min_indent) space0_around(term(min_indent), min_indent)
)) ))
.parse(arena, state)?; .parse(arena, state)?;

View file

@ -1,6 +1,6 @@
platform folkertdev/foo platform folkertdev/foo
provides [ mainForHost ] provides [ mainForHost ]
requires [ main ] requires { main : Effect {} }
imports [] imports []
effects Effect effects Effect
{ putChar : Int -> Effect {}, putLine : Str -> Effect {} } { putChar : Int -> Effect {}, putLine : Str -> Effect {} }