Parse comments in whitespace

This commit is contained in:
Joscha 2022-11-18 20:55:44 +01:00
parent a559966c1d
commit 41723eb4ca
2 changed files with 41 additions and 8 deletions

View file

@ -2,15 +2,25 @@ use std::fmt;
use crate::span::{HasSpan, Span}; use crate::span::{HasSpan, Span};
#[derive(Clone)]
pub enum Line {
Empty,
Comment(String),
}
#[derive(Clone)] #[derive(Clone)]
pub struct Space { pub struct Space {
pub comment: Vec<(String, Span)>, pub lines: Vec<Line>,
pub span: Span, pub span: Span,
} }
impl fmt::Debug for Space { impl fmt::Debug for Space {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Space").finish() if self.lines.iter().any(|l| matches!(l, Line::Comment(_))) {
write!(f, "space with comments")
} else {
write!(f, "space")
}
} }
} }

View file

@ -1,20 +1,43 @@
//! Corresponds to `ast::basic`. //! Corresponds to `ast::basic`.
use chumsky::prelude::*; use chumsky::prelude::*;
use chumsky::text::Character;
use crate::ast::{Ident, Space}; use crate::ast::{Ident, Line, Space};
use crate::span::Span; use crate::span::Span;
pub type Error = Simple<char, Span>; pub type Error = Simple<char, Span>;
// TODO https://github.com/rust-lang/rust/issues/63063 // TODO https://github.com/rust-lang/rust/issues/63063
pub fn inline() -> impl Parser<char, (), Error = Error> {
filter(|c: &char| c.is_whitespace() && *c != '\n')
.repeated()
.to(())
}
pub fn newline() -> impl Parser<char, (), Error = Error> {
just('\n').to(())
}
pub fn line() -> impl Parser<char, Line, Error = Error> {
let empty = newline().to(Line::Empty);
let comment = just('#')
.ignore_then(take_until(newline()))
.map(|(s, _)| s)
.collect::<String>()
.map(Line::Comment);
empty.or(comment)
}
pub fn space() -> impl Parser<char, Space, Error = Error> { pub fn space() -> impl Parser<char, Space, Error = Error> {
// TODO Parse comments inline()
text::whitespace().map_with_span(|(), span| Space { .ignore_then(line())
comment: vec![], .repeated()
span, .then_ignore(inline())
}) .map_with_span(|lines, span| Space { lines, span })
} }
pub fn ident() -> impl Parser<char, Ident, Error = Error> { pub fn ident() -> impl Parser<char, Ident, Error = Error> {