Handle toplevel @debug, @warn, @error

This commit is contained in:
ConnorSkees 2020-01-19 00:10:37 -05:00
parent c35940b84e
commit 635f00baa6
3 changed files with 27 additions and 14 deletions

View File

@ -187,6 +187,8 @@ enum Expr {
Include(Vec<Stmt>),
/// A multiline comment: `/* foobar */`
MultilineComment(String),
Debug(Pos, String),
Warn(Pos, String),
// /// Function call: `calc(10vw - 1px)`
// FuncCall(String, Vec<Token>),
}
@ -300,7 +302,7 @@ impl<'a> StyleSheetParser<'a> {
self.error(pos, "unexpected variable use at toplevel");
}
let val = eat_variable_value(&mut self.lexer, &self.global_scope)
.unwrap_or_else(|err| self.error(err.0, err.1));
.unwrap_or_else(|err| self.error(err.0, &err.1));
self.global_scope.vars.insert(name, val);
}
TokenKind::MultilineComment(_) => {
@ -392,7 +394,7 @@ impl<'a> StyleSheetParser<'a> {
fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
let mut stmts = Vec::new();
while let Some(tok) = eat_expr(&mut self.lexer, scope, super_selector)
.unwrap_or_else(|error| self.error(error.0, error.1))
.unwrap_or_else(|error| self.error(error.0, &error.1))
{
match tok {
Expr::Style(s) => stmts.push(Stmt::Style(s)),
@ -402,6 +404,12 @@ impl<'a> StyleSheetParser<'a> {
Expr::Include(rules) => {
stmts.extend(rules);
}
Expr::Debug(pos, ref message) => {
self.debug(pos, message);
}
Expr::Warn(pos, ref message) => {
self.warn(pos, message);
}
Expr::Selector(s) => {
self.scope += 1;
let rules = self.eat_rules(&super_selector.zip(&s), scope);
@ -475,7 +483,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
super_selector: &Selector,
) -> Result<Option<Expr>, (Pos, &'static str)> {
) -> Result<Option<Expr>, (Pos, String)> {
let mut values = Vec::with_capacity(5);
while let Some(tok) = toks.peek() {
match &tok.kind {
@ -554,8 +562,11 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
pos,
}) = toks.next()
{
if let Ok(a) = eat_at_rule(rule, pos, toks, scope) {
return Ok(Some(a));
match eat_at_rule(rule, pos, toks, scope) {
Ok(a) => return Ok(Some(a)),
Err(Printer::Debug(a, b)) => return Ok(Some(Expr::Debug(a, b))),
Err(Printer::Warn(a, b)) => return Ok(Some(Expr::Warn(a, b))),
Err(Printer::Error(a, b)) => return Err((a, b)),
}
}
}

View File

@ -93,16 +93,18 @@ impl Mixin {
self
}
pub fn call(mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, &'static str)> {
pub fn call(mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, String)> {
self.eval(super_selector)
}
pub fn eval(&mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, &'static str)> {
pub fn eval(&mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, String)> {
let mut stmts = Vec::new();
while let Some(expr) = eat_expr(&mut self.body, &self.scope, super_selector)? {
match expr {
Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::Include(_) | Expr::MixinDecl(_, _) => todo!(),
Expr::Include(..) | Expr::MixinDecl(..) | Expr::Debug(..) | Expr::Warn(..) => {
todo!()
}
Expr::Selector(selector) => {
let rules = self.eval(&super_selector.zip(&selector))?;
stmts.push(Stmt::RuleSet(RuleSet {
@ -125,7 +127,7 @@ pub fn eat_include<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
super_selector: &Selector,
) -> Result<Vec<Stmt>, (Pos, &'static str)> {
) -> Result<Vec<Stmt>, (Pos, String)> {
toks.next();
devour_whitespace(toks);
let Token { kind, pos } = toks
@ -133,7 +135,7 @@ pub fn eat_include<I: Iterator<Item = Token>>(
.expect("this must exist because we have already peeked");
let name = match kind {
TokenKind::Ident(s) => s,
_ => return Err((pos, "expected identifier")),
_ => return Err((pos, String::from("expected identifier"))),
};
devour_whitespace(toks);
@ -142,10 +144,10 @@ pub fn eat_include<I: Iterator<Item = Token>>(
match tok.kind {
TokenKind::Symbol(Symbol::SemiColon) => CallArgs::new(),
TokenKind::Symbol(Symbol::OpenParen) => eat_call_args(toks),
_ => return Err((pos, "expected `(` or `;`")),
_ => return Err((pos, String::from("expected `(` or `;`"))),
}
} else {
return Err((pos, "unexpected EOF"));
return Err((pos, String::from("unexpected EOF")));
};
devour_whitespace(toks);
@ -160,7 +162,7 @@ pub fn eat_include<I: Iterator<Item = Token>>(
let mixin = match scope.mixins.get(&name) {
Some(m) => m.clone(),
_ => return Err((pos, "expected identifier")),
_ => return Err((pos, String::from("expected identifier"))),
};
let rules = mixin.args(&args).call(super_selector)?;

View File

@ -66,7 +66,7 @@ pub fn eat_interpolation<I: Iterator<Item = Token>>(
pub fn eat_variable_value<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>,
scope: &Scope,
) -> Result<Vec<Token>, (Pos, &'static str)> {
) -> Result<Vec<Token>, (Pos, String)> {
devour_whitespace(toks);
// todo!(line might not end with semicolon)
let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon));