Implement type-of builtin function

This commit is contained in:
ConnorSkees 2020-02-03 07:56:21 -05:00
parent c92781a20e
commit 901bdcae3b
3 changed files with 96 additions and 5 deletions

View File

@ -44,4 +44,8 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
}; };
Some(Value::Ident(unit, QuoteKind::Double)) Some(Value::Ident(unit, QuoteKind::Double))
}); });
decl!(f "type-of", |args| {
let value = arg!(args, 0, "value");
Some(Value::Ident(value.kind().to_owned(), QuoteKind::None))
});
} }

View File

@ -197,11 +197,7 @@ impl Display for Value {
.join(sep.as_str()) .join(sep.as_str())
), ),
Self::Color(c) => write!(f, "{}", c), Self::Color(c) => write!(f, "{}", c),
Self::BinaryOp(lhs, op, rhs) => match op { Self::BinaryOp(..) => write!(f, "{}", self.eval()),
Op::Plus => write!(f, "{}", *lhs.clone() + *rhs.clone()),
Op::Minus => write!(f, "{}", *lhs.clone() - *rhs.clone()),
_ => write!(f, "{}{}{}", lhs, op, rhs),
},
Self::Paren(val) => write!(f, "{}", val), Self::Paren(val) => write!(f, "{}", val),
Self::Ident(val, kind) => write!(f, "{}{}{}", kind.as_str(), val, kind.as_str()), Self::Ident(val, kind) => write!(f, "{}{}{}", kind.as_str(), val, kind.as_str()),
Self::True => write!(f, "true"), Self::True => write!(f, "true"),
@ -227,6 +223,32 @@ impl Value {
} }
} }
pub fn kind(&self) -> &'static str {
match self {
Value::Color(..) => "color",
Value::Ident(..) => "string",
Value::Dimension(..) => "number",
Value::List(..) => "list",
// Value::Function(..) => "function",
Value::True | Value::False => "bool",
Value::Null => "null",
Value::BinaryOp(..) => self.eval().kind(),
_ => "unknown",
}
}
pub fn eval(&self) -> Self {
match self {
Self::BinaryOp(lhs, op, rhs) => match op {
Op::Plus => *lhs.clone() + *rhs.clone(),
Op::Minus => *lhs.clone() - *rhs.clone(),
_ => Self::BinaryOp(lhs.clone(), op.clone(), rhs.clone()),
}
_ => self.clone(),
}
}
pub fn from_tokens<I: Iterator<Item = Token>>( pub fn from_tokens<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>, toks: &mut Peekable<I>,
scope: &Scope, scope: &Scope,

View File

@ -58,3 +58,68 @@ test!(
"a {\n color: unit($number: 1px)\n}\n", "a {\n color: unit($number: 1px)\n}\n",
"a {\n color: \"px\";\n}\n" "a {\n color: \"px\";\n}\n"
); );
test!(
type_of_number,
"a {\n color: type-of(1)\n}\n",
"a {\n color: number;\n}\n"
);
test!(
type_of_number_unit,
"a {\n color: type-of(1px)\n}\n",
"a {\n color: number;\n}\n"
);
test!(
type_of_unquoted,
"a {\n color: type-of(foo)\n}\n",
"a {\n color: string;\n}\n"
);
test!(
type_of_sgl_unquoted,
"a {\n color: type-of('red')\n}\n",
"a {\n color: string;\n}\n"
);
test!(
type_of_dbl_unquoted,
"a {\n color: type-of(\"red\")\n}\n",
"a {\n color: string;\n}\n"
);
// test!(
// type_of_3_hex_color,
// "a {\n color: type-of(#fff)\n}\n",
// "a {\n color: color;\n}\n"
// );
// test!(
// type_of_6_hex_color,
// "a {\n color: type-of(#ffffff)\n}\n",
// "a {\n color: color;\n}\n"
// );
// test!(
// type_of_named_color,
// "a {\n color: type-of(red)\n}\n",
// "a {\n color: color;\n}\n"
// );
// test!(
// type_of_spaced_list,
// "a {\n color: type-of(1 2 3)\n}\n",
// "a {\n color: list;\n}\n"
// );
test!(
type_of_true,
"a {\n color: type-of(true)\n}\n",
"a {\n color: bool;\n}\n"
);
test!(
type_of_false,
"a {\n color: type-of(false)\n}\n",
"a {\n color: bool;\n}\n"
);
test!(
type_of_null,
"a {\n color: type-of(null)\n}\n",
"a {\n color: null;\n}\n"
);
test!(
type_of_ident_plus_ident,
"a {\n color: type-of(hi + bye)\n}\n",
"a {\n color: string;\n}\n"
);