refactor parsing of toplevel variables

This commit is contained in:
ConnorSkees 2020-05-21 13:25:37 -04:00
parent 6b9f68922f
commit c68576bb23
3 changed files with 35 additions and 34 deletions

View File

@ -22,7 +22,7 @@ use crate::selector::Selector;
use crate::token::Token;
use crate::utils::{
devour_whitespace, eat_comment, eat_ident, eat_variable_value, parse_quoted_string,
read_until_newline, VariableDecl,
peek_ident_no_interpolation, peek_whitespace, read_until_newline, VariableDecl,
};
use crate::{eat_expr, Expr, RuleSet, Stmt};
@ -79,7 +79,7 @@ impl StyleSheet {
let file = map.add_file("stdin".into(), input);
Css::from_stylesheet(StyleSheet(
StyleSheetParser {
lexer: Lexer::new(&file).peekmore(),
lexer: &mut Lexer::new(&file).peekmore(),
nesting: 0,
map: &mut map,
path: Path::new(""),
@ -111,7 +111,7 @@ impl StyleSheet {
let file = map.add_file(p.into(), String::from_utf8(fs::read(p)?)?);
Css::from_stylesheet(StyleSheet(
StyleSheetParser {
lexer: Lexer::new(&file).peekmore(),
lexer: &mut Lexer::new(&file).peekmore(),
nesting: 0,
map: &mut map,
path: p.as_ref(),
@ -131,7 +131,7 @@ impl StyleSheet {
) -> SassResult<(Vec<Spanned<Stmt>>, Scope)> {
let file = map.add_file(p.clone().into(), String::from_utf8(fs::read(p)?)?);
Ok(StyleSheetParser {
lexer: Lexer::new(&file).peekmore(),
lexer: &mut Lexer::new(&file).peekmore(),
nesting: 0,
map,
path: p.as_ref(),
@ -145,7 +145,7 @@ impl StyleSheet {
}
struct StyleSheetParser<'a> {
lexer: PeekMoreIterator<Lexer<'a>>,
lexer: &'a mut PeekMoreIterator<Lexer<'a>>,
nesting: u32,
map: &'a mut CodeMap,
path: &'a Path,
@ -171,36 +171,35 @@ impl<'a> StyleSheetParser<'a> {
continue;
}
'$' => {
let span_before = self.lexer.next().unwrap().pos();
let name = eat_ident(
&mut self.lexer,
&Scope::new(),
&Selector::new(),
span_before
)?;
devour_whitespace(&mut self.lexer);
let Token { kind, pos } = self
.lexer
.next()
.unwrap();
if kind != ':' {
return Err(("expected \":\".", pos).into());
}
self.lexer.next();
let name = peek_ident_no_interpolation(self.lexer, false)?;
let whitespace = peek_whitespace(self.lexer);
match self.lexer.peek() {
Some(Token { kind: ':', .. }) => {
self.lexer.take(name.node.chars().count() + whitespace + 1)
.for_each(drop);
devour_whitespace(self.lexer);
let VariableDecl { val, default, .. } =
eat_variable_value(&mut self.lexer, &Scope::new(), &Selector::new())?;
eat_variable_value(self.lexer, &Scope::new(), &Selector::new())?;
if !(default && global_var_exists(&name)) {
insert_global_var(&name.node, val)?;
}
}
Some(..) | None => return Err(("expected \":\".", name.span).into()),
}
}
'/' => {
let pos = self.lexer.next().unwrap().pos;
match self.lexer.next() {
Some(Token { kind: '/', .. }) => {
read_until_newline(&mut self.lexer);
devour_whitespace(&mut self.lexer);
read_until_newline(self.lexer);
devour_whitespace(self.lexer);
}
Some(Token { kind: '*', .. }) => {
let comment = eat_comment(&mut self.lexer, &Scope::new(), &Selector::new())?;
let comment = eat_comment(self.lexer, &Scope::new(), &Selector::new())?;
rules.push(comment.map_node(Stmt::MultilineComment));
}
_ => return Err(("expected selector.", pos).into())
@ -209,7 +208,7 @@ impl<'a> StyleSheetParser<'a> {
'@' => {
let span_before = self.lexer.next().unwrap().pos();
let Spanned { node: at_rule_kind, span } = eat_ident(
&mut self.lexer,
self.lexer,
&Scope::new(),
&Selector::new(),
span_before
@ -219,14 +218,14 @@ impl<'a> StyleSheetParser<'a> {
}
match AtRuleKind::from(at_rule_kind.as_str()) {
AtRuleKind::Include => rules.extend(eat_include(
&mut self.lexer,
self.lexer,
&Scope::new(),
&Selector::new(),
None,
span
)?),
AtRuleKind::Import => {
devour_whitespace(&mut self.lexer);
devour_whitespace(self.lexer);
let mut file_name = String::new();
let next = match self.lexer.next() {
Some(v) => v,
@ -236,7 +235,7 @@ impl<'a> StyleSheetParser<'a> {
q @ '"' | q @ '\'' => {
file_name.push_str(
&parse_quoted_string(
&mut self.lexer,
self.lexer,
&Scope::new(),
q,
&Selector::new())?
@ -250,7 +249,7 @@ impl<'a> StyleSheetParser<'a> {
}
}
devour_whitespace(&mut self.lexer);
devour_whitespace(self.lexer);
let (new_rules, new_scope) = import(self.path, file_name.as_ref(), &mut self.map)?;
rules.extend(new_rules);
@ -259,7 +258,7 @@ impl<'a> StyleSheetParser<'a> {
});
}
v => {
let rule = AtRule::from_tokens(v, span, &mut self.lexer, &mut Scope::new(), &Selector::new(), None)?;
let rule = AtRule::from_tokens(v, span, self.lexer, &mut Scope::new(), &Selector::new(), None)?;
match rule.node {
AtRule::Mixin(name, mixin) => {
insert_global_mixin(&name, *mixin);
@ -320,7 +319,7 @@ impl<'a> StyleSheetParser<'a> {
scope: &mut Scope,
) -> SassResult<Vec<Spanned<Stmt>>> {
let mut stmts = Vec::new();
while let Some(expr) = eat_expr(&mut self.lexer, scope, super_selector, None)? {
while let Some(expr) = eat_expr(self.lexer, scope, super_selector, None)? {
let span = expr.span;
match expr.node {
Expr::Style(s) => stmts.push(Spanned {

View File

@ -161,6 +161,7 @@ pub(crate) fn peek_ident_no_interpolation<I: Iterator<Item = Token>>(
toks: &mut PeekMoreIterator<I>,
unit: bool,
) -> SassResult<Spanned<String>> {
// todo: panics on "$"
let mut span = toks.peek().unwrap().pos();
let mut text = String::new();
if toks.peek().unwrap().kind == '-' {

View File

@ -123,3 +123,4 @@ error!(
"#{", "Error: expected \"}\"."
);
error!(toplevel_hash, "#", "Error: expected \"{\".");
error!(toplevel_var_no_colon, "$r", "Error: expected \":\".");