Compare commits
2 Commits
3e422291f4
...
1a48e9b43a
Author | SHA1 | Date | |
---|---|---|---|
|
1a48e9b43a | ||
|
1797136156 |
@ -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,32 +329,19 @@ 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(separated_list1(toknl(char(',')), toknl(record_variant_item)), opt(toknl(char(',')))),
|
||||||
terminated(
|
pair(many0(statement_delimiter), tok(char('}'))),
|
||||||
separated_list1(pair(tok(char(',')), many0(statement_delimiter)), record_variant_item),
|
|
||||||
opt(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> {
|
||||||
map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct {
|
context(
|
||||||
name,
|
"named-struct",
|
||||||
fields,
|
map(pair(qualified_identifier, record_block), |(name, fields)| ExpressionKind::NamedStruct {
|
||||||
})(input)
|
name,
|
||||||
|
fields,
|
||||||
|
}),
|
||||||
|
)(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> {
|
||||||
alt((
|
context(
|
||||||
map(
|
"lambda-expr",
|
||||||
preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))),
|
preceded(
|
||||||
|(params, type_anno, body)| ExpressionKind::Lambda { params, type_anno, body },
|
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(
|
)(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> {
|
||||||
map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| {
|
context(
|
||||||
ExpressionKind::WhileExpression { condition: condition.map(Box::new), body }
|
"while-expr",
|
||||||
})(input)
|
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> {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
map(preceded(kw("if"), pair(opt(expression_no_struct), if_expr_body)), |(discriminator, body)| {
|
context(
|
||||||
ExpressionKind::IfExpression { discriminator: discriminator.map(Box::new), body: Box::new(body) }
|
"if-expr",
|
||||||
})(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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| {
|
context(
|
||||||
ExpressionKind::ForExpression { enumerators, body }
|
"for-expr",
|
||||||
})(input)
|
map(preceded(kw("for"), pair(for_enumerators, for_body)), |(enumerators, body)| {
|
||||||
|
ExpressionKind::ForExpression { enumerators, body }
|
||||||
|
}),
|
||||||
|
)(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> {
|
||||||
tok(map(
|
context(
|
||||||
alt((
|
"float-literal",
|
||||||
recognize(tuple((digits(digit_group_dec), char('.'), opt(digits(digit_group_dec))))),
|
tok(map(
|
||||||
recognize(tuple((char('.'), digits(digit_group_dec)))),
|
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> {
|
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> {
|
||||||
|
@ -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
|
||||||
|
,
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user