Compare commits

...

2 Commits

Author SHA1 Message Date
Greg Shuflin
1a48e9b43a A bit more refactoring in the parser 2021-11-20 23:26:12 -08:00
Greg Shuflin
1797136156 Some refactoring in parser combinator 2021-11-20 23:09:40 -08:00
2 changed files with 67 additions and 56 deletions

View File

@ -74,7 +74,7 @@ fn tok<'a, O>(
fn toknl<'a, O>( fn toknl<'a, O>(
input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>, input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>,
) -> impl FnMut(Span<'a>) -> IResult<Span<'a>, O, VerboseError<Span<'a>>> { ) -> impl FnMut(Span<'a>) -> IResult<Span<'a>, O, VerboseError<Span<'a>>> {
context("token/newline", preceded(ws0, input_parser)) context("token/newline", preceded(pair(many0(tok(statement_delimiter)), ws0), input_parser))
} }
fn kw<'a>(keyword_str: &'static str) -> impl FnMut(Span<'a>) -> ParseResult<()> { fn kw<'a>(keyword_str: &'static str) -> impl FnMut(Span<'a>) -> ParseResult<()> {
@ -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<()> { 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> { pub fn program(input: Span) -> ParseResult<AST> {
@ -329,33 +329,20 @@ fn type_body(input: Span) -> ParseResult<TypeBody> {
context( context(
"type-body", "type-body",
alt(( alt((
map( map(record_variant, move |fields| TypeBody::ImmediateRecord { id, fields }),
delimited(
tok(char('{')),
separated_list1(tok(char(',')), record_variant_item),
tok(char('}')),
),
move |items| TypeBody::ImmediateRecord { id, fields: items },
),
map(separated_list0(tok(char('|')), variant_spec), TypeBody::Variants), map(separated_list0(tok(char('|')), variant_spec), TypeBody::Variants),
)), )),
)(input) )(input)
} }
fn record_variant(input: Span) -> ParseResult<VariantKind> { fn record_variant(input: Span) -> ParseResult<Vec<(Rc<String>, TypeIdentifier)>> {
context( context(
"record-variant", "record-variant",
map(
delimited( delimited(
pair(tok(char('{')), many0(statement_delimiter)), pair(tok(char('{')), many0(statement_delimiter)),
terminated( terminated(separated_list1(toknl(char(',')), toknl(record_variant_item)), opt(toknl(char(',')))),
separated_list1(pair(tok(char(',')), many0(statement_delimiter)), record_variant_item),
opt(tok(char(','))),
),
pair(many0(statement_delimiter), tok(char('}'))), pair(many0(statement_delimiter), tok(char('}'))),
), ),
VariantKind::Record,
),
)(input) )(input)
} }
@ -369,7 +356,7 @@ fn variant_spec(input: Span) -> ParseResult<Variant> {
let id = fresh_id(&input); let id = fresh_id(&input);
let (rest, (name, kind)) = alt(( let (rest, (name, kind)) = alt((
pair(identifier, record_variant), pair(identifier, map(record_variant, VariantKind::Record)),
pair(identifier, tuple_variant), pair(identifier, tuple_variant),
map(identifier, |ident| (ident, VariantKind::UnitStruct)), map(identifier, |ident| (ident, VariantKind::UnitStruct)),
))(input)?; ))(input)?;
@ -478,8 +465,8 @@ fn operator(input: Span) -> ParseResult<BinOp> {
context( context(
"operator", "operator",
tok(map( tok(map(
tuple((cut(not(tag("*/"))), recognize(many1(one_of("+-*/%<>=!$&|?^`"))))), preceded(cut(not(tag("*/"))), recognize(many1(one_of("+-*/%<>=!$&|?^`")))),
|(_, sigil_span): ((), Span)| BinOp::from_sigil(sigil_span.fragment()), |sigil_span: Span| BinOp::from_sigil(sigil_span.fragment()),
)), )),
)(input) )(input)
} }
@ -609,10 +596,13 @@ fn primary_expr_no_struct(input: Span) -> ParseResult<ExpressionKind> {
} }
fn named_struct(input: Span) -> ParseResult<ExpressionKind> { fn named_struct(input: Span) -> ParseResult<ExpressionKind> {
context(
"named-struct",
map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct { map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct {
name, name,
fields, fields,
})(input) }),
)(input)
} }
//TODO support anonymous structs and Elm-style update syntax for structs //TODO support anonymous structs and Elm-style update syntax for structs
@ -624,22 +614,29 @@ fn record_block(input: Span) -> ParseResult<Vec<(Rc<String>, Expression)>> {
} }
fn lambda_expr(input: Span) -> ParseResult<ExpressionKind> { fn lambda_expr(input: Span) -> ParseResult<ExpressionKind> {
context(
"lambda-expr",
preceded(
tok(char('\\')),
alt(( alt((
map( map(tuple((formal_params, opt(type_anno), block)), |(params, type_anno, body)| {
preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))), ExpressionKind::Lambda { params, type_anno, body }
|(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( )(input)
preceded(tok(char('\\')), tuple((formal_param, opt(type_anno), block))),
|(param, type_anno, body)| ExpressionKind::Lambda { params: vec![param], type_anno, body },
),
))(input)
} }
fn while_expr(input: Span) -> ParseResult<ExpressionKind> { fn while_expr(input: Span) -> ParseResult<ExpressionKind> {
context(
"while-expr",
map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| { map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| {
ExpressionKind::WhileExpression { condition: condition.map(Box::new), body } ExpressionKind::WhileExpression { condition: condition.map(Box::new), body }
})(input) }),
)(input)
} }
fn if_expr(input: Span) -> ParseResult<ExpressionKind> { fn if_expr(input: Span) -> ParseResult<ExpressionKind> {
@ -688,9 +685,12 @@ fn if_expr(input: Span) -> ParseResult<ExpressionKind> {
alt((cond_block, simple_pattern_match, simple_conditional))(input) alt((cond_block, simple_pattern_match, simple_conditional))(input)
} }
context(
"if-expr",
map(preceded(kw("if"), pair(opt(expression_no_struct), if_expr_body)), |(discriminator, body)| { 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) } ExpressionKind::IfExpression { discriminator: discriminator.map(Box::new), body: Box::new(body) }
})(input) }),
)(input)
} }
fn pattern(input: Span) -> ParseResult<Pattern> { fn pattern(input: Span) -> ParseResult<Pattern> {
@ -782,9 +782,12 @@ fn for_expr(input: Span) -> ParseResult<ExpressionKind> {
))(input) ))(input)
} }
context(
"for-expr",
map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| { map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| {
ExpressionKind::ForExpression { enumerators, body } ExpressionKind::ForExpression { enumerators, body }
})(input) }),
)(input)
} }
fn paren_expr(input: Span) -> ParseResult<ExpressionKind> { fn paren_expr(input: Span) -> ParseResult<ExpressionKind> {
@ -859,17 +862,23 @@ fn bool_literal(input: Span) -> ParseResult<ExpressionKind> {
} }
fn float_literal(input: Span) -> ParseResult<ExpressionKind> { fn float_literal(input: Span) -> ParseResult<ExpressionKind> {
context(
"float-literal",
tok(map( tok(map(
alt(( alt((
recognize(tuple((digits(digit_group_dec), char('.'), opt(digits(digit_group_dec))))), recognize(tuple((digits(digit_group_dec), char('.'), opt(digits(digit_group_dec))))),
recognize(tuple((char('.'), 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> { 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> { fn dec_literal(input: Span) -> ParseResult<u64> {

View File

@ -254,9 +254,11 @@ fn duplicate_modules() {
fn duplicate_struct_members() { fn duplicate_struct_members() {
let source = r#" let source = r#"
type Tarak = Tarak { type Tarak = Tarak {
loujet: i32, loujet: i32
mets: i32, ,
mets: i32, mets: i32,
mets: i32
,
} }
"#; "#;