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

          Line data    Source code
       1             : /* parser_numeric_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/parser.h"
      37             : #include    "as2js/message.h"
      38             : 
      39             : 
      40             : namespace as2js
      41             : {
      42             : 
      43             : 
      44             : /**********************************************************************/
      45             : /**********************************************************************/
      46             : /***  PARSER NUMERIC TYPE  ********************************************/
      47             : /**********************************************************************/
      48             : /**********************************************************************/
      49             : 
      50       98316 : void Parser::numeric_type(Node::pointer_t& numeric_type_node, Node::pointer_t& name)
      51             : {
      52             :     // TBD: can we really use NODE_TYPE here?
      53       98316 :     numeric_type_node = f_lexer->get_new_node(Node::node_t::NODE_TYPE);
      54             : 
      55       98316 :     numeric_type_node->append_child(name);
      56             : 
      57             :     // we are called with the current token set to NODE_AS, get
      58             :     // the following token, it has to be a literal number
      59             :     //
      60             :     // TODO: support any constant expression
      61             :     //
      62       98316 :     get_token();
      63      196632 :     if(f_node->get_type() == Node::node_t::NODE_IDENTIFIER
      64       98316 :     && f_node->get_string() == "mod")
      65             :     {
      66       24579 :         numeric_type_node->set_flag(Node::flag_t::NODE_TYPE_FLAG_MODULO, true);
      67             : 
      68             :         // skip the word 'mod'
      69       24579 :         get_token();
      70             : 
      71       24579 :         if(f_node->get_type() == Node::node_t::NODE_SEMICOLON)
      72             :         {
      73        8193 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
      74        8193 :             msg << "missing literal number for a numeric type declaration.";
      75        8193 :             return;
      76             :         }
      77             : 
      78       32772 :         if(f_node->get_type() != Node::node_t::NODE_INT64
      79       16386 :         && f_node->get_type() != Node::node_t::NODE_FLOAT64)
      80             :         {
      81        8193 :             Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
      82        8193 :             msg << "invalid numeric type declaration, the modulo must be a literal number.";
      83             : 
      84             :             // skip that token because it's useless, and we expect
      85             :             // a semi-colon right after that
      86        8193 :             get_token();
      87        8193 :             return;
      88             :         }
      89             : 
      90             :         // RESULT OF: use name as mod 123;
      91        8193 :         numeric_type_node->append_child(f_node);
      92        8193 :         get_token();
      93        8193 :         return;
      94             :     }
      95             : 
      96       73737 :     Node::node_t left_type(f_node->get_type());
      97       73737 :     int sign(1);
      98       73737 :     if(left_type == Node::node_t::NODE_ADD)
      99             :     {
     100        8193 :         get_token();
     101        8193 :         left_type = f_node->get_type();
     102             :     }
     103       65544 :     else if(left_type == Node::node_t::NODE_SUBTRACT)
     104             :     {
     105       16386 :         sign = -1;
     106       16386 :         get_token();
     107       16386 :         left_type = f_node->get_type();
     108             :     }
     109       73737 :     if(left_type == Node::node_t::NODE_INT64)
     110             :     {
     111       40965 :         Int64 i(f_node->get_int64());
     112       40965 :         i.set(i.get() * sign);
     113       40965 :         f_node->set_int64(i);
     114             :     }
     115       32772 :     else if(left_type == Node::node_t::NODE_FLOAT64)
     116             :     {
     117       24579 :         Float64 f(f_node->get_float64());
     118       24579 :         f.set(f.get() * sign);
     119       24579 :         f_node->set_float64(f);
     120             :     }
     121             :     else
     122             :     {
     123        8193 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     124        8193 :         msg << "invalid numeric type declaration, the range must start with a literal number.";
     125             :         // TODO: we may want to check whether the next
     126             :         //       token is '..' or ';'...
     127        8193 :         return;
     128             :     }
     129             : 
     130       65544 :     Node::pointer_t left_node(f_node);
     131       65544 :     numeric_type_node->append_child(f_node);
     132             : 
     133             :     // now we expect '..'
     134       65544 :     get_token();
     135       65544 :     if(f_node->get_type() != Node::node_t::NODE_RANGE)
     136             :     {
     137       32772 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     138       32772 :         msg << "invalid numeric type declaration, the range must use '..' to separate the minimum and maximum boundaries (unexpected '" << f_node->get_type_name() << "').";
     139             : 
     140             :         // in case the user put '...' instead of '..'
     141       32772 :         if(f_node->get_type() == Node::node_t::NODE_REST)
     142             :         {
     143       32772 :             get_token();
     144       32772 :         }
     145             :     }
     146             :     else
     147             :     {
     148       32772 :         get_token();
     149             :     }
     150             : 
     151       65544 :     Node::node_t right_type(f_node->get_type());
     152       65544 :     sign = 1;
     153       65544 :     if(right_type == Node::node_t::NODE_ADD)
     154             :     {
     155        8193 :         get_token();
     156        8193 :         right_type = f_node->get_type();
     157             :     }
     158       57351 :     else if(right_type == Node::node_t::NODE_SUBTRACT)
     159             :     {
     160       16386 :         sign = -1;
     161       16386 :         get_token();
     162       16386 :         right_type = f_node->get_type();
     163             :     }
     164       65544 :     if(right_type == Node::node_t::NODE_INT64)
     165             :     {
     166       32772 :         Int64 i(f_node->get_int64());
     167       32772 :         i.set(i.get() * sign);
     168       32772 :         f_node->set_int64(i);
     169             :     }
     170       32772 :     else if(right_type == Node::node_t::NODE_FLOAT64)
     171             :     {
     172       24579 :         Float64 f(f_node->get_float64());
     173       24579 :         f.set(f.get() * sign);
     174       24579 :         f_node->set_float64(f);
     175             :     }
     176             :     else
     177             :     {
     178        8193 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     179        8193 :         msg << "invalid numeric type declaration, the range must end with a literal number.";
     180        8193 :         if(f_node->get_type() != Node::node_t::NODE_SEMICOLON)
     181             :         {
     182             :             // avoid an additional error
     183        8193 :             get_token();
     184             :         }
     185        8193 :         return;
     186             :     }
     187             : 
     188             :     // RESULT OF: use name as 0 .. 100;
     189      122895 :     Node::pointer_t right_node(f_node);
     190       57351 :     numeric_type_node->append_child(f_node);
     191             : 
     192       57351 :     get_token();
     193             : 
     194             :     // we verify this after the get_token() to skip the
     195             :     // second number so we do not generate yet another error
     196       57351 :     if(right_type != left_type)
     197             :     {
     198       16386 :         Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     199       16386 :         msg << "invalid numeric type declaration, the range must use numbers of the same type on both sides.";
     200             :     }
     201       40965 :     else if(left_type == Node::node_t::NODE_INT64)
     202             :     {
     203       24579 :         if(left_node->get_int64().get() > right_node->get_int64().get())
     204             :         {
     205        8193 :             Message msg(message_level_t::MESSAGE_LEVEL_WARNING, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     206       24579 :             msg << "numeric type declaration is empty (only accepts 'null') because left value of range is larger than right value.";
     207             :         }
     208             :     }
     209             :     else
     210             :     {
     211       16386 :         if(left_node->get_float64().get() > right_node->get_float64().get())
     212             :         {
     213        8193 :             Message msg(message_level_t::MESSAGE_LEVEL_WARNING, err_code_t::AS_ERR_BAD_NUMERIC_TYPE, f_lexer->get_input()->get_position());
     214        8193 :             msg << "numeric type declaration is empty (only accepts 'null') because left value of range is larger than right value.";
     215             :         }
     216       98316 :     }
     217             : }
     218             : 
     219             : 
     220             : 
     221             : 
     222             : 
     223             : 
     224          20 : }
     225             : // namespace as2js
     226             : 
     227             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9