as2js: /home/snapwebsites/snapcpp/contrib/as2js/lib/node_operator.cpp Source File

as2js  0.1.14
AlexScript to JavaScript
node_operator.cpp
Go to the documentation of this file.
1 /* lib/node_operator.cpp
2 
3 Copyright (c) 2005-2019 Made to Order Software Corp. All Rights Reserved
4 
6 
7 Permission is hereby granted, free of charge, to any
8 person obtaining a copy of this software and
9 associated documentation files (the "Software"), to
10 deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify,
12 merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the
15 following conditions:
16 
17 The above copyright notice and this permission notice
18 shall be included in all copies or substantial
19 portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
22 ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
23 LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
24 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
25 EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 SOFTWARE.
31 
32 */
33 
34 #include "as2js/node.h"
35 
36 #include "as2js/exceptions.h"
37 
38 
49 namespace as2js
50 {
51 
52 
53 
54 /**********************************************************************/
55 /**********************************************************************/
56 /*** NODE OPERATOR **************************************************/
57 /**********************************************************************/
58 /**********************************************************************/
59 
66 namespace
67 {
68 
69 
78 {
86 
93  char const * f_name;
94 
103  int f_line;
104 };
105 
117 {
118  // single character -- sorted in ASCII
119  { Node::node_t::NODE_LOGICAL_NOT, "!", __LINE__ },
120  { Node::node_t::NODE_MODULO, "%", __LINE__ },
121  { Node::node_t::NODE_BITWISE_AND, "&", __LINE__ },
122  { Node::node_t::NODE_MULTIPLY, "*", __LINE__ },
123  { Node::node_t::NODE_ADD, "+", __LINE__ },
124  { Node::node_t::NODE_SUBTRACT, "-", __LINE__ },
125  { Node::node_t::NODE_DIVIDE, "/", __LINE__ },
126  { Node::node_t::NODE_LESS, "<", __LINE__ },
127  { Node::node_t::NODE_ASSIGNMENT, "=", __LINE__ },
128  { Node::node_t::NODE_GREATER, ">", __LINE__ },
129  { Node::node_t::NODE_BITWISE_XOR, "^", __LINE__ },
130  { Node::node_t::NODE_BITWISE_OR, "|", __LINE__ },
131  { Node::node_t::NODE_BITWISE_NOT, "~", __LINE__ },
132 
133  // two or more characters transformed to an enum only
134  { Node::node_t::NODE_ASSIGNMENT_ADD, "+=", __LINE__ },
135  { Node::node_t::NODE_ASSIGNMENT_BITWISE_AND, "&=", __LINE__ },
136  { Node::node_t::NODE_ASSIGNMENT_BITWISE_OR, "|=", __LINE__ },
137  { Node::node_t::NODE_ASSIGNMENT_BITWISE_XOR, "^=", __LINE__ },
138  { Node::node_t::NODE_ASSIGNMENT_DIVIDE, "/=", __LINE__ },
139  { Node::node_t::NODE_ASSIGNMENT_LOGICAL_AND, "&&=", __LINE__ },
140  { Node::node_t::NODE_ASSIGNMENT_LOGICAL_OR, "||=", __LINE__ },
141  { Node::node_t::NODE_ASSIGNMENT_LOGICAL_XOR, "^^=", __LINE__ },
142  { Node::node_t::NODE_ASSIGNMENT_MAXIMUM, ">?=", __LINE__ },
143  { Node::node_t::NODE_ASSIGNMENT_MINIMUM, "<?=", __LINE__ },
144  { Node::node_t::NODE_ASSIGNMENT_MODULO, "%=", __LINE__ },
145  { Node::node_t::NODE_ASSIGNMENT_MULTIPLY, "*=", __LINE__ },
146  { Node::node_t::NODE_ASSIGNMENT_POWER, "**=", __LINE__ },
147  { Node::node_t::NODE_ASSIGNMENT_ROTATE_LEFT, "<%=", __LINE__ },
148  { Node::node_t::NODE_ASSIGNMENT_ROTATE_RIGHT, ">%=", __LINE__ },
149  { Node::node_t::NODE_ASSIGNMENT_SHIFT_LEFT, "<<=", __LINE__ },
150  { Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT, ">>=", __LINE__ },
152  { Node::node_t::NODE_ASSIGNMENT_SUBTRACT, "-=", __LINE__ },
153  { Node::node_t::NODE_CALL, "()", __LINE__ },
154  { Node::node_t::NODE_COMPARE, "<=>", __LINE__ },
155  { Node::node_t::NODE_DECREMENT, "--x", __LINE__ },
156  { Node::node_t::NODE_EQUAL, "==", __LINE__ },
157  { Node::node_t::NODE_GREATER_EQUAL, ">=", __LINE__ },
158  { Node::node_t::NODE_INCREMENT, "++x", __LINE__ },
159  { Node::node_t::NODE_LESS_EQUAL, "<=", __LINE__ },
160  { Node::node_t::NODE_LOGICAL_AND, "&&", __LINE__ },
161  { Node::node_t::NODE_LOGICAL_OR, "||", __LINE__ },
162  { Node::node_t::NODE_LOGICAL_XOR, "^^", __LINE__ },
163  { Node::node_t::NODE_MATCH, "~=", __LINE__ },
164  { Node::node_t::NODE_MAXIMUM, ">?", __LINE__ },
165  { Node::node_t::NODE_MINIMUM, "<?", __LINE__ },
166  { Node::node_t::NODE_NOT_EQUAL, "!=", __LINE__ },
167  { Node::node_t::NODE_NOT_MATCH, "!~", __LINE__ },
168  { Node::node_t::NODE_POST_DECREMENT, "x--", __LINE__ },
169  { Node::node_t::NODE_POST_INCREMENT, "x++", __LINE__ },
170  { Node::node_t::NODE_POWER, "**", __LINE__ },
171  { Node::node_t::NODE_ROTATE_LEFT, "<%", __LINE__ },
172  { Node::node_t::NODE_ROTATE_RIGHT, ">%", __LINE__ },
173  { Node::node_t::NODE_SHIFT_LEFT, "<<", __LINE__ },
174  { Node::node_t::NODE_SHIFT_RIGHT, ">>", __LINE__ },
175  { Node::node_t::NODE_SHIFT_RIGHT_UNSIGNED, ">>>", __LINE__ },
176  { Node::node_t::NODE_SMART_MATCH, "~~", __LINE__ },
177  { Node::node_t::NODE_STRICTLY_EQUAL, "===", __LINE__ },
178  { Node::node_t::NODE_STRICTLY_NOT_EQUAL, "!==", __LINE__ }
179 
180  // the following does not make it in user redefinable operators
181  //{ Node::node_t::NODE_CONDITIONAL, "", __LINE__ },
182  //{ Node::node_t::NODE_DELETE, "", __LINE__ },
183  //{ Node::node_t::NODE_IN, "", __LINE__ },
184  //{ Node::node_t::NODE_INSTANCEOF, "", __LINE__ },
185  //{ Node::node_t::NODE_IS, "", __LINE__ },
186  //{ Node::node_t::NODE_LIST, "", __LINE__ },
187  //{ Node::node_t::NODE_NEW, "", __LINE__ },
188  //{ Node::node_t::NODE_RANGE, "", __LINE__ },
189  //{ Node::node_t::NODE_SCOPE, "", __LINE__ },
190 };
191 
197 size_t const g_operator_to_string_size = sizeof(g_operator_to_string) / sizeof(g_operator_to_string[0]);
198 
199 }
200 // no name namespace
201 
202 
203 
221 {
222 #if defined(_DEBUG) || defined(DEBUG)
223  {
224  // make sure that the node types are properly sorted
225  static bool checked = false;
226  if(!checked)
227  {
228  // check only once
229  checked = true;
230  for(size_t idx = 1; idx < g_operator_to_string_size; ++idx)
231  {
232  if(g_operator_to_string[idx].f_node <= g_operator_to_string[idx - 1].f_node)
233  {
234  std::cerr << "INTERNAL ERROR at offset " << idx // LCOV_EXCL_LINE
235  << " (line #" << g_operator_to_string[idx].f_line // LCOV_EXCL_LINE
236  << ", node type " << static_cast<uint32_t>(g_operator_to_string[idx].f_node) // LCOV_EXCL_LINE
237  << " vs. " << static_cast<uint32_t>(g_operator_to_string[idx - 1].f_node) // LCOV_EXCL_LINE
238  << "): the g_operator_to_string table isn't sorted properly. We can't binary search it." // LCOV_EXCL_LINE
239  << std::endl; // LCOV_EXCL_LINE
240  throw exception_internal_error("INTERNAL ERROR: node types not properly sorted, cannot properly search for operators using a binary search."); // LCOV_EXCL_LINE
241  }
242  }
243  }
244  }
245 #endif
246 
247  size_t i(0);
248  size_t j(g_operator_to_string_size);
249  while(i < j)
250  {
251  size_t p((j - i) / 2 + i);
252  int r(static_cast<int>(g_operator_to_string[p].f_node) - static_cast<int>(op));
253  if(r == 0)
254  {
255  return g_operator_to_string[p].f_name;
256  }
257  if(r < 0)
258  {
259  i = p + 1;
260  }
261  else
262  {
263  j = p;
264  }
265  }
266 
267  return nullptr;
268 }
269 
270 
303 {
304  for(size_t idx(0); idx < g_operator_to_string_size; ++idx)
305  {
306  // not sorted by name so we use a slow poke search...
307  if(str == g_operator_to_string[idx].f_name)
308  {
309  return g_operator_to_string[idx].f_node;
310  }
311  }
312 
313  if(str == "<>")
314  {
315  // this is an overload of the '!='
316  return node_t::NODE_NOT_EQUAL;
317  }
318  if(str == ":=")
319  {
320  // this is an overload of the '='
321  return node_t::NODE_ASSIGNMENT;
322  }
323 
324  return node_t::NODE_UNKNOWN;
325 }
326 
327 
328 }
329 // namespace as2js
330 
331 // vim: ts=4 sw=4 et
static node_t string_to_operator(String const &str)
Transform a string in an operator.
int f_line
The line on which the operator is defined.
The AlexScript to JavaScript namespace.
Definition: compiler.cpp:37
operator_to_string_t const g_operator_to_string[]
Table of operators and operator names.
static char const * operator_to_string(node_t op)
Transform an operator to a string.
size_t const g_operator_to_string_size
The size of the g_operator_to_string table.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly