Rustfmt
This commit is contained in:
parent
f1ffeb155a
commit
d37be75478
@ -1,17 +1,20 @@
|
|||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
Err,
|
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{take_till, tag},
|
bytes::complete::{tag, take_till},
|
||||||
character::complete::{alpha1, alphanumeric0, not_line_ending,none_of, char, one_of, space0, space1, multispace0, line_ending},
|
character::complete::{
|
||||||
combinator::{opt, peek, not, value, map, recognize},
|
alpha1, alphanumeric0, char, line_ending, multispace0, none_of, not_line_ending, one_of, space0,
|
||||||
error::{context, VerboseError, ParseError},
|
space1,
|
||||||
multi::{fold_many1, many1, many0, separated_list1, separated_list0},
|
},
|
||||||
sequence::{pair, tuple, preceded},
|
combinator::{map, not, opt, peek, recognize, value},
|
||||||
IResult, Parser,
|
error::{context, ParseError, VerboseError},
|
||||||
|
multi::{fold_many1, many0, many1, separated_list0, separated_list1},
|
||||||
|
sequence::{pair, preceded, tuple},
|
||||||
|
Err, IResult, Parser,
|
||||||
};
|
};
|
||||||
use nom_locate::{position, LocatedSpan};
|
use nom_locate::{position, LocatedSpan};
|
||||||
use std::rc::Rc;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use crate::identifier::{Id, IdStore};
|
use crate::identifier::{Id, IdStore};
|
||||||
|
|
||||||
type StoreRef = Rc<RefCell<IdStore<ASTItem>>>;
|
type StoreRef = Rc<RefCell<IdStore<ASTItem>>>;
|
||||||
@ -29,92 +32,80 @@ fn fresh_id(span: &Span) -> Id<ASTItem> {
|
|||||||
table_handle.fresh()
|
table_handle.fresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tok<'a, O>(input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>) -> impl FnMut(Span<'a>)
|
fn tok<'a, O>(
|
||||||
-> IResult<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>>> {
|
||||||
context("tok",
|
context("tok", map(tuple((ws0, input_parser)), |(_, output)| output))
|
||||||
map(tuple((ws0, input_parser)), |(_, output)|
|
|
||||||
output))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kw<'a>(keyword_str: &'static str) -> impl FnMut(Span<'a>) -> ParseResult<()> {
|
fn kw<'a>(keyword_str: &'static str) -> impl FnMut(Span<'a>) -> ParseResult<()> {
|
||||||
context("keyword",
|
context("keyword", tok(value((), tag(keyword_str))))
|
||||||
tok(value((), tag(keyword_str))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// whitespace does consume at least one piece of whitespace - use ws0 for maybe none
|
// whitespace does consume at least one piece of whitespace - use ws0 for maybe none
|
||||||
fn whitespace(input: Span) -> ParseResult<()> {
|
fn whitespace(input: Span) -> ParseResult<()> {
|
||||||
context("whitespace",
|
context("whitespace", alt((block_comment, line_comment, value((), space1))))(input)
|
||||||
alt((
|
|
||||||
block_comment,
|
|
||||||
line_comment,
|
|
||||||
value((), space1),
|
|
||||||
)))(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ws0(input: Span) -> ParseResult<()> {
|
fn ws0(input: Span) -> ParseResult<()> {
|
||||||
context("WS0",
|
context("WS0", value((), many0(whitespace)))(input)
|
||||||
value((), many0(whitespace)))(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn line_comment(input: Span) -> ParseResult<()> {
|
fn line_comment(input: Span) -> ParseResult<()> {
|
||||||
value((),
|
value((), tuple((tag("//"), not_line_ending)))(input)
|
||||||
tuple((tag("//"), not_line_ending)),
|
|
||||||
)(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_comment(input: Span) -> ParseResult<()> {
|
fn block_comment(input: Span) -> ParseResult<()> {
|
||||||
context("Block-comment",
|
context(
|
||||||
value((),
|
"Block-comment",
|
||||||
tuple((
|
value(
|
||||||
tag("/*"),
|
(),
|
||||||
many0(alt((
|
tuple((
|
||||||
value((), none_of("*/")),
|
tag("/*"),
|
||||||
value((), none_of("/*")),
|
many0(alt((value((), none_of("*/")), value((), none_of("/*")), block_comment))),
|
||||||
block_comment,
|
tag("*/"),
|
||||||
))),
|
)),
|
||||||
tag("*/")
|
),
|
||||||
))))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn statement_delimiter(input: Span) -> ParseResult<()> {
|
|
||||||
tok(alt((
|
|
||||||
value((), line_ending),
|
|
||||||
value((), char(';'))
|
|
||||||
))
|
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn statement_delimiter(input: Span) -> ParseResult<()> {
|
||||||
|
tok(alt((value((), line_ending), value((), char(';')))))(input)
|
||||||
|
}
|
||||||
|
|
||||||
fn block(input: Span) -> ParseResult<Block> {
|
fn block(input: Span) -> ParseResult<Block> {
|
||||||
context("block",
|
context(
|
||||||
map(
|
"block",
|
||||||
tuple((
|
map(
|
||||||
tok(char('{')),
|
tuple((
|
||||||
many0(statement_delimiter),
|
tok(char('{')),
|
||||||
separated_list0(statement_delimiter, statement),
|
many0(statement_delimiter),
|
||||||
many0(statement_delimiter),
|
separated_list0(statement_delimiter, statement),
|
||||||
tok(char('}')),
|
many0(statement_delimiter),
|
||||||
)), |(_, _, items, _, _)| items.into()))(input)
|
tok(char('}')),
|
||||||
|
)),
|
||||||
|
|(_, _, items, _, _)| items.into(),
|
||||||
|
),
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statement(input: Span) -> ParseResult<Statement> {
|
fn statement(input: Span) -> ParseResult<Statement> {
|
||||||
let (input, pos) = position(input)?;
|
let (input, pos) = position(input)?;
|
||||||
let pos: usize = pos.location_offset();
|
let pos: usize = pos.location_offset();
|
||||||
let id = fresh_id(&input);
|
let id = fresh_id(&input);
|
||||||
context("Parsing-statement",
|
context(
|
||||||
map(expression, move |expr| Statement {
|
"Parsing-statement",
|
||||||
id,
|
map(expression, move |expr| Statement {
|
||||||
location: pos.into(),
|
id,
|
||||||
kind: StatementKind::Expression(expr),
|
location: pos.into(),
|
||||||
}))(input)
|
kind: StatementKind::Expression(expr),
|
||||||
|
}),
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expression(input: Span) -> ParseResult<Expression> {
|
fn expression(input: Span) -> ParseResult<Expression> {
|
||||||
let id = fresh_id(&input);
|
let id = fresh_id(&input);
|
||||||
map(pair(expression_kind, opt(type_anno)), move |(kind, maybe_anno)| {
|
map(pair(expression_kind, opt(type_anno)), move |(kind, maybe_anno)| Expression::new(id, kind))(input)
|
||||||
Expression::new(id, kind)
|
|
||||||
})(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_anno(input: Span) -> ParseResult<TypeIdentifier> {
|
fn type_anno(input: Span) -> ParseResult<TypeIdentifier> {
|
||||||
@ -140,13 +131,7 @@ pub fn expression_kind(input: Span) -> ParseResult<ExpressionKind> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn primary_expr(input: Span) -> ParseResult<ExpressionKind> {
|
fn primary_expr(input: Span) -> ParseResult<ExpressionKind> {
|
||||||
context("primary-expr",
|
context("primary-expr", alt((number_literal, bool_literal, identifier_expr)))(input)
|
||||||
alt((
|
|
||||||
number_literal,
|
|
||||||
bool_literal,
|
|
||||||
identifier_expr,
|
|
||||||
)))(input)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier_expr(input: Span) -> ParseResult<ExpressionKind> {
|
fn identifier_expr(input: Span) -> ParseResult<ExpressionKind> {
|
||||||
@ -155,27 +140,23 @@ fn identifier_expr(input: Span) -> ParseResult<ExpressionKind> {
|
|||||||
|
|
||||||
fn qualified_identifier(input: Span) -> ParseResult<QualifiedName> {
|
fn qualified_identifier(input: Span) -> ParseResult<QualifiedName> {
|
||||||
let id = fresh_id(&input);
|
let id = fresh_id(&input);
|
||||||
tok(
|
tok(map(separated_list1(tag("::"), map(identifier, |x| rc_string(x.fragment()))), move |items| {
|
||||||
map(
|
QualifiedName { id, components: items }
|
||||||
separated_list1(tag("::"), map(identifier, |x| rc_string(x.fragment()))),
|
}))(input)
|
||||||
move |items| QualifiedName { id, components: items }
|
|
||||||
))(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier(input: Span) -> ParseResult<Span> {
|
fn identifier(input: Span) -> ParseResult<Span> {
|
||||||
recognize(
|
recognize(tuple((alt((tag("_"), alpha1)), alphanumeric0)))(input)
|
||||||
tuple((
|
|
||||||
alt((tag("_"), alpha1)),
|
|
||||||
alphanumeric0,
|
|
||||||
)))(input)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bool_literal(input: Span) -> ParseResult<ExpressionKind> {
|
fn bool_literal(input: Span) -> ParseResult<ExpressionKind> {
|
||||||
context("bool-literal",
|
context(
|
||||||
alt((
|
"bool-literal",
|
||||||
map(kw("true"), |_| ExpressionKind::BoolLiteral(true)),
|
alt((
|
||||||
map(kw("false"), |_| ExpressionKind::BoolLiteral(false)),
|
map(kw("true"), |_| ExpressionKind::BoolLiteral(true)),
|
||||||
)))(input)
|
map(kw("false"), |_| ExpressionKind::BoolLiteral(false)),
|
||||||
|
)),
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn number_literal(input: Span) -> ParseResult<ExpressionKind> {
|
fn number_literal(input: Span) -> ParseResult<ExpressionKind> {
|
||||||
@ -282,14 +263,11 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! span {
|
macro_rules! span {
|
||||||
($func:expr, $input:expr) => {
|
($func:expr, $input:expr) => {{
|
||||||
{
|
|
||||||
let id_store: IdStore<ASTItem> = IdStore::new();
|
let id_store: IdStore<ASTItem> = IdStore::new();
|
||||||
let span = Span::new_extra($input,
|
let span = Span::new_extra($input, Rc::new(RefCell::new(id_store)));
|
||||||
Rc::new(RefCell::new(id_store)));
|
|
||||||
$func(span).map(|(span, x)| (*span.fragment(), x))
|
$func(span).map(|(span, x)| (*span.fragment(), x))
|
||||||
}
|
}};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -313,7 +291,10 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(span!(expression_kind, " /*gay*/ true").unwrap().1, ExpressionKind::BoolLiteral(true));
|
assert_eq!(span!(expression_kind, " /*gay*/ true").unwrap().1, ExpressionKind::BoolLiteral(true));
|
||||||
assert_eq!(span!(expression_kind, " /*yolo*/ barnaby").unwrap().1, ExpressionKind::Value(qn!(barnaby)));
|
assert_eq!(
|
||||||
|
span!(expression_kind, " /*yolo*/ barnaby").unwrap().1,
|
||||||
|
ExpressionKind::Value(qn!(barnaby))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -328,10 +309,12 @@ mod test {
|
|||||||
}"#;
|
}"#;
|
||||||
let parsed = span!(block, source).map_err(|err| match err {
|
let parsed = span!(block, source).map_err(|err| match err {
|
||||||
Err::Error(err) | Err::Failure(err) => {
|
Err::Error(err) | Err::Failure(err) => {
|
||||||
let err = VerboseError { errors: err.errors.into_iter().map(|(sp, kind)| (*sp.fragment(), kind)).collect() };
|
let err = VerboseError {
|
||||||
|
errors: err.errors.into_iter().map(|(sp, kind)| (*sp.fragment(), kind)).collect(),
|
||||||
|
};
|
||||||
nom::error::convert_error(source, err)
|
nom::error::convert_error(source, err)
|
||||||
},
|
}
|
||||||
_ => panic!()
|
_ => panic!(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(err) = parsed {
|
if let Err(err) = parsed {
|
||||||
@ -339,16 +322,35 @@ mod test {
|
|||||||
panic!("parse error desu!");
|
panic!("parse error desu!");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(parsed.unwrap().1, vec![
|
assert_eq!(
|
||||||
Statement { id: Default::default(), location:
|
parsed.unwrap().1,
|
||||||
Default::default(), kind: StatementKind::Expression(Expression::new(Default::default(),
|
vec![
|
||||||
ExpressionKind::NatLiteral(45))) },
|
Statement {
|
||||||
Statement { id: Default::default(), location:
|
id: Default::default(),
|
||||||
Default::default(), kind: StatementKind::Expression(Expression::new(Default::default(),
|
location: Default::default(),
|
||||||
ExpressionKind::NatLiteral(11))) },
|
kind: StatementKind::Expression(Expression::new(
|
||||||
Statement { id: Default::default(), location:
|
Default::default(),
|
||||||
Default::default(), kind: StatementKind::Expression(Expression::new(Default::default(),
|
ExpressionKind::NatLiteral(45)
|
||||||
ExpressionKind::NatLiteral(15))) },
|
))
|
||||||
].into());
|
},
|
||||||
|
Statement {
|
||||||
|
id: Default::default(),
|
||||||
|
location: Default::default(),
|
||||||
|
kind: StatementKind::Expression(Expression::new(
|
||||||
|
Default::default(),
|
||||||
|
ExpressionKind::NatLiteral(11)
|
||||||
|
))
|
||||||
|
},
|
||||||
|
Statement {
|
||||||
|
id: Default::default(),
|
||||||
|
location: Default::default(),
|
||||||
|
kind: StatementKind::Expression(Expression::new(
|
||||||
|
Default::default(),
|
||||||
|
ExpressionKind::NatLiteral(15)
|
||||||
|
))
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1352,5 +1352,3 @@ fn backtick_operators() {
|
|||||||
assert_eq!(output, vec![digit!("1"), op!("plus"), digit!("2")]);
|
assert_eq!(output, vec![digit!("1"), op!("plus"), digit!("2")]);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user