A bit more refactoring in the parser

This commit is contained in:
Greg Shuflin 2021-11-20 23:26:12 -08:00
parent 1797136156
commit 1a48e9b43a
1 changed files with 57 additions and 41 deletions

View File

@ -120,11 +120,11 @@ fn block_comment(input: Span) -> ParseResult<()> {
}
}
context("Block-comment", value((), tuple((tag("/*"), inner_parser, tag("*/")))))(input)
context("block-comment", value((), tuple((tag("/*"), inner_parser, tag("*/")))))(input)
}
fn statement_delimiter(input: Span) -> ParseResult<()> {
tok(alt((value((), line_ending), value((), char(';')))))(input)
context("statement-delimiter", tok(alt((value((), line_ending), value((), char(';'))))))(input)
}
pub fn program(input: Span) -> ParseResult<AST> {
@ -329,10 +329,7 @@ fn type_body(input: Span) -> ParseResult<TypeBody> {
context(
"type-body",
alt((
map(
record_variant,
move |fields| TypeBody::ImmediateRecord { id, fields },
),
map(record_variant, move |fields| TypeBody::ImmediateRecord { id, fields }),
map(separated_list0(tok(char('|')), variant_spec), TypeBody::Variants),
)),
)(input)
@ -343,10 +340,7 @@ fn record_variant(input: Span) -> ParseResult<Vec<(Rc<String>, TypeIdentifier)>>
"record-variant",
delimited(
pair(tok(char('{')), many0(statement_delimiter)),
terminated(
separated_list1(toknl(char(',')), toknl(record_variant_item)),
opt(toknl(char(','))),
),
terminated(separated_list1(toknl(char(',')), toknl(record_variant_item)), opt(toknl(char(',')))),
pair(many0(statement_delimiter), tok(char('}'))),
),
)(input)
@ -471,8 +465,8 @@ fn operator(input: Span) -> ParseResult<BinOp> {
context(
"operator",
tok(map(
tuple((cut(not(tag("*/"))), recognize(many1(one_of("+-*/%<>=!$&|?^`"))))),
|(_, sigil_span): ((), Span)| BinOp::from_sigil(sigil_span.fragment()),
preceded(cut(not(tag("*/"))), recognize(many1(one_of("+-*/%<>=!$&|?^`")))),
|sigil_span: Span| BinOp::from_sigil(sigil_span.fragment()),
)),
)(input)
}
@ -602,10 +596,13 @@ fn primary_expr_no_struct(input: Span) -> ParseResult<ExpressionKind> {
}
fn named_struct(input: Span) -> ParseResult<ExpressionKind> {
map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct {
name,
fields,
})(input)
context(
"named-struct",
map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct {
name,
fields,
}),
)(input)
}
//TODO support anonymous structs and Elm-style update syntax for structs
@ -617,22 +614,29 @@ fn record_block(input: Span) -> ParseResult<Vec<(Rc<String>, Expression)>> {
}
fn lambda_expr(input: Span) -> ParseResult<ExpressionKind> {
alt((
map(
preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))),
|(params, type_anno, body)| ExpressionKind::Lambda { params, type_anno, body },
context(
"lambda-expr",
preceded(
tok(char('\\')),
alt((
map(tuple((formal_params, opt(type_anno), block)), |(params, type_anno, body)| {
ExpressionKind::Lambda { params, type_anno, body }
}),
map(tuple((formal_param, opt(type_anno), block)), |(param, type_anno, body)| {
ExpressionKind::Lambda { params: vec![param], type_anno, body }
}),
)),
),
map(
preceded(tok(char('\\')), tuple((formal_param, opt(type_anno), block))),
|(param, type_anno, body)| ExpressionKind::Lambda { params: vec![param], type_anno, body },
),
))(input)
)(input)
}
fn while_expr(input: Span) -> ParseResult<ExpressionKind> {
map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| {
ExpressionKind::WhileExpression { condition: condition.map(Box::new), body }
})(input)
context(
"while-expr",
map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| {
ExpressionKind::WhileExpression { condition: condition.map(Box::new), body }
}),
)(input)
}
fn if_expr(input: Span) -> ParseResult<ExpressionKind> {
@ -681,9 +685,12 @@ fn if_expr(input: Span) -> ParseResult<ExpressionKind> {
alt((cond_block, simple_pattern_match, simple_conditional))(input)
}
map(preceded(kw("if"), pair(opt(expression_no_struct), if_expr_body)), |(discriminator, body)| {
ExpressionKind::IfExpression { discriminator: discriminator.map(Box::new), body: Box::new(body) }
})(input)
context(
"if-expr",
map(preceded(kw("if"), pair(opt(expression_no_struct), if_expr_body)), |(discriminator, body)| {
ExpressionKind::IfExpression { discriminator: discriminator.map(Box::new), body: Box::new(body) }
}),
)(input)
}
fn pattern(input: Span) -> ParseResult<Pattern> {
@ -775,9 +782,12 @@ fn for_expr(input: Span) -> ParseResult<ExpressionKind> {
))(input)
}
map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| {
ExpressionKind::ForExpression { enumerators, body }
})(input)
context(
"for-expr",
map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| {
ExpressionKind::ForExpression { enumerators, body }
}),
)(input)
}
fn paren_expr(input: Span) -> ParseResult<ExpressionKind> {
@ -852,17 +862,23 @@ fn bool_literal(input: Span) -> ParseResult<ExpressionKind> {
}
fn float_literal(input: Span) -> ParseResult<ExpressionKind> {
tok(map(
alt((
recognize(tuple((digits(digit_group_dec), char('.'), opt(digits(digit_group_dec))))),
recognize(tuple((char('.'), digits(digit_group_dec)))),
context(
"float-literal",
tok(map(
alt((
recognize(tuple((digits(digit_group_dec), char('.'), opt(digits(digit_group_dec))))),
recognize(tuple((char('.'), digits(digit_group_dec)))),
)),
|ds| ExpressionKind::FloatLiteral(ds.fragment().parse().unwrap()),
)),
|ds| ExpressionKind::FloatLiteral(ds.fragment().parse().unwrap()),
))(input)
)(input)
}
fn number_literal(input: Span) -> ParseResult<ExpressionKind> {
map(alt((tok(hex_literal), tok(bin_literal), tok(dec_literal))), ExpressionKind::NatLiteral)(input)
context(
"number-literal",
map(alt((tok(hex_literal), tok(bin_literal), tok(dec_literal))), ExpressionKind::NatLiteral),
)(input)
}
fn dec_literal(input: Span) -> ParseResult<u64> {