Commit f5dfac98 by Aaron Leung

Handling hex arithmetic. Ignoring more janky edge cases. Probably need to handle…

Handling hex arithmetic. Ignoring more janky edge cases. Probably need to handle decimal rgb formats too.
parent 12fcaccb
......@@ -57,18 +57,11 @@ namespace Sass {
} break;
case Node::textual_hex: {
// long numval = std::strtol(expr.token.begin + 1, NULL, 16);
// Node result(expr.line_number, numval);
// result.is_hex = true;
// return result;
Node triple(expr.line_number, Node::hex_triple, 3);
Token hext(expr.token.begin+1, expr.token.end);
if (hext.length() == 6) {
for (int i = 0; i < 6; i += 2) {
Node thing(expr.line_number, static_cast<double>(std::strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
cerr << "evaled a hex triplet: " << thing.to_string("") << endl;
triple << Node(expr.line_number, static_cast<double>(std::strtol(string(hext.begin+i, 2).c_str(), NULL, 16)));
}
}
......@@ -77,9 +70,7 @@ namespace Sass {
triple << Node(expr.line_number, static_cast<double>(std::strtol(string(2, hext.begin[i]).c_str(), NULL, 16)));
}
}
return triple;
} break;
default: {
......@@ -88,7 +79,6 @@ namespace Sass {
}
}
Node accumulate(const Node::Type op, Node& acc, Node& rhs)
{
Node lhs(acc.children->back());
......@@ -100,6 +90,7 @@ namespace Sass {
acc.children->pop_back();
acc.children->push_back(result);
}
// TO DO: find a way to merge the following two clauses
else if (lhs.type == Node::number && rhs.type == Node::numeric_dimension) {
// TO DO: disallow division
Node result(acc.line_number, operate(op, lnum, rnum), rhs.token);
......@@ -121,6 +112,42 @@ namespace Sass {
acc.children->pop_back();
acc.children->push_back(result);
}
// TO DO: find a way to merge the following two clauses
else if (lhs.type == Node::number && rhs.type == Node::hex_triple) {
if (op != Node::sub && op != Node::div) {
double h1 = operate(op, lhs.numeric_value, rhs.children->at(0).numeric_value);
double h2 = operate(op, lhs.numeric_value, rhs.children->at(1).numeric_value);
double h3 = operate(op, lhs.numeric_value, rhs.children->at(2).numeric_value);
acc.children->pop_back();
acc << Node(acc.line_number, h1, h2, h3);
}
// trying to handle weird edge cases ... not sure if it's worth it
else if (op == Node::div) {
acc << Node(acc.line_number, Node::div);
acc << rhs;
}
else if (op == Node::sub) {
acc << Node(acc.line_number, Node::sub);
acc << rhs;
}
else {
acc << rhs;
}
}
else if (lhs.type == Node::hex_triple && rhs.type == Node::number) {
double h1 = operate(op, lhs.children->at(0).numeric_value, rhs.numeric_value);
double h2 = operate(op, lhs.children->at(1).numeric_value, rhs.numeric_value);
double h3 = operate(op, lhs.children->at(2).numeric_value, rhs.numeric_value);
acc.children->pop_back();
acc << Node(acc.line_number, h1, h2, h3);
}
else if (lhs.type == Node::hex_triple && rhs.type == Node::hex_triple) {
double h1 = operate(op, lhs.children->at(0).numeric_value, rhs.children->at(0).numeric_value);
double h2 = operate(op, lhs.children->at(1).numeric_value, rhs.children->at(1).numeric_value);
double h3 = operate(op, lhs.children->at(2).numeric_value, rhs.children->at(2).numeric_value);
acc.children->pop_back();
acc << Node(acc.line_number, h1, h2, h3);
}
else {
// TO DO: disallow division and multiplication on lists
acc.children->push_back(rhs);
......
......@@ -11,5 +11,11 @@ div {
p10: #000000 - 1; // black
p11: #000000 - #000001; // black
p12: #ffff00 + #010100; // yellow
p13: (#101010 / 7)
p13: (#101010 / 7);
p14: #000 + 0;
p15: 10 - #222;
p16: #000 - #001;
p17: #f0f + #101;
p18: 10 #222 + 1;
p19: (10 / #222);
}
\ No newline at end of file
......@@ -78,9 +78,8 @@ namespace Sass {
case attribute_selector: {
string result("[");
result += children->at(0).to_string(prefix);
result += children->at(1).to_string(prefix);
result += children->at(2).to_string(prefix);
for (int i = 0; i < 3; ++i)
{ result += children->at(i).to_string(prefix); }
result += ']';
return result;
} break;
......@@ -116,7 +115,7 @@ namespace Sass {
// }
for (int i = 1; i < children->size(); ++i) {
if (!(children->at(i).type == add ||
children->at(i).type == sub ||
// children->at(i).type == sub || // another edge case -- consider uncommenting
children->at(i).type == mul)) {
result += children->at(i).to_string(prefix);
}
......@@ -124,6 +123,15 @@ namespace Sass {
return result;
} break;
//edge case
case sub: {
return "-";
} break;
case div: {
return "/";
} break;
case numeric_dimension: {
stringstream ss;
// ss.setf(std::ios::fixed, std::ios::floatfield);
......@@ -141,12 +149,37 @@ namespace Sass {
} break;
case hex_triple: {
double a = children->at(0).numeric_value;
double b = children->at(1).numeric_value;
double c = children->at(2).numeric_value;
if (a > 0xff && b > 0xff && c > 0xff)
{ return "white"; }
else if (a > 0xff && b > 0xff && c == 0)
{ return "yellow"; }
else if (a == 0 && b > 0xff && c > 0xff)
{ return "aqua"; }
else if (a > 0xff && b == 0 && c > 0xff)
{ return "fuchsia"; }
else if (a > 0xff && b == 0 && c == 0)
{ return "red"; }
else if (a == 0 && b > 0xff && c == 0)
{ return "green"; }
else if (a == 0 && b == 0 && c > 0xff)
{ return "blue"; }
else if (a <= 0 && b <= 0 && c <= 0)
{ return "black"; }
else
{
stringstream ss;
ss << '#' << std::setw(2) << std::setfill('0');
ss << '#' << std::setw(2) << std::setfill('0') << std::hex;
for (int i = 0; i < 3; ++i) {
ss << std::hex << std::setw(2) << static_cast<long>(children->at(i).numeric_value);
double x = children->at(i).numeric_value;
if (x > 0xff) x = 0xff;
else if (x < 0) x = 0;
ss << std::hex << std::setw(2) << static_cast<unsigned long>(x);
}
return ss.str();
}
} break;
default: {
......@@ -218,12 +251,14 @@ namespace Sass {
size_t depth,
const vector<string>& prefixes)
{
switch (type) {
switch (type)
{
case root:
for (int i = 0; i < children->size(); ++i) {
children->at(i).emit_nested_css(buf, depth, prefixes);
}
break;
case ruleset: {
Node sel_group(children->at(0));
Node block(children->at(1));
......@@ -268,6 +303,7 @@ namespace Sass {
if (block.has_rules_or_comments) --depth;
if (depth == 0 && prefixes.empty()) buf << endl;
} break;
default:
emit_nested_css(buf, depth); // pass it along to the simpler version
break;
......@@ -276,26 +312,31 @@ namespace Sass {
void Node::emit_nested_css(stringstream& buf, size_t depth)
{
switch (type) {
switch (type)
{
case rule:
buf << endl << string(2*depth, ' ');
children->at(0).emit_nested_css(buf, depth); // property
children->at(1).emit_nested_css(buf, depth); // values
buf << ";";
break;
case property:
buf << string(token) << ": ";
break;
case values:
for (int i = 0; i < children->size(); ++i) {
buf << " " << string(children->at(i).token);
}
break;
case comment:
if (depth != 0) buf << endl;
buf << string(2*depth, ' ') << string(token);
if (depth == 0) buf << endl;
break;
default:
buf << to_string("");
break;
......
......@@ -191,6 +191,27 @@ namespace Sass {
is_hex(false)
{ ++fresh; }
Node(size_t line_number, double a, double b, double c)
: line_number(line_number),
children(new vector<Node>()),
token(Token()),
numeric_value(0),
type(hex_triple),
has_rules_or_comments(false),
has_rulesets(false),
has_propsets(false),
has_backref(false),
from_variable(false),
eval_me(false),
is_hex(true)
{
children->reserve(3);
children->push_back(Node(line_number, a));
children->push_back(Node(line_number, b));
children->push_back(Node(line_number, c));
++fresh;
}
//~Node() { delete children; }
Node& operator=(const Node& n)
......
div {
p01: #abc;
p02: #aabbcc;
p03: #abc + hello;
p04: #abc + 1; // add 1 to each triplet
p05: #abc + #001; // triplet-wise addition
p06: #0000ff + 1; // add 1 to each triplet; ignore overflow because it doesn't correspond to a color name
p07: #0000ff + #000001; // convert overflow to name of color (blue)
p08: #00ffff + #000101; // aqua
p09: #000000;
p10: #000000 - 1; // black
p11: #000000 - #000001; // black
p12: #ffff00 + #010100; // yellow
p13: (#101010 / 7);
p14: #000 + 0;
p15: 10 - #222;
p16: #000 - #001;
p17: #f0f + #101;
p18: 10 #222 + 1;
p19: (10 / #222);
}
\ No newline at end of file
div {
p01: #abc;
p02: #aabbcc;
p03: #aabbcchello;
p04: #abbccd;
p05: #aabbdd;
p06: #0101ff;
p07: blue;
p08: aqua;
p09: #000000;
p10: black;
p11: black;
p12: yellow;
p13: #020202;
p14: black;
p15: 10-#222222;
p16: black;
p17: fuchsia;
p18: 10 #232323;
p19: 10/#222222; }
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