Skip to content
This repository was archived by the owner on Jun 14, 2019. It is now read-only.

Commit a78ca00

Browse files
author
Aaron Leung
committed
Implemented the @each directive.
1 parent 8354bde commit a78ca00

File tree

6 files changed

+67
-15
lines changed

6 files changed

+67
-15
lines changed

document.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ namespace Sass {
162162
Node parse_value_schema();
163163
Node parse_if_directive(Node surrounding_ruleset);
164164
Node parse_for_directive(Node surrounding_ruleset);
165-
165+
Node parse_each_directive(Node surrounding_ruleset);
166166

167167
Selector_Lookahead lookahead_for_selector(const char* start = 0);
168168

document_parser.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ namespace Sass {
4242
else if (peek< for_directive >()) {
4343
root << parse_for_directive(Node());
4444
}
45+
else if (peek< each_directive >()) {
46+
root << parse_each_directive(Node());
47+
}
4548
else {
4649
lex< spaces_and_comments >();
4750
throw_syntax_error("invalid top-level expression");
@@ -496,6 +499,9 @@ namespace Sass {
496499
else if (peek< for_directive >()) {
497500
block << parse_for_directive(surrounding_ruleset);
498501
}
502+
else if (peek< each_directive >()) {
503+
block << parse_each_directive(surrounding_ruleset);
504+
}
499505
else if (!peek< exactly<';'> >()) {
500506
Node rule(parse_rule());
501507
// check for lbrace; if it's there, we have a namespace property with a value
@@ -920,10 +926,25 @@ namespace Sass {
920926
Node upper_bound(parse_expression());
921927
if (!peek< exactly<'{'> >()) throw_syntax_error("expected '{' after the upper bound in @for directive");
922928
Node body(parse_block(surrounding_ruleset));
923-
Node loop(context.new_Node(for_type, path, for_line, 3));
929+
Node loop(context.new_Node(for_type, path, for_line, 4));
924930
loop << var << lower_bound << upper_bound << body;
925931
return loop;
926932
}
933+
934+
Node Document::parse_each_directive(Node surrounding_ruleset)
935+
{
936+
lex < each_directive >();
937+
size_t each_line = line;
938+
if (!lex< variable >()) throw_syntax_error("@each directive requires an iteration variable");
939+
Node var(context.new_Node(Node::variable, path, line, lexed));
940+
if (!lex< in >()) throw_syntax_error("expected 'in' keyword in @each directive");
941+
Node list(parse_list());
942+
if (!peek< exactly<'{'> >()) throw_syntax_error("expected '{' after the upper bound in @each directive");
943+
Node body(parse_block(surrounding_ruleset));
944+
Node each(context.new_Node(Node::each_directive, path, each_line, 3));
945+
each << var << list << body;
946+
return each;
947+
}
927948

928949
Selector_Lookahead Document::lookahead_for_selector(const char* start)
929950
{

eval_apply.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,21 @@ namespace Sass {
342342
}
343343
} break;
344344

345+
case Node::each_directive: {
346+
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
347+
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1));
348+
fake_mixin << new_Node(Node::none, "", 0, 0) << (fake_param << expr[0]) << expr[2];
349+
Node list(expr[1]);
350+
expr.pop_back();
351+
expr.pop_back();
352+
expr.pop_back();
353+
for (size_t i = 0, S = list.size(); i < S; ++i) {
354+
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 1));
355+
fake_arg << eval(list[i], prefix, env, f_env, new_Node, ctx);
356+
expr += apply_mixin(fake_mixin, fake_arg, prefix, env, f_env, new_Node, ctx);
357+
}
358+
} break;
359+
345360
default: {
346361
return expr;
347362
} break;

node.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,28 @@ namespace Sass {
1616
if (type() != block && type() != expansion && type() != root && type() != for_through_directive && type() != for_to_directive) return;
1717
// size can change during flattening, so we need to call size() on each pass
1818
for (size_t i = 0; i < size(); ++i) {
19-
Type i_type = at(i).type();
20-
if ((i_type == expansion) || (i_type == block) || (i_type == for_through_directive) || (i_type == for_to_directive)) {
21-
Node expn(at(i));
22-
if (expn.has_expansions()) expn.flatten();
23-
ip_->has_statements |= expn.has_statements();
24-
ip_->has_blocks |= expn.has_blocks();
25-
ip_->has_expansions |= expn.has_expansions();
26-
// TO DO: make this more efficient -- replace with a dummy node instead of erasing
27-
ip_->children.erase(begin() + i);
28-
insert(begin() + i, expn.begin(), expn.end());
29-
// skip over what we just spliced in
30-
i += expn.size() - 1;
19+
switch (at(i).type())
20+
{
21+
case expansion:
22+
case block:
23+
case for_through_directive:
24+
case for_to_directive:
25+
case each_directive:
26+
case while_directive: {
27+
Node expn(at(i));
28+
if (expn.has_expansions()) expn.flatten();
29+
ip_->has_statements |= expn.has_statements();
30+
ip_->has_blocks |= expn.has_blocks();
31+
ip_->has_expansions |= expn.has_expansions();
32+
// TO DO: make this more efficient -- replace with a dummy node instead of erasing
33+
ip_->children.erase(begin() + i);
34+
insert(begin() + i, expn.begin(), expn.end());
35+
// skip over what we just spliced in
36+
i += expn.size() - 1;
37+
} break;
38+
39+
default: {
40+
} break;
3141
}
3242
}
3343
}

prelexer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ namespace Sass {
152152
const char* each_directive(const char* src) {
153153
return exactly<each_kwd>(src);
154154
}
155+
extern const char in_kwd[] = "in";
156+
const char* in(const char* src) {
157+
return exactly<in_kwd>(src);
158+
}
159+
155160
extern const char while_kwd[] = "@while";
156161
const char* while_directive(const char* src) {
157162
return exactly<while_kwd>(src);
@@ -214,7 +219,7 @@ namespace Sass {
214219
extern const char px_kwd[] = "px";
215220
extern const char cm_kwd[] = "cm";
216221
extern const char mm_kwd[] = "mm";
217-
extern const char in_kwd[] = "in";
222+
// extern const char in_kwd[] = "in";
218223
extern const char pt_kwd[] = "pt";
219224
extern const char pc_kwd[] = "pc";
220225
extern const char deg_kwd[] = "deg";

prelexer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ namespace Sass {
322322
const char* through(const char* src);
323323

324324
const char* each_directive(const char* src);
325+
const char* in(const char* src);
325326

326327
const char* while_directive(const char* src);
327328

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy