Skip to content

Commit c1b3676

Browse files
committed
Move misc functions to own compile unit
- clean up definitions of function macros
1 parent 47354ad commit c1b3676

13 files changed

+313
-292
lines changed

Makefile.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SOURCES = \
1111
context.cpp \
1212
constants.cpp \
1313
fn_utils.cpp \
14+
fn_miscs.cpp \
1415
fn_maps.cpp \
1516
fn_lists.cpp \
1617
fn_colors.cpp \

src/context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "prelexer.hpp"
3131
#include "emitter.hpp"
3232
#include "fn_utils.hpp"
33+
#include "fn_miscs.hpp"
3334
#include "fn_maps.hpp"
3435
#include "fn_lists.hpp"
3536
#include "fn_colors.hpp"

src/error_handling.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string>
55
#include <sstream>
66
#include <stdexcept>
7+
#include "units.hpp"
78
#include "position.hpp"
89
#include "backtrace.hpp"
910
#include "ast_fwd_decl.hpp"

src/file.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "prelexer.hpp"
2222
#include "utf8_string.hpp"
2323
#include "sass_functions.hpp"
24+
#include "error_handling.hpp"
2425
#include "sass2scss.h"
2526

2627
#ifdef _WIN32

src/fn_miscs.cpp

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
#include "ast.hpp"
2+
#include "expand.hpp"
3+
#include "fn_utils.hpp"
4+
#include "fn_miscs.hpp"
5+
#include "debugger.hpp"
6+
7+
namespace Sass {
8+
9+
namespace Functions {
10+
11+
// features
12+
static std::set<std::string> features {
13+
"global-variable-shadowing",
14+
"extend-selector-pseudoclass",
15+
"at-error",
16+
"units-level-3",
17+
"custom-property"
18+
};
19+
20+
//////////////////////////
21+
// INTROSPECTION FUNCTIONS
22+
//////////////////////////
23+
24+
Signature type_of_sig = "type-of($value)";
25+
BUILT_IN(type_of)
26+
{
27+
Expression_Ptr v = ARG("$value", Expression);
28+
return SASS_MEMORY_NEW(String_Quoted, pstate, v->type());
29+
}
30+
31+
Signature variable_exists_sig = "variable-exists($name)";
32+
BUILT_IN(variable_exists)
33+
{
34+
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
35+
36+
if(d_env.has("$"+s)) {
37+
return SASS_MEMORY_NEW(Boolean, pstate, true);
38+
}
39+
else {
40+
return SASS_MEMORY_NEW(Boolean, pstate, false);
41+
}
42+
}
43+
44+
Signature global_variable_exists_sig = "global-variable-exists($name)";
45+
BUILT_IN(global_variable_exists)
46+
{
47+
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
48+
49+
if(d_env.has_global("$"+s)) {
50+
return SASS_MEMORY_NEW(Boolean, pstate, true);
51+
}
52+
else {
53+
return SASS_MEMORY_NEW(Boolean, pstate, false);
54+
}
55+
}
56+
57+
Signature function_exists_sig = "function-exists($name)";
58+
BUILT_IN(function_exists)
59+
{
60+
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]);
61+
if (!ss) {
62+
error("$name: " + (env["$name"]->to_string()) + " is not a string for `function-exists'", pstate, traces);
63+
}
64+
65+
std::string name = Util::normalize_underscores(unquote(ss->value()));
66+
67+
if(d_env.has_global(name+"[f]")) {
68+
return SASS_MEMORY_NEW(Boolean, pstate, true);
69+
}
70+
else {
71+
return SASS_MEMORY_NEW(Boolean, pstate, false);
72+
}
73+
}
74+
75+
Signature mixin_exists_sig = "mixin-exists($name)";
76+
BUILT_IN(mixin_exists)
77+
{
78+
std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value()));
79+
80+
if(d_env.has_global(s+"[m]")) {
81+
return SASS_MEMORY_NEW(Boolean, pstate, true);
82+
}
83+
else {
84+
return SASS_MEMORY_NEW(Boolean, pstate, false);
85+
}
86+
}
87+
88+
Signature feature_exists_sig = "feature-exists($name)";
89+
BUILT_IN(feature_exists)
90+
{
91+
std::string s = unquote(ARG("$name", String_Constant)->value());
92+
93+
if(features.find(s) == features.end()) {
94+
return SASS_MEMORY_NEW(Boolean, pstate, false);
95+
}
96+
else {
97+
return SASS_MEMORY_NEW(Boolean, pstate, true);
98+
}
99+
}
100+
101+
Signature call_sig = "call($name, $args...)";
102+
BUILT_IN(call)
103+
{
104+
std::string name;
105+
Function_Ptr ff = Cast<Function>(env["$name"]);
106+
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]);
107+
108+
if (ss) {
109+
name = Util::normalize_underscores(unquote(ss->value()));
110+
std::cerr << "DEPRECATION WARNING: ";
111+
std::cerr << "Passing a string to call() is deprecated and will be illegal" << std::endl;
112+
std::cerr << "in Sass 4.0. Use call(get-function(" + quote(name) + ")) instead." << std::endl;
113+
std::cerr << std::endl;
114+
} else if (ff) {
115+
name = ff->name();
116+
}
117+
118+
List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List));
119+
120+
Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
121+
// std::string full_name(name + "[f]");
122+
// Definition_Ptr def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0;
123+
// Parameters_Ptr params = def ? def->parameters() : 0;
124+
// size_t param_size = params ? params->length() : 0;
125+
for (size_t i = 0, L = arglist->length(); i < L; ++i) {
126+
Expression_Obj expr = arglist->value_at_index(i);
127+
// if (params && params->has_rest_parameter()) {
128+
// Parameter_Obj p = param_size > i ? (*params)[i] : 0;
129+
// List_Ptr list = Cast<List>(expr);
130+
// if (list && p && !p->is_rest_parameter()) expr = (*list)[0];
131+
// }
132+
if (arglist->is_arglist()) {
133+
Expression_Obj obj = arglist->at(i);
134+
Argument_Obj arg = (Argument_Ptr) obj.ptr(); // XXX
135+
args->append(SASS_MEMORY_NEW(Argument,
136+
pstate,
137+
expr,
138+
arg ? arg->name() : "",
139+
arg ? arg->is_rest_argument() : false,
140+
arg ? arg->is_keyword_argument() : false));
141+
} else {
142+
args->append(SASS_MEMORY_NEW(Argument, pstate, expr));
143+
}
144+
}
145+
Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, name, args);
146+
Expand expand(ctx, &d_env, &selector_stack);
147+
func->via_call(true); // calc invoke is allowed
148+
if (ff) func->func(ff);
149+
return func->perform(&expand.eval);
150+
}
151+
152+
////////////////////
153+
// BOOLEAN FUNCTIONS
154+
////////////////////
155+
156+
Signature not_sig = "not($value)";
157+
BUILT_IN(sass_not)
158+
{
159+
return SASS_MEMORY_NEW(Boolean, pstate, ARG("$value", Expression)->is_false());
160+
}
161+
162+
Signature if_sig = "if($condition, $if-true, $if-false)";
163+
// BUILT_IN(sass_if)
164+
// { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); }
165+
BUILT_IN(sass_if)
166+
{
167+
Expand expand(ctx, &d_env, &selector_stack);
168+
Expression_Obj cond = ARG("$condition", Expression)->perform(&expand.eval);
169+
bool is_true = !cond->is_false();
170+
Expression_Obj res = ARG(is_true ? "$if-true" : "$if-false", Expression);
171+
Value_Obj qwe = Cast<Value>(res->perform(&expand.eval));
172+
// if (qwe == 0) debug_ast(res);
173+
// res = res->perform(&expand.eval.val_eval);
174+
qwe->set_delayed(false); // clone?
175+
return qwe.detach();
176+
}
177+
178+
//////////////////////////
179+
// MISCELLANEOUS FUNCTIONS
180+
//////////////////////////
181+
182+
// value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String)
183+
// unquoted_string(value.to_sass)
184+
185+
Signature inspect_sig = "inspect($value)";
186+
BUILT_IN(inspect)
187+
{
188+
Expression_Ptr v = ARG("$value", Expression);
189+
if (v->concrete_type() == Expression::NULL_VAL) {
190+
return SASS_MEMORY_NEW(String_Quoted, pstate, "null");
191+
} else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) {
192+
return SASS_MEMORY_NEW(String_Quoted, pstate, "false");
193+
} else if (v->concrete_type() == Expression::STRING) {
194+
return Cast<String>(v);
195+
} else {
196+
// ToDo: fix to_sass for nested parentheses
197+
Sass_Output_Style old_style;
198+
old_style = ctx.c_options.output_style;
199+
ctx.c_options.output_style = TO_SASS;
200+
Emitter emitter(ctx.c_options);
201+
Inspect i(emitter);
202+
i.in_declaration = false;
203+
v->perform(&i);
204+
ctx.c_options.output_style = old_style;
205+
return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer());
206+
}
207+
// return v;
208+
}
209+
210+
Signature content_exists_sig = "content-exists()";
211+
BUILT_IN(content_exists)
212+
{
213+
if (!d_env.has_global("is_in_mixin")) {
214+
error("Cannot call content-exists() except within a mixin.", pstate, traces);
215+
}
216+
return SASS_MEMORY_NEW(Boolean, pstate, d_env.has_lexical("@content[m]"));
217+
}
218+
219+
Signature get_function_sig = "get-function($name, $css: false)";
220+
BUILT_IN(get_function)
221+
{
222+
String_Constant_Ptr ss = Cast<String_Constant>(env["$name"]);
223+
if (!ss) {
224+
error("$name: " + (env["$name"]->to_string()) + " is not a string for `get-function'", pstate, traces);
225+
}
226+
227+
std::string name = Util::normalize_underscores(unquote(ss->value()));
228+
std::string full_name = name + "[f]";
229+
230+
Boolean_Obj css = ARG("$css", Boolean);
231+
if (!css->is_false()) {
232+
Definition_Ptr def = SASS_MEMORY_NEW(Definition,
233+
pstate,
234+
name,
235+
SASS_MEMORY_NEW(Parameters, pstate),
236+
SASS_MEMORY_NEW(Block, pstate, 0, false),
237+
Definition::FUNCTION);
238+
return SASS_MEMORY_NEW(Function, pstate, def, true);
239+
}
240+
241+
242+
if (!d_env.has_global(full_name)) {
243+
error("Function not found: " + name, pstate, traces);
244+
}
245+
246+
Definition_Ptr def = Cast<Definition>(d_env[full_name]);
247+
return SASS_MEMORY_NEW(Function, pstate, def, false);
248+
}
249+
250+
}
251+
252+
}

