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

          Line data    Source code
       1             : /* parser_pragma.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             : 
      38             : #include    "as2js/message.h"
      39             : 
      40             : 
      41             : namespace as2js
      42             : {
      43             : 
      44             : 
      45             : /**********************************************************************/
      46             : /**********************************************************************/
      47             : /***  PARSER PRAGMA  **************************************************/
      48             : /**********************************************************************/
      49             : /**********************************************************************/
      50             : 
      51       73817 : void Parser::pragma()
      52             : {
      53     2244875 :     while(f_node->get_type() == Node::node_t::NODE_IDENTIFIER)
      54             :     {
      55     2097241 :         String const name(f_node->get_string());
      56     4194482 :         Node::pointer_t argument;
      57     2097241 :         get_token();
      58     2097241 :         if(f_node->get_type() == Node::node_t::NODE_OPEN_PARENTHESIS)
      59             :         {
      60             :             // has zero or one argument
      61     1794049 :             get_token();
      62             :             // accept an empty argument '()'
      63     1794049 :             if(f_node->get_type() != Node::node_t::NODE_CLOSE_PARENTHESIS)
      64             :             {
      65     1384449 :                 bool const negative(f_node->get_type() == Node::node_t::NODE_SUBTRACT);
      66     1384449 :                 if(negative)
      67             :                 {
      68             :                     // skip the '-' sign
      69       73728 :                     get_token();
      70             :                 }
      71             :                 // TODO: add support for 'positive'?
      72     1384449 :                 switch(f_node->get_type())
      73             :                 {
      74             :                 case Node::node_t::NODE_FALSE:
      75             :                 case Node::node_t::NODE_STRING:
      76             :                 case Node::node_t::NODE_TRUE:
      77       90112 :                     if(negative)
      78             :                     {
      79       24576 :                         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
      80       24576 :                         msg << "invalid negative argument for a pragma.";
      81             :                     }
      82       90112 :                     argument = f_node;
      83       90112 :                     get_token();
      84       90112 :                     break;
      85             : 
      86             :                 case Node::node_t::NODE_FLOAT64:
      87       32768 :                     argument = f_node;
      88       32768 :                     if(negative)
      89             :                     {
      90       16384 :                         argument->set_float64(-argument->get_float64().get());
      91             :                     }
      92       32768 :                     get_token();
      93       32768 :                     break;
      94             : 
      95             :                 case Node::node_t::NODE_INT64:
      96     1245185 :                     argument = f_node;
      97     1245185 :                     if(negative)
      98             :                     {
      99       24576 :                         argument->set_int64(-argument->get_int64().get());
     100             :                     }
     101     1245185 :                     get_token();
     102     1245185 :                     break;
     103             : 
     104             :                 case Node::node_t::NODE_CLOSE_PARENTHESIS:
     105        8192 :                     if(negative)
     106             :                     {
     107             :                         // we cannot negate "nothingness"
     108             :                         // (i.e. use blah(-); is not valid)
     109        8192 :                         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
     110        8192 :                         msg << "a pragma argument cannot just be '-'.";
     111             :                     }
     112        8192 :                     break;
     113             : 
     114             :                 default:
     115             :                 {
     116        8192 :                     Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
     117        8192 :                     msg << "invalid argument type for a pragma.";
     118             :                 }
     119        8192 :                     break;
     120             : 
     121             :                 }
     122             :             }
     123     1794049 :             if(f_node->get_type() != Node::node_t::NODE_CLOSE_PARENTHESIS)
     124             :             {
     125        8192 :                 Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
     126        8192 :                 msg << "invalid argument for a pragma.";
     127             :             }
     128             :             else
     129             :             {
     130     1785857 :                 get_token();
     131             :             }
     132             :         }
     133     2097241 :         bool const prima(f_node->get_type() == Node::node_t::NODE_CONDITIONAL);
     134     2097241 :         if(prima)
     135             :         {
     136             :             // skip the '?'
     137     1449984 :             get_token();
     138             :         }
     139             : 
     140             :         // Check out this pragma. We have the following
     141             :         // info about each pragma:
     142             :         //
     143             :         //    name        The pragma name
     144             :         //    argument    The pragma argument (unknown by default)
     145             :         //    prima       True if pragma name followed by '?'
     146             :         //
     147             :         // NOTE: pragmas that we do not recognize are simply
     148             :         //       being ignored.
     149             :         //
     150     2097241 :         Options::option_value_t value(1);
     151     2097241 :         Options::option_t option = Options::option_t::OPTION_UNKNOWN;
     152     2097241 :         if(name == "allow_with")
     153             :         {
     154       90112 :             option = Options::option_t::OPTION_ALLOW_WITH;
     155             :         }
     156     2007129 :         else if(name == "no_allow_with")
     157             :         {
     158       81920 :             option = Options::option_t::OPTION_ALLOW_WITH;
     159       81920 :             value = 0;
     160             :         }
     161     1925209 :         else if(name == "binary")
     162             :         {
     163       98304 :             option = Options::option_t::OPTION_BINARY;
     164             :         }
     165     1826905 :         else if(name == "no_binary")
     166             :         {
     167       81920 :             option = Options::option_t::OPTION_BINARY;
     168       81920 :             value = 0;
     169             :         }
     170     1744985 :         else if(name == "coverage")
     171             :         {
     172       90112 :             option = Options::option_t::OPTION_COVERAGE;
     173             :         }
     174     1654873 :         else if(name == "no_coverage")
     175             :         {
     176       81920 :             option = Options::option_t::OPTION_COVERAGE;
     177       81920 :             value = 0;
     178             :         }
     179     1572953 :         else if(name == "debug")
     180             :         {
     181       98304 :             option = Options::option_t::OPTION_DEBUG;
     182             :         }
     183     1474649 :         else if(name == "no_debug")
     184             :         {
     185       81920 :             option = Options::option_t::OPTION_DEBUG;
     186       81920 :             value = 0;
     187             :         }
     188     1392729 :         else if(name == "extended_escape_sequences")
     189             :         {
     190       90112 :             option = Options::option_t::OPTION_EXTENDED_ESCAPE_SEQUENCES;
     191             :         }
     192     1302617 :         else if(name == "no_extended_escape_sequences")
     193             :         {
     194       81920 :             option = Options::option_t::OPTION_EXTENDED_ESCAPE_SEQUENCES;
     195       81920 :             value = 0;
     196             :         }
     197     1220697 :         else if(name == "extended_operators")
     198             :         {
     199      114777 :             option = Options::option_t::OPTION_EXTENDED_OPERATORS;
     200             :         }
     201     1105920 :         else if(name == "no_extended_operators")
     202             :         {
     203       98304 :             option = Options::option_t::OPTION_EXTENDED_OPERATORS;
     204       98304 :             value = 0;
     205             :         }
     206     1007616 :         else if(name == "extended_statements")
     207             :         {
     208       90112 :             option = Options::option_t::OPTION_EXTENDED_STATEMENTS;
     209             :         }
     210      917504 :         else if(name == "no_extended_statements")
     211             :         {
     212       81920 :             option = Options::option_t::OPTION_EXTENDED_STATEMENTS;
     213       81920 :             value = 0;
     214             :         }
     215      835584 :         else if(name == "octal")
     216             :         {
     217       98304 :             option = Options::option_t::OPTION_OCTAL;
     218             :         }
     219      737280 :         else if(name == "no_octal")
     220             :         {
     221       81920 :             option = Options::option_t::OPTION_OCTAL;
     222       81920 :             value = 0;
     223             :         }
     224      655360 :         else if(name == "strict")
     225             :         {
     226       98304 :             option = Options::option_t::OPTION_STRICT;
     227             :         }
     228      557056 :         else if(name == "no_strict")
     229             :         {
     230       90112 :             option = Options::option_t::OPTION_STRICT;
     231       90112 :             value = 0;
     232             :         }
     233      466944 :         else if(name == "trace")
     234             :         {
     235       98304 :             option = Options::option_t::OPTION_TRACE;
     236             :         }
     237      368640 :         else if(name == "no_trace")
     238             :         {
     239       81920 :             option = Options::option_t::OPTION_TRACE;
     240       81920 :             value = 0;
     241             :         }
     242      286720 :         else if(name == "unsafe_math")
     243             :         {
     244       98304 :             option = Options::option_t::OPTION_UNSAFE_MATH;
     245             :         }
     246      188416 :         else if(name == "no_unsafe_math")
     247             :         {
     248       73728 :             option = Options::option_t::OPTION_UNSAFE_MATH;
     249       73728 :             value = 0;
     250             :         }
     251     2097241 :         if(option != Options::option_t::OPTION_UNKNOWN)
     252             :         {
     253     1982553 :             pragma_option(option, prima, argument, value);
     254             :         }
     255             : 
     256     2097241 :         if(f_node->get_type() == Node::node_t::NODE_COMMA)
     257             :         {
     258     2015232 :             get_token();
     259             :         }
     260       82009 :         else if(f_node->get_type() == Node::node_t::NODE_IDENTIFIER)
     261             :         {
     262        8192 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
     263        8192 :             msg << "pragmas must be separated by commas.";
     264             :         }
     265       73817 :         else if(f_node->get_type() != Node::node_t::NODE_SEMICOLON)
     266             :         {
     267        8192 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_PRAGMA, f_lexer->get_input()->get_position());
     268        8192 :             msg << "pragmas must be separated by commas and ended by a semicolon.";
     269             :             // no need for a break since the while() will exit already
     270             :         }
     271     2097241 :     }
     272       73817 : }
     273             : 
     274             : 
     275             : 
     276     1982553 : void Parser::pragma_option(Options::option_t option, bool prima, Node::pointer_t& argument, Options::option_value_t value)
     277             : {
     278             :     // user overloaded the value?
     279             :     // if argument is a null pointer, then keep the input value as is
     280     1982553 :     if(argument) switch(argument->get_type())
     281             :     {
     282             :     case Node::node_t::NODE_TRUE:
     283       24576 :         value = 1;
     284       24576 :         break;
     285             : 
     286             :     case Node::node_t::NODE_INT64:
     287     1163265 :         value = argument->get_int64().get();
     288     1163265 :         break;
     289             : 
     290             :     case Node::node_t::NODE_FLOAT64:
     291             :         // should we round up instead of using floor()?
     292       32768 :         value = static_cast<Options::option_value_t>(argument->get_float64().get());
     293       32768 :         break;
     294             : 
     295             :     case Node::node_t::NODE_STRING:
     296             :     {
     297             :         // TBD: we could try to convert the string, but is that really
     298             :         //      necessary?
     299       40960 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INCOMPATIBLE_PRAGMA_ARGUMENT, f_lexer->get_input()->get_position());
     300       40960 :         msg << "incompatible pragma argument.";
     301             :     }
     302       40960 :         break;
     303             : 
     304             :     default: // Node::node_t::NODE_FALSE
     305       24576 :         value = 0;
     306       24576 :         break;
     307             : 
     308             :     }
     309             : 
     310     1982553 :     if(prima)
     311             :     {
     312     1384448 :         if(f_options->get_option(option) != value)
     313             :         {
     314      368640 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_PRAGMA_FAILED, f_lexer->get_input()->get_position());
     315      368640 :             msg << "prima pragma failed.";
     316             :         }
     317     3367001 :         return;
     318             :     }
     319             : 
     320      598105 :     f_options->set_option(option, value);
     321             : }
     322             : 
     323             : 
     324             : 
     325             : 
     326             : 
     327          63 : }
     328             : // namespace as2js
     329             : 
     330             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10