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

          Line data    Source code
       1             : /* compiler_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/compiler.h"
      37             : 
      38             : #include    "as2js/message.h"
      39             : 
      40             : 
      41             : namespace as2js
      42             : {
      43             : 
      44             : 
      45             : 
      46        8192 : Node::pointer_t Compiler::directive_list(Node::pointer_t directive_list_node)
      47             : {
      48        8192 :     size_t const p(f_scope->get_children_size());
      49             : 
      50             :     // TODO: should we go through the list a first time
      51             :     //       so we get the list of namespaces for these
      52             :     //       directives at once; so in other words you
      53             :     //       could declare the namespaces in use at the
      54             :     //       start or the end of this scope and it works
      55             :     //       the same way...
      56             : 
      57        8192 :     size_t const max_children(directive_list_node->get_children_size());
      58             : 
      59             :     // get rid of any declaration marked false
      60       16384 :     for(size_t idx(0); idx < max_children; ++idx)
      61             :     {
      62        8192 :         Node::pointer_t child(directive_list_node->get_child(idx));
      63        8192 :         if(get_attribute(child, Node::attribute_t::NODE_ATTR_FALSE))
      64             :         {
      65           0 :             child->to_unknown();
      66             :         }
      67        8192 :     }
      68             : 
      69        8192 :     bool no_access(false);
      70        8192 :     Node::pointer_t end_list;
      71             : 
      72             :     // compile each directive one by one...
      73             :     {
      74        8192 :         NodeLock ln(directive_list_node);
      75       16384 :         for(size_t idx(0); idx < max_children; ++idx)
      76             :         {
      77        8192 :             Node::pointer_t child(directive_list_node->get_child(idx));
      78        8192 :             if(!no_access && end_list)
      79             :             {
      80             :                 // err only once on this one
      81           0 :                 no_access = true;
      82           0 :                 Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INACCESSIBLE_STATEMENT, child->get_position());
      83           0 :                 msg << "code is not accessible after a break, continue, goto, throw or return statement.";
      84             :             }
      85             : #if 0
      86             : fprintf(stderr, "Directive at ");
      87             : child.DisplayPtr(stderr);
      88             : fprintf(stderr, " (%d + 1 of %d)\n", idx, max);
      89             : #endif
      90             : 
      91        8192 :             switch(child->get_type()) {
      92             :             case Node::node_t::NODE_PACKAGE:
      93             :                 // there is nothing to do on those
      94             :                 // until users reference them...
      95           0 :                 break;
      96             : 
      97             :             case Node::node_t::NODE_DIRECTIVE_LIST:
      98             :                 // Recursive!
      99           0 :                 end_list = directive_list(child);
     100             :                 // TODO: we need a real control flow
     101             :                 //       information to know whether this
     102             :                 //       latest list had a break, continue,
     103             :                 //       goto or return statement which
     104             :                 //       was (really) breaking us too.
     105           0 :                 break;
     106             : 
     107             :             case Node::node_t::NODE_LABEL:
     108             :                 // labels do not require any compile whatever...
     109           0 :                 break;
     110             : 
     111             :             case Node::node_t::NODE_VAR:
     112           0 :                 var(child);
     113           0 :                 break;
     114             : 
     115             :             case Node::node_t::NODE_WITH:
     116           0 :                 with(child);
     117           0 :                 break;
     118             : 
     119             :             case Node::node_t::NODE_USE: // TODO: should that move in a separate loop?
     120           0 :                 use_namespace(child);
     121           0 :                 break;
     122             : 
     123             :             case Node::node_t::NODE_GOTO:
     124           0 :                 goto_directive(child);
     125           0 :                 end_list = child;
     126           0 :                 break;
     127             : 
     128             :             case Node::node_t::NODE_FOR:
     129           0 :                 for_directive(child);
     130           0 :                 break;
     131             : 
     132             :             case Node::node_t::NODE_SWITCH:
     133           0 :                 switch_directive(child);
     134           0 :                 break;
     135             : 
     136             :             case Node::node_t::NODE_CASE:
     137           0 :                 case_directive(child);
     138           0 :                 break;
     139             : 
     140             :             case Node::node_t::NODE_DEFAULT:
     141           0 :                 default_directive(child);
     142           0 :                 break;
     143             : 
     144             :             case Node::node_t::NODE_IF:
     145           0 :                 if_directive(child);
     146           0 :                 break;
     147             : 
     148             :             case Node::node_t::NODE_WHILE:
     149           0 :                 while_directive(child);
     150           0 :                 break;
     151             : 
     152             :             case Node::node_t::NODE_DO:
     153           0 :                 do_directive(child);
     154           0 :                 break;
     155             : 
     156             :             case Node::node_t::NODE_THROW:
     157           0 :                 throw_directive(child);
     158           0 :                 end_list = child;
     159           0 :                 break;
     160             : 
     161             :             case Node::node_t::NODE_TRY:
     162           0 :                 try_directive(child);
     163           0 :                 break;
     164             : 
     165             :             case Node::node_t::NODE_CATCH:
     166           0 :                 catch_directive(child);
     167           0 :                 break;
     168             : 
     169             :             case Node::node_t::NODE_FINALLY:
     170           0 :                 finally(child);
     171           0 :                 break;
     172             : 
     173             :             case Node::node_t::NODE_BREAK:
     174             :             case Node::node_t::NODE_CONTINUE:
     175           0 :                 break_continue(child);
     176           0 :                 end_list = child;
     177           0 :                 break;
     178             : 
     179             :             case Node::node_t::NODE_ENUM:
     180           0 :                 enum_directive(child);
     181           0 :                 break;
     182             : 
     183             :             case Node::node_t::NODE_FUNCTION:
     184           0 :                 function(child);
     185           0 :                 break;
     186             : 
     187             :             case Node::node_t::NODE_RETURN:
     188           0 :                 end_list = return_directive(child);
     189           0 :                 break;
     190             : 
     191             :             case Node::node_t::NODE_CLASS:
     192             :             case Node::node_t::NODE_INTERFACE:
     193             :                 // TODO: any non-intrinsic function or
     194             :                 //       variable member referenced in
     195             :                 //       a class requires that the
     196             :                 //       whole class be assembled.
     197             :                 //       (Unless we can just assemble
     198             :                 //       what the user accesses.)
     199        8192 :                 class_directive(child);
     200        8192 :                 break;
     201             : 
     202             :             case Node::node_t::NODE_IMPORT:
     203           0 :                 import(child);
     204           0 :                 break;
     205             : 
     206             :             // all the possible expression entries
     207             :             case Node::node_t::NODE_ASSIGNMENT:
     208             :             case Node::node_t::NODE_ASSIGNMENT_ADD:
     209             :             case Node::node_t::NODE_ASSIGNMENT_BITWISE_AND:
     210             :             case Node::node_t::NODE_ASSIGNMENT_BITWISE_OR:
     211             :             case Node::node_t::NODE_ASSIGNMENT_BITWISE_XOR:
     212             :             case Node::node_t::NODE_ASSIGNMENT_DIVIDE:
     213             :             case Node::node_t::NODE_ASSIGNMENT_LOGICAL_AND:
     214             :             case Node::node_t::NODE_ASSIGNMENT_LOGICAL_OR:
     215             :             case Node::node_t::NODE_ASSIGNMENT_LOGICAL_XOR:
     216             :             case Node::node_t::NODE_ASSIGNMENT_MAXIMUM:
     217             :             case Node::node_t::NODE_ASSIGNMENT_MINIMUM:
     218             :             case Node::node_t::NODE_ASSIGNMENT_MODULO:
     219             :             case Node::node_t::NODE_ASSIGNMENT_MULTIPLY:
     220             :             case Node::node_t::NODE_ASSIGNMENT_POWER:
     221             :             case Node::node_t::NODE_ASSIGNMENT_ROTATE_LEFT:
     222             :             case Node::node_t::NODE_ASSIGNMENT_ROTATE_RIGHT:
     223             :             case Node::node_t::NODE_ASSIGNMENT_SHIFT_LEFT:
     224             :             case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT:
     225             :             case Node::node_t::NODE_ASSIGNMENT_SHIFT_RIGHT_UNSIGNED:
     226             :             case Node::node_t::NODE_ASSIGNMENT_SUBTRACT:
     227             :             case Node::node_t::NODE_CALL:
     228             :             case Node::node_t::NODE_DECREMENT:
     229             :             case Node::node_t::NODE_DELETE:
     230             :             case Node::node_t::NODE_INCREMENT:
     231             :             case Node::node_t::NODE_MEMBER:
     232             :             case Node::node_t::NODE_NEW:
     233             :             case Node::node_t::NODE_POST_DECREMENT:
     234             :             case Node::node_t::NODE_POST_INCREMENT:
     235           0 :                 expression(child);
     236           0 :                 break;
     237             : 
     238             :             case Node::node_t::NODE_UNKNOWN:
     239             :                 // ignore nodes marked as unknown ("nearly deleted")
     240           0 :                 break;
     241             : 
     242             :             default:
     243             :                 {
     244           0 :                     Message msg(message_level_t::MESSAGE_LEVEL_ERROR, err_code_t::AS_ERR_INTERNAL_ERROR, child->get_position());
     245           0 :                     msg << "directive node '" << child->get_type_name() << "' not handled yet in Compiler::directive_list().";
     246             :                 }
     247           0 :                 break;
     248             : 
     249             :             }
     250             : 
     251        8192 :             if(end_list && idx + 1 < max_children)
     252             :             {
     253           0 :                 Node::pointer_t next(directive_list_node->get_child(idx + 1));
     254           0 :                 if(next->get_type() == Node::node_t::NODE_CASE
     255           0 :                 || next->get_type() == Node::node_t::NODE_DEFAULT)
     256             :                 {
     257             :                     // process can continue with another case or default
     258             :                     // statement following a return, throw, etc.
     259           0 :                     end_list.reset();
     260           0 :                 }
     261             :             }
     262       16384 :         }
     263             :     }
     264             : 
     265        8192 :     if(directive_list_node->get_flag(Node::flag_t::NODE_DIRECTIVE_LIST_FLAG_NEW_VARIABLES))
     266             :     {
     267           0 :         size_t const max_variables(directive_list_node->get_variable_size());
     268           0 :         for(size_t idx(0); idx < max_variables; ++idx)
     269             :         {
     270           0 :             Node::pointer_t variable_node(directive_list_node->get_variable(idx));
     271           0 :             Node::pointer_t var_parent(variable_node->get_parent());
     272           0 :             if(var_parent && var_parent->get_flag(Node::flag_t::NODE_VARIABLE_FLAG_TOADD))
     273             :             {
     274             :                 // TBD: is that just the var declaration and no
     275             :                 //      assignment? because the assignment needs to
     276             :                 //      happen at the proper time!!!
     277           0 :                 var_parent->set_flag(Node::flag_t::NODE_VARIABLE_FLAG_TOADD, false);
     278           0 :                 directive_list_node->insert_child(0, var_parent); // insert at the start!
     279             :             }
     280           0 :         }
     281           0 :         directive_list_node->set_flag(Node::flag_t::NODE_DIRECTIVE_LIST_FLAG_NEW_VARIABLES, false);
     282             :     }
     283             : 
     284             :     // go through the f_scope list and remove the "use namespace" that
     285             :     // were added while working on the items of this list
     286             :     // (why?!? because those are NOT like in C++, they are standalone
     287             :     // instructions... weird!)
     288        8192 :     size_t max_use_namespace(f_scope->get_children_size());
     289       16384 :     while(p < max_use_namespace)
     290             :     {
     291           0 :         max_use_namespace--;
     292           0 :         f_scope->delete_child(max_use_namespace);
     293             :     }
     294             : 
     295        8192 :     return end_list;
     296             : }
     297             : 
     298             : 
     299             : 
     300             : 
     301          63 : }
     302             : // namespace as2js
     303             : 
     304             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10