1 | #include "operators.hpp" |
2 | #include "fn_utils.hpp" |
3 | #include "fn_maps.hpp" |
4 | |
5 | namespace Sass { |
6 | |
7 | namespace Functions { |
8 | |
9 | ///////////////// |
10 | // MAP FUNCTIONS |
11 | ///////////////// |
12 | |
13 | Signature map_get_sig = "map-get($map, $key)" ; |
14 | BUILT_IN(map_get) |
15 | { |
16 | // leaks for "map-get((), foo)" if not Obj |
17 | // investigate why this is (unexpected) |
18 | Map_Obj m = ARGM("$map" , Map); |
19 | ExpressionObj v = ARG("$key" , Expression); |
20 | try { |
21 | ValueObj val = m->at(k: v); |
22 | if (!val) return SASS_MEMORY_NEW(Null, pstate); |
23 | val->set_delayed(false); |
24 | return val.detach(); |
25 | } catch (const std::out_of_range&) { |
26 | return SASS_MEMORY_NEW(Null, pstate); |
27 | } |
28 | catch (...) { throw; } |
29 | } |
30 | |
31 | Signature map_has_key_sig = "map-has-key($map, $key)" ; |
32 | BUILT_IN(map_has_key) |
33 | { |
34 | Map_Obj m = ARGM("$map" , Map); |
35 | ExpressionObj v = ARG("$key" , Expression); |
36 | return SASS_MEMORY_NEW(Boolean, pstate, m->has(v)); |
37 | } |
38 | |
39 | Signature map_keys_sig = "map-keys($map)" ; |
40 | BUILT_IN(map_keys) |
41 | { |
42 | Map_Obj m = ARGM("$map" , Map); |
43 | List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); |
44 | for ( auto key : m->keys()) { |
45 | result->append(element: key); |
46 | } |
47 | return result; |
48 | } |
49 | |
50 | Signature map_values_sig = "map-values($map)" ; |
51 | BUILT_IN(map_values) |
52 | { |
53 | Map_Obj m = ARGM("$map" , Map); |
54 | List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); |
55 | for ( auto key : m->keys()) { |
56 | result->append(element: m->at(k: key)); |
57 | } |
58 | return result; |
59 | } |
60 | |
61 | Signature map_merge_sig = "map-merge($map1, $map2)" ; |
62 | BUILT_IN(map_merge) |
63 | { |
64 | Map_Obj m1 = ARGM("$map1" , Map); |
65 | Map_Obj m2 = ARGM("$map2" , Map); |
66 | |
67 | size_t len = m1->length() + m2->length(); |
68 | Map* result = SASS_MEMORY_NEW(Map, pstate, len); |
69 | // concat not implemented for maps |
70 | *result += m1; |
71 | *result += m2; |
72 | return result; |
73 | } |
74 | |
75 | Signature map_remove_sig = "map-remove($map, $keys...)" ; |
76 | BUILT_IN(map_remove) |
77 | { |
78 | bool remove; |
79 | Map_Obj m = ARGM("$map" , Map); |
80 | List_Obj arglist = ARG("$keys" , List); |
81 | Map* result = SASS_MEMORY_NEW(Map, pstate, 1); |
82 | for (auto key : m->keys()) { |
83 | remove = false; |
84 | for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) { |
85 | remove = Operators::eq(key, arglist->value_at_index(i: j)); |
86 | } |
87 | if (!remove) *result << std::make_pair(x&: key, y: m->at(k: key)); |
88 | } |
89 | return result; |
90 | } |
91 | |
92 | } |
93 | |
94 | } |