Commit 018c82e2 by Aaron Leung

Preparing to handle boolean expressions.

parent 5eac82d3
...@@ -86,4 +86,14 @@ div { ...@@ -86,4 +86,14 @@ div {
/* hsl tests */ /* hsl tests */
a: hsl(23, 100%, 50%); a: hsl(23, 100%, 50%);
b: hsl(120, 100%, 50%); b: hsl(120, 100%, 50%);
/* logical relations */
a: not(false);
b: not(true);
c: not(hello);
d: not("");
/* a: 1 < 2;
b: 1 > 2;
c: 1 > 2 or 3 < 4;
d: 1 > 3 and unit(10px);
e: not (false);*/
} }
\ No newline at end of file
...@@ -75,6 +75,8 @@ namespace Sass { ...@@ -75,6 +75,8 @@ namespace Sass {
register_function(unit_descriptor, unit); register_function(unit_descriptor, unit);
register_function(unitless_descriptor, unitless); register_function(unitless_descriptor, unitless);
register_function(comparable_descriptor, comparable); register_function(comparable_descriptor, comparable);
// Boolean Functions
register_function(not_descriptor, not_impl);
} }
} }
\ No newline at end of file
...@@ -56,13 +56,17 @@ namespace Sass { ...@@ -56,13 +56,17 @@ namespace Sass {
++context.ref_count; ++context.ref_count;
} }
Document::Document(Token t, Context& context) Document::Document(size_t line_number, Token t, Context& context)
: context(context) : path(string()),
{ source(const_cast<char*>(t.begin)),
position(t.begin),
end(t.end),
line_number(line_number),
} own_source(false),
context(context),
root(Node(Node::root, 1)),
lexed(Token::make())
{ }
Document::~Document() { Document::~Document() {
--context.ref_count; --context.ref_count;
......
...@@ -29,7 +29,7 @@ namespace Sass { ...@@ -29,7 +29,7 @@ namespace Sass {
Document(string path, char* source = 0); Document(string path, char* source = 0);
Document(string path, Context& context); Document(string path, Context& context);
Document(Token t, Context& context); Document(size_t line_number, Token t, Context& context);
~Document(); ~Document();
template <prelexer mx> template <prelexer mx>
......
...@@ -526,20 +526,21 @@ namespace Sass { ...@@ -526,20 +526,21 @@ namespace Sass {
return result; return result;
} }
// if (lex< rgb_prefix >()) if (lex< true_kwd >())
// { {
// Node result(Node::numeric_color, line_number, 3); Node T(Node::boolean);
// lex< number >(); T.line_number = line_number;
// result << Node(line_number, std::atof(lexed.begin)); T.content.boolean_value = true;
// lex< exactly<','> >(); return T;
// lex< number >(); }
// result << Node(line_number, std::atof(lexed.begin));
// lex< exactly<','> >(); if (lex< false_kwd >())
// lex< number >(); {
// result << Node(line_number, std::atof(lexed.begin)); Node F(Node::boolean);
// lex< exactly<')'> >(); F.line_number = line_number;
// return result; F.content.boolean_value = false;
// } return F;
}
if (peek< functional >()) if (peek< functional >())
{ return parse_function_call(); } { return parse_function_call(); }
......
...@@ -364,15 +364,9 @@ namespace Sass { ...@@ -364,15 +364,9 @@ namespace Sass {
case Node::numeric_percentage: case Node::numeric_percentage:
type.content.token = Token::make(number_name); type.content.token = Token::make(number_name);
break; break;
case Node::identifier: { case Node::boolean:
string text(val.content.token.to_string());
if (text == "true" || text == "false") {
type.content.token = Token::make(bool_name); type.content.token = Token::make(bool_name);
} break;
else {
type.content.token = Token::make(string_name);
}
} break;
case Node::string_constant: case Node::string_constant:
type.content.token = Token::make(string_name); type.content.token = Token::make(string_name);
break; break;
...@@ -427,13 +421,19 @@ namespace Sass { ...@@ -427,13 +421,19 @@ namespace Sass {
result.unquoted = true; result.unquoted = true;
switch (val.type) switch (val.type)
{ {
case Node::number: case Node::number: {
result.content.token = Token::make(true_str); Node T(Node::boolean);
break; T.line_number = val.line_number;
T.content.boolean_value = true;
return T;
} break;
case Node::numeric_percentage: case Node::numeric_percentage:
case Node::numeric_dimension: case Node::numeric_dimension: {
result.content.token = Token::make(false_str); Node F(Node::boolean);
break; F.line_number = val.line_number;
F.content.boolean_value = false;
return F;
} break;
default: default:
// TO DO: throw an exception; // TO DO: throw an exception;
break; break;
...@@ -449,10 +449,16 @@ namespace Sass { ...@@ -449,10 +449,16 @@ namespace Sass {
Node::Type t1 = n1.type; Node::Type t1 = n1.type;
Node::Type t2 = n2.type; Node::Type t2 = n2.type;
if (t1 == Node::number || t2 == Node::number) { if (t1 == Node::number || t2 == Node::number) {
return Node(Node::identifier, n1.line_number, Token::make(true_str)); Node T(Node::boolean);
T.line_number = n1.line_number;
T.content.boolean_value = true;
return T;
} }
else if (t1 == Node::numeric_percentage && t2 == Node::numeric_percentage) { else if (t1 == Node::numeric_percentage && t2 == Node::numeric_percentage) {
return Node(Node::identifier, n1.line_number, Token::make(true_str)); Node T(Node::boolean);
T.line_number = n1.line_number;
T.content.boolean_value = true;
return T;
} }
else if (t1 == Node::numeric_dimension && t2 == Node::numeric_dimension) { else if (t1 == Node::numeric_dimension && t2 == Node::numeric_dimension) {
string u1(Token::make(n1.content.dimension.unit, Prelexer::identifier(n1.content.dimension.unit)).to_string()); string u1(Token::make(n1.content.dimension.unit, Prelexer::identifier(n1.content.dimension.unit)).to_string());
...@@ -461,17 +467,44 @@ namespace Sass { ...@@ -461,17 +467,44 @@ namespace Sass {
u1 == "em" && u2 == "em" || u1 == "em" && u2 == "em" ||
(u1 == "in" || u1 == "cm" || u1 == "mm" || u1 == "pt" || u1 == "pc") && (u1 == "in" || u1 == "cm" || u1 == "mm" || u1 == "pt" || u1 == "pc") &&
(u2 == "in" || u2 == "cm" || u2 == "mm" || u2 == "pt" || u2 == "pc")) { (u2 == "in" || u2 == "cm" || u2 == "mm" || u2 == "pt" || u2 == "pc")) {
return Node(Node::identifier, n1.line_number, Token::make(true_str)); Node T(Node::boolean);
T.line_number = n1.line_number;
T.content.boolean_value = true;
return T;
} }
else { else {
return Node(Node::identifier, n1.line_number, Token::make(false_str)); Node F(Node::boolean);
F.line_number = n1.line_number;
F.content.boolean_value = false;
return F;
} }
} }
else { else {
return Node(Node::identifier, n1.line_number, Token::make(false_str)); Node F(Node::boolean);
F.line_number = n1.line_number;
F.content.boolean_value = false;
return F;
} }
} }
// Boolean Functions ///////////////////////////////////////////////////
Function_Descriptor not_descriptor =
{ "not", "value", 0 };
Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings) {
Node val(bindings[parameters[0]]);
if (val.type == Node::boolean && val.content.boolean_value == false) {
Node T(Node::boolean);
T.line_number = val.line_number;
T.content.boolean_value = true;
return T;
}
else {
Node F(Node::boolean);
F.line_number = val.line_number;
F.content.boolean_value = false;
return F;
}
}
} }
......
...@@ -148,6 +148,11 @@ namespace Sass { ...@@ -148,6 +148,11 @@ namespace Sass {
extern Function_Descriptor comparable_descriptor; extern Function_Descriptor comparable_descriptor;
Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings); Node comparable(const vector<Token>& parameters, map<Token, Node>& bindings);
// Boolean Functions ///////////////////////////////////////////////////
extern Function_Descriptor not_descriptor;
Node not_impl(const vector<Token>& parameters, map<Token, Node>& bindings);
} }
} }
...@@ -233,6 +233,11 @@ namespace Sass { ...@@ -233,6 +233,11 @@ namespace Sass {
} }
} break; } break;
case boolean: {
if (content.boolean_value) return "true";
else return "false";
} break;
default: { default: {
// return content.token.to_string(); // return content.token.to_string();
if (!has_children && type != flags) return content.token.to_string(); if (!has_children && type != flags) return content.token.to_string();
......
...@@ -39,6 +39,9 @@ namespace Sass { ...@@ -39,6 +39,9 @@ namespace Sass {
comma_list, comma_list,
space_list, space_list,
disjunction,
conjunction,
expression, expression,
add, add,
sub, sub,
...@@ -62,6 +65,7 @@ namespace Sass { ...@@ -62,6 +65,7 @@ namespace Sass {
numeric_dimension, numeric_dimension,
number, number,
numeric_color, numeric_color,
boolean,
function_call, function_call,
mixin, mixin,
...@@ -94,6 +98,7 @@ namespace Sass { ...@@ -94,6 +98,7 @@ namespace Sass {
mutable vector<Node>* children; mutable vector<Node>* children;
Dimension dimension; Dimension dimension;
double numeric_value; double numeric_value;
bool boolean_value;
} content; } content;
static size_t allocations; static size_t allocations;
...@@ -159,7 +164,7 @@ namespace Sass { ...@@ -159,7 +164,7 @@ namespace Sass {
Node() Node()
{ clear(); } { clear(); }
Node(Type t) // flags Node(Type t) // flags or booleans
{ clear(); type = t; } { clear(); type = t; }
Node(Type t, unsigned int ln, size_t s = 0) // nodes with children Node(Type t, unsigned int ln, size_t s = 0) // nodes with children
......
...@@ -206,9 +206,9 @@ namespace Sass { ...@@ -206,9 +206,9 @@ namespace Sass {
return sequence< identifier, exactly<'('> >(src); return sequence< identifier, exactly<'('> >(src);
} }
// Match the CSS negation pseudo-class. // Match the CSS negation pseudo-class.
extern const char not_kwd[] = ":not("; extern const char pseudo_not_chars[] = ":not(";
const char* pseudo_not(const char* src) { const char* pseudo_not(const char* src) {
return exactly< not_kwd >(src); return exactly< pseudo_not_chars >(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 even_chars[] = "even";
...@@ -250,6 +250,53 @@ namespace Sass { ...@@ -250,6 +250,53 @@ namespace Sass {
return sequence<exactly<'$'>, name>(src); return sequence<exactly<'$'>, name>(src);
} }
// Match Sass boolean keywords.
extern const char and_chars[] = "and";
extern const char or_chars[] = "or";
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) {
return exactly<false_chars>(src);
}
const char* and_kwd(const char* src) {
return exactly<and_chars>(src);
}
const char* or_kwd(const char* src) {
return exactly<or_chars>(src);
}
const char* not_kwd(const char* src) {
return exactly<not_chars>(src);
}
const char* eq_op(const char* src) {
return exactly<eq_chars>(src);
}
const char* neq_op(const char* src) {
return exactly<neq_chars>(src);
}
const char* gt_op(const char* src) {
return exactly<gt_chars>(src);
}
const char* gte_op(const char* src) {
return exactly<gte_chars>(src);
}
const char* lt_op(const char* src) {
return exactly<lt_chars>(src);
}
const char* lte_op(const char* src) {
return exactly<lte_chars>(src);
}
// Path matching functions. // Path matching functions.
const char* folder(const char* src) { const char* folder(const char* src) {
return sequence< zero_plus< any_char_except<'/'> >, return sequence< zero_plus< any_char_except<'/'> >,
......
...@@ -326,6 +326,19 @@ namespace Sass { ...@@ -326,6 +326,19 @@ namespace Sass {
// Match SCSS variable names. // Match SCSS variable names.
const char* variable(const char* src); const char* variable(const char* src);
// Match Sass boolean keywords.
const char* true_kwd(const char* src);
const char* false_kwd(const char* src);
const char* and_kwd(const char* src);
const char* or_kwd(const char* src);
const char* not_kwd(const char* src);
const char* eq_op(const char* src);
const char* neq_op(const char* src);
const char* gt_op(const char* src);
const char* gte_op(const char* src);
const char* lt_op(const char* src);
const char* lte_op(const char* src);
// Path matching functions. // Path matching functions.
const char* folder(const char* src); const char* folder(const char* src);
const char* folders(const char* src); const char* folders(const char* src);
......
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