implement aliased sass:math
functions
This commit is contained in:
parent
c0631c75a0
commit
060641b86d
@ -13,7 +13,7 @@ use crate::{
|
|||||||
value::{Number, Value},
|
value::{Number, Value},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
let num = match args.get_err(0, "number")? {
|
let num = match args.get_err(0, "number")? {
|
||||||
Value::Dimension(n, Unit::None, _) => n * Number::from(100),
|
Value::Dimension(n, Unit::None, _) => n * Number::from(100),
|
||||||
@ -38,7 +38,7 @@ fn percentage(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
|
|||||||
Ok(Value::Dimension(num, Unit::Percent, true))
|
Ok(Value::Dimension(num, Unit::Percent, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
match args.get_err(0, "number")? {
|
match args.get_err(0, "number")? {
|
||||||
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.round(), u, true)),
|
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.round(), u, true)),
|
||||||
@ -50,7 +50,7 @@ fn round(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
match args.get_err(0, "number")? {
|
match args.get_err(0, "number")? {
|
||||||
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.ceil(), u, true)),
|
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.ceil(), u, true)),
|
||||||
@ -62,7 +62,7 @@ fn ceil(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
match args.get_err(0, "number")? {
|
match args.get_err(0, "number")? {
|
||||||
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.floor(), u, true)),
|
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.floor(), u, true)),
|
||||||
@ -74,7 +74,7 @@ fn floor(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
match args.get_err(0, "number")? {
|
match args.get_err(0, "number")? {
|
||||||
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.abs(), u, true)),
|
Value::Dimension(n, u, _) => Ok(Value::Dimension(n.abs(), u, true)),
|
||||||
@ -86,7 +86,7 @@ fn abs(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(2)?;
|
args.max_args(2)?;
|
||||||
let unit1 = match args.get_err(0, "number1")? {
|
let unit1 = match args.get_err(0, "number1")? {
|
||||||
Value::Dimension(_, u, _) => u,
|
Value::Dimension(_, u, _) => u,
|
||||||
@ -114,7 +114,7 @@ fn comparable(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value>
|
|||||||
|
|
||||||
// TODO: write tests for this
|
// TODO: write tests for this
|
||||||
#[cfg(feature = "random")]
|
#[cfg(feature = "random")]
|
||||||
fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
let limit = match args.default_arg(0, "limit", Value::Null)? {
|
let limit = match args.default_arg(0, "limit", Value::Null)? {
|
||||||
Value::Dimension(n, ..) => n,
|
Value::Dimension(n, ..) => n,
|
||||||
@ -170,7 +170,7 @@ fn random(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.min_args(1)?;
|
args.min_args(1)?;
|
||||||
let span = args.span();
|
let span = args.span();
|
||||||
let mut nums = args
|
let mut nums = args
|
||||||
@ -208,7 +208,7 @@ fn min(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
Ok(Value::Dimension(min.0, min.1, true))
|
Ok(Value::Dimension(min.0, min.1, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn max(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.min_args(1)?;
|
args.min_args(1)?;
|
||||||
let span = args.span();
|
let span = args.span();
|
||||||
let mut nums = args
|
let mut nums = args
|
||||||
|
@ -50,7 +50,7 @@ fn feature_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn unit(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
let unit = match args.get_err(0, "number")? {
|
let unit = match args.get_err(0, "number")? {
|
||||||
Value::Dimension(_, u, _) => u.to_string(),
|
Value::Dimension(_, u, _) => u.to_string(),
|
||||||
@ -71,7 +71,7 @@ fn type_of(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
Ok(Value::String(value.kind().to_owned(), QuoteKind::None))
|
Ok(Value::String(value.kind().to_owned(), QuoteKind::None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
pub(crate) fn unitless(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
#[allow(clippy::match_same_arms)]
|
#[allow(clippy::match_same_arms)]
|
||||||
Ok(match args.get_err(0, "number")? {
|
Ok(match args.get_err(0, "number")? {
|
||||||
|
@ -13,13 +13,13 @@ use crate::{args::CallArgs, error::SassResult, parse::Parser, value::Value};
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
mod color;
|
pub mod color;
|
||||||
mod list;
|
pub mod list;
|
||||||
mod map;
|
pub mod map;
|
||||||
mod math;
|
pub mod math;
|
||||||
mod meta;
|
pub mod meta;
|
||||||
mod selector;
|
pub mod selector;
|
||||||
mod string;
|
pub mod string;
|
||||||
|
|
||||||
pub(crate) type GlobalFunctionMap = HashMap<&'static str, Builtin>;
|
pub(crate) type GlobalFunctionMap = HashMap<&'static str, Builtin>;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
mod functions;
|
mod functions;
|
||||||
mod modules;
|
pub(crate) mod modules;
|
||||||
|
|
||||||
pub(crate) use functions::{Builtin, GLOBAL_FUNCTIONS};
|
pub(crate) use functions::{math, meta, Builtin, GLOBAL_FUNCTIONS};
|
||||||
pub(crate) use modules::*;
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -1,3 +1,88 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs,
|
||||||
|
builtin::{
|
||||||
|
math::{abs, ceil, comparable, floor, max, min, percentage, round},
|
||||||
|
meta::{unit, unitless},
|
||||||
|
modules::Module,
|
||||||
|
},
|
||||||
|
error::SassResult,
|
||||||
|
parse::Parser,
|
||||||
|
value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
#[cfg(feature = "random")]
|
||||||
|
use crate::builtin::math::random;
|
||||||
|
|
||||||
|
fn clamp(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(3)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hypot(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(2)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pow(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(2)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sqrt(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sin(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tan(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asin(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(1)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan2(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
|
args.max_args(2)?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn declare(f: &mut Module) {
|
||||||
|
f.insert_builtin("ceil", ceil);
|
||||||
|
f.insert_builtin("floor", floor);
|
||||||
|
f.insert_builtin("max", max);
|
||||||
|
f.insert_builtin("min", min);
|
||||||
|
f.insert_builtin("round", round);
|
||||||
|
f.insert_builtin("abs", abs);
|
||||||
|
f.insert_builtin("compatible", comparable);
|
||||||
|
f.insert_builtin("is-unitless", unitless);
|
||||||
|
f.insert_builtin("unit", unit);
|
||||||
|
f.insert_builtin("percentage", percentage);
|
||||||
|
#[cfg(feature = "random")]
|
||||||
|
f.insert_builtin("random", random);
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
|
#![allow(unused_imports, unused_variables, dead_code, unused_mut)]
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use codemap::Spanned;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
args::CallArgs,
|
||||||
atrule::Mixin,
|
atrule::Mixin,
|
||||||
|
builtin::Builtin,
|
||||||
common::Identifier,
|
common::Identifier,
|
||||||
|
error::SassResult,
|
||||||
|
parse::Parser,
|
||||||
value::{SassFunction, Value},
|
value::{SassFunction, Value},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,6 +29,29 @@ pub(crate) struct Module {
|
|||||||
functions: BTreeMap<Identifier, SassFunction>,
|
functions: BTreeMap<Identifier, SassFunction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Module {
|
||||||
|
pub fn get_var(&self, name: Spanned<Identifier>) -> SassResult<&Value> {
|
||||||
|
match self.vars.get(&name.node) {
|
||||||
|
Some(v) => Ok(&v),
|
||||||
|
None => Err(("Undefined variable.", name.span).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_fn(&self, name: Identifier) -> Option<SassFunction> {
|
||||||
|
self.functions.get(&name).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_builtin(
|
||||||
|
&mut self,
|
||||||
|
name: &'static str,
|
||||||
|
function: fn(CallArgs, &mut Parser<'_>) -> SassResult<Value>,
|
||||||
|
) {
|
||||||
|
let ident = name.into();
|
||||||
|
self.functions
|
||||||
|
.insert(ident, SassFunction::Builtin(Builtin::new(function), ident));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn declare_module_color() -> Module {
|
pub(crate) fn declare_module_color() -> Module {
|
||||||
let mut module = Module::default();
|
let mut module = Module::default();
|
||||||
color::declare(&mut module);
|
color::declare(&mut module);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
use crate::builtin::Module;
|
use crate::{
|
||||||
|
args::CallArgs, builtin::modules::Module, error::SassResult, parse::Parser, value::Value,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) fn declare(_f: &mut Module) {}
|
pub(crate) fn declare(_f: &mut Module) {}
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
media::MediaRule,
|
media::MediaRule,
|
||||||
AtRuleKind, Content, SupportsRule, UnknownAtRule,
|
AtRuleKind, Content, SupportsRule, UnknownAtRule,
|
||||||
},
|
},
|
||||||
builtin::*,
|
builtin::modules::*,
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
scope::{Scope, Scopes},
|
scope::{Scope, Scopes},
|
||||||
selector::{
|
selector::{
|
||||||
|
@ -207,6 +207,53 @@ impl<'a> Parser<'a> {
|
|||||||
.parse_value(in_paren)
|
.parse_value(in_paren)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_module_item(
|
||||||
|
&mut self,
|
||||||
|
module: &str,
|
||||||
|
mut module_span: Span,
|
||||||
|
) -> SassResult<Spanned<IntermediateValue>> {
|
||||||
|
Ok(IntermediateValue::Value(
|
||||||
|
if matches!(self.toks.peek(), Some(Token { kind: '$', .. })) {
|
||||||
|
let var = self
|
||||||
|
.parse_identifier_no_interpolation(false)?
|
||||||
|
.map_node(|i| i.into());
|
||||||
|
|
||||||
|
module_span = module_span.merge(var.span);
|
||||||
|
|
||||||
|
let value = self
|
||||||
|
.modules
|
||||||
|
.get(module)
|
||||||
|
.ok_or(("todo: module dne", module_span))?
|
||||||
|
.get_var(var)?;
|
||||||
|
HigherIntermediateValue::Literal(value.clone())
|
||||||
|
} else {
|
||||||
|
let fn_name = self
|
||||||
|
.parse_identifier_no_interpolation(false)?
|
||||||
|
.map_node(|i| i.into());
|
||||||
|
|
||||||
|
let function = self
|
||||||
|
.modules
|
||||||
|
.get(module)
|
||||||
|
.ok_or(("todo: module dne", module_span))?
|
||||||
|
.get_fn(fn_name.node)
|
||||||
|
.ok_or(("todo: fn dne", fn_name.span))?;
|
||||||
|
|
||||||
|
if !matches!(self.toks.next(), Some(Token { kind: '(', .. })) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
let call_args = self.parse_call_args()?;
|
||||||
|
|
||||||
|
HigherIntermediateValue::Function(function, call_args)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.span(module_span))
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn parse_module_fn_call(&mut self, name: &str) -> SassResult<Spanned<IntermediateValue>> {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
fn parse_ident_value(&mut self) -> SassResult<Spanned<IntermediateValue>> {
|
fn parse_ident_value(&mut self) -> SassResult<Spanned<IntermediateValue>> {
|
||||||
let Spanned { node: mut s, span } = self.parse_identifier()?;
|
let Spanned { node: mut s, span } = self.parse_identifier()?;
|
||||||
|
|
||||||
@ -228,83 +275,92 @@ impl<'a> Parser<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Token { kind: '(', .. }) = self.toks.peek() {
|
match self.toks.peek() {
|
||||||
self.toks.next();
|
Some(Token { kind: '(', .. }) => {
|
||||||
|
self.toks.next();
|
||||||
|
|
||||||
if lower == "min" {
|
if lower == "min" {
|
||||||
match self.try_parse_min_max("min", true)? {
|
match self.try_parse_min_max("min", true)? {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
self.toks.truncate_iterator_to_cursor();
|
self.toks.truncate_iterator_to_cursor();
|
||||||
self.toks.next();
|
self.toks.next();
|
||||||
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
||||||
Value::String(val, QuoteKind::None),
|
Value::String(val, QuoteKind::None),
|
||||||
))
|
))
|
||||||
.span(span));
|
.span(span));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.toks.reset_cursor();
|
self.toks.reset_cursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if lower == "max" {
|
} else if lower == "max" {
|
||||||
match self.try_parse_min_max("max", true)? {
|
match self.try_parse_min_max("max", true)? {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
self.toks.truncate_iterator_to_cursor();
|
self.toks.truncate_iterator_to_cursor();
|
||||||
self.toks.next();
|
self.toks.next();
|
||||||
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
||||||
Value::String(val, QuoteKind::None),
|
Value::String(val, QuoteKind::None),
|
||||||
))
|
))
|
||||||
.span(span));
|
.span(span));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.toks.reset_cursor();
|
self.toks.reset_cursor();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let as_ident = Identifier::from(&s);
|
|
||||||
let func = match self.scopes.get_fn(
|
|
||||||
Spanned {
|
|
||||||
node: as_ident,
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
self.global_scope,
|
|
||||||
) {
|
|
||||||
Some(f) => f,
|
|
||||||
None => {
|
|
||||||
if let Some(f) = GLOBAL_FUNCTIONS.get(as_ident.as_str()) {
|
|
||||||
return Ok(IntermediateValue::Value(HigherIntermediateValue::Function(
|
|
||||||
SassFunction::Builtin(f.clone(), as_ident),
|
|
||||||
self.parse_call_args()?,
|
|
||||||
))
|
|
||||||
.span(span));
|
|
||||||
} else {
|
|
||||||
// check for special cased CSS functions
|
|
||||||
match lower.as_str() {
|
|
||||||
"calc" | "element" | "expression" => {
|
|
||||||
s = lower;
|
|
||||||
self.parse_calc_args(&mut s)?;
|
|
||||||
}
|
|
||||||
"url" => match self.try_parse_url()? {
|
|
||||||
Some(val) => s = val,
|
|
||||||
None => s.push_str(&self.parse_call_args()?.to_css_string()?),
|
|
||||||
},
|
|
||||||
_ => s.push_str(&self.parse_call_args()?.to_css_string()?),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
|
||||||
Value::String(s, QuoteKind::None),
|
|
||||||
))
|
|
||||||
.span(span));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let call_args = self.parse_call_args()?;
|
let as_ident = Identifier::from(&s);
|
||||||
return Ok(IntermediateValue::Value(HigherIntermediateValue::Function(
|
let func = match self.scopes.get_fn(
|
||||||
SassFunction::UserDefined(Box::new(func), as_ident),
|
Spanned {
|
||||||
call_args,
|
node: as_ident,
|
||||||
))
|
span,
|
||||||
.span(span));
|
},
|
||||||
|
self.global_scope,
|
||||||
|
) {
|
||||||
|
Some(f) => f,
|
||||||
|
None => {
|
||||||
|
if let Some(f) = GLOBAL_FUNCTIONS.get(as_ident.as_str()) {
|
||||||
|
return Ok(IntermediateValue::Value(
|
||||||
|
HigherIntermediateValue::Function(
|
||||||
|
SassFunction::Builtin(f.clone(), as_ident),
|
||||||
|
self.parse_call_args()?,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.span(span));
|
||||||
|
} else {
|
||||||
|
// check for special cased CSS functions
|
||||||
|
match lower.as_str() {
|
||||||
|
"calc" | "element" | "expression" => {
|
||||||
|
s = lower;
|
||||||
|
self.parse_calc_args(&mut s)?;
|
||||||
|
}
|
||||||
|
"url" => match self.try_parse_url()? {
|
||||||
|
Some(val) => s = val,
|
||||||
|
None => s.push_str(&self.parse_call_args()?.to_css_string()?),
|
||||||
|
},
|
||||||
|
_ => s.push_str(&self.parse_call_args()?.to_css_string()?),
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(IntermediateValue::Value(HigherIntermediateValue::Literal(
|
||||||
|
Value::String(s, QuoteKind::None),
|
||||||
|
))
|
||||||
|
.span(span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let call_args = self.parse_call_args()?;
|
||||||
|
return Ok(IntermediateValue::Value(HigherIntermediateValue::Function(
|
||||||
|
SassFunction::UserDefined(Box::new(func), as_ident),
|
||||||
|
call_args,
|
||||||
|
))
|
||||||
|
.span(span));
|
||||||
|
}
|
||||||
|
Some(Token { kind: '.', .. }) => {
|
||||||
|
self.toks.next();
|
||||||
|
return self.parse_module_item(&s, span);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for named colors
|
// check for named colors
|
||||||
|
Loading…
x
Reference in New Issue
Block a user