Commit 350f04a1 by Aaron Leung

Redoing the arithmetic. Should fix some erroneous behavior on complex…

Redoing the arithmetic. Should fix some erroneous behavior on complex expressions in weird contexts.
parent 6cda1442
......@@ -224,15 +224,19 @@ namespace Sass {
} break;
case Node::expression: {
Node acc(new_Node(Node::expression, expr.path(), expr.line(), 1));
acc << eval(expr[0], prefix, env, f_env, new_Node, ctx);
Node rhs(eval(expr[2], prefix, env, f_env, new_Node, ctx));
accumulate(expr[1].type(), acc, rhs, new_Node);
for (size_t i = 3, S = expr.size(); i < S; i += 2) {
Node rhs(eval(expr[i+1], prefix, env, f_env, new_Node, ctx));
accumulate(expr[i].type(), acc, rhs, new_Node);
for (size_t i = 0, S = expr.size(); i < S; ++i) {
expr[i] = eval(expr[i], prefix, env, f_env, new_Node, ctx);
}
return acc.size() == 1 ? acc[0] : acc;
return reduce(expr, 0, Node(), new_Node);
// Node acc(new_Node(Node::expression, expr.path(), expr.line(), 1));
// acc << eval(expr[0], prefix, env, f_env, new_Node, ctx);
// Node rhs(eval(expr[2], prefix, env, f_env, new_Node, ctx));
// accumulate(expr[1].type(), acc, rhs, new_Node);
// for (size_t i = 3, S = expr.size(); i < S; i += 2) {
// Node rhs(eval(expr[i+1], prefix, env, f_env, new_Node, ctx));
// accumulate(expr[i].type(), acc, rhs, new_Node);
// }
// return acc.size() == 1 ? acc[0] : acc;
} break;
case Node::term: {
......@@ -487,6 +491,46 @@ namespace Sass {
// expressions are stored as vectors of operands with operators interspersed,
// rather than as the usual binary tree.
Node reduce(Node list, size_t head, Node acc, Node_Factory& new_Node)
{
if (head >= list.size()) return acc;
Node rhs(list[head]);
Node op(list[head + 1]);
Node::Type optype = op.type();
if (acc.is_string()) {
acc = new_Node(Node::concatenation, list.path(), list.line(), 2);
if (optype == Node::sub || optype == Node::div || optype == Node::mul) {
acc << op;
}
acc << rhs;
}
Node::Type ltype = acc.type();
Node::Type rtype = rhs.type();
if (ltype == Node::number && rtype == Node::number) {
acc = new_Node(list.path(), list.line(), operate(optype, acc.numeric_value(), rhs.numeric_value()));
}
else if (ltype == Node::number && rtype == Node::numeric_dimension) {
acc = new_Node(list.path(), list.line(), operate(optype, acc.numeric_value(), rhs.numeric_value()), rhs.unit());
}
else if (ltype == Node::number && rtype == Node::numeric_dimension) {
acc = new_Node(list.path(), list.line(), operate(optype, acc.numeric_value(), rhs.numeric_value()), acc.unit());
}
else if (ltype == Node::numeric_dimension && rtype == Node::numeric_dimension) {
// TO DO: TRUE UNIT ARITHMETIC
if (optype == Node::div) {
acc = new_Node(list.path(), list.line(), operate(optype, acc.numeric_value(), rhs.numeric_value()));
}
else {
acc = new_Node(list.path(), list.line(), operate(optype, acc.numeric_value(), rhs.numeric_value()), acc.unit());
}
}
else if (ltype == Node::number && rtype == Node::numeric_color) {
}
return reduce(list, head + 3, acc, new_Node);
}
Node accumulate(Node::Type op, Node acc, Node rhs, Node_Factory& new_Node)
{
Node lhs(acc.back());
......
......@@ -193,6 +193,7 @@ namespace Sass {
bool& is_unquoted() const; // for strings
bool& is_quoted() const; // for identifiers
bool is_numeric() const;
bool is_string() const; // for all string-like types
bool is_guarded() const;
bool& has_been_extended() const;
bool is_false() const;
......@@ -293,6 +294,27 @@ namespace Sass {
bool is_numeric()
{ return type >= Node::number && type <= Node::numeric_dimension; }
bool is_string()
{
switch (type)
{
case Node::string_t:
case Node::identifier:
case Node::value_schema:
case Node::identifier_schema:
case Node::string_constant:
case Node::string_schema:
case Node::concatenation: {
return true;
} break;
default: {
return false;
} break;
}
return false;
}
size_t size()
{ return children.size(); }
......@@ -405,6 +427,7 @@ namespace Sass {
inline bool& Node::is_unquoted() const { return ip_->is_unquoted; }
inline bool& Node::is_quoted() const { return ip_->is_quoted; }
inline bool Node::is_numeric() const { return ip_->is_numeric(); }
inline bool Node::is_string() const { return ip_->is_string(); }
inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); }
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
inline bool Node::is_false() const { return (type() == boolean) && (boolean_value() == false); }
......
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