Commit 5a145434 by Aaron Leung

Factoring out all the string constants into their own module.

parent bff3e4e2
...@@ -2,7 +2,7 @@ CC=g++ ...@@ -2,7 +2,7 @@ CC=g++
CFLAGS=-c -Wall -O2 -fPIC CFLAGS=-c -Wall -O2 -fPIC
LDFLAGS= -fPIC LDFLAGS= -fPIC
SOURCES = \ SOURCES = \
context.cpp functions.cpp document.cpp \ constants.cpp context.cpp functions.cpp document.cpp \
document_parser.cpp eval_apply.cpp node.cpp \ document_parser.cpp eval_apply.cpp node.cpp \
node_factory.cpp node_emitters.cpp prelexer.cpp \ node_factory.cpp node_emitters.cpp prelexer.cpp \
sass_interface.cpp sass_interface.cpp
......
#include "constants.hpp"
namespace Sass {
namespace Constants {
// hidden variable name for the image path (for the image-url built-in)
extern const char image_path_var[] = "$[image path]";
// sass keywords
extern const char import_kwd[] = "@import";
extern const char mixin_kwd[] = "@mixin";
extern const char function_kwd[] = "@function";
extern const char return_kwd[] = "@return";
extern const char include_kwd[] = "@include";
extern const char extend_kwd[] = "@extend";
extern const char if_kwd[] = "@if";
extern const char else_kwd[] = "@else";
extern const char if_after_else_kwd[] = "if";
extern const char for_kwd[] = "@for";
extern const char from_kwd[] = "from";
extern const char to_kwd[] = "to";
extern const char through_kwd[] = "through";
extern const char each_kwd[] = "@each";
extern const char in_kwd[] = "in";
extern const char while_kwd[] = "@while";
extern const char warn_kwd[] = "@warn";
extern const char default_kwd[] = "default";
// css standard units
extern const char em_kwd[] = "em";
extern const char ex_kwd[] = "ex";
extern const char px_kwd[] = "px";
extern const char cm_kwd[] = "cm";
extern const char mm_kwd[] = "mm";
extern const char pt_kwd[] = "pt";
extern const char pc_kwd[] = "pc";
extern const char deg_kwd[] = "deg";
extern const char rad_kwd[] = "rad";
extern const char grad_kwd[] = "grad";
extern const char ms_kwd[] = "ms";
extern const char s_kwd[] = "s";
extern const char Hz_kwd[] = "Hz";
extern const char kHz_kwd[] = "kHz";
// css functions and keywords
extern const char media_kwd[] = "@media";
extern const char only_kwd[] = "only";
extern const char rgb_kwd[] = "rgb(";
extern const char url_kwd[] = "url(";
extern const char image_url_kwd[] = "image-url(";
extern const char important_kwd[] = "important";
extern const char pseudo_not_kwd[] = ":not(";
extern const char even_kwd[] = "even";
extern const char odd_kwd[] = "odd";
// css attribute-matching operators
extern const char tilde_equal[] = "~=";
extern const char pipe_equal[] = "|=";
extern const char caret_equal[] = "^=";
extern const char dollar_equal[] = "$=";
extern const char star_equal[] = "*=";
// relational & logical operators and constants
extern const char and_kwd[] = "and";
extern const char or_kwd[] = "or";
extern const char not_kwd[] = "not";
extern const char gt[] = ">";
extern const char gte[] = ">=";
extern const char lt[] = "<";
extern const char lte[] = "<=";
extern const char eq[] = "==";
extern const char neq[] = "!=";
extern const char true_kwd[] = "true";
extern const char false_kwd[] = "false";
// miscellaneous punctuation and delimiters
extern const char percent_str[] = "%";
extern const char empty_str[] = "";
extern const char slash_slash[] = "//";
extern const char slash_star[] = "/*";
extern const char star_slash[] = "*/";
extern const char hash_lbrace[] = "#{";
extern const char rbrace[] = "}";
extern const char sign_chars[] = "-+";
// type names
extern const char numeric_name[] = "numeric value";
extern const char number_name[] = "number";
extern const char string_name[] = "string";
extern const char bool_name[] = "bool";
extern const char color_name[] = "color";
extern const char list_name[] = "list";
}
}
\ No newline at end of file
#define SASS_CONSTANTS
namespace Sass {
namespace Constants {
// hidden variable name for the image path (for the image-url built-in)
extern const char image_path_var[];
// sass keywords
extern const char import_kwd[];
extern const char mixin_kwd[];
extern const char function_kwd[];
extern const char return_kwd[];
extern const char include_kwd[];
extern const char extend_kwd[];
extern const char if_kwd[];
extern const char else_kwd[];
extern const char if_after_else_kwd[];
extern const char for_kwd[];
extern const char from_kwd[];
extern const char to_kwd[];
extern const char through_kwd[];
extern const char each_kwd[];
extern const char in_kwd[];
extern const char while_kwd[];
extern const char warn_kwd[];
extern const char default_kwd[];
// css standard units
extern const char em_kwd[];
extern const char ex_kwd[];
extern const char px_kwd[];
extern const char cm_kwd[];
extern const char mm_kwd[];
extern const char pt_kwd[];
extern const char pc_kwd[];
extern const char deg_kwd[];
extern const char rad_kwd[];
extern const char grad_kwd[];
extern const char ms_kwd[];
extern const char s_kwd[];
extern const char Hz_kwd[];
extern const char kHz_kwd[];
// css functions and keywords
extern const char media_kwd[];
extern const char only_kwd[];
extern const char rgb_kwd[];
extern const char url_kwd[];
extern const char image_url_kwd[];
extern const char important_kwd[];
extern const char pseudo_not_kwd[];
extern const char even_kwd[];
extern const char odd_kwd[];
// css attribute-matching operators
extern const char tilde_equal[];
extern const char pipe_equal[];
extern const char caret_equal[];
extern const char dollar_equal[];
extern const char star_equal[];
// relational & logical operators and constants
extern const char and_kwd[];
extern const char or_kwd[];
extern const char not_kwd[];
extern const char gt[];
extern const char gte[];
extern const char lt[];
extern const char lte[];
extern const char eq[];
extern const char neq[];
extern const char true_kwd[];
extern const char false_kwd[];
// miscellaneous punctuation and delimiters
extern const char percent_str[];
extern const char empty_str[];
extern const char slash_slash[];
extern const char slash_star[];
extern const char star_slash[];
extern const char hash_lbrace[];
extern const char rbrace[];
extern const char sign_chars[];
// type names
extern const char numeric_name[];
extern const char number_name[];
extern const char string_name[];
extern const char bool_name[];
extern const char color_name[];
extern const char list_name[];
}
}
\ No newline at end of file
#include "context.hpp"
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <unistd.h> #include <unistd.h>
#include "prelexer.hpp" #include "context.hpp"
#include "constants.hpp"
#include "color_names.hpp" #include "color_names.hpp"
using std::cerr; using std::endl; #include "prelexer.hpp"
namespace Sass { namespace Sass {
using std::pair; using namespace Constants;
using std::pair; using std::cerr; using std::endl;
void Context::collect_include_paths(const char* paths_str) void Context::collect_include_paths(const char* paths_str)
{ {
const size_t wd_len = 1024; const size_t wd_len = 1024;
...@@ -65,6 +67,7 @@ namespace Sass { ...@@ -65,6 +67,7 @@ namespace Sass {
path_string = "'" + path_string + "/'"; path_string = "'" + path_string + "/'";
image_path = new char[path_string.length() + 1]; image_path = new char[path_string.length() + 1];
std::strcpy(image_path, path_string.c_str()); std::strcpy(image_path, path_string.c_str());
global_env[Token::make(image_path_var)] = new_Node(Node::string_constant, "", 0, Token::make(image_path));
} }
Context::~Context() Context::~Context()
......
#include <iostream>
#include "document.hpp" #include "document.hpp"
#include "constants.hpp"
#include "error.hpp" #include "error.hpp"
#include <iostream>
#ifndef SASS_PRELEXER
#include "prelexer.hpp"
#endif
namespace Sass { namespace Sass {
using namespace std; using namespace std;
using namespace Constants;
void Document::parse_scss() void Document::parse_scss()
{ {
...@@ -315,8 +321,6 @@ namespace Sass { ...@@ -315,8 +321,6 @@ namespace Sass {
return ruleset; return ruleset;
} }
extern const char hash_lbrace[] = "#{";
extern const char rbrace[] = "}";
Node Document::parse_selector_schema(const char* end_of_selector) Node Document::parse_selector_schema(const char* end_of_selector)
{ {
const char* i = position; const char* i = position;
...@@ -713,11 +717,11 @@ namespace Sass { ...@@ -713,11 +717,11 @@ namespace Sass {
{ {
Node conj1(parse_conjunction()); Node conj1(parse_conjunction());
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< or_kwd, negate< identifier > > >()) return conj1; if (!peek< sequence< or_op, negate< identifier > > >()) return conj1;
Node disjunction(context.new_Node(Node::disjunction, path, line, 2)); Node disjunction(context.new_Node(Node::disjunction, path, line, 2));
disjunction << conj1; disjunction << conj1;
while (lex< sequence< or_kwd, negate< identifier > > >()) disjunction << parse_conjunction(); while (lex< sequence< or_op, negate< identifier > > >()) disjunction << parse_conjunction();
disjunction.should_eval() = true; disjunction.should_eval() = true;
return disjunction; return disjunction;
...@@ -727,11 +731,11 @@ namespace Sass { ...@@ -727,11 +731,11 @@ namespace Sass {
{ {
Node rel1(parse_relation()); Node rel1(parse_relation());
// if it's a singleton, return it directly; don't wrap it // if it's a singleton, return it directly; don't wrap it
if (!peek< sequence< and_kwd, negate< identifier > > >()) return rel1; if (!peek< sequence< and_op, negate< identifier > > >()) return rel1;
Node conjunction(context.new_Node(Node::conjunction, path, line, 2)); Node conjunction(context.new_Node(Node::conjunction, path, line, 2));
conjunction << rel1; conjunction << rel1;
while (lex< sequence< and_kwd, negate< identifier > > >()) conjunction << parse_relation(); while (lex< sequence< and_op, negate< identifier > > >()) conjunction << parse_relation();
conjunction.should_eval() = true; conjunction.should_eval() = true;
return conjunction; return conjunction;
} }
...@@ -901,10 +905,10 @@ namespace Sass { ...@@ -901,10 +905,10 @@ namespace Sass {
if (lex< value_schema >()) if (lex< value_schema >())
{ return Document::make_from_token(context, lexed, path, line).parse_value_schema(); } { return Document::make_from_token(context, lexed, path, line).parse_value_schema(); }
if (lex< sequence< true_kwd, negate< identifier > > >()) if (lex< sequence< true_val, negate< identifier > > >())
{ return context.new_Node(Node::boolean, path, line, true); } { return context.new_Node(Node::boolean, path, line, true); }
if (lex< sequence< false_kwd, negate< identifier > > >()) if (lex< sequence< false_val, negate< identifier > > >())
{ return context.new_Node(Node::boolean, path, line, false); } { return context.new_Node(Node::boolean, path, line, false); }
if (lex< important >()) if (lex< important >())
...@@ -1208,13 +1212,11 @@ namespace Sass { ...@@ -1208,13 +1212,11 @@ namespace Sass {
return media_query; return media_query;
} }
// extern const char not_kwd[] = "not";
extern const char only_kwd[] = "only";
Node Document::parse_media_expression() Node Document::parse_media_expression()
{ {
Node media_expr(context.new_Node(Node::media_expression, path, line, 1)); Node media_expr(context.new_Node(Node::media_expression, path, line, 1));
// if the query begins with 'not' or 'only', then a media type is required // if the query begins with 'not' or 'only', then a media type is required
if (lex< not_kwd >() || lex< exactly<only_kwd> >()) { if (lex< not_op >() || lex< exactly<only_kwd> >()) {
media_expr << context.new_Node(Node::identifier, path, line, lexed); media_expr << context.new_Node(Node::identifier, path, line, lexed);
if (!lex< identifier >()) throw_syntax_error("media type expected in media query"); if (!lex< identifier >()) throw_syntax_error("media type expected in media query");
media_expr << context.new_Node(Node::identifier, path, line, lexed); media_expr << context.new_Node(Node::identifier, path, line, lexed);
...@@ -1231,7 +1233,7 @@ namespace Sass { ...@@ -1231,7 +1233,7 @@ namespace Sass {
} }
// parse the rest of the properties for this disjunct // parse the rest of the properties for this disjunct
while (!peek< exactly<','> >() && !peek< exactly<'{'> >()) { while (!peek< exactly<','> >() && !peek< exactly<'{'> >()) {
if (!lex< and_kwd >()) throw_syntax_error("invalid media query"); if (!lex< and_op >()) throw_syntax_error("invalid media query");
media_expr << context.new_Node(Node::identifier, path, line, lexed); media_expr << context.new_Node(Node::identifier, path, line, lexed);
if (!lex< exactly<'('> >()) throw_syntax_error("invalid media query"); if (!lex< exactly<'('> >()) throw_syntax_error("invalid media query");
media_expr << parse_rule(); media_expr << parse_rule();
......
#include "prelexer.hpp"
#include "eval_apply.hpp" #include "eval_apply.hpp"
#include "constants.hpp"
#include "prelexer.hpp"
#include "document.hpp" #include "document.hpp"
#include "error.hpp" #include "error.hpp"
#include <cctype> #include <cctype>
...@@ -8,6 +9,7 @@ ...@@ -8,6 +9,7 @@
#include <cstdlib> #include <cstdlib>
namespace Sass { namespace Sass {
using namespace Constants;
using std::cerr; using std::endl; using std::cerr; using std::endl;
static void throw_eval_error(string message, string path, size_t line) static void throw_eval_error(string message, string path, size_t line)
...@@ -417,7 +419,7 @@ namespace Sass { ...@@ -417,7 +419,7 @@ namespace Sass {
case Node::for_to_directive: { case Node::for_to_directive: {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3)); Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1)); Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(Prelexer::for_kwd)) << (fake_param << expr[0]) << expr[3]; fake_mixin << new_Node(Node::identifier, "", 0, Token::make(for_kwd)) << (fake_param << expr[0]) << expr[3];
Node lower_bound(eval(expr[1], prefix, env, f_env, new_Node, ctx)); Node lower_bound(eval(expr[1], prefix, env, f_env, new_Node, ctx));
Node upper_bound(eval(expr[2], prefix, env, f_env, new_Node, ctx)); Node upper_bound(eval(expr[2], prefix, env, f_env, new_Node, ctx));
if (!(lower_bound.is_numeric() && upper_bound.is_numeric())) { if (!(lower_bound.is_numeric() && upper_bound.is_numeric())) {
...@@ -441,7 +443,7 @@ namespace Sass { ...@@ -441,7 +443,7 @@ namespace Sass {
case Node::each_directive: { case Node::each_directive: {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3)); Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1)); Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 1));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(Prelexer::each_kwd)) << (fake_param << expr[0]) << expr[2]; fake_mixin << new_Node(Node::identifier, "", 0, Token::make(each_kwd)) << (fake_param << expr[0]) << expr[2];
Node list(eval(expr[1], prefix, env, f_env, new_Node, ctx)); Node list(eval(expr[1], prefix, env, f_env, new_Node, ctx));
// If the list isn't really a list, make a singleton out of it. // If the list isn't really a list, make a singleton out of it.
if (list.type() != Node::space_list && list.type() != Node::comma_list) { if (list.type() != Node::space_list && list.type() != Node::comma_list) {
...@@ -461,7 +463,7 @@ namespace Sass { ...@@ -461,7 +463,7 @@ namespace Sass {
Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3)); Node fake_mixin(new_Node(Node::mixin, expr.path(), expr.line(), 3));
Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 0)); Node fake_param(new_Node(Node::parameters, expr.path(), expr.line(), 0));
Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 0)); Node fake_arg(new_Node(Node::arguments, expr.path(), expr.line(), 0));
fake_mixin << new_Node(Node::identifier, "", 0, Token::make(Prelexer::while_kwd)) << fake_param << expr[1]; fake_mixin << new_Node(Node::identifier, "", 0, Token::make(while_kwd)) << fake_param << expr[1];
Node pred(expr[0]); Node pred(expr[0]);
expr.pop_back(); expr.pop_back();
expr.pop_back(); expr.pop_back();
...@@ -504,26 +506,13 @@ namespace Sass { ...@@ -504,26 +506,13 @@ namespace Sass {
Node::Type optype = op.type(); Node::Type optype = op.type();
Node::Type ltype = acc.type(); Node::Type ltype = acc.type();
Node::Type rtype = rhs.type(); Node::Type rtype = rhs.type();
if (ltype == Node::concatenation && rtype == Node::concatenation) { if (ltype == Node::number && rhs.is_string()) {
if (optype != Node::add) acc << op;
acc += rhs;
}
else if (ltype == Node::concatenation) {
if (optype != Node::add) acc << op;
acc << rhs;
}
else if (rtype == Node::concatenation) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
acc += rhs;
acc.is_quoted() = acc[0].is_quoted();
acc.is_unquoted() = acc[0].is_unquoted();
}
else if (acc.is_string() || rhs.is_string()) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc); acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op; if (optype != Node::add) acc << op;
acc << rhs; if (rtype == Node::concatenation) acc += rhs;
acc.is_quoted() = acc[0].is_quoted(); else acc << rhs;
acc.is_unquoted() = acc[0].is_unquoted(); acc.is_quoted() = rhs.is_quoted();
acc.is_unquoted() = rhs.is_unquoted();
} }
else if (ltype == Node::number && rtype == Node::number) { else if (ltype == Node::number && rtype == Node::number) {
acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value())); acc = new_Node(list.path(), list.line(), operate(op, acc.numeric_value(), rhs.numeric_value()));
...@@ -574,6 +563,30 @@ namespace Sass { ...@@ -574,6 +563,30 @@ namespace Sass {
double a = acc[3].numeric_value(); double a = acc[3].numeric_value();
acc = new_Node(list.path(), list.line(), r, g, b, a); acc = new_Node(list.path(), list.line(), r, g, b, a);
} }
else if (ltype == Node::concatenation && rtype == Node::concatenation) {
if (optype != Node::add) acc << op;
acc += rhs;
}
else if (ltype == Node::concatenation) {
if (optype != Node::add) acc << op;
acc << rhs;
}
else if (rtype == Node::concatenation) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc += rhs;
acc.is_quoted() = acc[0].is_quoted();
acc.is_unquoted() = acc[0].is_unquoted();
}
else if (acc.is_string() || rhs.is_string()) {
acc = (new_Node(Node::concatenation, list.path(), list.line(), 2) << acc);
if (optype != Node::add) acc << op;
acc << rhs;
if (!acc[0].is_string()) {
acc.is_quoted() = false;
acc.is_unquoted() = true;
}
}
else { // lists or schemas else { // lists or schemas
if (acc.is_schema() && rhs.is_schema()) { if (acc.is_schema() && rhs.is_schema()) {
if (optype != Node::add) acc << op; if (optype != Node::add) acc << op;
......
#ifndef SASS_PRELEXER #include <iostream>
#include "prelexer.hpp" #include <sstream>
#endif #include <cmath>
#include <algorithm>
#include "node_factory.hpp"
#include "functions.hpp" #include "functions.hpp"
#include "constants.hpp"
#include "node_factory.hpp"
#include "context.hpp" #include "context.hpp"
#include "document.hpp" #include "document.hpp"
#include "eval_apply.hpp" #include "eval_apply.hpp"
#include "error.hpp" #include "error.hpp"
#include <iostream> #ifndef SASS_PRELEXER
#include <sstream> #include "prelexer.hpp"
#include <cmath> #endif
#include <algorithm>
using std::cerr; using std::endl; using std::stringstream; using std::cerr; using std::endl; using std::stringstream;
namespace Sass { namespace Sass {
using namespace Constants;
// this constructor needs context.hpp, so it can't be defined in functions.hpp // this constructor needs context.hpp, so it can't be defined in functions.hpp
// because including context.hpp in functions.hpp would be circular // because including context.hpp in functions.hpp would be circular
...@@ -45,20 +47,6 @@ namespace Sass { ...@@ -45,20 +47,6 @@ namespace Sass {
namespace Functions { namespace Functions {
extern const char true_str[] = "true";
extern const char false_str[] = "false";
extern const char empty_str[] = "";
extern const char percent_str[] = "%";
extern const char deg_str[] = "deg";
extern const char numeric_name[] = "numeric value";
extern const char number_name[] = "number";
extern const char string_name[] = "string";
extern const char bool_name[] = "bool";
extern const char color_name[] = "color";
extern const char list_name[] = "list";
static void throw_eval_error(string message, string& path, size_t line) static void throw_eval_error(string message, string& path, size_t line)
{ {
if (!path.empty() && Prelexer::string_constant(path.c_str())) if (!path.empty() && Prelexer::string_constant(path.c_str()))
...@@ -336,7 +324,7 @@ namespace Sass { ...@@ -336,7 +324,7 @@ namespace Sass {
rgb_color[1].numeric_value(), rgb_color[1].numeric_value(),
rgb_color[2].numeric_value(), rgb_color[2].numeric_value(),
new_Node, path, line)); new_Node, path, line));
return new_Node(path, line, hsl_color[0].numeric_value(), Token::make(deg_str)); return new_Node(path, line, hsl_color[0].numeric_value(), Token::make(deg_kwd));
} }
extern Signature saturation_sig = "saturation($color)"; extern Signature saturation_sig = "saturation($color)";
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
namespace Sass { namespace Sass {
struct Environment; struct Environment;
struct Context; struct Context;
struct Node_Factory;
using std::map; using std::map;
......
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <iostream>
#include "node.hpp" #include "node.hpp"
#include "constants.hpp"
#include "error.hpp" #include "error.hpp"
#include <iostream>
namespace Sass { namespace Sass {
using namespace std; using namespace std;
using namespace Constants;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Node method implementations // Node method implementations
...@@ -340,8 +342,6 @@ namespace Sass { ...@@ -340,8 +342,6 @@ namespace Sass {
return 0; return 0;
} }
extern const char percent_str[] = "%";
extern const char empty_str[] = "";
Token Node_Impl::unit() Token Node_Impl::unit()
{ {
switch (type) switch (type)
......
#include <cctype> #include <cctype>
#include "prelexer.hpp"
#include <iostream> #include <iostream>
#include "constants.hpp"
#include "prelexer.hpp"
namespace Sass { namespace Sass {
using namespace Constants;
namespace Prelexer { namespace Prelexer {
using std::cerr; using std::endl; using std::cerr; using std::endl;
// Matches zero characters (always succeeds without consuming input). // Matches zero characters (always succeeds without consuming input).
...@@ -33,11 +37,11 @@ namespace Sass { ...@@ -33,11 +37,11 @@ namespace Sass {
const char* puncts(const char* src) { return one_plus<punct>(src); } const char* puncts(const char* src) { return one_plus<punct>(src); }
// Match a line comment. // Match a line comment.
extern const char slash_slash[] = "//";
const char* line_comment(const char* src) { return to_endl<slash_slash>(src); } const char* line_comment(const char* src) { return to_endl<slash_slash>(src); }
// Match a block comment. // Match a block comment.
extern const char slash_star[] = "/*";
extern const char star_slash[] = "*/";
const char* block_comment(const char* src) { const char* block_comment(const char* src) {
return sequence< optional_spaces, delimited_by<slash_star, star_slash, false> >(src); return sequence< optional_spaces, delimited_by<slash_star, star_slash, false> >(src);
} }
...@@ -56,8 +60,8 @@ namespace Sass { ...@@ -56,8 +60,8 @@ namespace Sass {
return alternatives<double_quoted_string, single_quoted_string>(src); return alternatives<double_quoted_string, single_quoted_string>(src);
} }
// Match interpolants. // Match interpolants.
extern const char hash_lbrace[] = "#{";
extern const char rbrace[] = "}";
const char* interpolant(const char* src) { const char* interpolant(const char* src) {
return delimited_by<hash_lbrace, rbrace, false>(src); return delimited_by<hash_lbrace, rbrace, false>(src);
} }
...@@ -109,77 +113,73 @@ namespace Sass { ...@@ -109,77 +113,73 @@ namespace Sass {
const char* at_keyword(const char* src) { const char* at_keyword(const char* src) {
return sequence<exactly<'@'>, identifier>(src); return sequence<exactly<'@'>, identifier>(src);
} }
extern const char import_kwd[] = "@import";
const char* import(const char* src) { const char* import(const char* src) {
return exactly<import_kwd>(src); return exactly<import_kwd>(src);
} }
extern const char media_kwd[] = "@media";
const char* media(const char* src) { const char* media(const char* src) {
return exactly<media_kwd>(src); return exactly<media_kwd>(src);
} }
extern const char mixin_kwd[] = "@mixin";
const char* mixin(const char* src) { const char* mixin(const char* src) {
return exactly<mixin_kwd>(src); return exactly<mixin_kwd>(src);
} }
extern const char function_kwd[] = "@function";
const char* function(const char* src) { const char* function(const char* src) {
return exactly<function_kwd>(src); return exactly<function_kwd>(src);
} }
extern const char return_kwd[] = "@return";
const char* return_directive(const char* src) { const char* return_directive(const char* src) {
return exactly<return_kwd>(src); return exactly<return_kwd>(src);
} }
extern const char include_kwd[] = "@include";
const char* include(const char* src) { const char* include(const char* src) {
return exactly<include_kwd>(src); return exactly<include_kwd>(src);
} }
extern const char extend_kwd[] = "@extend";
const char* extend(const char* src) { const char* extend(const char* src) {
return exactly<extend_kwd>(src); return exactly<extend_kwd>(src);
} }
extern const char if_kwd[] = "@if";
extern const char if_chars[] = "if";
const char* if_directive(const char* src) { const char* if_directive(const char* src) {
return exactly<if_kwd>(src); return exactly<if_kwd>(src);
} }
extern const char else_kwd[] = "@else";
const char* else_directive(const char* src) { const char* else_directive(const char* src) {
return exactly<else_kwd>(src); return exactly<else_kwd>(src);
} }
const char* elseif_directive(const char* src) { const char* elseif_directive(const char* src) {
return sequence< else_directive, return sequence< else_directive,
spaces_and_comments, spaces_and_comments,
exactly< if_chars > >(src); exactly< if_after_else_kwd > >(src);
} }
extern const char for_kwd[] = "@for";
const char* for_directive(const char* src) { const char* for_directive(const char* src) {
return exactly<for_kwd>(src); return exactly<for_kwd>(src);
} }
extern const char from_kwd[] = "from";
const char* from(const char* src) { const char* from(const char* src) {
return exactly<from_kwd>(src); return exactly<from_kwd>(src);
} }
extern const char to_kwd[] = "to";
const char* to(const char* src) { const char* to(const char* src) {
return exactly<to_kwd>(src); return exactly<to_kwd>(src);
} }
extern const char through_kwd[] = "through";
const char* through(const char* src) { const char* through(const char* src) {
return exactly<through_kwd>(src); return exactly<through_kwd>(src);
} }
extern const char each_kwd[] = "@each";
const char* each_directive(const char* src) { const char* each_directive(const char* src) {
return exactly<each_kwd>(src); return exactly<each_kwd>(src);
} }
extern const char in_kwd[] = "in";
const char* in(const char* src) { const char* in(const char* src) {
return exactly<in_kwd>(src); return exactly<in_kwd>(src);
} }
extern const char while_kwd[] = "@while";
const char* while_directive(const char* src) { const char* while_directive(const char* src) {
return exactly<while_kwd>(src); return exactly<while_kwd>(src);
} }
...@@ -190,7 +190,6 @@ namespace Sass { ...@@ -190,7 +190,6 @@ namespace Sass {
exactly<'_'> > >(src); exactly<'_'> > >(src);
} }
extern const char warn_kwd[] = "@warn";
const char* warn(const char* src) { const char* warn(const char* src) {
return exactly<warn_kwd>(src); return exactly<warn_kwd>(src);
} }
...@@ -219,7 +218,7 @@ namespace Sass { ...@@ -219,7 +218,7 @@ namespace Sass {
return sequence<exactly<'.'>, identifier>(src); return sequence<exactly<'.'>, identifier>(src);
} }
// Match CSS numeric constants. // Match CSS numeric constants.
extern const char sign_chars[] = "-+";
const char* sign(const char* src) { const char* sign(const char* src) {
return class_char<sign_chars>(src); return class_char<sign_chars>(src);
} }
...@@ -246,21 +245,7 @@ namespace Sass { ...@@ -246,21 +245,7 @@ namespace Sass {
const char* percentage(const char* src) { const char* percentage(const char* src) {
return sequence< number, exactly<'%'> >(src); return sequence< number, exactly<'%'> >(src);
} }
extern const char em_kwd[] = "em";
extern const char ex_kwd[] = "ex";
extern const char px_kwd[] = "px";
extern const char cm_kwd[] = "cm";
extern const char mm_kwd[] = "mm";
// extern const char in_kwd[] = "in";
extern const char pt_kwd[] = "pt";
extern const char pc_kwd[] = "pc";
extern const char deg_kwd[] = "deg";
extern const char rad_kwd[] = "rad";
extern const char grad_kwd[] = "grad";
extern const char ms_kwd[] = "ms";
extern const char s_kwd[] = "s";
extern const char Hz_kwd[] = "Hz";
extern const char kHz_kwd[] = "kHz";
const char* em(const char* src) { const char* em(const char* src) {
return sequence< number, exactly<em_kwd> >(src); return sequence< number, exactly<em_kwd> >(src);
} }
...@@ -272,12 +257,12 @@ namespace Sass { ...@@ -272,12 +257,12 @@ namespace Sass {
int len = p - src; int len = p - src;
return (len != 4 && len != 7) ? 0 : p; return (len != 4 && len != 7) ? 0 : p;
} }
extern const char rgb_kwd[] = "rgb(";
const char* rgb_prefix(const char* src) { const char* rgb_prefix(const char* src) {
return exactly<rgb_kwd>(src); return exactly<rgb_kwd>(src);
} }
// Match CSS uri specifiers. // Match CSS uri specifiers.
extern const char url_kwd[] = "url(";
const char* uri_prefix(const char* src) { const char* uri_prefix(const char* src) {
return exactly<url_kwd>(src); return exactly<url_kwd>(src);
} }
...@@ -299,19 +284,16 @@ namespace Sass { ...@@ -299,19 +284,16 @@ namespace Sass {
filename_schema >(src); // optional trailing slash filename_schema >(src); // optional trailing slash
} }
// Match SCSS image-url function // Match SCSS image-url function
extern const char image_url_kwd[] = "image-url(";
const char* image_url_prefix(const char* src) { const char* image_url_prefix(const char* src) {
return exactly<image_url_kwd>(src); return exactly<image_url_kwd>(src);
} }
// Match CSS "!important" keyword. // Match CSS "!important" keyword.
extern const char important_kwd[] = "important";
const char* important(const char* src) { const char* important(const char* src) {
return sequence< exactly<'!'>, return sequence< exactly<'!'>,
spaces_and_comments, spaces_and_comments,
exactly<important_kwd> >(src); exactly<important_kwd> >(src);
} }
// Match Sass "!default" keyword. // Match Sass "!default" keyword.
extern const char default_kwd[] = "default";
const char* default_flag(const char* src) { const char* default_flag(const char* src) {
return sequence< exactly<'!'>, return sequence< exactly<'!'>,
spaces_and_comments, spaces_and_comments,
...@@ -326,25 +308,17 @@ namespace Sass { ...@@ -326,25 +308,17 @@ namespace Sass {
return sequence< alternatives< identifier_schema, identifier >, exactly<'('> >(src); return sequence< alternatives< identifier_schema, identifier >, exactly<'('> >(src);
} }
// Match the CSS negation pseudo-class. // Match the CSS negation pseudo-class.
extern const char pseudo_not_chars[] = ":not(";
const char* pseudo_not(const char* src) { const char* pseudo_not(const char* src) {
return exactly< pseudo_not_chars >(src); return exactly< pseudo_not_kwd >(src);
} }
// Match CSS 'odd' and 'even' keywords for functional pseudo-classes. // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.
extern const char even_chars[] = "even";
extern const char odd_chars[] = "odd";
const char* even(const char* src) { const char* even(const char* src) {
return exactly<even_chars>(src); return exactly<even_kwd>(src);
} }
const char* odd(const char* src) { const char* odd(const char* src) {
return exactly<odd_chars>(src); return exactly<odd_kwd>(src);
} }
// Match CSS attribute-matching operators. // Match CSS attribute-matching operators.
extern const char tilde_equal[] = "~=";
extern const char pipe_equal[] = "|=";
extern const char caret_equal[] = "^=";
extern const char dollar_equal[] = "$=";
extern const char star_equal[] = "*=";
const char* exact_match(const char* src) { return exactly<'='>(src); } const char* exact_match(const char* src) { return exactly<'='>(src); }
const char* class_match(const char* src) { return exactly<tilde_equal>(src); } const char* class_match(const char* src) { return exactly<tilde_equal>(src); }
const char* dash_match(const char* src) { return exactly<pipe_equal>(src); } const char* dash_match(const char* src) { return exactly<pipe_equal>(src); }
...@@ -371,50 +345,38 @@ namespace Sass { ...@@ -371,50 +345,38 @@ namespace Sass {
} }
// Match Sass boolean keywords. // Match Sass boolean keywords.
extern const char and_chars[] = "and"; const char* true_val(const char* src) {
extern const char or_chars[] = "or"; return exactly<true_kwd>(src);
extern const char not_chars[] = "not";
extern const char gt_chars[] = ">";
extern const char gte_chars[] = ">=";
extern const char lt_chars[] = "<";
extern const char lte_chars[] = "<=";
extern const char eq_chars[] = "==";
extern const char neq_chars[] = "!=";
extern const char true_chars[] = "true";
extern const char false_chars[] = "false";
const char* true_kwd(const char* src) {
return exactly<true_chars>(src);
} }
const char* false_kwd(const char* src) { const char* false_val(const char* src) {
return exactly<false_chars>(src); return exactly<false_kwd>(src);
} }
const char* and_kwd(const char* src) { const char* and_op(const char* src) {
return exactly<and_chars>(src); return exactly<and_kwd>(src);
} }
const char* or_kwd(const char* src) { const char* or_op(const char* src) {
return exactly<or_chars>(src); return exactly<or_kwd>(src);
} }
const char* not_kwd(const char* src) { const char* not_op(const char* src) {
return exactly<not_chars>(src); return exactly<not_kwd>(src);
} }
const char* eq_op(const char* src) { const char* eq_op(const char* src) {
return exactly<eq_chars>(src); return exactly<eq>(src);
} }
const char* neq_op(const char* src) { const char* neq_op(const char* src) {
return exactly<neq_chars>(src); return exactly<neq>(src);
} }
const char* gt_op(const char* src) { const char* gt_op(const char* src) {
return exactly<gt_chars>(src); return exactly<gt>(src);
} }
const char* gte_op(const char* src) { const char* gte_op(const char* src) {
return exactly<gte_chars>(src); return exactly<gte>(src);
} }
const char* lt_op(const char* src) { const char* lt_op(const char* src) {
return exactly<lt_chars>(src); return exactly<lt>(src);
} }
const char* lte_op(const char* src) { const char* lte_op(const char* src) {
return exactly<lte_chars>(src); return exactly<lte>(src);
} }
// Path matching functions. // Path matching functions.
......
...@@ -390,11 +390,11 @@ namespace Sass { ...@@ -390,11 +390,11 @@ namespace Sass {
const char* variable(const char* src); const char* variable(const char* src);
// Match Sass boolean keywords. // Match Sass boolean keywords.
const char* true_kwd(const char* src); const char* true_val(const char* src);
const char* false_kwd(const char* src); const char* false_val(const char* src);
const char* and_kwd(const char* src); const char* and_op(const char* src);
const char* or_kwd(const char* src); const char* or_op(const char* src);
const char* not_kwd(const char* src); const char* not_op(const char* src);
const char* eq_op(const char* src); const char* eq_op(const char* src);
const char* neq_op(const char* src); const char* neq_op(const char* src);
const char* gt_op(const char* src); const char* gt_op(const char* src);
...@@ -449,11 +449,5 @@ namespace Sass { ...@@ -449,11 +449,5 @@ namespace Sass {
} }
return counter; return counter;
} }
extern const char if_kwd[];
extern const char for_kwd[];
extern const char each_kwd[];
extern const char while_kwd[];
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment