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 {
val.from_variable = 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;
}
......@@ -281,16 +285,29 @@ namespace Sass {
Node Document::parse_list()
{
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position))
{ return Node(line_number, Node::nil); }
else
{ return parse_comma_list(); }
Node val(parse_comma_list());
if (val.type != Node::comma_list && val.type != Node::space_list && val.eval_me) {
return eval(val);
}
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()
{
if (peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position)) {
return Node(line_number, Node::nil);
}
Node list1(parse_space_list());
// if it's a singleton, return it directly; don't wrap it
if (!peek< exactly<','> >(position)) return list1;
......@@ -312,19 +329,20 @@ namespace Sass {
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);
// space_list << expr1;
space_list << (expr1.eval_me ? eval(expr1) : expr1);
space_list << expr1;
// space_list << (expr1.eval_me ? eval(expr1) : expr1);
while (!(peek< exactly<';'> >(position) ||
peek< exactly<'}'> >(position) ||
peek< exactly<')'> >(position) ||
peek< exactly<','> >(position)))
{ Node expr(parse_expression());
space_list << (expr.eval_me ? eval(expr) : expr); }
// { space_list << parse_expression(); }
// { Node expr(parse_expression());
// space_list << (expr.eval_me ? eval(expr) : expr); }
{ space_list << parse_expression(); }
return space_list;
}
......@@ -395,7 +413,8 @@ namespace Sass {
Node Document::parse_factor()
{
if (lex< exactly<'('> >()) {
Node value(parse_list());
// Node value(parse_list());
Node value(parse_comma_list());
value.eval_me = true;
if (value.type == Node::comma_list || value.type == Node::space_list) {
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 {
/* a: 1 + 2;
b: 3 + 2/3;
c: 1/2 + 1/2;*/
a: 1 + 2;
b: 3 + 3/4;
c: 1/2 + 1/2;
/* shouldn't eval the following "300" */
/* d: 300; */
/* e: 1 + (5/10 2 3);*/
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);
/* 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
......@@ -6,3 +6,17 @@ a {
color: $color;
background: $background;
}
$y: before;
$x: 1 2 $y;
foo {
a: $x;
}
$y: after;
foo {
a: $x;
}
\ No newline at end of file
a {
color: red;
background: "blue"; }
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