Comment parsing
This commit is contained in:
parent
e72a22d294
commit
b4fb2deb55
14
axc/foo.axs
14
axc/foo.axs
|
@ -1 +1,13 @@
|
||||||
def a (x: String) = 2 + a::b["xyz"] + fn x y -> x + y + {a : b};
|
// Need tuples, f x is broken
|
||||||
|
def a (x: String) = 2 + a::b["xyz"] // foo
|
||||||
|
+ fn x y -> x + y + {a : b};
|
||||||
|
|
||||||
|
def b = let (x, y) = 20 in x + y;
|
||||||
|
|
||||||
|
def c = match x + 1 {
|
||||||
|
a => {c: d, e: f},
|
||||||
|
};
|
||||||
|
|
||||||
|
class Cat a {
|
||||||
|
def meow (cat: a);
|
||||||
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ impl Default for ParserMeta {
|
||||||
|
|
||||||
/// Parser for AlexScript code.
|
/// Parser for AlexScript code.
|
||||||
pub fn parser<'a>(m: &'a ParserMeta) -> impl Parser<char, SyntaxTree, Error = Simple<char>> + 'a {
|
pub fn parser<'a>(m: &'a ParserMeta) -> impl Parser<char, SyntaxTree, Error = Simple<char>> + 'a {
|
||||||
|
whitespace_cmt().ignore_then(
|
||||||
parse_statement(m)
|
parse_statement(m)
|
||||||
.repeated()
|
.repeated()
|
||||||
.map(SyntaxTree)
|
.map(SyntaxTree)
|
||||||
|
@ -222,7 +223,8 @@ pub fn parser<'a>(m: &'a ParserMeta) -> impl Parser<char, SyntaxTree, Error = Si
|
||||||
.map(|exprs| {
|
.map(|exprs| {
|
||||||
println!("{:#?}", exprs);
|
println!("{:#?}", exprs);
|
||||||
todo!()
|
todo!()
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_statement<'a>(
|
fn parse_statement<'a>(
|
||||||
|
@ -237,16 +239,16 @@ fn parse_statement<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_type_def(m: &ParserMeta) -> impl Parser<char, Statement, Error = Simple<char>> {
|
fn parse_type_def(m: &ParserMeta) -> impl Parser<char, Statement, Error = Simple<char>> {
|
||||||
keyword("data")
|
pad(keyword("data"))
|
||||||
.ignore_then(parse_type(m))
|
.ignore_then(parse_type(m))
|
||||||
.then_ignore(just('=').then(whitespace()))
|
.then_ignore(pad(just('=')))
|
||||||
.then(parse_constructor(m).repeated())
|
.then(parse_constructor(m).repeated())
|
||||||
.then_ignore(just(';').then(whitespace()))
|
.then_ignore(pad(just(';')))
|
||||||
.map(|(typ, constructors)| Statement::TypeDefinition { typ, constructors })
|
.map(|(typ, constructors)| Statement::TypeDefinition { typ, constructors })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_constructor(m: &ParserMeta) -> impl Parser<char, TypeConstructor, Error = Simple<char>> {
|
fn parse_constructor(m: &ParserMeta) -> impl Parser<char, TypeConstructor, Error = Simple<char>> {
|
||||||
ident()
|
pad(ident())
|
||||||
.then(parse_type(m).repeated())
|
.then(parse_type(m).repeated())
|
||||||
.map(|(name, args)| TypeConstructor { name, args })
|
.map(|(name, args)| TypeConstructor { name, args })
|
||||||
}
|
}
|
||||||
|
@ -254,13 +256,13 @@ fn parse_constructor(m: &ParserMeta) -> impl Parser<char, TypeConstructor, Error
|
||||||
fn parse_instance_def<'a>(
|
fn parse_instance_def<'a>(
|
||||||
m: &'a ParserMeta,
|
m: &'a ParserMeta,
|
||||||
) -> impl Parser<char, Statement, Error = Simple<char>> + 'a {
|
) -> impl Parser<char, Statement, Error = Simple<char>> + 'a {
|
||||||
keyword("instance")
|
pad(keyword("instance"))
|
||||||
.ignore_then(ident())
|
.ignore_then(pad(ident()))
|
||||||
.then(parse_type(m))
|
.then(parse_type(m))
|
||||||
.then(
|
.then(
|
||||||
parse_class_member(m)
|
parse_class_member(m)
|
||||||
.repeated()
|
.repeated()
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace())),
|
.delimited_by(pad(just('{')), pad(just('}'))),
|
||||||
)
|
)
|
||||||
.map(|((classname, typ), decls)| Statement::InstanceDefinition {
|
.map(|((classname, typ), decls)| Statement::InstanceDefinition {
|
||||||
class_name: classname,
|
class_name: classname,
|
||||||
|
@ -284,17 +286,11 @@ fn parse_class_member<'a>(
|
||||||
fn parse_func_decl<'a>(
|
fn parse_func_decl<'a>(
|
||||||
m: &'a ParserMeta,
|
m: &'a ParserMeta,
|
||||||
) -> impl Parser<char, ClassMember, Error = Simple<char>> + 'a {
|
) -> impl Parser<char, ClassMember, Error = Simple<char>> + 'a {
|
||||||
keyword("def")
|
pad(keyword("def"))
|
||||||
.then_ignore(whitespace())
|
.ignore_then(pad(ident()))
|
||||||
.ignore_then(ident().then_ignore(whitespace()))
|
|
||||||
.then(parse_pattern(m).repeated())
|
.then(parse_pattern(m).repeated())
|
||||||
.then(
|
.then(pad(just('=')).ignore_then(parse_expression(m)).or_not())
|
||||||
just('=')
|
.then_ignore(pad(just(';')))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(parse_expression(m))
|
|
||||||
.or_not(),
|
|
||||||
)
|
|
||||||
.then_ignore(just(';').then(whitespace()))
|
|
||||||
.map(|((name, arguments), definition)| ClassMember::Function {
|
.map(|((name, arguments), definition)| ClassMember::Function {
|
||||||
name,
|
name,
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -303,29 +299,23 @@ fn parse_func_decl<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_type_alias(m: &ParserMeta) -> impl Parser<char, ClassMember, Error = Simple<char>> {
|
fn parse_type_alias(m: &ParserMeta) -> impl Parser<char, ClassMember, Error = Simple<char>> {
|
||||||
keyword("type")
|
pad(keyword("type"))
|
||||||
.then_ignore(whitespace())
|
|
||||||
.ignore_then(parse_type(m))
|
.ignore_then(parse_type(m))
|
||||||
.then(
|
.then(pad(just('=')).ignore_then(parse_type(m)).or_not())
|
||||||
just('=')
|
.then_ignore(pad(just(';')))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(parse_type(m))
|
|
||||||
.or_not(),
|
|
||||||
)
|
|
||||||
.then_ignore(just(';').then(whitespace()))
|
|
||||||
.map(|(left, right)| ClassMember::TypeAlias { left, right })
|
.map(|(left, right)| ClassMember::TypeAlias { left, right })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_class_def<'a>(
|
fn parse_class_def<'a>(
|
||||||
m: &'a ParserMeta,
|
m: &'a ParserMeta,
|
||||||
) -> impl Parser<char, Statement, Error = Simple<char>> + 'a {
|
) -> impl Parser<char, Statement, Error = Simple<char>> + 'a {
|
||||||
keyword("class")
|
pad(keyword("class"))
|
||||||
.ignore_then(ident())
|
.ignore_then(pad(ident()))
|
||||||
.then(ident())
|
.then(pad(ident()))
|
||||||
.then(
|
.then(
|
||||||
parse_class_member(m)
|
parse_class_member(m)
|
||||||
.repeated()
|
.repeated()
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace())),
|
.delimited_by(pad(just('{')), pad(just('}'))),
|
||||||
)
|
)
|
||||||
.map(|((name, var), decls)| Statement::ClassDefinition { name, var, decls })
|
.map(|((name, var), decls)| Statement::ClassDefinition { name, var, decls })
|
||||||
}
|
}
|
||||||
|
@ -355,8 +345,7 @@ fn parse_unary(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
choice((just("-").to("-"), just("+").to("+")))
|
pad(choice((just("-").to("-"), just("+").to("+"))))
|
||||||
.then_ignore(whitespace())
|
|
||||||
.repeated()
|
.repeated()
|
||||||
.then(base.clone())
|
.then(base.clone())
|
||||||
.map(|(ops, exp)| {
|
.map(|(ops, exp)| {
|
||||||
|
@ -374,8 +363,7 @@ fn parse_binary<'a>(
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + 'a + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + 'a + Clone {
|
||||||
let op_defs = m.operators.iter().filter(|def| def.precedence == prec);
|
let op_defs = m.operators.iter().filter(|def| def.precedence == prec);
|
||||||
let op_parsers = op_defs.map(|def| {
|
let op_parsers = op_defs.map(|def| {
|
||||||
just(def.name.to_string())
|
pad(just(def.name.to_string()))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(base.clone())
|
.ignore_then(base.clone())
|
||||||
.map(|e| (&def.name, &def.assoc, e))
|
.map(|e| (&def.name, &def.assoc, e))
|
||||||
});
|
});
|
||||||
|
@ -452,12 +440,11 @@ fn parse_let_expr(
|
||||||
m: &ParserMeta,
|
m: &ParserMeta,
|
||||||
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
keyword("let")
|
pad(keyword("let"))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(parse_pattern(m))
|
.ignore_then(parse_pattern(m))
|
||||||
.then_ignore(just('=').then(whitespace()))
|
.then_ignore(pad(just('=')))
|
||||||
.then(base.clone())
|
.then(base.clone())
|
||||||
.then_ignore(keyword("in").then(whitespace()))
|
.then_ignore(pad(keyword("in")))
|
||||||
.then(base.clone())
|
.then(base.clone())
|
||||||
.map(|((left, right), into)| Expr::Let {
|
.map(|((left, right), into)| Expr::Let {
|
||||||
left,
|
left,
|
||||||
|
@ -470,16 +457,15 @@ fn parse_match_expr(
|
||||||
m: &ParserMeta,
|
m: &ParserMeta,
|
||||||
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
keyword("match")
|
pad(keyword("match"))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(base.clone())
|
.ignore_then(base.clone())
|
||||||
.then(
|
.then(
|
||||||
parse_pattern(m)
|
parse_pattern(m)
|
||||||
.then_ignore(just("=>").then(whitespace()))
|
.then_ignore(pad(just("=>")))
|
||||||
.then(base.clone())
|
.then(base.clone())
|
||||||
.separated_by(just(",").then(whitespace()))
|
.separated_by(pad(just(",")))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace())),
|
.delimited_by(pad(just('{')), pad(just('}'))),
|
||||||
)
|
)
|
||||||
.map(|(matcher, cases)| Expr::Match {
|
.map(|(matcher, cases)| Expr::Match {
|
||||||
matcher: Box::new(matcher),
|
matcher: Box::new(matcher),
|
||||||
|
@ -491,14 +477,12 @@ fn parse_record_expr(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
ident()
|
pad(ident())
|
||||||
.then_ignore(whitespace())
|
.then_ignore(pad(just(':')))
|
||||||
.then_ignore(just(':'))
|
|
||||||
.then_ignore(whitespace())
|
|
||||||
.then(base)
|
.then(base)
|
||||||
.separated_by(just(',').then(whitespace()))
|
.separated_by(pad(just(',')))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace()))
|
.delimited_by(pad(just('{')), pad(just('}')))
|
||||||
.map(Expr::Record)
|
.map(Expr::Record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,10 +490,9 @@ fn parse_lambda_expr(
|
||||||
m: &ParserMeta,
|
m: &ParserMeta,
|
||||||
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
base: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
keyword("fn")
|
pad(keyword("fn"))
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(parse_pattern(m).repeated())
|
.ignore_then(parse_pattern(m).repeated())
|
||||||
.then_ignore(just("->").then(whitespace()))
|
.then_ignore(pad(just("->")))
|
||||||
.then(base)
|
.then(base)
|
||||||
.map(|(arguments, result)| Expr::Lambda {
|
.map(|(arguments, result)| Expr::Lambda {
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -529,12 +512,11 @@ fn parse_subscript_expr(
|
||||||
base.clone()
|
base.clone()
|
||||||
.then(
|
.then(
|
||||||
choice((
|
choice((
|
||||||
just('.')
|
pad(just('.'))
|
||||||
.ignore_then(whitespace())
|
|
||||||
.ignore_then(base.clone())
|
.ignore_then(base.clone())
|
||||||
.map(|e| (SubscriptKind::Dot, e)),
|
.map(|e| (SubscriptKind::Dot, e)),
|
||||||
base.clone()
|
base.clone()
|
||||||
.delimited_by(just('[').then(whitespace()), just(']').then(whitespace()))
|
.delimited_by(pad(just('[')), pad(just(']')))
|
||||||
.map(|e| (SubscriptKind::Bracket, e)),
|
.map(|e| (SubscriptKind::Bracket, e)),
|
||||||
))
|
))
|
||||||
.repeated(),
|
.repeated(),
|
||||||
|
@ -554,9 +536,8 @@ fn parse_subscript_expr(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_var_ref_expr(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
fn parse_var_ref_expr(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char>> + Clone {
|
||||||
ident()
|
pad(ident())
|
||||||
.then_ignore(whitespace())
|
.separated_by(pad(just("::")))
|
||||||
.separated_by(just("::").then(whitespace()))
|
|
||||||
.map(Expr::VariableReference)
|
.map(Expr::VariableReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +565,6 @@ fn parse_literal(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char
|
||||||
))));
|
))));
|
||||||
|
|
||||||
let int = int(10)
|
let int = int(10)
|
||||||
.then_ignore(whitespace())
|
|
||||||
.map(|s: String| s.parse().unwrap())
|
.map(|s: String| s.parse().unwrap())
|
||||||
.map(Literal::Integer);
|
.map(Literal::Integer);
|
||||||
|
|
||||||
|
@ -603,9 +583,7 @@ fn parse_literal(_m: &ParserMeta) -> impl Parser<char, Expr, Error = Simple<char
|
||||||
.map(|(l, r)| (l + "." + &r).parse().unwrap())
|
.map(|(l, r)| (l + "." + &r).parse().unwrap())
|
||||||
.map(Literal::Float);
|
.map(Literal::Float);
|
||||||
|
|
||||||
choice((int, float, string))
|
pad(choice((int, float, string))).map(Expr::Literal)
|
||||||
.then_ignore(whitespace())
|
|
||||||
.map(Expr::Literal)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_type(m: &ParserMeta) -> impl Parser<char, Type, Error = Simple<char>> {
|
fn parse_type(m: &ParserMeta) -> impl Parser<char, Type, Error = Simple<char>> {
|
||||||
|
@ -630,16 +608,16 @@ fn parse_type(m: &ParserMeta) -> impl Parser<char, Type, Error = Simple<char>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_named_type(_m: &ParserMeta) -> impl Parser<char, Type, Error = Simple<char>> {
|
fn parse_named_type(_m: &ParserMeta) -> impl Parser<char, Type, Error = Simple<char>> {
|
||||||
ident().then_ignore(whitespace()).map(Type::Named)
|
pad(ident()).map(Type::Named)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tuple_type(
|
fn parse_tuple_type(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
rec: impl Parser<char, Type, Error = Simple<char>>,
|
rec: impl Parser<char, Type, Error = Simple<char>>,
|
||||||
) -> impl Parser<char, Type, Error = Simple<char>> {
|
) -> impl Parser<char, Type, Error = Simple<char>> {
|
||||||
rec.separated_by(just(',').then(whitespace()))
|
rec.separated_by(pad(just(',')))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just('(').then(whitespace()), just(')').then(whitespace()))
|
.delimited_by(pad(just('(')), pad(just(')')))
|
||||||
.map(|types| {
|
.map(|types| {
|
||||||
if types.len() == 1 {
|
if types.len() == 1 {
|
||||||
// `(Int)` is the same as `Int`
|
// `(Int)` is the same as `Int`
|
||||||
|
@ -654,14 +632,12 @@ fn parse_record_type(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
rec: impl Parser<char, Type, Error = Simple<char>>,
|
rec: impl Parser<char, Type, Error = Simple<char>>,
|
||||||
) -> impl Parser<char, Type, Error = Simple<char>> {
|
) -> impl Parser<char, Type, Error = Simple<char>> {
|
||||||
ident()
|
pad(ident())
|
||||||
.then_ignore(whitespace())
|
.then_ignore(pad(just(':')))
|
||||||
.then_ignore(just(':'))
|
|
||||||
.then_ignore(whitespace())
|
|
||||||
.then(rec)
|
.then(rec)
|
||||||
.separated_by(just(',').then(whitespace()))
|
.separated_by(pad(just(',')))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace()))
|
.delimited_by(pad(just('{')), pad(just('}')))
|
||||||
.map(Type::Record)
|
.map(Type::Record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,12 +657,7 @@ fn parse_pattern(m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<ch
|
||||||
.reduce(|l, r| Pattern::Destructure(Box::new(l), Box::new(r)))
|
.reduce(|l, r| Pattern::Destructure(Box::new(l), Box::new(r)))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
.then(
|
.then(pad(just(':')).ignore_then(parse_type(m)).or_not())
|
||||||
just(':')
|
|
||||||
.then(whitespace())
|
|
||||||
.ignore_then(parse_type(m))
|
|
||||||
.or_not(),
|
|
||||||
)
|
|
||||||
.map(|(pat, typ)| match typ {
|
.map(|(pat, typ)| match typ {
|
||||||
Some(typ) => Pattern::TypeAnnotated {
|
Some(typ) => Pattern::TypeAnnotated {
|
||||||
pat: Box::new(pat),
|
pat: Box::new(pat),
|
||||||
|
@ -698,20 +669,20 @@ fn parse_pattern(m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<ch
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ignore_pattern(_m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
fn parse_ignore_pattern(_m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
||||||
keyword("_").then_ignore(whitespace()).to(Pattern::Ignore)
|
pad(keyword("_")).to(Pattern::Ignore)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_capture_pattern(_m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
fn parse_capture_pattern(_m: &ParserMeta) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
||||||
ident().then_ignore(whitespace()).map(Pattern::Capture)
|
pad(ident()).map(Pattern::Capture)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tuple_pattern(
|
fn parse_tuple_pattern(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
rec: impl Parser<char, Pattern, Error = Simple<char>>,
|
rec: impl Parser<char, Pattern, Error = Simple<char>>,
|
||||||
) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
||||||
rec.separated_by(just(',').then(whitespace()))
|
rec.separated_by(pad(just(',')))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.delimited_by(just('(').then(whitespace()), just(')').then(whitespace()))
|
.delimited_by(pad(just('(')), pad(just(')')))
|
||||||
.map(|pats| {
|
.map(|pats| {
|
||||||
if pats.len() == 1 {
|
if pats.len() == 1 {
|
||||||
// `(Int)` is the same as `Int`
|
// `(Int)` is the same as `Int`
|
||||||
|
@ -726,25 +697,13 @@ fn parse_record_pattern(
|
||||||
_m: &ParserMeta,
|
_m: &ParserMeta,
|
||||||
rec: impl Parser<char, Pattern, Error = Simple<char>>,
|
rec: impl Parser<char, Pattern, Error = Simple<char>>,
|
||||||
) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
) -> impl Parser<char, Pattern, Error = Simple<char>> {
|
||||||
let item = ident().then_ignore(whitespace()).then(
|
let item = pad(ident()).then(pad(just(':')).ignore_then(rec).or_not());
|
||||||
just(':')
|
let items = item.separated_by(pad(just(','))).allow_trailing();
|
||||||
.ignore_then(whitespace())
|
let ellipsis = pad(just("...")).or_not().map(|ellipsis| ellipsis.is_some());
|
||||||
.ignore_then(rec)
|
|
||||||
.or_not(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let items = item
|
|
||||||
.separated_by(just(',').then(whitespace()))
|
|
||||||
.allow_trailing();
|
|
||||||
|
|
||||||
let ellipsis = just("...")
|
|
||||||
.ignore_then(whitespace())
|
|
||||||
.or_not()
|
|
||||||
.map(|ellipsis| ellipsis.is_some());
|
|
||||||
|
|
||||||
items
|
items
|
||||||
.then(ellipsis)
|
.then(ellipsis)
|
||||||
.delimited_by(just('{').then(whitespace()), just('}').then(whitespace()))
|
.delimited_by(pad(just('{')), pad(just('}')))
|
||||||
.map(|(members, inexhaustive)| Pattern::Record {
|
.map(|(members, inexhaustive)| Pattern::Record {
|
||||||
members,
|
members,
|
||||||
inexhaustive,
|
inexhaustive,
|
||||||
|
@ -758,3 +717,19 @@ fn parse_literal_pattern(m: &ParserMeta) -> impl Parser<char, Pattern, Error = S
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn whitespace_cmt() -> impl Parser<char, (), Error = Simple<char>> + Clone {
|
||||||
|
whitespace().then_ignore(
|
||||||
|
just("//")
|
||||||
|
.then(none_of("\n").repeated())
|
||||||
|
.then(just('\n'))
|
||||||
|
.then(whitespace())
|
||||||
|
.repeated(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pad<T>(
|
||||||
|
p: impl Parser<char, T, Error = Simple<char>> + Clone,
|
||||||
|
) -> impl Parser<char, T, Error = Simple<char>> + Clone {
|
||||||
|
p.then_ignore(whitespace_cmt())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue