Current Version: 1.0.10
Project Name: csspp
expr_relational.cpp
Go to the documentation of this file.
1 // CSS Preprocessor
2 // Copyright (C) 2015-2016 Made to Order Software Corp.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
27 #include "csspp/expression.h"
28 
29 #include "csspp/exceptions.h"
30 #include "csspp/parser.h"
31 #include "csspp/unicode_range.h"
32 
33 #include <algorithm>
34 #include <cmath>
35 #include <iostream>
36 
37 namespace csspp
38 {
39 
41 {
42  switch(mix_node_types(lhs->get_type(), rhs->get_type()))
43  {
45  return lhs->get_boolean() < rhs->get_boolean();
46 
48  // TBD: should we generate an error if these are not
49  // equivalent dimensions?
50  return lhs->get_integer() < rhs->get_integer();
51 
53  // TBD: should we generate an error if these are not
54  // equivalent dimensions?
55  return lhs->get_integer() < rhs->get_decimal_number();
56 
58  // TBD: should we generate an error if these are not
59  // equivalent dimensions?
60  return lhs->get_decimal_number() < rhs->get_integer();
61 
63  // TBD: should we generate an error if these are not
64  // equivalent dimensions?
65  return lhs->get_decimal_number() < rhs->get_decimal_number();
66 
68  return lhs->get_decimal_number() < rhs->get_decimal_number();
69 
71  return lhs->get_string() < rhs->get_string();
72 
73  }
74 
75  // at this time this only really applies to 'COLOR op COLOR'
76  error::instance() << lhs->get_position()
77  << "incompatible types between "
78  << lhs->get_type()
79  << " and "
80  << rhs->get_type()
81  << " for operator '<', '<=', '>', or '>='."
83 
84  return false;
85 }
86 
88 {
89  switch(n->get_type())
90  {
95  return n->get_type();
96 
97  default:
98  return node_type_t::UNKNOWN;
99 
100  }
101 }
102 
104 {
105  // relational: additive
106  // | relational '<' additive
107  // | relational '<=' additive
108  // | relational '>' additive
109  // | relational '>=' additive
110 
111  node::pointer_t result(additive());
112  if(!result)
113  {
114  return node::pointer_t();
115  }
116 
118  while(op != node_type_t::UNKNOWN)
119  {
120  position pos(f_current->get_position());
121 
122  // skip the relational operator
123  next();
124 
125  node::pointer_t rhs(additive());
126  if(!rhs)
127  {
128  return node::pointer_t();
129  }
130 
131  // if not comparable, go on, although we already generated an
132  // error; but at least the rest of the expression can be
133  // parsed properly
134  if(is_comparable(result, rhs))
135  {
136  // apply the equality operation
137  bool boolean_result(false);
138  switch(op)
139  {
141  boolean_result = is_less_than(result, rhs);
142  break;
143 
145  boolean_result = is_less_than(result, rhs) || is_equal(result, rhs);
146  break;
147 
149  boolean_result = !is_less_than(result, rhs) && !is_equal(result, rhs);
150  break;
151 
153  boolean_result = !is_less_than(result, rhs);
154  break;
155 
156  default:
157  throw csspp_exception_logic("expression.cpp:relational(): unexpected operator in 'op'."); // LCOV_EXCL_LINE
158 
159  }
160  result.reset(new node(node_type_t::BOOLEAN, pos));
161  result->set_boolean(boolean_result);
162  }
163 
165  }
166 
167  return result;
168 }
169 
170 } // namespace csspp
171 
172 // Local Variables:
173 // mode: cpp
174 // indent-tabs-mode: nil
175 // c-basic-offset: 4
176 // tab-width: 4
177 // End:
178 
179 // vim: ts=4 sw=4 et
node::pointer_t additive()
std::shared_ptr< node > pointer_t
Definition: node.h:122
node_type_t
Definition: node.h:36
node_type_t relational_operator(node::pointer_t n)
node::pointer_t relational()
int32_t constexpr mix_node_types(node_type_t a, node_type_t b)
Definition: node.h:114
bool is_comparable(node::pointer_t lhs, node::pointer_t rhs)
bool is_less_than(node::pointer_t lhs, node::pointer_t rhs)
bool is_equal(node::pointer_t lhs, node::pointer_t rhs)
node::pointer_t f_current
Definition: expression.h:151
static error & instance()
Definition: error.cpp:78

Documentation of CSS Preprocessor.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.