Skip to content

Commit

Permalink
Merge pull request sass#966 from xzyfer/feat/ampersand-in-sassscript
Browse files Browse the repository at this point in the history
Implement using & in SassScript
  • Loading branch information
xzyfer committed Mar 18, 2015
2 parents 62314f6 + 6735dd5 commit c15b384
Show file tree
Hide file tree
Showing 26 changed files with 405 additions and 82 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ SOURCES = \
constants.cpp \
context.cpp \
contextualize.cpp \
contextualize_eval.cpp \
cssize.cpp \
listize.cpp \
error_handling.cpp \
eval.cpp \
expand.cpp \
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ libsass_la_SOURCES = \
constants.cpp constants.hpp \
context.cpp context.hpp \
contextualize.cpp contextualize.hpp \
contextualize_eval.cpp contextualize_eval.hpp \
error_handling.cpp error_handling.hpp \
eval.cpp eval.hpp \
expand.cpp expand.hpp \
extend.cpp extend.hpp \
cssize.cpp cssize.hpp \
listize.cpp listize.hpp \
file.cpp file.hpp \
functions.cpp functions.hpp \
inspect.cpp inspect.hpp \
Expand Down
17 changes: 17 additions & 0 deletions ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ namespace Sass {
STRING,
LIST,
MAP,
SELECTOR,
NULL_VAL,
NUM_TYPES
};
Expand Down Expand Up @@ -1695,6 +1696,22 @@ namespace Sass {
//////////////////////////////////////////////////////////////////////////////////////////
inline Expression* List::value_at_index(size_t i) { return is_arglist_ ? ((Argument*)(*this)[i])->value() : (*this)[i]; }

////////////
// The Parent Selector Expression.
////////////
class Parent_Selector : public Expression {
ADD_PROPERTY(Selector*, selector);
public:
Parent_Selector(ParserState pstate, Selector* r = 0)
: Expression(pstate), selector_(r)
{ concrete_type(SELECTOR); }
virtual Selector* selector() { return selector_; }
string type() { return "selector"; }
static string type_name() { return "selector"; }

ATTACH_OPERATIONS();
};

/////////////////////////////////////////
// Abstract base class for CSS selectors.
/////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions ast_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,15 @@ namespace Sass {
String_Constant* new_String_Constant(string p, size_t l, const char* beg, const char* end);
Feature_Query_Condition* new_Feature_Query_Condition(string p, size_t l, String* f, Expression* v);
Media_Expression* new_Media_Expression(string p, size_t l, String* f, Expression* v);
Parent_Selector* new_Parent_Selector(string p, size_t l, Selector* s);
// parameters and arguments
Parameter* new_Parameter(string p, size_t l, string n, Expression* def = 0, bool rest = false);
Parameters* new_Parameters(string p, size_t l);
Argument* new_Argument(string p, size_t l, Expression* val, string n = "", bool rest = false);
Arguments* new_Arguments(string p, size_t l);
// selectors
Selector_Schema* new_Selector_Schema(string p, size_t l, String* c);
Attribute_Selector* new_Attribute_Selector(string p, size_t l, string n, string m, String* v);
Simple_Selector* new_Simple_Selector(string p, size_t l, string c);
Reference_Selector* new_Reference_Selector(string p, size_t l);
Placeholder_Selector* new_Placeholder_Selector(string p, size_t l, string n);
Expand Down
1 change: 1 addition & 0 deletions ast_fwd_decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace Sass {
class Feature_Query_Condition;
class At_Root_Expression;
class Null;
class Parent_Selector;
// parameters and arguments
class Parameter;
class Parameters;
Expand Down
2 changes: 2 additions & 0 deletions bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,11 @@ namespace Sass {
// make sure to eval the default value in the env that we've been populating
Env* old_env = eval->env;
Backtrace* old_bt = eval->backtrace;
Contextualize* old_context = eval->contextualize;
Expression* dv = leftover->default_value()->perform(eval->with(env, eval->backtrace));
eval->env = old_env;
eval->backtrace = old_bt;
eval->contextualize = old_context;
// dv->perform(&to_string);
env->current_frame()[leftover->name()] = dv;
}
Expand Down
10 changes: 7 additions & 3 deletions context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include "expand.hpp"
#include "eval.hpp"
#include "contextualize.hpp"
#include "contextualize_eval.hpp"
#include "cssize.hpp"
#include "listize.hpp"
#include "extend.hpp"
#include "remove_placeholders.hpp"
#include "color_names.hpp"
Expand Down Expand Up @@ -311,9 +313,11 @@ namespace Sass {
for (size_t i = 0, S = c_functions.size(); i < S; ++i) {
register_c_function(*this, &tge, c_functions[i]);
}
Eval eval(*this, &tge, &backtrace);
Contextualize contextualize(*this, &eval, &tge, &backtrace);
Expand expand(*this, &eval, &contextualize, &tge, &backtrace);
Contextualize contextualize(*this, &tge, &backtrace);
Listize listize(*this, &tge, &backtrace);
Eval eval(*this, &contextualize, &listize, &tge, &backtrace);
Contextualize_Eval contextualize_eval(*this, &eval, &tge, &backtrace);
Expand expand(*this, &eval, &contextualize_eval, &tge, &backtrace);
Cssize cssize(*this, &tge, &backtrace);
root = root->perform(&expand)->block();
root = root->perform(&cssize)->block();
Expand Down
30 changes: 2 additions & 28 deletions contextualize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

namespace Sass {

Contextualize::Contextualize(Context& ctx, Eval* eval, Env* env, Backtrace* bt, Selector* placeholder, Selector* extender)
: ctx(ctx), eval(eval), env(env), parent(0), backtrace(bt), placeholder(placeholder), extender(extender)
Contextualize::Contextualize(Context& ctx, Env* env, Backtrace* bt, Selector* placeholder, Selector* extender)
: ctx(ctx), env(env), backtrace(bt), parent(0), placeholder(placeholder), extender(extender)
{ }

Contextualize::~Contextualize() { }
Expand All @@ -26,18 +26,6 @@ namespace Sass {
return this;
}

Selector* Contextualize::operator()(Selector_Schema* s)
{
To_String to_string(&ctx);
string result_str(s->contents()->perform(eval->with(env, backtrace))->perform(&to_string));
result_str += '{'; // the parser looks for a brace to end the selector
Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate());
p.block_stack.push_back(s->last_block());
p.last_media_block = s->media_block();
Selector* result_sel = p.parse_selector_group();
return result_sel->perform(this);
}

Selector* Contextualize::operator()(Selector_List* s)
{
Selector_List* p = static_cast<Selector_List*>(parent);
Expand Down Expand Up @@ -126,18 +114,6 @@ namespace Sass {
Selector* Contextualize::operator()(Pseudo_Selector* s)
{ return s; }

Selector* Contextualize::operator()(Attribute_Selector* s)
{
// the value might be interpolated; evaluate it
String* v = s->value();
if (v && eval) {
v = static_cast<String*>(v->perform(eval->with(env, backtrace)));
}
Attribute_Selector* ss = new (ctx.mem) Attribute_Selector(*s);
ss->value(v);
return ss;
}

Selector* Contextualize::operator()(Selector_Qualifier* s)
{ return s; }

Expand All @@ -162,6 +138,4 @@ namespace Sass {
ss->selector(parent);
return ss;
}


}
16 changes: 6 additions & 10 deletions contextualize.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef SASS_CONTEXTUALIZE_H
#define SASS_CONTEXTUALIZE_H

#include "eval.hpp"
#include "context.hpp"
#include "operation.hpp"
#include "environment.hpp"
Expand All @@ -14,29 +13,26 @@ namespace Sass {

class Contextualize : public Operation_CRTP<Selector*, Contextualize> {


public:
Context& ctx;
Eval* eval;
Env* env;
Selector* parent;
Backtrace* backtrace;

Selector* fallback_impl(AST_Node* n);

public:
Selector* parent;
Selector* placeholder;
Selector* extender;
Contextualize(Context&, Eval*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);

Selector* fallback_impl(AST_Node* n);
Contextualize(Context&, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
virtual ~Contextualize();
Contextualize* with(Selector*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
using Operation<Selector*>::operator();

Selector* operator()(Selector_Schema*);
Selector* operator()(Selector_List*);
Selector* operator()(Complex_Selector*);
Selector* operator()(Compound_Selector*);
Selector* operator()(Wrapped_Selector*);
Selector* operator()(Pseudo_Selector*);
Selector* operator()(Attribute_Selector*);
Selector* operator()(Selector_Qualifier*);
Selector* operator()(Type_Selector*);
Selector* operator()(Selector_Placeholder*);
Expand Down
88 changes: 88 additions & 0 deletions contextualize_eval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "contextualize_eval.hpp"
#include "ast.hpp"
#include "eval.hpp"
#include "backtrace.hpp"
#include "to_string.hpp"
#include "parser.hpp"

namespace Sass {

Contextualize_Eval::Contextualize_Eval(Context& ctx, Eval* eval, Env* env, Backtrace* bt)
: Contextualize(ctx, env, bt), eval(eval)
{ }

Contextualize_Eval::~Contextualize_Eval() { }

Selector* Contextualize_Eval::fallback_impl(AST_Node* n)
{ return Contextualize::fallback_impl(n); }

Contextualize_Eval* Contextualize_Eval::with(Selector* s, Env* e, Backtrace* bt, Selector* p, Selector* ex)
{
Contextualize::with(s, e, bt, p, ex);
eval = eval->with(s, e, bt, p, ex);
return this;
}

Selector* Contextualize_Eval::operator()(Selector_Schema* s)
{
To_String to_string;
string result_str(s->contents()->perform(eval)->perform(&to_string));
result_str += '{'; // the parser looks for a brace to end the selector
Selector* result_sel = Parser::from_c_str(result_str.c_str(), ctx, s->pstate()).parse_selector_group();
return result_sel->perform(this);
}

Selector* Contextualize_Eval::operator()(Selector_List* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Complex_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Compound_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Wrapped_Selector* s)
{
return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Pseudo_Selector* s)
{ return Contextualize::operator ()(s); }

Selector* Contextualize_Eval::operator()(Attribute_Selector* s)
{
// the value might be interpolated; evaluate it
String* v = s->value();
if (v && eval) {
v = static_cast<String*>(v->perform(eval->with(env, backtrace)));
}
To_String toString;
Attribute_Selector* ss = new (ctx.mem) Attribute_Selector(*s);
ss->value(v);
return ss;
}

Selector* Contextualize_Eval::operator()(Selector_Qualifier* s)
{ return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Type_Selector* s)
{ return Contextualize::operator ()(s);
}

Selector* Contextualize_Eval::operator()(Selector_Placeholder* p)
{
return Contextualize::operator ()(p);
}

Selector* Contextualize_Eval::operator()(Selector_Reference* s)
{
return Contextualize::operator ()(s);
}
}
44 changes: 44 additions & 0 deletions contextualize_eval.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef SASS_CONTEXTUALIZE_EVAL_H
#define SASS_CONTEXTUALIZE_EVAL_H

#include "eval.hpp"
#include "context.hpp"
#include "operation.hpp"
#include "environment.hpp"
#include "ast_fwd_decl.hpp"

namespace Sass {
struct Backtrace;

typedef Environment<AST_Node*> Env;

class Contextualize_Eval : public Contextualize {

Eval* eval;

Selector* fallback_impl(AST_Node* n);

public:
Contextualize_Eval(Context&, Eval*, Env*, Backtrace*);
virtual ~Contextualize_Eval();
Contextualize_Eval* with(Selector*, Env*, Backtrace*, Selector* placeholder = 0, Selector* extender = 0);
using Operation<Selector*>::operator();

Selector* operator()(Selector_Schema*);
Selector* operator()(Selector_List*);
Selector* operator()(Complex_Selector*);
Selector* operator()(Compound_Selector*);
Selector* operator()(Wrapped_Selector*);
Selector* operator()(Pseudo_Selector*);
Selector* operator()(Attribute_Selector*);
Selector* operator()(Selector_Qualifier*);
Selector* operator()(Type_Selector*);
Selector* operator()(Selector_Placeholder*);
Selector* operator()(Selector_Reference*);

template <typename U>
Selector* fallback(U x) { return fallback_impl(x); }
};
}

#endif
Loading

0 comments on commit c15b384

Please # to comment.