Commit c6394df2 by Aaron Leung

Comparison operators.

parent 018c82e2
build: sassc.cpp document.cpp node.cpp values.cpp prelexer.cpp
g++ -o bin/sassc sassc.cpp context.cpp functions.cpp document.cpp document_parser.cpp eval_apply.cpp node.cpp values.cpp prelexer.cpp
g++ -o bin/sassc sassc.cpp context.cpp functions.cpp document.cpp document_parser.cpp eval_apply.cpp node.cpp node_comparisons.cpp values.cpp prelexer.cpp
test: build
ruby spec.rb spec/basic/
......
......@@ -91,6 +91,15 @@ div {
b: not(true);
c: not(hello);
d: not("");
a: hello == hello;
b: (1 2 3) == (1 2 3);
c: "hello" == hello;
d: 1 + 2 < 3 + 4
/* e: 1 < 3 and 3 < 5;
f: (1 2 3) and (4 5 6);*/
/* a: 1 < 2;
b: 1 > 2;
c: 1 > 2 or 3 < 4;
......
......@@ -131,6 +131,7 @@ namespace Sass {
Node parse_list();
Node parse_comma_list();
Node parse_space_list();
Node parse_relation();
Node parse_expression();
Node parse_term();
Node parse_factor();
......
......@@ -419,31 +419,62 @@ namespace Sass {
Node Document::parse_space_list()
{
Node expr1(parse_expression());
Node rel1(parse_relation());
// if it's a singleton, return it directly; don't wrap it
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position))
{ return expr1; }
{ return rel1; }
Node space_list(Node::space_list, line_number, 2);
space_list << expr1;
space_list.eval_me |= expr1.eval_me;
space_list << rel1;
space_list.eval_me |= rel1.eval_me;
while (!(peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position)))
{
Node expr(parse_expression());
space_list << expr;
space_list.eval_me |= expr.eval_me;
Node rel(parse_relation());
space_list << rel;
space_list.eval_me |= rel.eval_me;
}
return space_list;
}
Node Document::parse_relation()
{
Node expr1(parse_expression());
// if it's a singleton, return it directly; don't wrap it
if (!(peek< eq_op >(position) ||
peek< neq_op >(position) ||
peek< gt_op >(position) ||
peek< gte_op >(position) ||
peek< lt_op >(position) ||
peek< lte_op >(position)))
{ return expr1; }
Node relation(Node::relation, line_number, 2);
expr1.eval_me = true;
relation << expr1;
if (lex< eq_op >()) relation << Node(Node::eq, line_number, lexed);
else if (lex< neq_op>()) relation << Node(Node::neq, line_number, lexed);
else if (lex< gt_op >()) relation << Node(Node::gt, line_number, lexed);
else if (lex< gte_op>()) relation << Node(Node::gte, line_number, lexed);
else if (lex< lt_op >()) relation << Node(Node::lt, line_number, lexed);
else if (lex< lte_op>()) relation << Node(Node::lte, line_number, lexed);
Node expr2(parse_expression());
expr2.eval_me = true;
relation << expr2;
relation.eval_me = true;
return relation;
}
Node Document::parse_expression()
{
Node term1(parse_term());
......
......@@ -85,6 +85,28 @@ namespace Sass {
return expr;
} break;
case Node::relation: {
Node lhs(eval(expr[0], env, f_env));
Node op(expr[1]);
Node rhs(eval(expr[2], env, f_env));
Node T(Node::boolean);
T.line_number = lhs.line_number;
T.content.boolean_value = true;
Node F(T);
F.content.boolean_value = false;
switch (op.type) {
case Node::eq: return (lhs == rhs) ? T : F;
case Node::neq: return (lhs != rhs) ? T : F;
case Node::gt: return (lhs > rhs) ? T : F;
case Node::gte: return (lhs >= rhs) ? T : F;
case Node::lt: return (lhs < rhs) ? T : F;
case Node::lte: return (lhs <= rhs) ? T : F;
}
} break;
case Node::expression: {
Node acc(Node::expression, expr.line_number, 1);
acc << eval(expr[0], env, f_env);
......
......@@ -42,6 +42,14 @@ namespace Sass {
disjunction,
conjunction,
relation,
eq,
neq,
gt,
gte,
lt,
lte,
expression,
add,
sub,
......@@ -126,7 +134,7 @@ namespace Sass {
return *this;
}
double numeric_value()
double numeric_value() const
{
switch (type)
{
......@@ -149,6 +157,13 @@ namespace Sass {
return *this;
}
bool operator==(const Node& rhs) const;
bool operator!=(const Node& rhs) const;
bool operator<(const Node& rhs) const;
bool operator<=(const Node& rhs) const;
bool operator>(const Node& rhs) const;
bool operator>=(const Node& rhs) const;
string to_string(const string& prefix) const;
void echo(stringstream& buf, size_t depth = 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment