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

Commit d828027

Browse files
committed
Move macros and helpers to fn_utils
- Remove obsolete ctx parameter - make ARGSEL(S) macro specific
1 parent 0dad856 commit d828027

File tree

8 files changed

+228
-224
lines changed

8 files changed

+228
-224
lines changed

src/ast.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,6 @@ namespace Sass {
944944
// by a type tag.
945945
/////////////////////////////////////////////////////////////////////////////
946946
struct Backtrace;
947-
typedef const char* Signature;
948947
typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtraces, std::vector<Selector_List_Obj>);
949948
class Definition : public Has_Block {
950949
public:

src/ast_fwd_decl.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,14 @@ namespace Sass {
419419
typedef std::set<Compound_Selector_Obj, OrderNodes> CompoundSelectorSet;
420420
typedef std::unordered_set<Simple_Selector_Obj, HashNodes, CompareNodes> SimpleSelectorDict;
421421

422+
typedef std::vector<Block_Ptr> BlockStack;
423+
typedef std::vector<AST_Node_Obj> CallStack;
424+
typedef std::vector<Media_Block_Ptr> MediaStack;
425+
typedef std::vector<Selector_List_Obj> SelectorStack;
422426
typedef std::vector<Sass_Import_Entry>* ImporterStack;
423427

428+
typedef const char* Signature;
429+
424430
// only to switch implementations for testing
425431
#define environment_map std::map
426432

src/context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "sass2scss.h"
3030
#include "prelexer.hpp"
3131
#include "emitter.hpp"
32+
#include "fn_utils.hpp"
3233

3334
namespace Sass {
3435
using namespace Constants;

src/fn_utils.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,153 @@
11
#include "sass.hpp"
2+
#include "parser.hpp"
23
#include "fn_utils.hpp"
4+
#include "functions.hpp"
5+
#include "error_handling.hpp"
36

47
namespace Sass {
58

9+
Definition_Ptr make_native_function(Signature sig, Native_Function func, Context& ctx)
10+
{
11+
Parser sig_parser = Parser::from_c_str(sig, ctx, ctx.traces, ParserState("[built-in function]"));
12+
sig_parser.lex<Prelexer::identifier>();
13+
std::string name(Util::normalize_underscores(sig_parser.lexed));
14+
Parameters_Obj params = sig_parser.parse_parameters();
15+
return SASS_MEMORY_NEW(Definition,
16+
ParserState("[built-in function]"),
17+
sig,
18+
name,
19+
params,
20+
func,
21+
false);
22+
}
23+
24+
Definition_Ptr make_c_function(Sass_Function_Entry c_func, Context& ctx)
25+
{
26+
using namespace Prelexer;
27+
28+
const char* sig = sass_function_get_signature(c_func);
29+
Parser sig_parser = Parser::from_c_str(sig, ctx, ctx.traces, ParserState("[c function]"));
30+
// allow to overload generic callback plus @warn, @error and @debug with custom functions
31+
sig_parser.lex < alternatives < identifier, exactly <'*'>,
32+
exactly < Constants::warn_kwd >,
33+
exactly < Constants::error_kwd >,
34+
exactly < Constants::debug_kwd >
35+
> >();
36+
std::string name(Util::normalize_underscores(sig_parser.lexed));
37+
Parameters_Obj params = sig_parser.parse_parameters();
38+
return SASS_MEMORY_NEW(Definition,
39+
ParserState("[c function]"),
40+
sig,
41+
name,
42+
params,
43+
c_func,
44+
false, true);
45+
}
46+
647
namespace Functions {
748

49+
Map_Ptr get_arg_m(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
50+
{
51+
// Minimal error handling -- the expectation is that built-ins will be written correctly!
52+
Map_Ptr val = Cast<Map>(env[argname]);
53+
if (val) return val;
54+
55+
List_Ptr lval = Cast<List>(env[argname]);
56+
if (lval && lval->length() == 0) return SASS_MEMORY_NEW(Map, pstate, 0);
57+
58+
// fallback on get_arg for error handling
59+
val = get_arg<Map>(argname, env, sig, pstate, traces);
60+
return val;
61+
}
62+
63+
double get_arg_r(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, double lo, double hi)
64+
{
65+
// Minimal error handling -- the expectation is that built-ins will be written correctly!
66+
Number_Ptr val = get_arg<Number>(argname, env, sig, pstate, traces);
67+
Number tmpnr(val);
68+
tmpnr.reduce();
69+
double v = tmpnr.value();
70+
if (!(lo <= v && v <= hi)) {
71+
std::stringstream msg;
72+
msg << "argument `" << argname << "` of `" << sig << "` must be between ";
73+
msg << lo << " and " << hi;
74+
error(msg.str(), pstate, traces);
75+
}
76+
return v;
77+
}
78+
79+
Number_Ptr get_arg_n(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
80+
{
81+
Number_Ptr val = get_arg<Number>(argname, env, sig, pstate, traces);
82+
val = SASS_MEMORY_COPY(val);
83+
val->reduce();
84+
return val;
85+
}
86+
87+
double get_arg_val(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
88+
{
89+
Number_Ptr val = get_arg<Number>(argname, env, sig, pstate, traces);
90+
Number tmpnr(val);
91+
tmpnr.reduce();
92+
return tmpnr.value();
93+
}
94+
95+
double color_num(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
96+
{
97+
Number_Ptr val = get_arg<Number>(argname, env, sig, pstate, traces);
98+
Number tmpnr(val);
99+
tmpnr.reduce();
100+
if (tmpnr.unit() == "%") {
101+
return std::min(std::max(tmpnr.value() * 255 / 100.0, 0.0), 255.0);
102+
} else {
103+
return std::min(std::max(tmpnr.value(), 0.0), 255.0);
104+
}
105+
}
106+
107+
double alpha_num(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces) {
108+
Number_Ptr val = get_arg<Number>(argname, env, sig, pstate, traces);
109+
Number tmpnr(val);
110+
tmpnr.reduce();
111+
if (tmpnr.unit() == "%") {
112+
return std::min(std::max(tmpnr.value(), 0.0), 100.0);
113+
} else {
114+
return std::min(std::max(tmpnr.value(), 0.0), 1.0);
115+
}
116+
}
117+
118+
Selector_List_Obj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
119+
Expression_Obj exp = ARG(argname, Expression);
120+
if (exp->concrete_type() == Expression::NULL_VAL) {
121+
std::stringstream msg;
122+
msg << argname << ": null is not a valid selector: it must be a string,\n";
123+
msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
124+
error(msg.str(), pstate, traces);
125+
}
126+
if (String_Constant_Ptr str = Cast<String_Constant>(exp)) {
127+
str->quote_mark(0);
128+
}
129+
std::string exp_src = exp->to_string(ctx.c_options);
130+
return Parser::parse_selector(exp_src.c_str(), ctx, traces);
131+
}
132+
133+
Compound_Selector_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx) {
134+
Expression_Obj exp = ARG(argname, Expression);
135+
if (exp->concrete_type() == Expression::NULL_VAL) {
136+
std::stringstream msg;
137+
msg << argname << ": null is not a string for `" << function_name(sig) << "'";
138+
error(msg.str(), pstate, traces);
139+
}
140+
if (String_Constant_Ptr str = Cast<String_Constant>(exp)) {
141+
str->quote_mark(0);
142+
}
143+
std::string exp_src = exp->to_string(ctx.c_options);
144+
Selector_List_Obj sel_list = Parser::parse_selector(exp_src.c_str(), ctx, traces);
145+
if (sel_list->length() == 0) return NULL;
146+
Complex_Selector_Obj first = sel_list->first();
147+
if (!first->tail()) return first->head();
148+
return first->tail()->head();
149+
}
150+
8151
}
9152

10153
}

src/fn_utils.hpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,73 @@
11
#ifndef SASS_FN_UTILS_H
22
#define SASS_FN_UTILS_H
33

4+
#include "backtrace.hpp"
5+
#include "environment.hpp"
6+
#include "ast_fwd_decl.hpp"
7+
48
namespace Sass {
59

10+
#define BUILT_IN(name) Expression_Ptr \
11+
name(Env& env, Env& d_env, Context& ctx, Signature sig, ParserState pstate, Backtraces traces, std::vector<Selector_List_Obj> selector_stack)
12+
13+
#define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, traces)
14+
#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig, pstate, traces)
15+
16+
// return a number object (copied since we want to have reduced units)
17+
#define ARGN(argname) get_arg_n(argname, env, sig, pstate, traces) // Number copy
18+
19+
// special function for weird hsla percent (10px == 10% == 10 != 0.1)
20+
#define ARGVAL(argname) get_arg_val(argname, env, sig, pstate, traces) // double
21+
22+
// macros for common ranges (u mean unsigned or upper, r for full range)
23+
#define DARG_U_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 1.0) // double
24+
#define DARG_R_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 1.0, 1.0) // double
25+
#define DARG_U_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 255.0) // double
26+
#define DARG_R_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 255.0, 255.0) // double
27+
#define DARG_U_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 100.0) // double
28+
#define DARG_R_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 100.0, 100.0) // double
29+
30+
// macros for color related inputs (rbg and alpha/opacity values)
31+
#define COLOR_NUM(argname) color_num(argname, env, sig, pstate, traces) // double
32+
#define ALPHA_NUM(argname) alpha_num(argname, env, sig, pstate, traces) // double
33+
34+
#define ARGSEL(argname) get_arg_sel(argname, env, sig, pstate, traces, ctx)
35+
#define ARGSELS(argname) get_arg_sels(argname, env, sig, pstate, traces, ctx)
36+
37+
typedef const char* Signature;
38+
39+
typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtraces, SelectorStack);
40+
41+
Definition_Ptr make_native_function(Signature, Native_Function, Context& ctx);
42+
Definition_Ptr make_c_function(Sass_Function_Entry c_func, Context& ctx);
43+
644
namespace Functions {
745

46+
template <typename T>
47+
T* get_arg(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces)
48+
{
49+
T* val = Cast<T>(env[argname]);
50+
if (!val) {
51+
std::string msg("argument `");
52+
msg += argname;
53+
msg += "` of `";
54+
msg += sig;
55+
msg += "` must be a ";
56+
msg += T::type_name();
57+
error(msg, pstate, traces);
58+
}
59+
return val;
60+
}
61+
62+
Map_Ptr get_arg_m(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // maps only
63+
Number_Ptr get_arg_n(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // numbers only
64+
double alpha_num(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // colors only
65+
double color_num(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // colors only
66+
double get_arg_r(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, double lo, double hi); // colors only
67+
double get_arg_val(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces); // shared
68+
Selector_List_Obj get_arg_sels(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
69+
Compound_Selector_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtraces traces, Context& ctx); // selectors only
70+
871
}
972

1073
}

0 commit comments

Comments
 (0)