Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit d3795e6

Browse files
author
Aaron Leung
committed
Cleaning up the list type tags and checks.
1 parent 068904a commit d3795e6

File tree

6 files changed

+75
-122
lines changed

6 files changed

+75
-122
lines changed

document_parser.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,12 +664,13 @@ namespace Sass {
664664
peek< exactly<'}'> >(position) ||
665665
peek< exactly<'{'> >(position) ||
666666
peek< exactly<')'> >(position))
667-
{ return context.new_Node(Node::nil, path, line, 0); }
667+
{ return context.new_Node(Node::list, path, line, 0); }
668668
Node list1(parse_space_list());
669669
// if it's a singleton, return it directly; don't wrap it
670670
if (!peek< exactly<','> >(position)) return list1;
671671

672-
Node comma_list(context.new_Node(Node::comma_list, path, line, 2));
672+
Node comma_list(context.new_Node(Node::list, path, line, 2));
673+
comma_list.is_comma_separated() = true;
673674
comma_list << list1;
674675
comma_list.should_eval() |= list1.should_eval();
675676

@@ -695,7 +696,7 @@ namespace Sass {
695696
peek< default_flag >(position))
696697
{ return disj1; }
697698

698-
Node space_list(context.new_Node(Node::space_list, path, line, 2));
699+
Node space_list(context.new_Node(Node::list, path, line, 2));
699700
space_list << disj1;
700701
space_list.should_eval() |= disj1.should_eval();
701702

