LCOV - code coverage report
Current view: top level - lib - parser_directive.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 208 208 100.0 %
Date: 2014-11-22 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* parser_directive.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/parser.h"
      37             : #include    "as2js/message.h"
      38             : #include    "as2js/exceptions.h"
      39             : 
      40             : 
      41             : namespace as2js
      42             : {
      43             : 
      44             : 
      45             : /**********************************************************************/
      46             : /**********************************************************************/
      47             : /***  PARSER DIRECTIVES  **********************************************/
      48             : /**********************************************************************/
      49             : /**********************************************************************/
      50             : 
      51     8530135 : void Parser::attributes(Node::pointer_t& node)
      52             : {
      53             :     // Attributes are read first.
      54             :     // Depending on what follows the first set of attributes
      55             :     // we can determine what we've got (expression, statement,
      56             :     // etc.)
      57             :     // There can be no attribute and the last IDENTIFIER may
      58             :     // not be an attribute, also...
      59             :     for(;;)
      60             :     {
      61     6522985 :         switch(f_node->get_type())
      62             :         {
      63             :         case Node::node_t::NODE_ABSTRACT:
      64             :         case Node::node_t::NODE_FALSE:
      65             :         case Node::node_t::NODE_FINAL:
      66             :         case Node::node_t::NODE_IDENTIFIER:
      67             :         case Node::node_t::NODE_NATIVE:
      68             :         case Node::node_t::NODE_PRIVATE:
      69             :         case Node::node_t::NODE_PROTECTED:
      70             :         case Node::node_t::NODE_PUBLIC:
      71             :         case Node::node_t::NODE_STATIC:
      72             :         case Node::node_t::NODE_TRANSIENT:
      73             :         case Node::node_t::NODE_TRUE:
      74             :         case Node::node_t::NODE_VOLATILE:
      75             :             // TODO: Check that we don't find the same type twice...
      76             :             //       We may also want to enforce an order in some cases?
      77     2007150 :             break;
      78             : 
      79             :         default:
      80     9031670 :             return;
      81             : 
      82             :         }
      83             : 
      84     2007150 :         if(!node)
      85             :         {
      86     1769582 :             node = f_lexer->get_new_node(Node::node_t::NODE_ATTRIBUTES);
      87             :         }
      88             : 
      89             :         // at this point attributes are kept as nodes, the directive()
      90             :         // function saves them as a link in the node, later the compiler
      91             :         // transform them in actual NODE_ATTR_... flags
      92     2007150 :         node->append_child(f_node);
      93     2007150 :         get_token();
      94             :     }
      95             : }
      96             : 
      97             : 
      98             : 
      99             : 
     100     6409777 : void Parser::directive_list(Node::pointer_t& node)
     101             : {
     102     2238021 :     if(node)
     103             :     {
     104             :         // should not happen, if it does, we have got a really bad internal error
     105             :         throw exception_internal_error("directive_list() called with a non-null node pointer"); // LCOV_EXCL_LINE
     106             :     }
     107             : 
     108     2238021 :     node = f_lexer->get_new_node(Node::node_t::NODE_DIRECTIVE_LIST);
     109             :     for(;;)
     110             :     {
     111             :         // skip empty statements quickly
     112    14187964 :         while(f_node->get_type() == Node::node_t::NODE_SEMICOLON)
     113             :         {
     114     1368410 :             get_token();
     115             :         }
     116             : 
     117     6409777 :         switch(f_node->get_type())
     118             :         {
     119             :         case Node::node_t::NODE_EOF:
     120             :         case Node::node_t::NODE_ELSE:
     121             :         case Node::node_t::NODE_CLOSE_CURVLY_BRACKET:
     122             :             // these end the list of directives
     123     4476042 :             return;
     124             : 
     125             :         default:
     126     4171756 :             directive(node);
     127     4171756 :             break;
     128             : 
     129             :         }
     130             :     }
     131             :     /*NOTREACHED*/
     132             : }
     133             : 
     134             : 
     135     4433915 : void Parser::directive(Node::pointer_t& node)
     136             : {
     137             :     // we expect node to be a list of directives already
     138             :     // when defined (see directive_list())
     139     4433915 :     if(!node)
     140             :     {
     141      262159 :         node = f_lexer->get_new_node(Node::node_t::NODE_DIRECTIVE_LIST);
     142             :     }
     143             : 
     144             :     // read attributes (identifiers, public/private, true/false)
     145             :     // if we find attributes and the directive accepts them,
     146             :     // then they are added to the directive as the last entry
     147     4433915 :     Node::pointer_t attr_list;
     148     4433915 :     attributes(attr_list);
     149     4433915 :     size_t attr_count(attr_list ? attr_list->get_children_size() : 0);
     150     8835062 :     Node::pointer_t instruction_node(f_node);
     151     4433915 :     Node::node_t type(f_node->get_type());
     152     8835062 :     Node::pointer_t last_attr;
     153             : 
     154             :     // depending on the following token, we may want to restore
     155             :     // the last "attribute" (if it is an identifier)
     156     4433915 :     switch(type)
     157             :     {
     158             :     case Node::node_t::NODE_COLON:
     159       57344 :         if(attr_count == 0)
     160             :         {
     161        8192 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_OPERATOR, f_lexer->get_input()->get_position());
     162        8192 :             msg << "unexpected ':' without an identifier.";
     163             :             // skip the spurious colon and return
     164        8192 :             get_token();
     165        8192 :             return;
     166             :         }
     167       49152 :         last_attr = attr_list->get_child(attr_count - 1);
     168       49152 :         if(last_attr->get_type() != Node::node_t::NODE_IDENTIFIER)
     169             :         {
     170             :             // special cases of labels in classes
     171       65536 :             if(last_attr->get_type() != Node::node_t::NODE_PRIVATE
     172       24576 :             && last_attr->get_type() != Node::node_t::NODE_PROTECTED
     173       49152 :             && last_attr->get_type() != Node::node_t::NODE_PUBLIC)
     174             :             {
     175        8192 :                 Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_OPERATOR, f_lexer->get_input()->get_position());
     176        8192 :                 msg << "unexpected ':' without a valid label.";
     177             :                 // skip the spurious colon and return
     178        8192 :                 get_token();
     179        8192 :                 return;
     180             :             }
     181       24576 :             last_attr->to_identifier();
     182             :         }
     183             :         /*FALLTHROUGH*/
     184             :     case Node::node_t::NODE_ADD:
     185             :     case Node::node_t::NODE_AS:
     186             :     case Node::node_t::NODE_ASSIGNMENT:
     187             :     case Node::node_t::NODE_ASSIGNMENT_ADD:
     188             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_AND:
     189             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_OR:
     190             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_XOR:
     191             :     case Node::node_t::NODE_ASSIGNMENT_DIVIDE:
     192             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_AND:
     193             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_OR:
     194             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_XOR:
     195             :     case Node::node_t::NODE_ASSIGNMENT_MAXIMUM:
     196             :     case Node::node_t::NODE_ASSIGNMENT_MINIMUM:
     197             :     case Node::node_t::NODE_ASSIGNMENT_MODULO:
     198             :     case Node::node_t::NODE_ASSIGNMENT_MULTIPLY:
     199             :     case Node::node_t::NODE_ASSIGNMENT_POWER:
     200             :     case Node::node_t::NODE_ASSIGNMENT_ROTATE_LEFT:
     201             :     case Node::node_t::NODE_ASSIGNMENT_ROTATE_RIGHT:
     202             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_LEFT:
     203             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT:
     204             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT_UNSIGNED:
     205             :     case Node::node_t::NODE_ASSIGNMENT_SUBTRACT:
     206             :     case Node::node_t::NODE_BITWISE_AND:
     207             :     case Node::node_t::NODE_BITWISE_OR:
     208             :     case Node::node_t::NODE_BITWISE_XOR:
     209             :     case Node::node_t::NODE_COMMA:
     210             :     case Node::node_t::NODE_CONDITIONAL:
     211             :     case Node::node_t::NODE_DECREMENT:
     212             :     case Node::node_t::NODE_DIVIDE:
     213             :     case Node::node_t::NODE_EQUAL:
     214             :     case Node::node_t::NODE_GREATER:
     215             :     case Node::node_t::NODE_GREATER_EQUAL:
     216             :     case Node::node_t::NODE_IMPLEMENTS:
     217             :     case Node::node_t::NODE_INSTANCEOF:
     218             :     case Node::node_t::NODE_IN:
     219             :     case Node::node_t::NODE_INCREMENT:
     220             :     case Node::node_t::NODE_IS:
     221             :     case Node::node_t::NODE_LESS:
     222             :     case Node::node_t::NODE_LESS_EQUAL:
     223             :     case Node::node_t::NODE_LOGICAL_AND:
     224             :     case Node::node_t::NODE_LOGICAL_OR:
     225             :     case Node::node_t::NODE_LOGICAL_XOR:
     226             :     case Node::node_t::NODE_MATCH:
     227             :     case Node::node_t::NODE_MAXIMUM:
     228             :     case Node::node_t::NODE_MEMBER:
     229             :     case Node::node_t::NODE_MINIMUM:
     230             :     case Node::node_t::NODE_MODULO:
     231             :     case Node::node_t::NODE_MULTIPLY:
     232             :     case Node::node_t::NODE_NOT_EQUAL:
     233             :     case Node::node_t::NODE_OPEN_PARENTHESIS:
     234             :     case Node::node_t::NODE_OPEN_SQUARE_BRACKET:
     235             :     case Node::node_t::NODE_POWER:
     236             :     case Node::node_t::NODE_PRIVATE:
     237             :     case Node::node_t::NODE_PUBLIC:
     238             :     case Node::node_t::NODE_RANGE:
     239             :     case Node::node_t::NODE_REST:
     240             :     case Node::node_t::NODE_ROTATE_LEFT:
     241             :     case Node::node_t::NODE_ROTATE_RIGHT:
     242             :     case Node::node_t::NODE_SCOPE:
     243             :     case Node::node_t::NODE_SEMICOLON:
     244             :     case Node::node_t::NODE_SHIFT_LEFT:
     245             :     case Node::node_t::NODE_SHIFT_RIGHT:
     246             :     case Node::node_t::NODE_SHIFT_RIGHT_UNSIGNED:
     247             :     case Node::node_t::NODE_STRICTLY_EQUAL:
     248             :     case Node::node_t::NODE_STRICTLY_NOT_EQUAL:
     249             :     case Node::node_t::NODE_SUBTRACT:
     250      917636 :         if(attr_count > 0)
     251             :         {
     252      876600 :             last_attr = attr_list->get_child(attr_count - 1);
     253      876600 :             unget_token(f_node);
     254      876600 :             f_node = last_attr;
     255      876600 :             --attr_count;
     256      876600 :             attr_list->delete_child(attr_count);
     257      876600 :             if(type != Node::node_t::NODE_COLON)
     258             :             {
     259      835640 :                 type = last_attr->get_type();
     260             :             }
     261             :         }
     262      917636 :         break;
     263             : 
     264             :     default:
     265             :         // do nothing here
     266     3499895 :         break;
     267             : 
     268             :     }
     269             : 
     270             :     // we have a special case where a USE can be
     271             :     // followed by NAMESPACE vs. an identifier.
     272             :     // (i.e. use a namespace or define a pragma)
     273     4417531 :     if(type == Node::node_t::NODE_USE)
     274             :     {
     275      188505 :         get_token();
     276             :         // Note that we do not change the variable 'type' here!
     277             :     }
     278             : 
     279             :     // check for directives which cannot have attributes
     280     4417531 :     if(attr_count > 0)
     281             :     {
     282      958518 :         switch(type)
     283             :         {
     284             :         case Node::node_t::NODE_USE:
     285        8192 :             if(f_node->get_type() == Node::node_t::NODE_NAMESPACE)
     286             :             {
     287        8192 :                 break;
     288             :             }
     289             :             /*FALLTHROUGH*/
     290             :             // pragma cannot be annotated
     291             :         case Node::node_t::NODE_ADD:
     292             :         case Node::node_t::NODE_ARRAY_LITERAL:
     293             :         case Node::node_t::NODE_BITWISE_NOT:
     294             :         case Node::node_t::NODE_BREAK:
     295             :         case Node::node_t::NODE_CONTINUE:
     296             :         case Node::node_t::NODE_CASE:
     297             :         case Node::node_t::NODE_CATCH:
     298             :         case Node::node_t::NODE_COLON:
     299             :         case Node::node_t::NODE_DECREMENT:
     300             :         case Node::node_t::NODE_DEFAULT:
     301             :         case Node::node_t::NODE_DELETE:
     302             :         case Node::node_t::NODE_DO:
     303             :         case Node::node_t::NODE_FALSE:
     304             :         case Node::node_t::NODE_FLOAT64:
     305             :         case Node::node_t::NODE_FOR:
     306             :         case Node::node_t::NODE_FINALLY:
     307             :         case Node::node_t::NODE_GOTO:
     308             :         case Node::node_t::NODE_IDENTIFIER:
     309             :         case Node::node_t::NODE_IF:
     310             :         case Node::node_t::NODE_INCREMENT:
     311             :         case Node::node_t::NODE_INT64:
     312             :         case Node::node_t::NODE_LOGICAL_NOT:
     313             :         case Node::node_t::NODE_NEW:
     314             :         case Node::node_t::NODE_NULL:
     315             :         case Node::node_t::NODE_OBJECT_LITERAL:
     316             :         case Node::node_t::NODE_OPEN_PARENTHESIS:
     317             :         case Node::node_t::NODE_OPEN_SQUARE_BRACKET:
     318             :         case Node::node_t::NODE_REGULAR_EXPRESSION:
     319             :         case Node::node_t::NODE_RETURN:
     320             :         case Node::node_t::NODE_SEMICOLON: // annotated empty statements are not allowed
     321             :         case Node::node_t::NODE_SMART_MATCH: // TBD?
     322             :         case Node::node_t::NODE_STRING:
     323             :         case Node::node_t::NODE_SUBTRACT:
     324             :         case Node::node_t::NODE_SUPER:    // will accept commas too even in expressions
     325             :         case Node::node_t::NODE_SWITCH:
     326             :         case Node::node_t::NODE_THIS:
     327             :         case Node::node_t::NODE_THROW:
     328             :         case Node::node_t::NODE_TRUE:
     329             :         case Node::node_t::NODE_TRY:
     330             :         case Node::node_t::NODE_TYPEOF:
     331             :         case Node::node_t::NODE_UNDEFINED:
     332             :         case Node::node_t::NODE_VIDENTIFIER:
     333             :         case Node::node_t::NODE_VOID:
     334             :         case Node::node_t::NODE_WITH:
     335             :         case Node::node_t::NODE_WHILE:
     336             :         {
     337       16384 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_ATTRIBUTES, f_lexer->get_input()->get_position());
     338       16384 :             msg << "no attributes were expected here (statements, expressions and pragmas cannot be annotated).";
     339       16384 :             attr_list.reset();
     340       16384 :             attr_count = 0;
     341             :         }
     342       16384 :             break;
     343             : 
     344             :         // everything else can be annotated
     345             :         default:
     346      933942 :             break;
     347             : 
     348             :         }
     349             :     }
     350             : 
     351             :     // The directive node, if created by a sub-function, will
     352             :     // be added to the list of directives.
     353     4417531 :     Node::pointer_t directive_node;
     354     4417531 :     switch(type)
     355             :     {
     356             :     // *** PRAGMA ***
     357             :     case Node::node_t::NODE_USE:
     358             :         // we alread did a GetToken() to skip the NODE_USE
     359      188505 :         if(f_node->get_type() == Node::node_t::NODE_NAMESPACE)
     360             :         {
     361             :             // use namespace ... ';'
     362       16384 :             get_token();
     363       16384 :             use_namespace(directive_node);
     364       16384 :             break;
     365             :         }
     366      172121 :         if(f_node->get_type() == Node::node_t::NODE_IDENTIFIER)
     367             :         {
     368      172121 :             Node::pointer_t name(f_node);
     369      172121 :             get_token();
     370      172121 :             if(f_node->get_type() == Node::node_t::NODE_AS)
     371             :             {
     372             :                 // creating a numeric type
     373       98304 :                 numeric_type(directive_node, name);
     374       98304 :                 break;
     375             :             }
     376             :             // not a numeric type, must be a pragma
     377       73817 :             unget_token(f_node);
     378       73817 :             f_node = name;
     379             :         }
     380             :         // TODO? Pragmas are not part of the tree
     381             :         //
     382             :         // Note: pragmas affect the Options and are
     383             :         //       not currently added to the final
     384             :         //       tree of nodes. [is that correct?! it
     385             :         //       should be fine as long as we do not
     386             :         //       have run-time pragmas]
     387       73817 :         pragma();
     388       73817 :         break;
     389             : 
     390             :     // *** PACKAGE ***
     391             :     case Node::node_t::NODE_PACKAGE:
     392      131083 :         get_token();
     393      131083 :         package(directive_node);
     394      131083 :         break;
     395             : 
     396             :     case Node::node_t::NODE_IMPORT:
     397      173179 :         get_token();
     398      173179 :         import(directive_node);
     399      173179 :         break;
     400             : 
     401             :     // *** CLASS DEFINITION ***
     402             :     case Node::node_t::NODE_CLASS:
     403             :     case Node::node_t::NODE_INTERFACE:
     404      262162 :         get_token();
     405      262162 :         class_declaration(directive_node, type);
     406      262162 :         break;
     407             : 
     408             :     case Node::node_t::NODE_ENUM:
     409      122881 :         get_token();
     410      122881 :         enum_declaration(directive_node);
     411      122881 :         break;
     412             : 
     413             :     case Node::node_t::NODE_INVARIANT:
     414       40960 :         get_token();
     415       40960 :         contract_declaration(directive_node, type);
     416       40960 :         break;
     417             : 
     418             :     // *** FUNCTION DEFINITION ***
     419             :     case Node::node_t::NODE_FUNCTION:
     420      917817 :         get_token();
     421      917817 :         function(directive_node, false);
     422      917817 :         break;
     423             : 
     424             :     // *** VARIABLE DEFINITION ***
     425             :     case Node::node_t::NODE_CONST:
     426       32784 :         get_token();
     427       32784 :         if(f_node->get_type() == Node::node_t::NODE_VAR)
     428             :         {
     429        8208 :             get_token();
     430             :         }
     431       32784 :         variable(directive_node, true);
     432       32784 :         break;
     433             : 
     434             :     case Node::node_t::NODE_VAR:
     435      180232 :         get_token();
     436      180232 :         variable(directive_node, false);
     437      180232 :         break;
     438             : 
     439             :     // *** STATEMENT ***
     440             :     case Node::node_t::NODE_OPEN_CURVLY_BRACKET:
     441      155651 :         get_token();
     442      155651 :         block(directive_node);
     443      155651 :         break;
     444             : 
     445             :     case Node::node_t::NODE_SEMICOLON:
     446             :         // empty statements are just skipped
     447             :         //
     448             :         // NOTE: we reach here only when we find attributes
     449             :         //       which are not identifiers and this means
     450             :         //       we will have gotten an error.
     451        8192 :         get_token();
     452        8192 :         break;
     453             : 
     454             :     case Node::node_t::NODE_BREAK:
     455             :     case Node::node_t::NODE_CONTINUE:
     456       81920 :         get_token();
     457       81920 :         break_continue(directive_node, type);
     458       81920 :         break;
     459             : 
     460             :     case Node::node_t::NODE_CASE:
     461       65536 :         get_token();
     462       65536 :         case_directive(directive_node);
     463       65536 :         break;
     464             : 
     465             :     case Node::node_t::NODE_CATCH:
     466       81920 :         get_token();
     467       81920 :         catch_directive(directive_node);
     468       81920 :         break;
     469             : 
     470             :     case Node::node_t::NODE_DEBUGGER:    // just not handled yet...
     471        8192 :         get_token();
     472        8192 :         debugger(directive_node);
     473        8192 :         break;
     474             : 
     475             :     case Node::node_t::NODE_DEFAULT:
     476       16384 :         get_token();
     477       16384 :         default_directive(directive_node);
     478       16384 :         break;
     479             : 
     480             :     case Node::node_t::NODE_DO:
     481       40962 :         get_token();
     482       40962 :         do_directive(directive_node);
     483       40962 :         break;
     484             : 
     485             :     case Node::node_t::NODE_FOR:
     486      114689 :         get_token();
     487      114689 :         for_directive(directive_node);
     488      114689 :         break;
     489             : 
     490             :     case Node::node_t::NODE_FINALLY:
     491             :     case Node::node_t::NODE_TRY:
     492       24576 :         get_token();
     493       24576 :         try_finally(directive_node, type);
     494       24576 :         break;
     495             : 
     496             :     case Node::node_t::NODE_GOTO:
     497       24576 :         get_token();
     498       24576 :         goto_directive(directive_node);
     499       24576 :         break;
     500             : 
     501             :     case Node::node_t::NODE_IF:
     502       65542 :         get_token();
     503       65542 :         if_directive(directive_node);
     504       65542 :         break;
     505             : 
     506             :     case Node::node_t::NODE_NAMESPACE:
     507       40960 :         get_token();
     508       40960 :         namespace_block(directive_node, attr_list);
     509       40960 :         break;
     510             : 
     511             :     case Node::node_t::NODE_RETURN:
     512      262144 :         get_token();
     513      262144 :         return_directive(directive_node);
     514      262144 :         break;
     515             : 
     516             :     case Node::node_t::NODE_SWITCH:
     517       90112 :         get_token();
     518       90112 :         switch_directive(directive_node);
     519       90112 :         break;
     520             : 
     521             :     case Node::node_t::NODE_SYNCHRONIZED:
     522       32768 :         get_token();
     523       32768 :         synchronized(directive_node);
     524       32768 :         break;
     525             : 
     526             :     case Node::node_t::NODE_THROW:
     527       24576 :         get_token();
     528       24576 :         throw_directive(directive_node);
     529       24576 :         break;
     530             : 
     531             :     case Node::node_t::NODE_WITH:
     532             :     case Node::node_t::NODE_WHILE:
     533      106499 :         get_token();
     534      106499 :         with_while(directive_node, type);
     535      106499 :         break;
     536             : 
     537             :     case Node::node_t::NODE_YIELD:
     538       16384 :         get_token();
     539       16384 :         yield(directive_node);
     540       16384 :         break;
     541             : 
     542             :     case Node::node_t::NODE_COLON:
     543             :         // the label was the last identifier in the
     544             :         // attributes which is now in f_node
     545       40960 :         f_node->to_label();
     546       40960 :         directive_node = f_node;
     547             :         // we skip the identifier here
     548       40960 :         get_token();
     549             :         // and then the ':'
     550       40960 :         get_token();
     551       40960 :         break;
     552             : 
     553             :     // *** EXPRESSION ***
     554             :     case Node::node_t::NODE_ARRAY_LITERAL:
     555             :     case Node::node_t::NODE_DECREMENT:
     556             :     case Node::node_t::NODE_DELETE:
     557             :     case Node::node_t::NODE_FALSE:
     558             :     case Node::node_t::NODE_FLOAT64:
     559             :     case Node::node_t::NODE_IDENTIFIER:
     560             :     case Node::node_t::NODE_INCREMENT:
     561             :     case Node::node_t::NODE_INT64:
     562             :     case Node::node_t::NODE_NEW:
     563             :     case Node::node_t::NODE_NULL:
     564             :     case Node::node_t::NODE_OBJECT_LITERAL:
     565             :     case Node::node_t::NODE_PRIVATE:
     566             :     case Node::node_t::NODE_PROTECTED:
     567             :     case Node::node_t::NODE_PUBLIC:
     568             :     case Node::node_t::NODE_UNDEFINED:
     569             :     case Node::node_t::NODE_REGULAR_EXPRESSION:
     570             :     case Node::node_t::NODE_STRING:
     571             :     case Node::node_t::NODE_SUPER:    // will accept commas too even in expressions
     572             :     case Node::node_t::NODE_THIS:
     573             :     case Node::node_t::NODE_TRUE:
     574             :     case Node::node_t::NODE_TYPEOF:
     575             :     case Node::node_t::NODE_VIDENTIFIER:
     576             :     case Node::node_t::NODE_VOID:
     577             :     case Node::node_t::NODE_LOGICAL_NOT:
     578             :     case Node::node_t::NODE_ADD:
     579             :     case Node::node_t::NODE_SUBTRACT:
     580             :     case Node::node_t::NODE_OPEN_PARENTHESIS:
     581             :     case Node::node_t::NODE_OPEN_SQUARE_BRACKET:
     582             :     case Node::node_t::NODE_BITWISE_NOT:
     583             :     case Node::node_t::NODE_SMART_MATCH: // if here, need to be broken up to ~ and ~
     584             :     case Node::node_t::NODE_NOT_MATCH: // if here, need to be broken up to ! and ~
     585      926121 :         expression(directive_node);
     586      926121 :         break;
     587             : 
     588             :     // *** TERMINATOR ***
     589             :     case Node::node_t::NODE_EOF:
     590             :     {
     591        8192 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_UNEXPECTED_EOF, f_lexer->get_input()->get_position());
     592        8192 :         msg << "unexpected end of file reached.";
     593             :     }
     594        8192 :         return;
     595             : 
     596             :     case Node::node_t::NODE_CLOSE_CURVLY_BRACKET:
     597             :         // this error does not seem required at this point
     598             :         // we get the error from the program already
     599             :     //{
     600             :     //    Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_CURVLY_BRACKETS_EXPECTED, f_lexer->get_input()->get_position());
     601             :     //    msg << "unexpected '}'.";
     602             :     //}
     603        8192 :         return;
     604             : 
     605             :     // *** INVALID ***
     606             :     // The following are for sure invalid tokens in this
     607             :     // context. If it looks like some of these could be
     608             :     // valid when this function returns, just comment
     609             :     // out the corresponding case.
     610             :     case Node::node_t::NODE_AS:
     611             :     case Node::node_t::NODE_ASSIGNMENT:
     612             :     case Node::node_t::NODE_ASSIGNMENT_ADD:
     613             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_AND:
     614             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_OR:
     615             :     case Node::node_t::NODE_ASSIGNMENT_BITWISE_XOR:
     616             :     case Node::node_t::NODE_ASSIGNMENT_DIVIDE:
     617             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_AND:
     618             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_OR:
     619             :     case Node::node_t::NODE_ASSIGNMENT_LOGICAL_XOR:
     620             :     case Node::node_t::NODE_ASSIGNMENT_MAXIMUM:
     621             :     case Node::node_t::NODE_ASSIGNMENT_MINIMUM:
     622             :     case Node::node_t::NODE_ASSIGNMENT_MODULO:
     623             :     case Node::node_t::NODE_ASSIGNMENT_MULTIPLY:
     624             :     case Node::node_t::NODE_ASSIGNMENT_POWER:
     625             :     case Node::node_t::NODE_ASSIGNMENT_ROTATE_LEFT:
     626             :     case Node::node_t::NODE_ASSIGNMENT_ROTATE_RIGHT:
     627             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_LEFT:
     628             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT:
     629             :     case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT_UNSIGNED:
     630             :     case Node::node_t::NODE_ASSIGNMENT_SUBTRACT:
     631             :     case Node::node_t::NODE_BITWISE_AND:
     632             :     case Node::node_t::NODE_BITWISE_XOR:
     633             :     case Node::node_t::NODE_BITWISE_OR:
     634             :     case Node::node_t::NODE_CLOSE_PARENTHESIS:
     635             :     case Node::node_t::NODE_CLOSE_SQUARE_BRACKET:
     636             :     case Node::node_t::NODE_COMMA:
     637             :     case Node::node_t::NODE_COMPARE:
     638             :     case Node::node_t::NODE_CONDITIONAL:
     639             :     case Node::node_t::NODE_DIVIDE:
     640             :     case Node::node_t::NODE_EQUAL:
     641             :     case Node::node_t::NODE_GREATER:
     642             :     case Node::node_t::NODE_GREATER_EQUAL:
     643             :     case Node::node_t::NODE_IMPLEMENTS:
     644             :     case Node::node_t::NODE_INSTANCEOF:
     645             :     case Node::node_t::NODE_IN:
     646             :     case Node::node_t::NODE_IS:
     647             :     case Node::node_t::NODE_LESS:
     648             :     case Node::node_t::NODE_LESS_EQUAL:
     649             :     case Node::node_t::NODE_LOGICAL_AND:
     650             :     case Node::node_t::NODE_LOGICAL_OR:
     651             :     case Node::node_t::NODE_LOGICAL_XOR:
     652             :     case Node::node_t::NODE_MATCH:
     653             :     case Node::node_t::NODE_MAXIMUM:
     654             :     case Node::node_t::NODE_MEMBER:
     655             :     case Node::node_t::NODE_MINIMUM:
     656             :     case Node::node_t::NODE_MODULO:
     657             :     case Node::node_t::NODE_MULTIPLY:
     658             :     case Node::node_t::NODE_NOT_EQUAL:
     659             :     case Node::node_t::NODE_POWER:
     660             :     case Node::node_t::NODE_RANGE:
     661             :     case Node::node_t::NODE_REST:
     662             :     case Node::node_t::NODE_ROTATE_LEFT:
     663             :     case Node::node_t::NODE_ROTATE_RIGHT:
     664             :     case Node::node_t::NODE_SCOPE:
     665             :     case Node::node_t::NODE_SHIFT_LEFT:
     666             :     case Node::node_t::NODE_SHIFT_RIGHT:
     667             :     case Node::node_t::NODE_SHIFT_RIGHT_UNSIGNED:
     668             :     case Node::node_t::NODE_STRICTLY_EQUAL:
     669             :     case Node::node_t::NODE_STRICTLY_NOT_EQUAL:
     670             :     case Node::node_t::NODE_VARIABLE:
     671             :     {
     672       32768 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_OPERATOR, f_lexer->get_input()->get_position());
     673       32768 :         msg << "unexpected operator '" << instruction_node->get_type_name() << "'.";
     674       32768 :         get_token();
     675             :     }
     676       32768 :         break;
     677             : 
     678             :     case Node::node_t::NODE_ELSE:
     679             :     case Node::node_t::NODE_ENSURE:
     680             :     case Node::node_t::NODE_EXTENDS:
     681             :     case Node::node_t::NODE_REQUIRE:
     682             :     case Node::node_t::NODE_THEN:
     683             :     {
     684       40960 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_KEYWORD, f_lexer->get_input()->get_position());
     685       40960 :         msg << "unexpected keyword '" << instruction_node->get_type_name() << "'.";
     686       40960 :         get_token();
     687             :     }
     688       40960 :         break;
     689             : 
     690             :     case Node::node_t::NODE_ABSTRACT:
     691             :     //case Node::node_t::NODE_FALSE:
     692             :     case Node::node_t::NODE_FINAL:
     693             :     case Node::node_t::NODE_INLINE:
     694             :     case Node::node_t::NODE_NATIVE:
     695             :     //case Node::node_t::NODE_PRIVATE:
     696             :     //case Node::node_t::NODE_PROTECTED:
     697             :     //case Node::node_t::NODE_PUBLIC:
     698             :     case Node::node_t::NODE_STATIC:
     699             :     case Node::node_t::NODE_TRANSIENT:
     700             :     //case Node::node_t::NODE_TRUE:
     701             :     case Node::node_t::NODE_VOLATILE:
     702             :     {
     703       49152 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INVALID_ATTRIBUTES, f_lexer->get_input()->get_position());
     704       49152 :         msg << "a statement with only attributes (" << Node::type_to_string(type) << ") is not allowed.";
     705       49152 :         attr_list.reset();
     706       49152 :         attr_count = 0;
     707             : 
     708             :         // skip that attribute which we cannot do anything with
     709       49152 :         get_token();
     710             :     }
     711       49152 :         break;
     712             : 
     713             :     // *** NOT POSSIBLE ***
     714             :     // These should never happen since they should be caught
     715             :     // before this switch is reached or it can't be a node
     716             :     // read by the lexer.
     717             :     case Node::node_t::NODE_ARRAY:
     718             :     case Node::node_t::NODE_ATTRIBUTES:
     719             :     case Node::node_t::NODE_AUTO:
     720             :     case Node::node_t::NODE_BOOLEAN:
     721             :     case Node::node_t::NODE_BYTE:
     722             :     case Node::node_t::NODE_CALL:
     723             :     case Node::node_t::NODE_CHAR:
     724             :     case Node::node_t::NODE_DIRECTIVE_LIST:
     725             :     case Node::node_t::NODE_DOUBLE:
     726             :     case Node::node_t::NODE_EMPTY:
     727             :     case Node::node_t::NODE_EXCLUDE:
     728             :     case Node::node_t::NODE_EXPORT:
     729             :     case Node::node_t::NODE_FLOAT:
     730             :     case Node::node_t::NODE_INCLUDE:
     731             :     case Node::node_t::NODE_LABEL:
     732             :     case Node::node_t::NODE_LIST:
     733             :     case Node::node_t::NODE_LONG:
     734             :     case Node::node_t::NODE_NAME:
     735             :     case Node::node_t::NODE_PARAM:
     736             :     case Node::node_t::NODE_PARAMETERS:
     737             :     case Node::node_t::NODE_PARAM_MATCH:
     738             :     case Node::node_t::NODE_POST_DECREMENT:
     739             :     case Node::node_t::NODE_POST_INCREMENT:
     740             :     case Node::node_t::NODE_PROGRAM:
     741             :     case Node::node_t::NODE_ROOT:
     742             :     case Node::node_t::NODE_SET:
     743             :     case Node::node_t::NODE_SHORT:
     744             :     case Node::node_t::NODE_THROWS:
     745             :     case Node::node_t::NODE_TYPE:
     746             :     case Node::node_t::NODE_UNKNOWN:    // ?!
     747             :     case Node::node_t::NODE_VAR_ATTRIBUTES:
     748             :     case Node::node_t::NODE_other:      // no node should be of this type
     749             :     case Node::node_t::NODE_max:        // no node should be of this type
     750             :         {
     751             :             Message msg(message_level_t::MESSAGE_LEVEL_FATAL, err_code_t::AS_ERR_INTERNAL_ERROR, f_lexer->get_input()->get_position()); // LCOV_EXCL_LINE
     752             :             msg << "INTERNAL ERROR: invalid node (" << Node::type_to_string(type) << ") in directive_list."; // LCOV_EXCL_LINE
     753             :         }
     754             :         throw exception_internal_error("unexpected node type found while parsing directives"); // LCOV_EXCL_LINE
     755             : 
     756             :     }
     757     4401147 :     if(directive_node)
     758             :     {
     759             :         // if there are attributes link them to the directive
     760     4106146 :         if(attr_list && attr_list->get_children_size() > 0)
     761             :         {
     762      860214 :             directive_node->set_link(Node::link_t::LINK_ATTRIBUTES, attr_list);
     763             :         }
     764     4106146 :         node->append_child(directive_node);
     765             :     }
     766             : 
     767             :     // Now make sure we have a semicolon for
     768             :     // those statements which have to have it.
     769     4401147 :     switch(type)
     770             :     {
     771             :     case Node::node_t::NODE_ARRAY_LITERAL:
     772             :     case Node::node_t::NODE_BREAK:
     773             :     case Node::node_t::NODE_CONST:
     774             :     case Node::node_t::NODE_CONTINUE:
     775             :     case Node::node_t::NODE_DECREMENT:
     776             :     case Node::node_t::NODE_DELETE:
     777             :     case Node::node_t::NODE_DO:
     778             :     case Node::node_t::NODE_FLOAT64:
     779             :     case Node::node_t::NODE_GOTO:
     780             :     case Node::node_t::NODE_IDENTIFIER:
     781             :     case Node::node_t::NODE_IMPORT:
     782             :     case Node::node_t::NODE_INCREMENT:
     783             :     case Node::node_t::NODE_INT64:
     784             :     case Node::node_t::NODE_NEW:
     785             :     case Node::node_t::NODE_NULL:
     786             :     case Node::node_t::NODE_OBJECT_LITERAL:
     787             :     case Node::node_t::NODE_RETURN:
     788             :     case Node::node_t::NODE_REGULAR_EXPRESSION:
     789             :     case Node::node_t::NODE_STRING:
     790             :     case Node::node_t::NODE_SUPER:
     791             :     case Node::node_t::NODE_THIS:
     792             :     case Node::node_t::NODE_THROW:
     793             :     case Node::node_t::NODE_TYPEOF:
     794             :     case Node::node_t::NODE_UNDEFINED:
     795             :     case Node::node_t::NODE_USE:
     796             :     case Node::node_t::NODE_VAR:
     797             :     case Node::node_t::NODE_VIDENTIFIER:
     798             :     case Node::node_t::NODE_VOID:
     799             :     case Node::node_t::NODE_LOGICAL_NOT:
     800             :     case Node::node_t::NODE_ADD:
     801             :     case Node::node_t::NODE_SUBTRACT:
     802             :     case Node::node_t::NODE_OPEN_PARENTHESIS:
     803             :     case Node::node_t::NODE_OPEN_SQUARE_BRACKET:
     804             :     case Node::node_t::NODE_BITWISE_NOT:
     805             :         // accept missing ';' when we find a '}' next
     806     3788050 :         if(f_node->get_type() != Node::node_t::NODE_SEMICOLON
     807     1894025 :         && f_node->get_type() != Node::node_t::NODE_CLOSE_CURVLY_BRACKET)
     808             :         {
     809      131072 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_SEMICOLON_EXPECTED, f_lexer->get_input()->get_position());
     810      131072 :             msg << "';' was expected after '" << instruction_node->get_type_name() << "' (current token: '" << f_node->get_type_name() << "').";
     811             :         }
     812             :         // skip all that whatever up to the next end of this
     813     6173595 :         while(f_node->get_type() != Node::node_t::NODE_SEMICOLON
     814      303104 :            && f_node->get_type() != Node::node_t::NODE_OPEN_CURVLY_BRACKET
     815      278528 :            && f_node->get_type() != Node::node_t::NODE_CLOSE_CURVLY_BRACKET
     816      262144 :            && f_node->get_type() != Node::node_t::NODE_ELSE
     817     2401929 :            && f_node->get_type() != Node::node_t::NODE_EOF)
     818             :         {
     819      245760 :             get_token();
     820             :         }
     821             :         // we need to skip one semi-colon here
     822             :         // in case we're not in a directive_list()
     823     1894025 :         if(f_node->get_type() == Node::node_t::NODE_SEMICOLON)
     824             :         {
     825     1836681 :             get_token();
     826             :         }
     827     1894025 :         break;
     828             : 
     829             :     default:
     830     2507122 :         break;
     831             : 
     832     8802294 :     }
     833             : }
     834             : 
     835             : 
     836             : 
     837             : 
     838             : 
     839          63 : }
     840             : // namespace as2js
     841             : 
     842             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10