Commit 4dd8d913 by Aaron Leung

Expression evaluator is mostly working. Still need to correctly handle…

Expression evaluator is mostly working. Still need to correctly handle multiplying and dividing with measurement units. Also need to correctly handle hex arithmetic. Finally, need to see if I can't handle more weird edge cases.
parent 3238f08b
...@@ -51,7 +51,11 @@ namespace Sass { ...@@ -51,7 +51,11 @@ namespace Sass {
val.from_variable = true; val.from_variable = true;
val.eval_me = true; val.eval_me = true;
context.environment[key] = eval(val); Node evaled(eval(val));
evaled.from_variable = true;
val.eval_me = true;
context.environment[key] = evaled;
// context.environment[key] = val; // context.environment[key] = val;
} }
...@@ -281,16 +285,29 @@ namespace Sass { ...@@ -281,16 +285,29 @@ namespace Sass {
Node Document::parse_list() Node Document::parse_list()
{ {
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) || Node val(parse_comma_list());
peek< exactly<')'> >(position)) if (val.type != Node::comma_list && val.type != Node::space_list && val.eval_me) {
{ return Node(line_number, Node::nil); } return eval(val);
else }
{ return parse_comma_list(); } else if (val.type == Node::comma_list || val.type == Node::space_list) {
for (int i = 0; i < val.children->size(); ++i) {
if (val.children->at(i).eval_me) {
val.children->at(i) = eval(val.children->at(i));
}
}
}
return val;
// return parse_comma_list();
} }
Node Document::parse_comma_list() Node Document::parse_comma_list()
{ {
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position)) {
return Node(line_number, Node::nil);
}
Node list1(parse_space_list()); Node list1(parse_space_list());
// 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)) return list1; if (!peek< exactly<','> >(position)) return list1;
...@@ -312,19 +329,20 @@ namespace Sass { ...@@ -312,19 +329,20 @@ namespace Sass {
peek< exactly<'}'> >(position) || peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) || peek< exactly<')'> >(position) ||
peek< exactly<','> >(position)) peek< exactly<','> >(position))
{ return expr1.eval_me ? eval(expr1) : expr1; } // { return expr1.eval_me ? eval(expr1) : expr1; }
{ return expr1; }
Node space_list(line_number, Node::space_list, 2); Node space_list(line_number, Node::space_list, 2);
// space_list << expr1; space_list << expr1;
space_list << (expr1.eval_me ? eval(expr1) : expr1); // space_list << (expr1.eval_me ? eval(expr1) : expr1);
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 expr(parse_expression()); // { Node expr(parse_expression());
space_list << (expr.eval_me ? eval(expr) : expr); } // space_list << (expr.eval_me ? eval(expr) : expr); }
// { space_list << parse_expression(); } { space_list << parse_expression(); }
return space_list; return space_list;
} }
...@@ -395,7 +413,8 @@ namespace Sass { ...@@ -395,7 +413,8 @@ namespace Sass {
Node Document::parse_factor() Node Document::parse_factor()
{ {
if (lex< exactly<'('> >()) { if (lex< exactly<'('> >()) {
Node value(parse_list()); // Node value(parse_list());
Node value(parse_comma_list());
value.eval_me = true; value.eval_me = true;
if (value.type == Node::comma_list || value.type == Node::space_list) { if (value.type == Node::comma_list || value.type == Node::space_list) {
value.children->front().eval_me = true; value.children->front().eval_me = true;
......
#ifndef SASS_NODE_INCLUDED
#include "node.hpp"
#endif
namespace Sass {
Node eval(const Node& expr);
Node accumulate(const Node::Type op, Node& acc, Node& rhs);
double operate(const Node::Type op, double lhs, double rhs);
}
\ No newline at end of file
$stuff: 1 2 3;
$three: 3;
div { div {
/* a: 1 + 2; a: 1 + 2;
b: 3 + 2/3; b: 3 + 3/4;
c: 1/2 + 1/2;*/ c: 1/2 + 1/2;
/* shouldn't eval the following "300" */ /* shouldn't eval the following "300" */
/* d: 300; */ d: 300;
/* e: 1 + (5/10 2 3);*/ /* increasingly jacked-up edge cases that combine arithmetic with lists */
e: 1 + (5/10 2 3);
f: 1 + ((2+(3 4) 5) 6); f: 1 + ((2+(3 4) 5) 6);
/* f: 1 + ((1+(14/7 8) 9) 6);*/ g: 1 + ((1+(14/7 8) 9) 6);
/* shouldn't perform the following division */
h: 15 / 3 / 5;
/* should perform the following division now */
i: (15 / 3 / 5);
/* this too */
j: (15 / 3) / 5;
/* and this */
k: 15 / $three;
l: 15 / 5 / $three;
m: 1/2 + $stuff;
m: 1/2 + (1 2 3);
n: $stuff + 1/2;
n: (1/2 2/4 3) + 1/2 + 1/2;
n: 1/2 + 1/2 + 1/2;
o: 3px + 3px;
p: 4 + 1em;
q: (20pt / 10pt);
r: 16em * 4;
} }
\ No newline at end of file
...@@ -5,4 +5,18 @@ $background: "blue"; ...@@ -5,4 +5,18 @@ $background: "blue";
a { a {
color: $color; color: $color;
background: $background; background: $background;
}
$y: before;
$x: 1 2 $y;
foo {
a: $x;
}
$y: after;
foo {
a: $x;
} }
\ No newline at end of file
a { a {
color: red; color: red;
background: "blue"; } background: "blue"; }
\ No newline at end of file
foo {
a: 1 2 before; }
foo {
a: 1 2 before; }
$stuff: 1 2 3;
$three: 3;
div {
a: 1 + 2;
b: 3 + 3/4;
c: 1/2 + 1/2;
/* shouldn't eval the following "300" */
d: 300;
/* increasingly jacked-up edge cases that combine arithmetic with lists */
e: 1 + (5/10 2 3);
f: 1 + ((2+(3 4) 5) 6);
g: 1 + ((1+(14/7 8) 9) 6);
/* shouldn't perform the following division */
h: 15 / 3 / 5;
/* should perform the following division now */
i: (15 / 3 / 5);
/* this too */
j: (15 / 3) / 5;
/* and this */
k: 15 / $three;
l: 15 / 5 / $three;
m: 1/2 + $stuff;
m: 1/2 + (1 2 3);
n: $stuff + 1/2;
n: (1/2 2/4 3) + 1/2 + 1/2;
n: 1/2 + 1/2 + 1/2;
o: 3px + 3px;
p: 4 + 1em;
q: (20pt / 10pt);
r: 16em * 4;
}
\ No newline at end of file
div {
a: 3;
b: 3.75;
c: 1;
/* shouldn't eval the following "300" */
d: 300;
/* increasingly jacked-up edge cases that combine arithmetic with lists */
e: 10.5 2 3;
f: 123 4 5 6;
g: 112 8 9 6;
/* shouldn't perform the following division */
h: 15/3/5;
/* should perform the following division now */
i: 1;
/* this too */
j: 1;
/* and this */
k: 5;
l: 1;
m: 1/21 2 3;
m: 1/21 2 3;
n: 1 2 31/2;
n: 0.5 2/4 31/21/2;
n: 1.5;
o: 6px;
p: 5em;
q: 2;
r: 64em; }
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