@@ -833,7 +834,7 @@ namespace Sass {
833834
if (lex< exactly<'('> >()) {
834835
Node value(parse_comma_list());
835836
value.should_eval() = true;
836-
if (value.type() == Node::comma_list || value.type() == Node::space_list) {
837+
if (value.type() == Node::list && value.size() > 0) {
837838
value[0].should_eval() = true;
838839
}
839840
if (!lex< exactly<')'> >()) throw_syntax_error("unclosed parenthesis");

eval_apply.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ namespace Sass {
138138

139139
case Node::assignment: {
140140
Node val(expr[1]);
141-
if (val.type() == Node::comma_list || val.type() == Node::space_list) {
141+
if (val.type() == Node::list) {
142142
for (size_t i = 0, S = val.size(); i < S; ++i) {
143143
if (val[i].should_eval()) val[i] = eval(val[i], prefix, env, f_env, new_Node, ctx);
144144
}
@@ -163,7 +163,7 @@ namespace Sass {
163163
Node lhs(expr[0]);
164164
if (lhs.should_eval()) eval(lhs, prefix, env, f_env, new_Node, ctx);
165165
Node rhs(expr[1]);
166-
if (rhs.type() == Node::comma_list || rhs.type() == Node::space_list) {
166+
if (rhs.type() == Node::list) {
167167
for (size_t i = 0, S = rhs.size(); i < S; ++i) {
168168
if (rhs[i].should_eval()) rhs[i] = eval(rhs[i], prefix, env, f_env, new_Node, ctx);
169169
}
@@ -177,8 +177,7 @@ namespace Sass {
177177
return expr;
178178
} break;
179179

180-
case Node::comma_list:
181-
case Node::space_list: {
180+
case Node::list: {
182181
if (expr.should_eval()) expr[0] = eval(expr[0], prefix, env, f_env, new_Node, ctx);
183182
return expr;
184183
} break;
@@ -426,8 +425,8 @@ namespace Sass {
426425
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(each_kwd)) << (fake_param << expr[0]) << expr[2];
427426
Node list(eval(expr[1], prefix, env, f_env, new_Node, ctx));
428427
// If the list isn't really a list, make a singleton out of it.
429-
if (list.type() != Node::space_list && list.type() != Node::comma_list) {
430-
list = (new_Node(Node::space_list, list.path(), list.line(), 1) << list);
428+
if (list.type() != Node::list) {
429+
list = (new_Node(Node::list, list.path(), list.line(), 1) << list);
431430
}
432431
expr.pop_back();
433432
expr.pop_back();
@@ -770,7 +769,7 @@ namespace Sass {
770769
{
771770
case Node::assignment: {
772771
Node val(new_Node(stm[1])); // clone the value because it might get mutated in place
773-
if (val.type() == Node::comma_list || val.type() == Node::space_list) {
772+
if (val.type() == Node::list) {
774773
for (size_t i = 0, S = val.size(); i < S; ++i) {
775774
if (val[i].should_eval()) val[i] = eval(val[i], Node(), bindings, ctx.function_env, new_Node, ctx);
776775
}
@@ -835,8 +834,8 @@ namespace Sass {
835834
case Node::each_directive: {
836835
Node iter_var(stm[0]);
837836
Node list(eval(new_Node(stm[1]), Node(), bindings, ctx.function_env, new_Node, ctx));
838-
if (list.type() != Node::comma_list && list.type() != Node::space_list) {
839-
list = (new_Node(Node::space_list, list.path(), list.line(), 1) << list);
837+
if (list.type() != Node::list) {
838+
list = (new_Node(Node::list, list.path(), list.line(), 1) << list);
840839
}
841840
Node each_body(stm[2]);
842841
Environment each_env; // re-use this env for each iteration
@@ -887,8 +886,8 @@ namespace Sass {
887886
} break;
888887

889888
case Node::return_directive: {
890-
Node retval(eval(stm[0], Node(), bindings, ctx.function_env, new_Node, ctx));
891-
if (retval.type() == Node::comma_list || retval.type() == Node::space_list) {
889+
Node retval(eval(new_Node(stm[0]), Node(), bindings, ctx.function_env, new_Node, ctx));
890+
if (retval.type() == Node::list) {
892891
for (size_t i = 0, S = retval.size(); i < S; ++i) {
893892
retval[i] = eval(retval[i], Node(), bindings, ctx.function_env, new_Node, ctx);
894893
}

functions.cpp

Lines changed: 48 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ namespace Sass {
9292
return color_name;
9393
} break;
9494

95-
case Node::space_list:
96-
case Node::comma_list: {
95+
case Node::list: {
9796
return list_name;
9897
} break;
9998

@@ -134,10 +133,6 @@ namespace Sass {
134133
} break;
135134
} break;
136135

137-
case Node::list: {
138-
if (arg_type == Node::space_list || arg_type == Node::comma_list) return the_arg;
139-
} break;
140-
141136
default: {
142137
if (arg_type == param_type) return the_arg;
143138
} break;
@@ -898,35 +893,18 @@ namespace Sass {
898893
extern Signature length_sig = "length($list)";
899894
Node length(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
900895
Node arg(bindings[parameter_names[0].token()]);
901-
switch (arg.type())
902-
{
903-
case Node::space_list:
904-
case Node::comma_list: {
905-
return new_Node(path, line, arg.size());
906-
} break;
907-
908-
case Node::nil: {
909-
return new_Node(path, line, 0);
910-
} break;
911-
912-
default: {
913-
// single objects should be reported as lists of length 1
914-
return new_Node(path, line, 1);
915-
} break;
916-
}
917-
// unreachable statement
918-
return Node();
896+
return new_Node(path, line, arg.type() == Node::list ? arg.size() : 1);
919897
}
920898

921899
extern Signature nth_sig = "nth($list, $n)";
922900
Node nth(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
923901
Node l(bindings[parameter_names[0].token()]);
924-
if (l.type() == Node::nil) {
925-
throw_eval_error("cannot index into an empty list", path, line);
926-
}
927902
// wrap the first arg if it isn't a list
928-
if (l.type() != Node::space_list && l.type() != Node::comma_list) {
929-
l = new_Node(Node::space_list, path, line, 1) << l;
903+
if (l.type() != Node::list) {
904+
l = new_Node(Node::list, path, line, 1) << l;
905+
}
906+
if (l.size() == 0) {
907+
throw_eval_error("cannot index into an empty list", path, line);
930908
}
931909
// just truncate the index if it's not an integer ... more permissive than Ruby Sass
932910
size_t n = std::floor(arg(nth_sig, path, line, parameter_names, bindings, 1, Node::numeric, 1, l.size()).numeric_value());
@@ -938,12 +916,7 @@ namespace Sass {
938916
Node lst(bindings[parameter_names[0].token()]);
939917
Node val(bindings[parameter_names[1].token()]);
940918
// if $list isn't a list, wrap it in a singleton list
941-
Node::Type lst_type = lst.type();
942-
if (lst_type != Node::space_list && lst_type != Node::comma_list && lst_type != Node::nil) {
943-
lst = (new_Node(Node::space_list, path, line, 1) << lst);
944-
}
945-
946-
if (lst_type == Node::nil) return new_Node(Node::boolean, path, line, false);
919+
if (lst.type() != Node::list) lst = (new_Node(Node::list, path, line, 1) << lst);
947920

948921
for (size_t i = 0, S = lst.size(); i < S; ++i) {
949922
if (lst[i] == val) return new_Node(path, line, i + 1);
@@ -956,94 +929,84 @@ namespace Sass {
956929
Node join(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
957930
// if the args aren't lists, turn them into singleton lists
958931
Node l1(bindings[parameter_names[0].token()]);
959-
if (l1.type() != Node::space_list && l1.type() != Node::comma_list && l1.type() != Node::nil) {
960-
l1 = new_Node(Node::space_list, path, line, 1) << l1;
932+
if (l1.type() != Node::list) {
933+
l1 = (new_Node(Node::list, path, line, 1) << l1);
961934
}
962935
Node l2(bindings[parameter_names[1].token()]);
963-
if (l2.type() != Node::space_list && l2.type() != Node::comma_list && l2.type() != Node::nil) {
964-
l2 = new_Node(Node::space_list, l2.path(), l2.line(), 1) << l2;
965-
}
966-
// nil + nil = nil
967-
if (l1.type() == Node::nil && l2.type() == Node::nil) {
968-
return new_Node(Node::nil, path, line, 0);
936+
if (l2.type() != Node::list) {
937+
l2 = (new_Node(Node::list, path, line, 1) << l2);
969938
}
970939
// figure out the combined size in advance
971-
size_t size = 0;
972-
if (l1.type() != Node::nil) size += l1.size();
973-
if (l2.type() != Node::nil) size += l2.size();
940+
size_t size = l1.size() + l2.size();
974941

975942
// figure out the result type in advance
976-
Node::Type rtype = Node::space_list;
943+
bool comma_sep;
977944
string sep(bindings[parameter_names[2].token()].token().unquote());
978-
if (sep == "comma") rtype = Node::comma_list;
979-
else if (sep == "space") rtype = Node::space_list;
980-
else if (sep == "auto") rtype = l1.type();
981-
else {
982-
throw_eval_error("third argument to 'join' must be 'space', 'comma', or 'auto'", path, line);
983-
}
984-
if (rtype == Node::nil) rtype = l2.type();
945+
946+
if (sep == "comma") comma_sep = true;
947+
else if (sep == "space") comma_sep = false;
948+
else if (sep == "auto") comma_sep = l1.is_comma_separated();
949+
else throw_eval_error("third argument to 'join' must be 'space', 'comma', or 'auto'", path, line);
950+
951+
if (l1.size() == 0) comma_sep = l2.is_comma_separated();
985952

986953
// accumulate the result
987-
Node lr(new_Node(rtype, path, line, size));
988-
if (l1.type() != Node::nil) lr += l1;
989-
if (l2.type() != Node::nil) lr += l2;
954+
Node lr(new_Node(Node::list, path, line, size));
955+
lr += l1;
956+
lr += l2;
957+
lr.is_comma_separated() = comma_sep;
990958
return lr;
991959
}
992960

993961
extern Signature append_sig = "append($list1, $list2, $separator: auto)";
994962
Node append(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
995963
Node list(bindings[parameter_names[0].token()]);
996-
switch (list.type())
997-
{
998-
case Node::space_list:
999-
case Node::comma_list:
1000-
case Node::nil: {
1001-
// do nothing
1002-
} break;
1003-
// if the first arg isn't a list, wrap it in a singleton
1004-
default: {
1005-
list = (new_Node(Node::space_list, path, line, 1) << list);
1006-
} break;
1007-
}
1008964

1009-
Node::Type sep_type;
1010-
string sep_string = bindings[parameter_names[2].token()].token().unquote();
1011-
if (sep_string == "comma") sep_type = Node::comma_list;
1012-
else if (sep_string == "space") sep_type = Node::space_list;
1013-
else if (sep_string == "auto") sep_type = list.type();
1014-
else throw_eval_error("third argument to 'append' must be 'space', 'comma', or 'auto'", path, line);
965+
// if the first arg isn't a list, wrap it in a singleton
966+
if (list.type() != Node::list) list = (new_Node(Node::list, path, line, 1) << list);
967+
968+
bool comma_sep;
969+
string sep(bindings[parameter_names[2].token()].token().unquote());
970+
971+
if (sep == "comma") comma_sep = true;
972+
else if (sep == "space") comma_sep = false;
973+
else if (sep == "auto") comma_sep = list.is_comma_separated();
974+
else throw_eval_error("third argument to 'append' must be 'space', 'comma', or 'auto'", path, line);
1015975

1016-
Node new_list(new_Node(sep_type, path, line, list.size() + 1));
976+
Node new_list(new_Node(Node::list, path, line, list.size() + 1));
1017977
new_list += list;
1018978
new_list << bindings[parameter_names[1].token()];
979+
new_list.is_comma_separated() = comma_sep;
1019980
return new_list;
1020981
}
1021982

1022983
extern Signature compact_1_sig = "compact($arg1)";
1023984
Node compact_1(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
1024985
Node the_arg(bindings[parameter_names[0].token()]);
1025986

1026-
if (the_arg.type() == Node::comma_list || the_arg.type() == Node::space_list) {
1027-
Node non_nils(new_Node(the_arg.type(), path, line, 0));
987+
if (the_arg.type() == Node::list) {
988+
Node non_nils(new_Node(Node::list, path, line, 0));
1028989
for (size_t i = 0, S = the_arg.size(); i < S; ++i) {
1029990
Node elt(the_arg[i]);
1030-
if (!elt.is_false()) non_nils << new_Node(path, line, elt);
991+
if (!elt.is_false()) non_nils << elt;
1031992
}
1032-
return non_nils.size() > 0 ? non_nils : new_Node(Node::nil, path, line, 0);
993+
return non_nils;
1033994
}
1034995

1035-
return new_Node(path, line, the_arg);
996+
return new_Node(Node::list, path, line, 1) << the_arg;
1036997
}
1037998

1038999
extern Signature compact_n_sig = "compact($arg1: false, $arg2: false, $arg3: false, $arg4: false, $arg5: false, $arg6: false, $arg7: false, $arg8: false, $arg9: false, $arg10: false, $arg11: false, $arg12: false)";
10391000
Node compact_n(const Node parameter_names, Environment& bindings, Node_Factory& new_Node, string& path, size_t line) {
1040-
Node non_nils(new_Node(Node::comma_list, path, line, 0));
1001+
Node non_nils(new_Node(Node::list, path, line, 0));
1002+
non_nils.is_comma_separated() = true;
1003+
10411004
for (size_t i = 0, S = bindings.current_frame.size(); i < S; ++i) {
10421005
Node the_arg(bindings[parameter_names[i].token()]);
1043-
if (!the_arg.is_false()) non_nils << new_Node(path, line, the_arg);
1006+
if (!the_arg.is_false()) non_nils << the_arg;
10441007
}
10451008

1046-
return non_nils.size() > 0 ? non_nils : new_Node(Node::nil, path, line, 0);
1009+
return non_nils;
10471010
}
10481011

10491012
////////////////////////////////////////////////////////////////////////
@@ -1071,9 +1034,7 @@ namespace Sass {
10711034
case Node::numeric_color: {
10721035
type_name = Token::make(color_name);
10731036
} break;
1074-
case Node::comma_list:
1075-
case Node::space_list:
1076-
case Node::nil: {
1037+
case Node::list: {
10771038
type_name = Token::make(list_name);
10781039
} break;
10791040
default: {

node.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ namespace Sass {
8282

8383
switch (t)
8484
{
85-
case comma_list:
86-
case space_list:
85+
case list:
8786
case expression:
8887
case term:
8988
case numeric_color: {
9089
if (size() != rhs.size()) return false;
90+
if ((t == list) && (is_comma_separated() != rhs.is_comma_separated())) return false;
9191
for (size_t i = 0, L = size(); i < L; ++i) {
9292
if (at(i) == rhs[i]) continue;
9393
else return false;

node.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ namespace Sass {
7474
any,
7575
numeric, // number, numeric_percentage, or numeric_dimension
7676
string_t, // string_constant, identifier, concatenation, schemata
77-
list, // space_list or comma_list
7877
comment,
7978

8079
root,
@@ -104,9 +103,7 @@ namespace Sass {
104103
rule,
105104
property,
106105

107-
nil,
108-
comma_list,
109-
space_list,
106+
list,
110107

111108
disjunction,
112109
conjunction,
@@ -196,6 +193,7 @@ namespace Sass {
196193
bool is_guarded() const;
197194
bool& has_been_extended() const;
198195
bool is_false() const;
196+
bool& is_comma_separated() const;
199197

200198
string& path() const;
201199
size_t line() const;
@@ -270,6 +268,7 @@ namespace Sass {
270268
bool should_eval;
271269
bool is_quoted;
272270
bool has_been_extended;
271+
bool is_comma_separated;
273272

274273
Node_Impl()
275274
: /* value(value_t()),
@@ -285,7 +284,8 @@ namespace Sass {
285284
from_variable(false),
286285
should_eval(false),
287286
is_quoted(false),
288-
has_been_extended(false)
287+
has_been_extended(false),
288+
is_comma_separated(false)
289289
{ }
290290

291291
bool is_numeric()
@@ -446,6 +446,7 @@ namespace Sass {
446446
inline bool Node::is_guarded() const { return (type() == assignment) && (size() == 3); }
447447
inline bool& Node::has_been_extended() const { return ip_->has_been_extended; }
448448
inline bool Node::is_false() const { return (type() == boolean) && (boolean_value() == false); }
449+
inline bool& Node::is_comma_separated() const { return ip_->is_comma_separated; }
449450

450451
inline string& Node::path() const { return ip_->path; }
451452
inline size_t Node::line() const { return ip_->line; }

0 commit comments

Comments
 (0)