LCOV - code coverage report
Current view: top level - as2js/lib - node_type.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 56 56 100.0 %
Date: 2014-08-10 Functions: 17 17 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* node_type.cpp -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2014 */
       2             : 
       3             : /*
       4             : 
       5             : Copyright (c) 2005-2014 Made to Order Software Corp.
       6             : 
       7             : http://snapwebsites.org/project/as2js
       8             : 
       9             : Permission is hereby granted, free of charge, to any
      10             : person obtaining a copy of this software and
      11             : associated documentation files (the "Software"), to
      12             : deal in the Software without restriction, including
      13             : without limitation the rights to use, copy, modify,
      14             : merge, publish, distribute, sublicense, and/or sell
      15             : copies of the Software, and to permit persons to whom
      16             : the Software is furnished to do so, subject to the
      17             : following conditions:
      18             : 
      19             : The above copyright notice and this permission notice
      20             : shall be included in all copies or substantial
      21             : portions of the Software.
      22             : 
      23             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
      24             : ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
      25             : LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
      26             : FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
      27             : EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      28             : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      29             : WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      30             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      31             : SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      32             : SOFTWARE.
      33             : 
      34             : */
      35             : 
      36             : #include    "as2js/node.h"
      37             : 
      38             : #include    "as2js/exceptions.h"
      39             : 
      40             : 
      41             : namespace as2js
      42             : {
      43             : 
      44             : 
      45             : 
      46             : /**********************************************************************/
      47             : /**********************************************************************/
      48             : /***  NODE  ***********************************************************/
      49             : /**********************************************************************/
      50             : /**********************************************************************/
      51             : 
      52             : 
      53             : namespace
      54             : {
      55             : 
      56             : struct type_name_t
      57             : {
      58             :     Node::node_t    f_type;
      59             :     char const *    f_name;
      60             :     int             f_line;
      61             : };
      62             : 
      63             : #define    TO_STR_sub(s)            #s
      64             : #define    NODE_TYPE_NAME(node)     { Node::node_t::NODE_##node, TO_STR_sub(node), __LINE__ }
      65             : 
      66             : type_name_t const g_node_type_name[] =
      67             : {
      68             :     // EOF is -1 on most C/C++ computers... so we have to do this one by hand
      69             :     { Node::node_t::NODE_EOF, "EOF", __LINE__ },
      70             :     NODE_TYPE_NAME(UNKNOWN),
      71             : 
      72             :     // the one character types have to be ordered by their character
      73             :     // which means it does not match the alphabetical order we
      74             :     // generally use
      75             :     NODE_TYPE_NAME(LOGICAL_NOT),                      // 0x21
      76             :     NODE_TYPE_NAME(MODULO),                           // 0x25
      77             :     NODE_TYPE_NAME(BITWISE_AND),                      // 0x26
      78             :     NODE_TYPE_NAME(OPEN_PARENTHESIS),                 // 0x28
      79             :     NODE_TYPE_NAME(CLOSE_PARENTHESIS),                // 0x29
      80             :     NODE_TYPE_NAME(MULTIPLY),                         // 0x2A
      81             :     NODE_TYPE_NAME(ADD),                              // 0x2B
      82             :     NODE_TYPE_NAME(COMMA),                            // 0x2C
      83             :     NODE_TYPE_NAME(SUBTRACT),                         // 0x2D
      84             :     NODE_TYPE_NAME(MEMBER),                           // 0x2E
      85             :     NODE_TYPE_NAME(DIVIDE),                           // 0x2F
      86             :     NODE_TYPE_NAME(COLON),                            // 0x3A
      87             :     NODE_TYPE_NAME(SEMICOLON),                        // 0x3B
      88             :     NODE_TYPE_NAME(LESS),                             // 0x3C
      89             :     NODE_TYPE_NAME(ASSIGNMENT),                       // 0x3D
      90             :     NODE_TYPE_NAME(GREATER),                          // 0x3E
      91             :     NODE_TYPE_NAME(CONDITIONAL),                      // 0x3F
      92             :     NODE_TYPE_NAME(OPEN_SQUARE_BRACKET),              // 0x5B
      93             :     NODE_TYPE_NAME(CLOSE_SQUARE_BRACKET),             // 0x5D
      94             :     NODE_TYPE_NAME(BITWISE_XOR),                      // 0x5E
      95             :     NODE_TYPE_NAME(OPEN_CURVLY_BRACKET),              // 0x7B
      96             :     NODE_TYPE_NAME(BITWISE_OR),                       // 0x7C
      97             :     NODE_TYPE_NAME(CLOSE_CURVLY_BRACKET),             // 0x7D
      98             :     NODE_TYPE_NAME(BITWISE_NOT),                      // 0x7E
      99             : 
     100             :     NODE_TYPE_NAME(ABSTRACT),
     101             :     NODE_TYPE_NAME(ARRAY),
     102             :     NODE_TYPE_NAME(ARRAY_LITERAL),
     103             :     NODE_TYPE_NAME(AS),
     104             :     NODE_TYPE_NAME(ASSIGNMENT_ADD),
     105             :     NODE_TYPE_NAME(ASSIGNMENT_BITWISE_AND),
     106             :     NODE_TYPE_NAME(ASSIGNMENT_BITWISE_OR),
     107             :     NODE_TYPE_NAME(ASSIGNMENT_BITWISE_XOR),
     108             :     NODE_TYPE_NAME(ASSIGNMENT_DIVIDE),
     109             :     NODE_TYPE_NAME(ASSIGNMENT_LOGICAL_AND),
     110             :     NODE_TYPE_NAME(ASSIGNMENT_LOGICAL_OR),
     111             :     NODE_TYPE_NAME(ASSIGNMENT_LOGICAL_XOR),
     112             :     NODE_TYPE_NAME(ASSIGNMENT_MAXIMUM),
     113             :     NODE_TYPE_NAME(ASSIGNMENT_MINIMUM),
     114             :     NODE_TYPE_NAME(ASSIGNMENT_MODULO),
     115             :     NODE_TYPE_NAME(ASSIGNMENT_MULTIPLY),
     116             :     NODE_TYPE_NAME(ASSIGNMENT_POWER),
     117             :     NODE_TYPE_NAME(ASSIGNMENT_ROTATE_LEFT),
     118             :     NODE_TYPE_NAME(ASSIGNMENT_ROTATE_RIGHT),
     119             :     NODE_TYPE_NAME(ASSIGNMENT_SHIFT_LEFT),
     120             :     NODE_TYPE_NAME(ASSIGNMENT_SHIFT_RIGHT),
     121             :     NODE_TYPE_NAME(ASSIGNMENT_SHIFT_RIGHT_UNSIGNED),
     122             :     NODE_TYPE_NAME(ASSIGNMENT_SUBTRACT),
     123             :     NODE_TYPE_NAME(ATTRIBUTES),
     124             :     NODE_TYPE_NAME(AUTO),
     125             :     NODE_TYPE_NAME(BOOLEAN),
     126             :     NODE_TYPE_NAME(BREAK),
     127             :     NODE_TYPE_NAME(BYTE),
     128             :     NODE_TYPE_NAME(CALL),
     129             :     NODE_TYPE_NAME(CASE),
     130             :     NODE_TYPE_NAME(CATCH),
     131             :     NODE_TYPE_NAME(CHAR),
     132             :     NODE_TYPE_NAME(CLASS),
     133             :     NODE_TYPE_NAME(COMPARE),
     134             :     NODE_TYPE_NAME(CONST),
     135             :     NODE_TYPE_NAME(CONTINUE),
     136             :     NODE_TYPE_NAME(DEBUGGER),
     137             :     NODE_TYPE_NAME(DECREMENT),
     138             :     NODE_TYPE_NAME(DEFAULT),
     139             :     NODE_TYPE_NAME(DELETE),
     140             :     NODE_TYPE_NAME(DIRECTIVE_LIST),
     141             :     NODE_TYPE_NAME(DO),
     142             :     NODE_TYPE_NAME(DOUBLE),
     143             :     NODE_TYPE_NAME(ELSE),
     144             :     NODE_TYPE_NAME(EMPTY),
     145             :     NODE_TYPE_NAME(ENSURE),
     146             :     NODE_TYPE_NAME(ENUM),
     147             :     NODE_TYPE_NAME(EQUAL),
     148             :     NODE_TYPE_NAME(EXCLUDE),
     149             :     NODE_TYPE_NAME(EXTENDS),
     150             :     NODE_TYPE_NAME(EXPORT),
     151             :     NODE_TYPE_NAME(FALSE),
     152             :     NODE_TYPE_NAME(FINAL),
     153             :     NODE_TYPE_NAME(FINALLY),
     154             :     NODE_TYPE_NAME(FLOAT),
     155             :     NODE_TYPE_NAME(FLOAT64),
     156             :     NODE_TYPE_NAME(FOR),
     157             :     NODE_TYPE_NAME(FUNCTION),
     158             :     NODE_TYPE_NAME(GOTO),
     159             :     NODE_TYPE_NAME(GREATER_EQUAL),
     160             :     NODE_TYPE_NAME(IDENTIFIER),
     161             :     NODE_TYPE_NAME(IF),
     162             :     NODE_TYPE_NAME(IMPLEMENTS),
     163             :     NODE_TYPE_NAME(IMPORT),
     164             :     NODE_TYPE_NAME(IN),
     165             :     NODE_TYPE_NAME(INCLUDE),
     166             :     NODE_TYPE_NAME(INCREMENT),
     167             :     NODE_TYPE_NAME(INSTANCEOF),
     168             :     NODE_TYPE_NAME(INT64),
     169             :     NODE_TYPE_NAME(INTERFACE),
     170             :     NODE_TYPE_NAME(INVARIANT),
     171             :     NODE_TYPE_NAME(IS),
     172             :     NODE_TYPE_NAME(LABEL),
     173             :     NODE_TYPE_NAME(LESS_EQUAL),
     174             :     NODE_TYPE_NAME(LIST),
     175             :     NODE_TYPE_NAME(LOGICAL_AND),
     176             :     NODE_TYPE_NAME(LOGICAL_OR),
     177             :     NODE_TYPE_NAME(LOGICAL_XOR),
     178             :     NODE_TYPE_NAME(LONG),
     179             :     NODE_TYPE_NAME(MATCH),
     180             :     NODE_TYPE_NAME(MAXIMUM),
     181             :     NODE_TYPE_NAME(MINIMUM),
     182             :     NODE_TYPE_NAME(NAME),
     183             :     NODE_TYPE_NAME(NAMESPACE),
     184             :     NODE_TYPE_NAME(NATIVE),
     185             :     NODE_TYPE_NAME(NEW),
     186             :     NODE_TYPE_NAME(NOT_EQUAL),
     187             :     NODE_TYPE_NAME(NOT_MATCH),
     188             :     //NODE_TYPE_NAME(NULL), -- macro does not work in this case
     189             :     { Node::node_t::NODE_NULL, "NULL", __LINE__ },
     190             :     NODE_TYPE_NAME(OBJECT_LITERAL),
     191             :     NODE_TYPE_NAME(PACKAGE),
     192             :     NODE_TYPE_NAME(PARAM),
     193             :     NODE_TYPE_NAME(PARAMETERS),
     194             :     NODE_TYPE_NAME(PARAM_MATCH),
     195             :     NODE_TYPE_NAME(POST_DECREMENT),
     196             :     NODE_TYPE_NAME(POST_INCREMENT),
     197             :     NODE_TYPE_NAME(POWER),
     198             :     NODE_TYPE_NAME(PRIVATE),
     199             :     NODE_TYPE_NAME(PROGRAM),
     200             :     NODE_TYPE_NAME(PROTECTED),
     201             :     NODE_TYPE_NAME(PUBLIC),
     202             :     NODE_TYPE_NAME(RANGE),
     203             :     NODE_TYPE_NAME(REGULAR_EXPRESSION),
     204             :     NODE_TYPE_NAME(REQUIRE),
     205             :     NODE_TYPE_NAME(REST),
     206             :     NODE_TYPE_NAME(RETURN),
     207             :     NODE_TYPE_NAME(ROOT),
     208             :     NODE_TYPE_NAME(ROTATE_LEFT),
     209             :     NODE_TYPE_NAME(ROTATE_RIGHT),
     210             :     NODE_TYPE_NAME(SCOPE),
     211             :     NODE_TYPE_NAME(SET),
     212             :     NODE_TYPE_NAME(SHIFT_LEFT),
     213             :     NODE_TYPE_NAME(SHIFT_RIGHT),
     214             :     NODE_TYPE_NAME(SHIFT_RIGHT_UNSIGNED),
     215             :     NODE_TYPE_NAME(SHORT),
     216             :     NODE_TYPE_NAME(SMART_MATCH),
     217             :     NODE_TYPE_NAME(STATIC),
     218             :     NODE_TYPE_NAME(STRICTLY_EQUAL),
     219             :     NODE_TYPE_NAME(STRICTLY_NOT_EQUAL),
     220             :     NODE_TYPE_NAME(STRING),
     221             :     NODE_TYPE_NAME(SUPER),
     222             :     NODE_TYPE_NAME(SWITCH),
     223             :     NODE_TYPE_NAME(SYNCHRONIZED),
     224             :     NODE_TYPE_NAME(THEN),
     225             :     NODE_TYPE_NAME(THIS),
     226             :     NODE_TYPE_NAME(THROW),
     227             :     NODE_TYPE_NAME(THROWS),
     228             :     NODE_TYPE_NAME(TRANSIENT),
     229             :     NODE_TYPE_NAME(TRUE),
     230             :     NODE_TYPE_NAME(TRY),
     231             :     NODE_TYPE_NAME(TYPE),
     232             :     NODE_TYPE_NAME(TYPEOF),
     233             :     NODE_TYPE_NAME(UNDEFINED),
     234             :     NODE_TYPE_NAME(USE),
     235             :     NODE_TYPE_NAME(VAR),
     236             :     NODE_TYPE_NAME(VARIABLE),
     237             :     NODE_TYPE_NAME(VAR_ATTRIBUTES),
     238             :     NODE_TYPE_NAME(VIDENTIFIER),
     239             :     NODE_TYPE_NAME(VOID),
     240             :     NODE_TYPE_NAME(VOLATILE),
     241             :     NODE_TYPE_NAME(WHILE),
     242             :     NODE_TYPE_NAME(WITH),
     243             :     NODE_TYPE_NAME(YIELD),
     244             : 
     245             :     // end list
     246             :     //{ Node::node_t::NODE_UNKNOWN, nullptr, __LINE__ }
     247             : };
     248             : size_t const g_node_type_name_size = sizeof(g_node_type_name) / sizeof(g_node_type_name[0]);
     249             : 
     250             : 
     251             : }
     252             : // no name namespace
     253             : 
     254             : 
     255             : /** \brief Retrieve the type of the node.
     256             :  *
     257             :  * This function gets the type of the node and returns it. The type
     258             :  * is one of the node_t::NODE_... values.
     259             :  *
     260             :  * Note the value of the node types are not all sequencial. The lower
     261             :  * portion used one to one with characters has many sparse places.
     262             :  * However, the node constructor ensures that only valid strings get
     263             :  * created.
     264             :  *
     265             :  * There are some functions available to convert a certain number of
     266             :  * nodes. These are used by the compiler and optimizer to implement
     267             :  * their functions.
     268             :  *
     269             :  * \li to_unknown() -- change any node to NODE_UNKNOWN
     270             :  * \li to_as() -- change a NODE_CALL to a NODE_AS
     271             :  * \li to_boolean_type_only() -- check whether a node represents NODE_TRUE
     272             :  *                               or NODE_FALSE
     273             :  * \li to_boolean() -- change to a NODE_TRUE or NODE_FALSE if possible
     274             :  * \li to_call() -- change a getter or setter to a NODE_CALL
     275             :  * \li to_int64() -- force a number to a NODE_INT64
     276             :  * \li to_float64() -- force a number to a NODE_FLOAT64
     277             :  * \li to_number() -- change a string to a NODE_FLOAT64
     278             :  * \li to_string() -- change a number to a NODE_STRING
     279             :  * \li to_videntifier() -- change a NODE_IDENTIFIER to a NODE_VIDENTIFIER
     280             :  * \li to_var_attributes() -- change a NODE_VARIABLE to a NODE_VAR_ATTRIBUTES
     281             :  *
     282             :  * \return The current type of the node.
     283             :  */
     284   311743344 : Node::node_t Node::get_type() const
     285             : {
     286   311743344 :     return f_type;
     287             : }
     288             : 
     289             : 
     290             : /** \breif Convert the specified type to a string.
     291             :  *
     292             :  * The type of the node (NODE_...) can be retrieved as a string using this
     293             :  * function. In pretty much all cases this is done whenever an error occurs
     294             :  * and not in normal circumstances. It is also used to debug the node tree.
     295             :  *
     296             :  * Note that if you have a node, you probably want to call get_type_name()
     297             :  * instead.
     298             :  *
     299             :  * \return A null terminated C-like string with the node name.
     300             :  *
     301             :  * \sa get_type_name()
     302             :  */
     303    21328945 : char const *Node::type_to_string(node_t type)
     304             : {
     305             : #if defined(_DEBUG) || defined(DEBUG)
     306             :     {
     307             :         // make sure that the node types are properly sorted
     308             :         static bool checked = false;
     309    21328945 :         if(!checked)
     310             :         {
     311             :             // check only once
     312           1 :             checked = true;
     313         169 :             for(size_t idx = 1; idx < g_node_type_name_size; ++idx)
     314             :             {
     315         168 :                 if(g_node_type_name[idx].f_type <= g_node_type_name[idx - 1].f_type)
     316             :                 {
     317             :                     // if the table is properly defined then we cannot reach
     318             :                     // these lines
     319             :                     std::cerr << "INTERNAL ERROR at offset " << idx                                                     // LCOV_EXCL_LINE
     320             :                               << " (line #" << g_node_type_name[idx].f_line                                             // LCOV_EXCL_LINE
     321             :                               << ", node type " << static_cast<uint32_t>(g_node_type_name[idx].f_type)                  // LCOV_EXCL_LINE
     322             :                               << " vs. " << static_cast<uint32_t>(g_node_type_name[idx - 1].f_type)                     // LCOV_EXCL_LINE
     323             :                               << "): the g_node_type_name table is not sorted properly. We cannot binary search it."    // LCOV_EXCL_LINE
     324             :                               << std::endl;                                                                             // LCOV_EXCL_LINE
     325             :                     throw exception_internal_error("INTERNAL ERROR: node type names not properly sorted, cannot properly search for names using a binary search."); // LCOV_EXCL_LINE
     326             :                 }
     327             :             }
     328             :         }
     329             :     }
     330             : #endif
     331             : 
     332             :     size_t i, j, p;
     333             :     int    r;
     334             : 
     335    21328945 :     i = 0;
     336    21328945 :     j = g_node_type_name_size;
     337   142607161 :     while(i < j)
     338             :     {
     339   142607161 :         p = (j - i) / 2 + i;
     340   142607161 :         r = static_cast<int>(g_node_type_name[p].f_type) - static_cast<int>(static_cast<node_t>(type));
     341   142607161 :         if(r == 0)
     342             :         {
     343    21328945 :             return g_node_type_name[p].f_name;
     344             :         }
     345   121278216 :         if(r < 0)
     346             :         {
     347    53133111 :             i = p + 1;
     348             :         }
     349             :         else
     350             :         {
     351    68145105 :             j = p;
     352             :         }
     353             :     }
     354             : 
     355             :     throw exception_internal_error("INTERNAL ERROR: node type name not found!?."); // LCOV_EXCL_LINE
     356             : }
     357             : 
     358             : 
     359             : /** \brief Retrieve the type of this node.
     360             :  *
     361             :  * This function retrieves the type of this node.
     362             :  *
     363             :  * This function is equivalent to:
     364             :  *
     365             :  * \code
     366             :  *      char const *name(Node::type_to_string(node->get_type()));
     367             :  * \endcode
     368             :  *
     369             :  * \return The type of this node as a string.
     370             :  *
     371             :  * \sa type_to_string()
     372             :  */
     373    21279787 : char const *Node::get_type_name() const
     374             : {
     375    21279787 :     return type_to_string(f_type);
     376             : }
     377             : 
     378             : 
     379             : /** \brief Return true if node represens a number.
     380             :  *
     381             :  * This function returns true if the node is an integer or a
     382             :  * floating point value.
     383             :  *
     384             :  * Note that this function returns false on a string that
     385             :  * represents a valid number.
     386             :  *
     387             :  * Note that JavaScript also considered Boolean values and null as
     388             :  * valid numbers. To test such, use is_nan() instead
     389             :  *
     390             :  * \return true if this node represents a number
     391             :  */
     392         340 : bool Node::is_number() const
     393             : {
     394         340 :     return f_type == node_t::NODE_INT64 || f_type == node_t::NODE_FLOAT64;
     395             : }
     396             : 
     397             : 
     398             : /** \brief Check whether this node represents a NaN if converted to a number.
     399             :  *
     400             :  * When converting a node to a number (to_number() function) we accept a
     401             :  * certain number of parameters as numbers:
     402             :  *
     403             :  * \li Integers (unchanged)
     404             :  * \li Float points (unchanged)
     405             :  * \li True (1) or False (0)
     406             :  * \li Null (0)
     407             :  * \li Strings that represent valid numbers as a whole
     408             :  *
     409             :  * \return true if the value could not be converted to a number.
     410             :  */
     411         502 : bool Node::is_nan() const
     412             : {
     413         502 :     if(f_type == node_t::NODE_STRING)
     414             :     {
     415           3 :         return f_str.is_number();
     416             :     }
     417             : 
     418         499 :     return f_type != node_t::NODE_INT64
     419         497 :         && f_type != node_t::NODE_FLOAT64
     420         495 :         && f_type != node_t::NODE_TRUE
     421         493 :         && f_type != node_t::NODE_FALSE
     422         996 :         && f_type != node_t::NODE_NULL;
     423             : }
     424             : 
     425             : 
     426             : /** \brief Check whether a node is an integer.
     427             :  *
     428             :  * This function checks whether the type of the node is NODE_INT64.
     429             :  *
     430             :  * \return true if the node type is NODE_INT64.
     431             :  */
     432         339 : bool Node::is_int64() const
     433             : {
     434         339 :     return f_type == node_t::NODE_INT64;
     435             : }
     436             : 
     437             : 
     438             : /** \brief Check whether a node is a floating point.
     439             :  *
     440             :  * This function checks whether the type of the node is NODE_FLOAT64.
     441             :  *
     442             :  * \return true if the node type is NODE_FLOAT64.
     443             :  */
     444         339 : bool Node::is_float64() const
     445             : {
     446         339 :     return f_type == node_t::NODE_FLOAT64;
     447             : }
     448             : 
     449             : 
     450             : /** \brief Check whether a node is a Boolean value.
     451             :  *
     452             :  * This function checks whether the type of the node is NODE_TRUE or
     453             :  * NODE_FALSE.
     454             :  *
     455             :  * \return true if the node type represents a boolean value.
     456             :  */
     457         340 : bool Node::is_boolean() const
     458             : {
     459         340 :     return f_type == node_t::NODE_TRUE || f_type == node_t::NODE_FALSE;
     460             : }
     461             : 
     462             : 
     463             : /** \brief Check whether a node represents the true Boolean value.
     464             :  *
     465             :  * This function checks whether the type of the node is NODE_TRUE.
     466             :  *
     467             :  * \return true if the node type represents true.
     468             :  */
     469         339 : bool Node::is_true() const
     470             : {
     471         339 :     return f_type == node_t::NODE_TRUE;
     472             : }
     473             : 
     474             : 
     475             : /** \brief Check whether a node represents the false Boolean value.
     476             :  *
     477             :  * This function checks whether the type of the node is NODE_FALSE.
     478             :  *
     479             :  * \return true if the node type represents false.
     480             :  */
     481         339 : bool Node::is_false() const
     482             : {
     483         339 :     return f_type == node_t::NODE_FALSE;
     484             : }
     485             : 
     486             : 
     487             : /** \brief Check whether a node is a string.
     488             :  *
     489             :  * This function checks whether the type of the node is NODE_STRING.
     490             :  *
     491             :  * \return true if the node type represents a string value.
     492             :  */
     493         339 : bool Node::is_string() const
     494             : {
     495         339 :     return f_type == node_t::NODE_STRING;
     496             : }
     497             : 
     498             : 
     499             : /** \brief Check whether a node is the special value undefined.
     500             :  *
     501             :  * This function checks whether the type of the node is NODE_UNDEFINED.
     502             :  *
     503             :  * \return true if the node type represents the undefined value.
     504             :  */
     505         339 : bool Node::is_undefined() const
     506             : {
     507         339 :     return f_type == node_t::NODE_UNDEFINED;
     508             : }
     509             : 
     510             : 
     511             : /** \brief Check whether a node is the special value null.
     512             :  *
     513             :  * This function checks whether the type of the node is NODE_NULL.
     514             :  *
     515             :  * \return true if the node type represents the null value.
     516             :  */
     517         339 : bool Node::is_null() const
     518             : {
     519         339 :     return f_type == node_t::NODE_NULL;
     520             : }
     521             : 
     522             : 
     523             : /** \brief Check whether a node is an identifier.
     524             :  *
     525             :  * This function checks whether the type of the node is NODE_IDENTIFIER
     526             :  * or NODE_VIDENTIFIER.
     527             :  *
     528             :  * \return true if the node type represents an identifier value.
     529             :  */
     530         340 : bool Node::is_identifier() const
     531             : {
     532         340 :     return f_type == node_t::NODE_IDENTIFIER || f_type == node_t::NODE_VIDENTIFIER;
     533             : }
     534             : 
     535             : 
     536             : /** \brief Check whether a node has side effects.
     537             :  *
     538             :  * This function checks whether a node, or any of its children, has a
     539             :  * side effect.
     540             :  *
     541             :  * Having a side effect means that the function of the node is to modify
     542             :  * something. For example an assignment modifies its destination which
     543             :  * is an obvious side effect.
     544             :  *
     545             :  * The test is run against this node and all of its children because if
     546             :  * any one node implies a modification, the tree as a whole implies a
     547             :  * modification and thus the function must return true.
     548             :  *
     549             :  * \return true if this node has a side effect.
     550             :  */
     551         388 : bool Node::has_side_effects() const
     552             : {
     553             :     //
     554             :     // Well... I'm wondering if we can really
     555             :     // trust this current version.
     556             :     //
     557             :     // Problem I:
     558             :     //    some identifiers can be getters and
     559             :     //    they can have side effects; though
     560             :     //    a getter should be considered constant
     561             :     //    toward the object being read and thus
     562             :     //    it should be fine in 99% of cases
     563             :     //    [imagine a serial number generator
     564             :     //    though...]
     565             :     //
     566             :     // Problem II:
     567             :     //    some operators may not have been
     568             :     //    compiled yet and they could have
     569             :     //    side effects too; now this is much
     570             :     //    less likely a problem because then
     571             :     //    the programmer is most certainly
     572             :     //    creating a really weird program
     573             :     //    with all sorts of side effects that
     574             :     //    he wants no one else to know about,
     575             :     //    etc. etc. etc.
     576             :     //
     577             :     // Problem III:
     578             :     //    Note that we do not memorize whether
     579             :     //    a node has side effects because its
     580             :     //    children may change and then side
     581             :     //    effects may appear and disappear.
     582             :     //
     583             : 
     584         388 :     switch(f_type)
     585             :     {
     586             :     case node_t::NODE_ASSIGNMENT:
     587             :     case node_t::NODE_ASSIGNMENT_ADD:
     588             :     case node_t::NODE_ASSIGNMENT_BITWISE_AND:
     589             :     case node_t::NODE_ASSIGNMENT_BITWISE_OR:
     590             :     case node_t::NODE_ASSIGNMENT_BITWISE_XOR:
     591             :     case node_t::NODE_ASSIGNMENT_DIVIDE:
     592             :     case node_t::NODE_ASSIGNMENT_LOGICAL_AND:
     593             :     case node_t::NODE_ASSIGNMENT_LOGICAL_OR:
     594             :     case node_t::NODE_ASSIGNMENT_LOGICAL_XOR:
     595             :     case node_t::NODE_ASSIGNMENT_MAXIMUM:
     596             :     case node_t::NODE_ASSIGNMENT_MINIMUM:
     597             :     case node_t::NODE_ASSIGNMENT_MODULO:
     598             :     case node_t::NODE_ASSIGNMENT_MULTIPLY:
     599             :     case node_t::NODE_ASSIGNMENT_POWER:
     600             :     case node_t::NODE_ASSIGNMENT_ROTATE_LEFT:
     601             :     case node_t::NODE_ASSIGNMENT_ROTATE_RIGHT:
     602             :     case node_t::NODE_ASSIGNMENT_SHIFT_LEFT:
     603             :     case node_t::NODE_ASSIGNMENT_SHIFT_RIGHT:
     604             :     case node_t::NODE_ASSIGNMENT_SHIFT_RIGHT_UNSIGNED:
     605             :     case node_t::NODE_ASSIGNMENT_SUBTRACT:
     606             :     case node_t::NODE_CALL:
     607             :     case node_t::NODE_DECREMENT:
     608             :     case node_t::NODE_DELETE:
     609             :     case node_t::NODE_INCREMENT:
     610             :     case node_t::NODE_NEW:
     611             :     case node_t::NODE_POST_DECREMENT:
     612             :     case node_t::NODE_POST_INCREMENT:
     613          85 :         return true;
     614             : 
     615             :     //case NODE_IDENTIFIER:
     616             :     //
     617             :     // TODO: Test whether this is a reference to a getter
     618             :     //       function (needs to be compiled already...)
     619             :     //    
     620             :     //    break;
     621             : 
     622             :     default:
     623         303 :         break;
     624             : 
     625             :     }
     626             : 
     627         312 :     for(size_t idx(0); idx < f_children.size(); ++idx)
     628             :     {
     629          15 :         if(f_children[idx] && f_children[idx]->has_side_effects())
     630             :         {
     631           6 :             return true;
     632             :         }
     633             :     }
     634             : 
     635         297 :     return false;
     636             : }
     637             : 
     638             : 
     639          20 : }
     640             : // namespace as2js
     641             : 
     642             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9