src/fn_miscs.hpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef SASS_FN_MISCS_H
2+
#define SASS_FN_MISCS_H
3+
4+
#include "fn_utils.hpp"
5+
6+
namespace Sass {
7+
8+
namespace Functions {
9+
10+
extern Signature type_of_sig;
11+
extern Signature variable_exists_sig;
12+
extern Signature global_variable_exists_sig;
13+
extern Signature function_exists_sig;
14+
extern Signature mixin_exists_sig;
15+
extern Signature feature_exists_sig;
16+
extern Signature call_sig;
17+
extern Signature not_sig;
18+
extern Signature if_sig;
19+
extern Signature set_nth_sig;
20+
extern Signature content_exists_sig;
21+
extern Signature get_function_sig;
22+
23+
BUILT_IN(type_of);
24+
BUILT_IN(variable_exists);
25+
BUILT_IN(global_variable_exists);
26+
BUILT_IN(function_exists);
27+
BUILT_IN(mixin_exists);
28+
BUILT_IN(feature_exists);
29+
BUILT_IN(call);
30+
BUILT_IN(sass_not);
31+
BUILT_IN(sass_if);
32+
BUILT_IN(set_nth);
33+
BUILT_IN(content_exists);
34+
BUILT_IN(get_function);
35+
36+
}
37+
38+
}
39+
40+
#endif

