use new predicate parsing for bracketed lists

This commit is contained in:
Connor Skees 2020-08-05 03:03:58 -04:00
parent b2e7270681
commit df1456f9b1
3 changed files with 30 additions and 78 deletions

View File

@ -15,8 +15,7 @@ use crate::{
error::SassResult, error::SassResult,
unit::Unit, unit::Unit,
utils::{ utils::{
devour_whitespace, eat_whole_number, read_until_closing_paren, devour_whitespace, eat_whole_number, read_until_closing_paren, IsWhitespace, ParsedNumber,
read_until_closing_square_brace, IsWhitespace, ParsedNumber,
}, },
value::{Number, SassFunction, SassMap, Value}, value::{Number, SassFunction, SassMap, Value},
Token, Token,
@ -30,7 +29,6 @@ use super::super::Parser;
enum IntermediateValue { enum IntermediateValue {
Value(HigherIntermediateValue), Value(HigherIntermediateValue),
Op(Op), Op(Op),
Bracketed(Vec<Token>),
Paren(Vec<Token>), Paren(Vec<Token>),
Comma, Comma,
Whitespace, Whitespace,
@ -127,22 +125,6 @@ impl<'a> Parser<'a> {
); );
} }
} }
IntermediateValue::Bracketed(t) => {
last_was_whitespace = false;
space_separated.push(
HigherIntermediateValue::Literal(
match iter.parser.parse_value_from_vec(t, in_paren)?.node {
Value::List(v, sep, Brackets::None) => {
Value::List(v, sep, Brackets::Bracketed)
}
v => {
Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed)
}
},
)
.span(val.span),
)
}
IntermediateValue::Paren(t) => { IntermediateValue::Paren(t) => {
last_was_whitespace = false; last_was_whitespace = false;
space_separated.push(iter.parse_paren(Spanned { space_separated.push(iter.parse_paren(Spanned {
@ -608,28 +590,42 @@ impl<'a> Parser<'a> {
.span(span_start.merge(span)) .span(span_start.merge(span))
} }
'[' => { '[' => {
let mut span = self.toks.next().unwrap().pos(); let mut span = self.span_before;
self.toks.next();
self.whitespace_or_comment(); self.whitespace_or_comment();
let mut inner = match read_until_closing_square_brace(self.toks) {
Ok(v) => v, if let Some(Token { kind: ']', pos }) = self.toks.peek() {
Err(e) => return Some(Err(e)), span = span.merge(*pos);
}; self.toks.next();
if let Some(last_tok) = inner.pop() {
if last_tok.kind != ']' {
return Some(Err(("expected \"]\".", span).into()));
}
span = span.merge(last_tok.pos());
}
if inner.is_empty() {
IntermediateValue::Value(HigherIntermediateValue::Literal(Value::List( IntermediateValue::Value(HigherIntermediateValue::Literal(Value::List(
Vec::new(), Vec::new(),
ListSeparator::Space, ListSeparator::Space,
Brackets::Bracketed, Brackets::Bracketed,
))) )))
} else {
IntermediateValue::Bracketed(inner)
}
.span(span) .span(span)
} else {
// todo: we don't know if we're `in_paren` here
let inner = match self.parse_value(false, &|toks| {
matches!(toks.peek(), Some(Token { kind: ']', .. }))
}) {
Ok(v) => v,
Err(e) => return Some(Err(e)),
};
span = span.merge(inner.span);
if !matches!(self.toks.next(), Some(Token { kind: ']', .. })) {
return Some(Err(("expected \"]\".", span).into()));
}
IntermediateValue::Value(HigherIntermediateValue::Literal(match inner.node {
Value::List(els, sep, Brackets::None) => {
Value::List(els, sep, Brackets::Bracketed)
}
v => Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed),
}))
.span(span)
}
} }
'$' => { '$' => {
self.toks.next(); self.toks.next();
@ -1131,14 +1127,6 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
IntermediateValue::Comma => { IntermediateValue::Comma => {
return Err(("Expected expression.", self.parser.span_before).into()) return Err(("Expected expression.", self.parser.span_before).into())
} }
IntermediateValue::Bracketed(t) => {
let v = self.parser.parse_value_from_vec(t, in_paren)?;
HigherIntermediateValue::Literal(match v.node {
Value::List(v, sep, Brackets::None) => Value::List(v, sep, Brackets::Bracketed),
v => Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed),
})
.span(v.span)
}
IntermediateValue::Paren(t) => { IntermediateValue::Paren(t) => {
let val = self.parse_paren(Spanned { let val = self.parse_paren(Spanned {
node: t, node: t,

View File

@ -235,39 +235,3 @@ pub(crate) fn read_until_closing_paren(
} }
Ok(t) Ok(t)
} }
pub(crate) fn read_until_closing_square_brace(
toks: &mut PeekMoreIterator<IntoIter<Token>>,
) -> SassResult<Vec<Token>> {
let mut t = Vec::new();
let mut scope = 0;
while let Some(tok) = toks.next() {
// TODO: comments
match tok.kind {
']' => {
if scope < 1 {
t.push(tok);
return Ok(t);
} else {
scope -= 1;
}
}
'[' => scope += 1,
'"' | '\'' => {
t.push(tok);
t.extend(read_until_closing_quote(toks, tok.kind)?);
continue;
}
'\\' => {
t.push(tok);
t.push(match toks.next() {
Some(tok) => tok,
None => continue,
});
}
_ => {}
}
t.push(tok)
}
Ok(t)
}

View File

@ -251,5 +251,5 @@ error!(
); );
error!( error!(
nothing_after_escape_inside_brackets, nothing_after_escape_inside_brackets,
"a { color: [\\", "Error: expected \"]\"." "a { color: [\\", "Error: Expected expression."
); );