From 635f00baa66a16d71731fd9fe6599879877737e8 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sun, 19 Jan 2020 00:10:37 -0500 Subject: [PATCH] Handle toplevel @debug, @warn, @error --- src/main.rs | 21 ++++++++++++++++----- src/mixin.rs | 18 ++++++++++-------- src/utils.rs | 2 +- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 797c45f..0698471 100644 --- a/src/main.rs +++ b/src/main.rs @@ -187,6 +187,8 @@ enum Expr { Include(Vec), /// A multiline comment: `/* foobar */` MultilineComment(String), + Debug(Pos, String), + Warn(Pos, String), // /// Function call: `calc(10vw - 1px)` // FuncCall(String, Vec), } @@ -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 { 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>( toks: &mut Peekable, scope: &Scope, super_selector: &Selector, -) -> Result, (Pos, &'static str)> { +) -> Result, (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>( 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)), } } } diff --git a/src/mixin.rs b/src/mixin.rs index b3ffab3..35d8adb 100644 --- a/src/mixin.rs +++ b/src/mixin.rs @@ -93,16 +93,18 @@ impl Mixin { self } - pub fn call(mut self, super_selector: &Selector) -> Result, (Pos, &'static str)> { + pub fn call(mut self, super_selector: &Selector) -> Result, (Pos, String)> { self.eval(super_selector) } - pub fn eval(&mut self, super_selector: &Selector) -> Result, (Pos, &'static str)> { + pub fn eval(&mut self, super_selector: &Selector) -> Result, (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>( toks: &mut Peekable, scope: &Scope, super_selector: &Selector, -) -> Result, (Pos, &'static str)> { +) -> Result, (Pos, String)> { toks.next(); devour_whitespace(toks); let Token { kind, pos } = toks @@ -133,7 +135,7 @@ pub fn eat_include>( .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>( 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>( 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)?; diff --git a/src/utils.rs b/src/utils.rs index 46ecc26..24e91ac 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -66,7 +66,7 @@ pub fn eat_interpolation>( pub fn eat_variable_value>( toks: &mut Peekable, scope: &Scope, -) -> Result, (Pos, &'static str)> { +) -> Result, (Pos, String)> { devour_whitespace(toks); // todo!(line might not end with semicolon) let iter1 = toks.take_while(|x| x.kind != TokenKind::Symbol(Symbol::SemiColon));