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

Generated by: LCOV version 1.9