Handle toplevel @debug, @warn, @error
This commit is contained in:
parent
c35940b84e
commit
635f00baa6
21
src/main.rs
21
src/main.rs
@ -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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
18
src/mixin.rs
18
src/mixin.rs
@ -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)?;
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user