src/fn_utils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ namespace Sass {
4545

4646
namespace Functions {
4747

48+
std::string function_name(Signature sig)
49+
{
50+
std::string str(sig);
51+
return str.substr(0, str.find('('));
52+
}
53+
4854
Map_Ptr get_arg_m(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
4955
{
5056
// Minimal error handling -- the expectation is that built-ins will be written correctly!

src/fn_utils.hpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,10 @@ namespace Sass {
1212
name(Env& env, Env& d_env, Context& ctx, Signature sig, ParserState pstate, Backtraces traces, std::vector<Selector_List_Obj> selector_stack)
1313

1414
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, traces)
15-
#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig, pstate, traces)
1615

1716
// special function for weird hsla percent (10px == 10% == 10 != 0.1)
1817
#define ARGVAL(argname) get_arg_val(argname, env, sig, pstate, traces) // double
1918

20-
// macros for common ranges (u mean unsigned or upper, r for full range)
21-
#define DARG_U_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 1.0) // double
22-
#define DARG_R_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 1.0, 1.0) // double
23-
#define DARG_U_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 255.0) // double
24-
#define DARG_R_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 255.0, 255.0) // double
25-
#define DARG_U_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 100.0) // double
26-
#define DARG_R_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 100.0, 100.0) // double
27-
28-
// macros for color related inputs (rbg and alpha/opacity values)
29-
#define COLOR_NUM(argname) color_num(argname, env, sig, pstate, traces) // double
30-
#define ALPHA_NUM(argname) alpha_num(argname, env, sig, pstate, traces) // double
31-
3219
typedef const char* Signature;
3320

3421
typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtraces, SelectorStack);

0 commit comments

Comments
 (0)