170 lines
3.5 KiB
Rust
170 lines
3.5 KiB
Rust
use super::{
|
|
Token,
|
|
SpannedData,
|
|
SpanRef,
|
|
PResult,
|
|
TokenList,
|
|
IResultExt,
|
|
SpanExt,
|
|
};
|
|
|
|
fn parse_bracketed<'a, O, C, F, T>(
|
|
open_tag: &'static str,
|
|
close_tag: &'static str,
|
|
open: O,
|
|
close: C,
|
|
constructor: F,
|
|
span: SpanRef<'a>,
|
|
) -> PResult<'a, SpannedData<T>>
|
|
where
|
|
F: FnOnce(SpannedData<O>, TokenList, SpannedData<C>) -> T,
|
|
{
|
|
use nom::{Offset, Slice};
|
|
|
|
let (rem_span, open_span) = nom::bytes::complete::tag(open_tag)(span)?;
|
|
let (rem_span, inner) = TokenList::parse_expression(rem_span).unrecoverable()?;
|
|
let (rem_span, close_span) = nom::bytes::complete::tag(close_tag)(rem_span).unrecoverable()?;
|
|
let result = constructor(open_span.data(open), inner, close_span.data(close));
|
|
let index = span.offset(&rem_span);
|
|
let bracket_span = span.slice(..index);
|
|
Ok((rem_span, bracket_span.data(result)))
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct CurlyOpen;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct CurlyClose;
|
|
|
|
#[derive(Clone)]
|
|
pub struct CurlyBrackets {
|
|
pub open: SpannedData<CurlyOpen>,
|
|
pub inner: TokenList,
|
|
pub close: SpannedData<CurlyClose>,
|
|
}
|
|
|
|
impl CurlyBrackets {
|
|
pub(super) fn parse(span: SpanRef) -> PResult<SpannedData<Token>> {
|
|
parse_bracketed(
|
|
"{", "}", CurlyOpen, CurlyClose,
|
|
|open, inner, close| {
|
|
Self { open, inner, close }.into()
|
|
},
|
|
span,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for CurlyBrackets {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
if self.inner.0.is_empty() {
|
|
f.write_str("{ }")
|
|
} else {
|
|
write!(f, "{{ {:?} }}", self.inner)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct SquareOpen;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct SquareClose;
|
|
|
|
#[derive(Clone)]
|
|
pub struct SquareBrackets {
|
|
pub open: SpannedData<SquareOpen>,
|
|
pub inner: TokenList,
|
|
pub close: SpannedData<SquareClose>,
|
|
}
|
|
|
|
impl SquareBrackets {
|
|
pub(super) fn parse(span: SpanRef) -> PResult<SpannedData<Token>> {
|
|
parse_bracketed(
|
|
"[", "]", SquareOpen, SquareClose,
|
|
|open, inner, close| {
|
|
Self { open, inner, close }.into()
|
|
},
|
|
span,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for SquareBrackets {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
if self.inner.0.is_empty() {
|
|
f.write_str("[ ]")
|
|
} else {
|
|
write!(f, "[ {:?} ]", self.inner)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct RoundOpen;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct RoundClose;
|
|
|
|
#[derive(Clone)]
|
|
pub struct RoundBrackets {
|
|
pub open: SpannedData<RoundOpen>,
|
|
pub inner: TokenList,
|
|
pub close: SpannedData<RoundClose>,
|
|
}
|
|
|
|
impl RoundBrackets {
|
|
pub(super) fn parse(span: SpanRef) -> PResult<SpannedData<Token>> {
|
|
parse_bracketed(
|
|
"(", ")", RoundOpen, RoundClose,
|
|
|open, inner, close| {
|
|
Self { open, inner, close }.into()
|
|
},
|
|
span,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for RoundBrackets {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
if self.inner.0.is_empty() {
|
|
f.write_str("( )")
|
|
} else {
|
|
write!(f, "( {:?} )", self.inner)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct InterpolateOpen;
|
|
|
|
/// Any `${...}` expresions, whether in strings or outside
|
|
#[derive(Clone)]
|
|
pub struct Interpolate {
|
|
pub open: SpannedData<InterpolateOpen>,
|
|
pub inner: TokenList,
|
|
pub close: SpannedData<CurlyClose>,
|
|
}
|
|
|
|
impl Interpolate {
|
|
pub(super) fn parse(span: SpanRef) -> PResult<SpannedData<Interpolate>> {
|
|
parse_bracketed(
|
|
"${", "}", InterpolateOpen, CurlyClose,
|
|
|open, inner, close| {
|
|
Self { open, inner, close }
|
|
},
|
|
span,
|
|
)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Debug for Interpolate {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
if self.inner.0.is_empty() {
|
|
f.write_str("${ }")
|
|
} else {
|
|
write!(f, "${{ {:?} }}", self.inner)
|
|
}
|
|
}
|
|
}
|