Commit e2c130b1 by Aaron Leung

Got logical operators working.

parent ea5aa3e8
...@@ -86,18 +86,24 @@ div { ...@@ -86,18 +86,24 @@ div {
/* hsl tests */ /* hsl tests */
a: hsl(23, 100%, 50%); a: hsl(23, 100%, 50%);
b: hsl(120, 100%, 50%); b: hsl(120, 100%, 50%);
/* logical relations */ /* logical negation */
a: not(false); a: not(false);
b: not(true); b: not(true);
c: not(hello); c: not(hello);
d: not(""); d: not("");
/* relational operators */
a: hello == hello; a: hello == hello;
b: (1 2 3) == (1 2 3); b: (1 2 3) == (1 2 3);
c: "hello" == hello; c: "hello" == hello;
d: 1 + 2 > 3; //false d: 1 + 2 > 3; //false
e: 1 + 2 < 4; //true e: 1 + 2 < 4; //true
f: 1+2*3 >= 6; //true f: 1+2*3 >= 6; //true
/* logical connectives */
a: 1 < 2 and 2 < 3;
b: not(true) or not(false);
b: hey or ho or false or hoo;
c: false and hey and ho;
d: true and false and (1/0);
/* e: 1 < 3 and 3 < 5; /* e: 1 < 3 and 3 < 5;
f: (1 2 3) and (4 5 6);*/ f: (1 2 3) and (4 5 6);*/
......
div {
a: hey and ho and hoo;
b: hey or ho or hoo;
c: hey and false and (1/0);
d: 1 > 2 or 1+3 < 1 or bungle;
}
\ No newline at end of file
...@@ -131,6 +131,8 @@ namespace Sass { ...@@ -131,6 +131,8 @@ namespace Sass {
Node parse_list(); Node parse_list();
Node parse_comma_list(); Node parse_comma_list();
Node parse_space_list(); Node parse_space_list();
Node parse_disjunction();
Node parse_conjunction();
Node parse_relation(); Node parse_relation();
Node parse_expression(); Node parse_expression();
Node parse_term(); Node parse_term();
......
...@@ -419,31 +419,58 @@ namespace Sass { ...@@ -419,31 +419,58 @@ namespace Sass {
Node Document::parse_space_list() Node Document::parse_space_list()
{ {
Node rel1(parse_relation()); Node disj1(parse_disjunction());
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (peek< exactly<';'> >(position) || if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) || peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) || peek< exactly<')'> >(position) ||
peek< exactly<','> >(position)) peek< exactly<','> >(position))
{ return rel1; } { return disj1; }
Node space_list(Node::space_list, line_number, 2); Node space_list(Node::space_list, line_number, 2);
space_list << rel1; space_list << disj1;
space_list.eval_me |= rel1.eval_me; space_list.eval_me |= disj1.eval_me;
while (!(peek< exactly<';'> >(position) || while (!(peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) || peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) || peek< exactly<')'> >(position) ||
peek< exactly<','> >(position))) peek< exactly<','> >(position)))
{ {
Node rel(parse_relation()); Node disj(parse_disjunction());
space_list << rel; space_list << disj;
space_list.eval_me |= rel.eval_me; space_list.eval_me |= disj.eval_me;
} }
return space_list; return space_list;
} }
Node Document::parse_disjunction()
{
Node conj1(parse_conjunction());
// if it's a singleton, return it directly; don't wrap it
if (!peek< or_kwd >()) return conj1;
Node disjunction(Node::disjunction, line_number, 2);
disjunction << conj1;
while (lex< or_kwd >()) disjunction << parse_conjunction();
disjunction.eval_me = true;
return disjunction;
}
Node Document::parse_conjunction()
{
Node rel1(parse_relation());
// if it's a singleton, return it directly; don't wrap it
if (!peek< and_kwd >()) return rel1;
Node conjunction(Node::conjunction, line_number, 2);
conjunction << rel1;
while (lex< and_kwd >()) conjunction << parse_relation();
conjunction.eval_me = true;
return conjunction;
}
Node Document::parse_relation() Node Document::parse_relation()
{ {
Node expr1(parse_expression()); Node expr1(parse_expression());
...@@ -456,14 +483,14 @@ namespace Sass { ...@@ -456,14 +483,14 @@ namespace Sass {
peek< lte_op >(position))) peek< lte_op >(position)))
{ return expr1; } { return expr1; }
Node relation(Node::relation, line_number, 2); Node relation(Node::relation, line_number, 3);
expr1.eval_me = true; expr1.eval_me = true;
relation << expr1; relation << expr1;
if (lex< eq_op >()) relation << Node(Node::eq, line_number, lexed); 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< neq_op >()) relation << Node(Node::neq, line_number, lexed);
else if (lex< gte_op>()) relation << Node(Node::gte, line_number, lexed); else if (lex< gte_op >()) relation << Node(Node::gte, line_number, lexed);
else if (lex< lte_op>()) relation << Node(Node::lte, line_number, lexed); else if (lex< lte_op >()) relation << Node(Node::lte, line_number, lexed);
else if (lex< gt_op >()) relation << Node(Node::gt, line_number, lexed); else if (lex< gt_op >()) relation << Node(Node::gt, line_number, lexed);
else if (lex< lt_op >()) relation << Node(Node::lt, line_number, lexed); else if (lex< lt_op >()) relation << Node(Node::lt, line_number, lexed);
......
...@@ -85,6 +85,27 @@ namespace Sass { ...@@ -85,6 +85,27 @@ namespace Sass {
return expr; return expr;
} break; } break;
case Node::disjunction: {
Node result;
for (int i = 0; i < expr.size(); ++i) {
// if (expr[i].type == Node::relation ||
// expr[i].type == Node::function_call && expr[0].content.token.to_string() == "not") {
result = eval(expr[i], env, f_env);
if (result.type == Node::boolean && result.content.boolean_value == false) continue;
else return result;
}
return result;
} break;
case Node::conjunction: {
Node result;
for (int i = 0; i < expr.size(); ++i) {
result = eval(expr[i], env, f_env);
if (result.type == Node::boolean && result.content.boolean_value == false) return result;
}
return result;
} break;
case Node::relation: { case Node::relation: {
Node lhs(eval(expr[0], env, f_env)); Node lhs(eval(expr[0], env, f_env));
......
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