Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/milestore 3.4 #1841

Merged
merged 17 commits into from
Jan 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,12 @@ namespace Sass {
bool Number::operator== (const Expression& rhs) const
{
if (const Number* r = dynamic_cast<const Number*>(&rhs)) {
size_t lhs_units = numerator_units_.size() + denominator_units_.size();
size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size();
// unitless and only having one unit seems equivalent (will change in future)
if (!lhs_units || !rhs_units) {
return std::fabs(value() - r->value()) < NUMBER_EPSILON;
}
return (numerator_units_ == r->numerator_units_) &&
(denominator_units_ == r->denominator_units_) &&
std::fabs(value() - r->value()) < NUMBER_EPSILON;
Expand All @@ -1743,11 +1749,18 @@ namespace Sass {

bool Number::operator< (const Number& rhs) const
{
size_t lhs_units = numerator_units_.size() + denominator_units_.size();
size_t rhs_units = rhs.numerator_units_.size() + rhs.denominator_units_.size();
// unitless and only having one unit seems equivalent (will change in future)
if (!lhs_units || !rhs_units) {
return value() < rhs.value();
}

Number tmp_r(rhs);
tmp_r.normalize(find_convertible_unit());
std::string l_unit(unit());
std::string r_unit(tmp_r.unit());
if (!l_unit.empty() && !r_unit.empty() && unit() != tmp_r.unit()) {
if (unit() != tmp_r.unit()) {
error("cannot compare numbers with incompatible units", pstate());
}
return value() < tmp_r.value();
Expand All @@ -1773,6 +1786,15 @@ namespace Sass {
return false;
}

bool String_Schema::is_left_interpolant(void) const
{
return length() && first()->is_left_interpolant();
}
bool String_Schema::is_right_interpolant(void) const
{
return length() && last()->is_right_interpolant();
}

bool String_Schema::operator== (const Expression& rhs) const
{
if (const String_Schema* r = dynamic_cast<const String_Schema*>(&rhs)) {
Expand Down Expand Up @@ -1930,6 +1952,15 @@ namespace Sass {
return value()->to_string(compressed, precision);
}

bool Binary_Expression::is_left_interpolant(void) const
{
return is_interpolant() || (left() && left()->is_left_interpolant());
}
bool Binary_Expression::is_right_interpolant(void) const
{
return is_interpolant() || (right() && right()->is_right_interpolant());
}

std::string Binary_Expression::to_string(bool compressed, int precision) const
{
std::string str("");
Expand Down Expand Up @@ -2215,9 +2246,17 @@ namespace Sass {
}

// some final cosmetics
if (res == "-0.0") res.erase(0, 1);
else if (res == "-0") res.erase(0, 1);
if (res == "0.0") res = "0";
else if (res == "") res = "0";
else if (res == "-0") res = "0";
else if (res == "-0.0") res = "0";
else if (compressed)
{
// check if handling negative nr
size_t off = res[0] == '-' ? 1 : 0;
// remove leading zero from floating point in compressed mode
if (zero() && res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
}

// add unit now
res += unit();
Expand All @@ -2227,11 +2266,21 @@ namespace Sass {

}

std::string String_Quoted::inspect() const
{
return quote(value_, '*', true);
}

std::string String_Quoted::to_string(bool compressed, int precision) const
{
return quote_mark_ ? quote(value_, quote_mark_, true) : value_;
}

std::string String_Constant::inspect() const
{
return quote(value_, '*', true);
}

std::string String_Constant::to_string(bool compressed, int precision) const
{
return quote_mark_ ? quote(value_, quote_mark_, true) : value_;
Expand All @@ -2251,9 +2300,10 @@ namespace Sass {
std::string str("");
auto end = this->end();
auto start = this->begin();
std::string sep(compressed ? "," : ", ");
while (start < end && *start) {
Complex_Selector* sel = *start;
if (!str.empty()) str += ", ";
if (!str.empty()) str += sep;
str += sel->to_string(compressed, precision);
++ start;
}
Expand Down Expand Up @@ -2289,6 +2339,7 @@ namespace Sass {
case ADJACENT_TO: str_op = "+"; break;
case REFERENCE: str_op = "/" + str_ref + "/"; break;
}

// prettify for non ancestors
if (combinator() != ANCESTOR_OF) {
// no spaces needed for compressed
Expand All @@ -2302,6 +2353,12 @@ namespace Sass {
else if (str_tail == "") {
str_op = ""; // superflous
}
else if (compressed)
{
if (str_tail[0] == '-') {
str_op = ""; // superflous
}
}
// now build the final result
return str_head + str_op + str_tail;
}
Expand Down
48 changes: 46 additions & 2 deletions src/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ namespace Sass {
virtual bool is_false() { return false; }
virtual bool operator== (const Expression& rhs) const { return false; }
virtual void set_delayed(bool delayed) { is_delayed(delayed); }
virtual bool has_interpolant() const { return is_interpolant(); }
virtual bool is_left_interpolant() const { return is_interpolant(); }
virtual bool is_right_interpolant() const { return is_interpolant(); }
virtual std::string inspect() const { return to_string(); } // defaults to to_string
virtual std::string to_string(bool compressed = false, int precision = 5) const = 0;
virtual size_t hash() { return 0; }
};
Expand Down Expand Up @@ -924,6 +928,27 @@ namespace Sass {
ATTACH_OPERATIONS()
};

inline static const std::string sass_op_to_name(enum Sass_OP op) {
switch (op) {
case AND: return "and"; break;
case OR: return "or"; break;
case EQ: return "eq"; break;
case NEQ: return "neq"; break;
case GT: return "gt"; break;
case GTE: return "gte"; break;
case LT: return "lt"; break;
case LTE: return "lte"; break;
case ADD: return "plus"; break;
case SUB: return "sub"; break;
case MUL: return "times"; break;
case DIV: return "div"; break;
case MOD: return "mod"; break;
// this is only used internally!
case NUM_OPS: return "[OPS]"; break;
default: return "invalid"; break;
}
}

//////////////////////////////////////////////////////////////////////////
// Binary expressions. Represents logical, relational, and arithmetic
// operations. Templatized to avoid large switch statements and repetitive
Expand Down Expand Up @@ -980,6 +1005,13 @@ namespace Sass {
default: return "invalid"; break;
}
}
bool is_left_interpolant(void) const;
bool is_right_interpolant(void) const;
bool has_interpolant() const
{
return is_left_interpolant() ||
is_right_interpolant();
}
virtual void set_delayed(bool delayed)
{
right()->set_delayed(delayed);
Expand Down Expand Up @@ -1439,15 +1471,25 @@ namespace Sass {
// evaluation phase.
///////////////////////////////////////////////////////////////////////
class String_Schema : public String, public Vectorized<Expression*> {
ADD_PROPERTY(bool, has_interpolants)
// ADD_PROPERTY(bool, has_interpolants)
size_t hash_;
public:
String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
: String(pstate), Vectorized<Expression*>(size), has_interpolants_(has_interpolants), hash_(0)
: String(pstate), Vectorized<Expression*>(size), hash_(0)
{ concrete_type(STRING); }
std::string type() { return "string"; }
static std::string type_name() { return "string"; }

bool is_left_interpolant(void) const;
bool is_right_interpolant(void) const;
// void has_interpolants(bool tc) { }
bool has_interpolants() {
for (auto el : elements()) {
if (el->is_interpolant()) return true;
}
return false;
}

virtual size_t hash()
{
if (hash_ == 0) {
Expand Down Expand Up @@ -1497,6 +1539,7 @@ namespace Sass {
}

virtual bool operator==(const Expression& rhs) const;
virtual std::string inspect() const; // quotes are forced on inspection
virtual std::string to_string(bool compressed = false, int precision = 5) const;

// static char auto_quote() { return '*'; }
Expand All @@ -1518,6 +1561,7 @@ namespace Sass {
if (q && quote_mark_) quote_mark_ = q;
}
virtual bool operator==(const Expression& rhs) const;
virtual std::string inspect() const; // quotes are forced on inspection
virtual std::string to_string(bool compressed = false, int precision = 5) const;
ATTACH_OPERATIONS()
};
Expand Down
2 changes: 2 additions & 0 deletions src/constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Sass {
extern const char odd_kwd[] = "odd";
extern const char progid_kwd[] = "progid";
extern const char expression_kwd[] = "expression";
extern const char calc_fn_kwd[] = "calc";
extern const char calc_kwd[] = "calc(";
extern const char moz_calc_kwd[] = "-moz-calc(";
extern const char webkit_calc_kwd[] = "-webkit-calc(";
Expand Down Expand Up @@ -125,6 +126,7 @@ namespace Sass {
extern const char rbrace[] = "}";
extern const char rparen[] = ")";
extern const char sign_chars[] = "-+";
extern const char op_chars[] = "-+";
extern const char hyphen[] = "-";
extern const char ellipsis[] = "...";
// extern const char url_space_chars[] = " \t\r\n\f";
Expand Down
2 changes: 2 additions & 0 deletions src/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ namespace Sass {
extern const char progid_kwd[];
extern const char expression_kwd[];
extern const char calc_kwd[];
extern const char calc_fn_kwd[];
extern const char moz_calc_kwd[];
extern const char webkit_calc_kwd[];
extern const char ms_calc_kwd[];
Expand Down Expand Up @@ -126,6 +127,7 @@ namespace Sass {
extern const char rbrace[];
extern const char rparen[];
extern const char sign_chars[];
extern const char op_chars[];
extern const char hyphen[];
extern const char ellipsis[];
// extern const char url_space_chars[];
Expand Down
1 change: 0 additions & 1 deletion src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,6 @@ namespace Sass {
Expand expand(*this, &global, &backtrace);
Cssize cssize(*this, &backtrace);
// expand and eval the tree
// debug_ast(root);
root = root->perform(&expand)->block();
// merge and bubble certain rules
root = root->perform(&cssize)->block();
Expand Down
4 changes: 1 addition & 3 deletions src/cssize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ namespace Sass {

public:
Cssize(Context&, Backtrace*);
virtual ~Cssize() { }

using Operation<Statement*>::operator();
~Cssize() { }

Statement* operator()(Block*);
Statement* operator()(Ruleset*);
Expand Down
20 changes: 18 additions & 2 deletions src/debugger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,25 +453,29 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]";
else if (expression->type() == Textual::HEX) std::cerr << " [HEX]";
std::cerr << expression << " [" << expression->value() << "]";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
if (expression->is_delayed()) std::cerr << " [delayed]";
std::cerr << std::endl;
} else if (dynamic_cast<Variable*>(node)) {
Variable* expression = dynamic_cast<Variable*>(node);
std::cerr << ind << "Variable " << expression;
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [" << expression->name() << "]" << std::endl;
std::string name(expression->name());
if (env && env->has(name)) debug_ast(static_cast<Expression*>((*env)[name]), ind + " -> ", env);
} else if (dynamic_cast<Function_Call_Schema*>(node)) {
Function_Call_Schema* expression = dynamic_cast<Function_Call_Schema*>(node);
std::cerr << ind << "Function_Call_Schema " << expression;
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << "" << std::endl;
debug_ast(expression->name(), ind + "name: ", env);
debug_ast(expression->arguments(), ind + " args: ", env);
} else if (dynamic_cast<Function_Call*>(node)) {
Function_Call* expression = dynamic_cast<Function_Call*>(node);
std::cerr << ind << "Function_Call " << expression;
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [" << expression->name() << "]";
if (expression->is_delayed()) std::cerr << " [delayed]";
Expand Down Expand Up @@ -515,20 +519,27 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
} else if (dynamic_cast<Unary_Expression*>(node)) {
Unary_Expression* expression = dynamic_cast<Unary_Expression*>(node);
std::cerr << ind << "Unary_Expression " << expression;
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [" << expression->type() << "]" << std::endl;
debug_ast(expression->operand(), ind + " operand: ", env);
} else if (dynamic_cast<Binary_Expression*>(node)) {
Binary_Expression* expression = dynamic_cast<Binary_Expression*>(node);
std::cerr << ind << "Binary_Expression " << expression;
if (expression->is_interpolant()) std::cerr << " [is interpolant] ";
if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
std::cerr << " [delayed: " << expression->is_delayed() << "] ";
std::cerr << " [ws_before: " << expression->op().ws_before << "] ";
std::cerr << " [ws_after: " << expression->op().ws_after << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [" << expression->type_name() << "]" << std::endl;
debug_ast(expression->left(), ind + " left: ", env);
debug_ast(expression->right(), ind + " right: ", env);
} else if (dynamic_cast<Map*>(node)) {
Map* expression = dynamic_cast<Map*>(node);
std::cerr << ind << "Map " << expression;
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [Hashed]" << std::endl;
for (auto i : expression->elements()) {
Expand Down Expand Up @@ -556,16 +567,19 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
Boolean* expression = dynamic_cast<Boolean*>(node);
std::cerr << ind << "Boolean " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " [" << expression->value() << "]" << std::endl;
} else if (dynamic_cast<Color*>(node)) {
Color* expression = dynamic_cast<Color*>(node);
std::cerr << ind << "Color " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl;
} else if (dynamic_cast<Number*>(node)) {
Number* expression = dynamic_cast<Number*>(node);
std::cerr << ind << "Number " << expression;
std::cerr << " (" << pstate_source_position(node) << ")";
std::cerr << " [interpolant: " << expression->is_interpolant() << "] ";
std::cerr << " [" << expression->value() << expression->unit() << "]" <<
" [hash: " << expression->hash() << "] " <<
std::endl;
Expand Down Expand Up @@ -596,8 +610,10 @@ inline void debug_ast(AST_Node* node, std::string ind, Env* env)
std::cerr << ind << "String_Schema " << expression;
std::cerr << " " << expression->concrete_type();
if (expression->is_delayed()) std::cerr << " [delayed]";
if (expression->has_interpolants()) std::cerr << " [has_interpolants]";
if (expression->is_interpolant()) std::cerr << " [interpolant]";
if (expression->is_interpolant()) std::cerr << " [is interpolant]";
if (expression->has_interpolant()) std::cerr << " [has interpolant]";
if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
for(auto i : expression->elements()) { debug_ast(i, ind + " ", env); }
} else if (dynamic_cast<String*>(node)) {
Expand Down
5 changes: 4 additions & 1 deletion src/emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ namespace Sass {
// MAIN BUFFER MANIPULATION

// add outstanding delimiter
void Emitter::finalize(void)
void Emitter::finalize(bool final)
{
scheduled_space = 0;
if (output_style() == SASS_STYLE_COMPRESSED)
if (final) scheduled_delimiter = false;
if (scheduled_linefeed)
scheduled_linefeed = 1;
flush_schedules();
Expand Down Expand Up @@ -107,6 +109,7 @@ namespace Sass {
// append some text or token to the buffer
void Emitter::append_string(const std::string& text)
{

// write space/lf
flush_schedules();

Expand Down
Loading