diff --git a/src/ast.cpp b/src/ast.cpp index 5de223a23e..e05322ed5b 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -2226,4 +2226,20 @@ namespace Sass { } } + ////////////////////////////////////////////////////////////////////////////////////////// + // Convert map to (key, value) list. + ////////////////////////////////////////////////////////////////////////////////////////// + List* Map::to_list(Context& ctx, ParserState& pstate) { + List* ret = SASS_MEMORY_NEW(ctx.mem, List, pstate, length(), SASS_COMMA); + + for (auto key : keys()) { + List* l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 2); + *l << key; + *l << at(key); + *ret << l; + } + + return ret; + } + } diff --git a/src/ast.hpp b/src/ast.hpp index ed177cf2d7..0fdb927026 100644 --- a/src/ast.hpp +++ b/src/ast.hpp @@ -924,6 +924,7 @@ namespace Sass { std::string type() { return "map"; } static std::string type_name() { return "map"; } bool is_invisible() const { return empty(); } + List* to_list(Context& ctx, ParserState& pstate); virtual size_t hash() { diff --git a/src/functions.cpp b/src/functions.cpp index 45f20ce5f7..549ceb03a2 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -1291,6 +1291,7 @@ namespace Sass { Signature set_nth_sig = "set-nth($list, $n, $value)"; BUILT_IN(set_nth) { + Map* m = dynamic_cast(env["$list"]); List* l = dynamic_cast(env["$list"]); Number* n = ARG("$n", Number); Expression* v = ARG("$value", Expression); @@ -1298,6 +1299,9 @@ namespace Sass { l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); *l << ARG("$list", Expression); } + if (m) { + l = m->to_list(ctx, pstate); + } if (l->empty()) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate); double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1); if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate); @@ -1311,12 +1315,16 @@ namespace Sass { Signature index_sig = "index($list, $value)"; BUILT_IN(index) { + Map* m = dynamic_cast(env["$list"]); List* l = dynamic_cast(env["$list"]); Expression* v = ARG("$value", Expression); if (!l) { l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); *l << ARG("$list", Expression); } + if (m) { + l = m->to_list(ctx, pstate); + } for (size_t i = 0, L = l->length(); i < L; ++i) { if (Eval::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(ctx.mem, Number, pstate, (double)(i+1)); } @@ -1326,6 +1334,8 @@ namespace Sass { Signature join_sig = "join($list1, $list2, $separator: auto)"; BUILT_IN(join) { + Map* m1 = dynamic_cast(env["$list1"]); + Map* m2 = dynamic_cast(env["$list2"]); List* l1 = dynamic_cast(env["$list1"]); List* l2 = dynamic_cast(env["$list2"]); String_Constant* sep = ARG("$separator", String_Constant); @@ -1339,6 +1349,13 @@ namespace Sass { l2 = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); *l2 << ARG("$list2", Expression); } + if (m1) { + l1 = m1->to_list(ctx, pstate); + sep_val = SASS_COMMA; + } + if (m2) { + l2 = m2->to_list(ctx, pstate); + } size_t len = l1->length() + l2->length(); std::string sep_str = unquote(sep->value()); if (sep_str == "space") sep_val = SASS_SPACE; @@ -1353,6 +1370,7 @@ namespace Sass { Signature append_sig = "append($list, $val, $separator: auto)"; BUILT_IN(append) { + Map* m = dynamic_cast(env["$list"]); List* l = dynamic_cast(env["$list"]); Expression* v = ARG("$val", Expression); if (CommaSequence_Selector* sl = dynamic_cast(env["$list"])) { @@ -1364,6 +1382,9 @@ namespace Sass { l = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); *l << ARG("$list", Expression); } + if (m) { + l = m->to_list(ctx, pstate); + } List* result = SASS_MEMORY_NEW(ctx.mem, List, pstate, l->length() + 1, l->separator()); std::string sep_str(unquote(sep->value())); if (sep_str == "space") result->separator(SASS_SPACE); @@ -1393,9 +1414,14 @@ namespace Sass { size_t shortest = 0; for (size_t i = 0, L = arglist->length(); i < L; ++i) { List* ith = dynamic_cast(arglist->value_at_index(i)); + Map* mith = dynamic_cast(arglist->value_at_index(i)); if (!ith) { - ith = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); - *ith << arglist->value_at_index(i); + if (mith) { + ith = mith->to_list(ctx, pstate); + } else { + ith = SASS_MEMORY_NEW(ctx.mem, List, pstate, 1); + *ith << arglist->value_at_index(i); + } if (arglist->is_arglist()) { ((Argument*)(*arglist)[i])->value(ith); } else {