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

as2js  0.1.14
AlexScript to JavaScript
node_convert.cpp
Go to the documentation of this file.
1 /* lib/node_convert.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 
61 namespace as2js
62 {
63 
64 
65 /**********************************************************************/
66 /**********************************************************************/
67 /*** DATA CONVERSION ************************************************/
68 /**********************************************************************/
69 /**********************************************************************/
70 
71 
89 {
90  modifying();
91 
92  // whatever the type of node we can always convert it to an unknown
93  // node since that's similar to "deleting" the node
95  // clear the node's data to avoid other problems?
96 }
97 
98 
124 {
125  modifying();
126 
127  // "a call to a getter" may be transformed from CALL to AS
128  // because a getter can very much look like a cast (false positive)
130  {
132  return true;
133  }
134 
135  return false;
136 }
137 
138 
165 {
166  switch(f_type)
167  {
168  case node_t::NODE_TRUE:
169  case node_t::NODE_FALSE:
170  // already a boolean
171  return f_type;
172 
173  case node_t::NODE_NULL:
175  return node_t::NODE_FALSE;
176 
177  case node_t::NODE_INT64:
178  return f_int.get() != 0 ? node_t::NODE_TRUE : node_t::NODE_FALSE;
179 
181 #pragma GCC diagnostic push
182 #pragma GCC diagnostic ignored "-Wfloat-equal"
183  return f_float.get() != 0.0 && !f_float.is_NaN() ? node_t::NODE_TRUE : node_t::NODE_FALSE;
184 #pragma GCC diagnostic pop
185 
186  case node_t::NODE_STRING:
188 
189  default:
190  // failure (cannot convert)
191  return node_t::NODE_UNDEFINED;
192 
193  }
194  /*NOTREACHED*/
195 }
196 
197 
227 {
228  modifying();
229 
230  switch(f_type)
231  {
232  case node_t::NODE_TRUE:
233  case node_t::NODE_FALSE:
234  // already a boolean
235  break;
236 
237  case node_t::NODE_NULL:
240  break;
241 
242  case node_t::NODE_INT64:
244  break;
245 
247 #pragma GCC diagnostic push
248 #pragma GCC diagnostic ignored "-Wfloat-equal"
250 #pragma GCC diagnostic pop
251  break;
252 
253  case node_t::NODE_STRING:
255  break;
256 
257  default:
258  // failure (cannot convert)
259  return false;
260 
261  }
262 
263  return true;
264 }
265 
266 
307 {
308  modifying();
309 
310  // getters are transformed from MEMBER to CALL
311  // setters are transformed from ASSIGNMENT to CALL
312  if(node_t::NODE_MEMBER == f_type // member getter
313  || node_t::NODE_ASSIGNMENT == f_type) // assignment setter
314  {
316  return true;
317  }
318 
319  return false;
320 }
321 
322 
340 {
341  modifying();
342 
343  switch(f_type)
344  {
346  // already an identifier
347  return true;
348 
351  set_string("private");
352  return true;
353 
356  set_string("protected");
357  return true;
358 
359  case node_t::NODE_PUBLIC:
361  set_string("public");
362  return true;
363 
364  default:
365  // failure (cannot convert)
366  return false;
367 
368  }
369  /*NOTREACHED*/
370 }
371 
372 
405 {
406  modifying();
407 
408  switch(f_type)
409  {
410  case node_t::NODE_INT64:
411  return true;
412 
414  if(f_float.is_NaN() || f_float.is_infinity())
415  {
416  // the C-like cast would use 0x800...000
417  // JavaScript expects zero instead
418  f_int.set(0);
419  }
420  else
421  {
422  f_int.set(f_float.get()); // C-like cast to integer with a floor() (no rounding)
423  }
424  break;
425 
426  case node_t::NODE_TRUE:
427  f_int.set(1);
428  break;
429 
430  case node_t::NODE_NULL:
431  case node_t::NODE_FALSE:
432  case node_t::NODE_UNDEFINED: // should return NaN, not possible with an integer...
433  f_int.set(0);
434  break;
435 
436  case node_t::NODE_STRING:
437  if(f_str.is_int64())
438  {
439  f_int.set(f_str.to_int64());
440  }
441  else if(f_str.is_float64())
442  {
443  f_int.set(f_str.to_float64()); // C-like cast to integer with a floor() (no rounding)
444  }
445  else
446  {
447  f_int.set(0); // should return NaN, not possible with an integer...
448  }
449  break;
450 
451  default:
452  // failure (cannot convert)
453  return false;
454 
455  }
456 
458  return true;
459 }
460 
461 
487 {
488  modifying();
489 
490  switch(f_type)
491  {
492  case node_t::NODE_INT64:
493  f_float.set(f_int.get());
494  break;
495 
497  return true;
498 
499  case node_t::NODE_TRUE:
500  f_float.set(1.0);
501  break;
502 
503  case node_t::NODE_NULL:
504  case node_t::NODE_FALSE:
505  f_float.set(0.0);
506  break;
507 
508  case node_t::NODE_STRING:
510  break;
511 
513  f_float.set_NaN();
514  break;
515 
516  default:
517  // failure (cannot convert)
518  return false;
519 
520  }
521 
523  return true;
524 }
525 
526 
537 {
538  modifying();
539 
540  switch(f_type)
541  {
544  break;
545 
546  default:
547  // failure (cannot convert)
548  return false;
549 
550  }
551 
552  return true;
553 }
554 
555 
588 {
589  modifying();
590 
591  switch(f_type)
592  {
593  case node_t::NODE_INT64:
595  break;
596 
597  case node_t::NODE_TRUE:
599  f_int.set(1);
600  break;
601 
602  case node_t::NODE_NULL:
603  case node_t::NODE_FALSE:
605  f_int.set(0);
606  break;
607 
610  f_float.set_NaN();
611  break;
612 
613  case node_t::NODE_STRING:
614  // JavaScript tends to force conversions from stings to numbers
615  // when possible (actually it nearly always is, and strings
616  // often become NaN as a result... the '+' and '+=' operators
617  // are an exception; also relational operators do not convert
618  // strings if both the left hand side and the right hand side
619  // are strings.)
622  break;
623 
624  default:
625  // failure (cannot convert)
626  return false;
627 
628  }
629 
630  return true;
631 }
632 
633 
676 {
677  modifying();
678 
679  switch(f_type)
680  {
681  case node_t::NODE_STRING:
682  return true;
683 
685  // this happens with special identifiers that are strings in the end
686  break;
687 
689  f_str = "undefined";
690  break;
691 
692  case node_t::NODE_NULL:
693  f_str = "null";
694  break;
695 
696  case node_t::NODE_TRUE:
697  f_str = "true";
698  break;
699 
700  case node_t::NODE_FALSE:
701  f_str = "false";
702  break;
703 
704  case node_t::NODE_INT64:
705  f_str = std::to_string(f_int.get());
706  break;
707 
709 #pragma GCC diagnostic push
710 #pragma GCC diagnostic ignored "-Wfloat-equal"
711  {
712  Float64::float64_type const value(f_float.get());
713  if(f_float.is_NaN())
714  {
715  f_str = "NaN";
716  }
717  else if(value == 0.0)
718  {
719  // make sure it does not become "0.0"
720  f_str = "0";
721  }
722  else if(f_float.is_negative_infinity())
723  {
724  f_str = "-Infinity";
725  }
726  else if(f_float.is_positive_infinity())
727  {
728  f_str = "Infinity";
729  }
730  else
731  {
732  f_str = std::to_string(value);
733  if(f_str.find('.') != f_str.npos)
734  {
735  while(f_str.back() == '0')
736  {
737  f_str.pop_back();
738  }
739  if(f_str.back() == '.')
740  {
741  f_str.pop_back();
742  }
743  }
744  }
745  }
746 #pragma GCC diagnostic pop
747  break;
748 
749  default:
750  // failure (cannot convert)
751  return false;
752 
753  }
755 
756  return true;
757 }
758 
759 
792 {
793  modifying();
794 
796  {
797  throw exception_internal_error("to_videntifier() called with a node other than a NODE_IDENTIFIER node");
798  }
799 
801 }
802 
803 
820 {
821  modifying();
822 
824  {
825  throw exception_internal_error("to_var_attribute() called with a node other than a NODE_VARIABLE node");
826  }
827 
829 }
830 
831 
832 }
833 // namespace as2js
834 
835 // vim: ts=4 sw=4 et
void to_videntifier()
Transform an identifier into a NODE_VIDENTIFIER.
float64_type get() const
Definition: float64.h:71
bool to_string()
Transform a node to a string.
double float64_type
Definition: float64.h:48
void set(float64_type const new_float)
Definition: float64.h:76
Float64::float64_type to_float64() const
Convert a string to a floating point number.
Definition: string.cpp:1230
bool to_identifier()
Convert this node to a NODE_IDENTIFIER.
bool to_call()
Convert a getter or setter to a function call.
node_t f_type
Definition: node.h:594
bool to_float64()
Convert this node to a NODE_FLOAT64.
void set_NaN()
Definition: float64.h:81
bool to_boolean()
Convert this node to a Boolean node.
bool to_number()
Convert this node to a number.
bool is_int64() const
Check whether this string represents a valid integer.
Definition: string.cpp:1037
bool to_as()
Transform a call in a NODE_AS node.
String f_str
Definition: node.h:610
bool is_infinity() const
Definition: float64.h:96
bool is_true() const
Check whether the string is considered true.
Definition: string.cpp:1253
bool is_positive_infinity() const
Definition: float64.h:101
void modifying() const
Test whether the node can be modified.
Definition: node_lock.cpp:91
bool to_int64()
Convert this node to a NODE_INT64.
void set(int64_type const new_int)
Definition: int64.h:74
bool is_NaN() const
Definition: float64.h:91
Int64::int64_type to_int64() const
Convert a string to an integer number.
Definition: string.cpp:1181
int64_type get() const
Definition: int64.h:69
node_t to_boolean_type_only() const
Check whether a node can be converted to Boolean.
bool to_label()
Convert this node to a label.
Float64 f_float
Definition: node.h:609
bool is_negative_infinity() const
Definition: float64.h:106
Int64 f_int
Definition: node.h:608
The AlexScript to JavaScript namespace.
Definition: compiler.cpp:37
bool is_float64() const
Check whether the string represents a valid floating pointer number.
Definition: string.cpp:1105
void to_var_attributes()
Transform a variable into a variable of attributes.
void to_unknown()
Transform any node to NODE_UNKNOWN.
void set_string(String const &value)
Set the string of this node.
Definition: node_value.cpp:183

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