mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
cleanup
This commit is contained in:
parent
0ad975113c
commit
963e7dee6a
2 changed files with 74 additions and 108 deletions
|
@ -1243,11 +1243,9 @@ macro_rules! one_of_with_error {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn specialize<'a, P, T, X, Y>(
|
pub fn specialize<'a, F, P, T, X, Y>(map_error: F, parser: P) -> impl Parser<'a, T, Y>
|
||||||
map_error: fn(X, Row, Col) -> Y,
|
|
||||||
parser: P,
|
|
||||||
) -> impl Parser<'a, T, Y>
|
|
||||||
where
|
where
|
||||||
|
F: Fn(X, Row, Col) -> Y,
|
||||||
P: Parser<'a, T, X>,
|
P: Parser<'a, T, X>,
|
||||||
Y: 'a,
|
Y: 'a,
|
||||||
{
|
{
|
||||||
|
@ -1257,13 +1255,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn specialize_ref<'a, P, T, X, Y>(
|
pub fn specialize_ref<'a, F, P, T, X, Y>(map_error: F, parser: P) -> impl Parser<'a, T, Y>
|
||||||
map_error: fn(&'a X, Row, Col) -> Y,
|
|
||||||
parser: P,
|
|
||||||
) -> impl Parser<'a, T, Y>
|
|
||||||
where
|
where
|
||||||
|
F: Fn(&'a X, Row, Col) -> Y,
|
||||||
P: Parser<'a, T, X>,
|
P: Parser<'a, T, X>,
|
||||||
Y: 'a,
|
Y: 'a,
|
||||||
|
X: 'a,
|
||||||
{
|
{
|
||||||
move |a, s| match parser.parse(a, s) {
|
move |a, s| match parser.parse(a, s) {
|
||||||
Ok(t) => Ok(t),
|
Ok(t) => Ok(t),
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::ast::{Attempting, CommentOrNewline, Tag, TypeAnnotation};
|
use crate::ast::{AssignedField, Attempting, CommentOrNewline, Tag, TypeAnnotation};
|
||||||
use crate::blankspace::{space0_around, space0_before, space1, space1_before};
|
use crate::blankspace::{space0_around, space0_before, space1, space1_before};
|
||||||
use crate::expr::{global_tag, private_tag};
|
use crate::expr::{global_tag, private_tag};
|
||||||
use crate::ident::join_module_parts;
|
use crate::ident::join_module_parts;
|
||||||
use crate::keyword;
|
use crate::keyword;
|
||||||
use crate::parser::{
|
use crate::parser::{
|
||||||
allocated, ascii_char, ascii_string, not, optional, peek_utf8_char, specialize, unexpected,
|
allocated, ascii_char, ascii_string, not, optional, peek_utf8_char, specialize, specialize_ref,
|
||||||
word1, BadInputError, Either, ParseResult, Parser,
|
unexpected, word1, BadInputError, Either, ParseResult, Parser,
|
||||||
Progress::{self, *},
|
Progress::{self, *},
|
||||||
State, SyntaxError, TRecord, Type,
|
State, SyntaxError, TRecord, Type,
|
||||||
};
|
};
|
||||||
|
@ -173,110 +173,79 @@ fn tag_type<'a>(min_indent: u16) -> impl Parser<'a, Tag<'a>, SyntaxError<'a>> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[macro_export]
|
fn record_type_field<'a>(
|
||||||
// macro_rules! zero_or_more {
|
min_indent: u16,
|
||||||
// ($parser:expr) => {
|
) -> impl Parser<'a, AssignedField<'a, TypeAnnotation<'a>>, TRecord<'a>> {
|
||||||
// move |arena, state: State<'a>| {
|
use crate::blankspace::{space0_before_e, space0_e};
|
||||||
// use bumpalo::collections::Vec;
|
use crate::ident::lowercase_ident;
|
||||||
//
|
use crate::parser::Either::*;
|
||||||
// let start_bytes_len = state.bytes.len();
|
use AssignedField::*;
|
||||||
//
|
|
||||||
// match $parser.parse(arena, state) {
|
|
||||||
// Ok((_, first_output, next_state)) => {
|
|
||||||
// let mut state = next_state;
|
|
||||||
// let mut buf = Vec::with_capacity_in(1, arena);
|
|
||||||
//
|
|
||||||
// buf.push(first_output);
|
|
||||||
//
|
|
||||||
// loop {
|
|
||||||
// match $parser.parse(arena, state) {
|
|
||||||
// Ok((_, next_output, next_state)) => {
|
|
||||||
// state = next_state;
|
|
||||||
// buf.push(next_output);
|
|
||||||
// }
|
|
||||||
// Err((fail_progress, fail, old_state)) => {
|
|
||||||
// match fail_progress {
|
|
||||||
// MadeProgress => {
|
|
||||||
// // made progress on an element and then failed; that's an error
|
|
||||||
// return Err((MadeProgress, fail, old_state));
|
|
||||||
// }
|
|
||||||
// NoProgress => {
|
|
||||||
// // the next element failed with no progress
|
|
||||||
// // report whether we made progress before
|
|
||||||
// let progress = Progress::from_lengths(start_bytes_len, old_state.bytes.len());
|
|
||||||
// return Ok((progress, buf, old_state));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err((fail_progress, fail, new_state)) => {
|
|
||||||
// match fail_progress {
|
|
||||||
// MadeProgress => {
|
|
||||||
// // made progress on an element and then failed; that's an error
|
|
||||||
// Err((MadeProgress, fail, new_state))
|
|
||||||
// }
|
|
||||||
// NoProgress => {
|
|
||||||
// // the first element failed (with no progress), but that's OK
|
|
||||||
// // because we only need to parse 0 elements
|
|
||||||
// Ok((NoProgress, Vec::new_in(arena), new_state))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! record_type_field {
|
|
||||||
($val_parser:expr, $min_indent:expr) => {
|
|
||||||
move |arena: &'a bumpalo::Bump,
|
|
||||||
state: $crate::parser::State<'a>|
|
|
||||||
-> $crate::parser::ParseResult<'a, $crate::ast::AssignedField<'a, _>, TRecord<'a>> {
|
|
||||||
use $crate::ast::AssignedField::*;
|
|
||||||
use $crate::blankspace::{space0_before_e, space0_e};
|
|
||||||
use $crate::ident::lowercase_ident;
|
|
||||||
use $crate::parser::Either::*;
|
|
||||||
|
|
||||||
|
move |arena, state: State<'a>| {
|
||||||
// You must have a field name, e.g. "email"
|
// You must have a field name, e.g. "email"
|
||||||
|
// using the initial row/col is important for error reporting
|
||||||
let row = state.line;
|
let row = state.line;
|
||||||
let col = state.column;
|
let col = state.column;
|
||||||
let (progress, loc_label, state) = loc!(lowercase_ident()).parse(arena, state).map_err(|(p, _, s)| (p, TRecord::Field(row, col), s))?;
|
let (progress, loc_label, state) = loc!(specialize(
|
||||||
|
move |_, _, _| TRecord::Field(row, col),
|
||||||
|
lowercase_ident()
|
||||||
|
))
|
||||||
|
.parse(arena, state)?;
|
||||||
debug_assert_eq!(progress, MadeProgress);
|
debug_assert_eq!(progress, MadeProgress);
|
||||||
|
|
||||||
let (_, spaces, state) =
|
let (_, spaces, state) =
|
||||||
space0_e($min_indent, TRecord::Space, TRecord::IndentEnd).parse(arena, state)?;
|
space0_e(min_indent, TRecord::Space, TRecord::IndentEnd).parse(arena, state)?;
|
||||||
|
|
||||||
|
|
||||||
// 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) = optional(either!(
|
||||||
skip_first!(word1(b':', TRecord::Colon), space0_before_e($val_parser, $min_indent, TRecord::Space, TRecord::IndentColon)),
|
word1(b':', TRecord::Colon),
|
||||||
skip_first!(word1(b'?', TRecord::Optional), space0_before_e($val_parser, $min_indent, TRecord::Space, TRecord::IndentOptional))
|
word1(b'?', TRecord::Optional)
|
||||||
))
|
))
|
||||||
.parse(arena, state)?;
|
.parse(arena, state)?;
|
||||||
|
|
||||||
let answer = match opt_loc_val {
|
let val_parser = specialize_ref(TRecord::Syntax, term(min_indent));
|
||||||
Some(either) => match either {
|
|
||||||
First(loc_val) => RequiredValue(loc_label, spaces, arena.alloc(loc_val)),
|
match opt_loc_val {
|
||||||
Second(loc_val) => OptionalValue(loc_label, spaces, arena.alloc(loc_val)),
|
Some(First(_)) => {
|
||||||
},
|
let (_, loc_val, state) =
|
||||||
|
space0_before_e(val_parser, min_indent, TRecord::Space, TRecord::IndentColon)
|
||||||
|
.parse(arena, state)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
MadeProgress,
|
||||||
|
RequiredValue(loc_label, spaces, arena.alloc(loc_val)),
|
||||||
|
state,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Some(Second(_)) => {
|
||||||
|
let (_, loc_val, state) = space0_before_e(
|
||||||
|
val_parser,
|
||||||
|
min_indent,
|
||||||
|
TRecord::Space,
|
||||||
|
TRecord::IndentOptional,
|
||||||
|
)
|
||||||
|
.parse(arena, state)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
MadeProgress,
|
||||||
|
OptionalValue(loc_label, spaces, arena.alloc(loc_val)),
|
||||||
|
state,
|
||||||
|
))
|
||||||
|
}
|
||||||
// If no value was provided, record it as a Var.
|
// If no value was provided, record it as a Var.
|
||||||
// Canonicalize will know what to do with a Var later.
|
// Canonicalize will know what to do with a Var later.
|
||||||
None => {
|
None => {
|
||||||
if !spaces.is_empty() {
|
let value = if !spaces.is_empty() {
|
||||||
SpaceAfter(arena.alloc(LabelOnly(loc_label)), spaces)
|
SpaceAfter(arena.alloc(LabelOnly(loc_label)), spaces)
|
||||||
} else {
|
} else {
|
||||||
LabelOnly(loc_label)
|
LabelOnly(loc_label)
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((MadeProgress, answer, state))
|
Ok((MadeProgress, value, state))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! collection_trailing_sep_e {
|
macro_rules! collection_trailing_sep_e {
|
||||||
|
@ -338,7 +307,7 @@ fn record_type_internal<'a>(min_indent: u16) -> impl Parser<'a, TypeAnnotation<'
|
||||||
move |arena, state| {
|
move |arena, state| {
|
||||||
let (_, (fields, final_comments), state) = collection_trailing_sep_e!(
|
let (_, (fields, final_comments), state) = collection_trailing_sep_e!(
|
||||||
word1(b'{', TRecord::Open),
|
word1(b'{', TRecord::Open),
|
||||||
loc!(record_type_field!(field_term, min_indent)),
|
loc!(record_type_field(min_indent)),
|
||||||
word1(b',', TRecord::End),
|
word1(b',', TRecord::End),
|
||||||
word1(b'}', TRecord::End),
|
word1(b'}', TRecord::End),
|
||||||
min_indent,
|
min_indent,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue