Code coverage for node_type.li


///////////////////////////////////////////////////////////////////////////////
//                             Lisaac Compiler                               //
//                                                                           //
//                   LSIIT - ULP - CNRS - INRIA - FRANCE                     //
//                                                                           //
//   This program is free software: you can redistribute it and/or modify    //
//   it under the terms of the GNU General Public License as published by    //
//   the Free Software Foundation, either version 3 of the License, or       //
//   (at your option) any later version.                                     //
//                                                                           //
//   This program is distributed in the hope that it will be useful,         //
//   but WITHOUT ANY WARRANTY; without even the implied warranty of          //
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
//   GNU General Public License for more details.                            //
//                                                                           //
//   You should have received a copy of the GNU General Public License       //
//   along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
//                                                                           //
//                     http://isaacproject.u-strasbg.fr/                     //
///////////////////////////////////////////////////////////////////////////////
Section Header

  + name        := NODE_TYPE;

  - copyright   := "2003-2007 Benoit Sonntag";


  - author      := "Sonntag Benoit (bsonntag@loria.fr)";
  - comment     := "Switch node for type";

Section Inherit

  + parent_node:Expanded NODE;

Section Public

  - result_expr:EXPR <- data.result_expr;

  + is_self:BOOLEAN;

  //
  // Creation.
  //

  - create e:EXPR with d:DTA :SELF <-
  // Create with back-link.
  [ -? {d.position != 0}; ]
  ( + result:SELF;

    result := clone;
    result.make e with d;
    result
  )
;

  - make e:EXPR with d:DTA <-
  (
    expr := e;
    data := d;
    late_binding_counter := late_binding_counter + 1;
  )
;

  //
  // Just for ITM_EXPRESSION
  //

  - create_partial d:DTA :SELF <-
  ( + result:SELF;

    result := clone;
    result.make_partial d;
    result
  )
;

  - make_partial d:DTA <-
  (
    data := d;
  )
;

Section Public

  - my_copy:SELF <-
  ( + result:SELF;

    result := SELF.create (expr.my_copy) with data;
    node_list.add_last result;
    result
  )
;

  //
  // Update.
  //

  - update:BOOLEAN <-
  (
    update_case NULL & update_depth NULL
  )
;

Section NODE, DTA

  - update_link self_type:TYPE_FULL :BOOLEAN <-
  (
    update_case self_type & update_depth self_type
  )
;

Section Private

  - update_case type_self:TYPE_FULL :BOOLEAN <-
  ( + typ_f:TYPE_FULL;
    + typ:TYPE;
    + lst_typ:TYPES_TMP;
    + list:FAST_ARRAY(CASE);
    + case:CASE;
    + result:BOOLEAN;

    typ_f := expr.static_type;

    (typ_f.is_expanded && {typ_f.raw != type_boolean}).if {
      (first_code = NULL).if {
        first_type := typ_f.raw;
        first_code := data.product first_type with expr self type_self;
      }
;
      result := TRUE;
    }
.elseif {(typ_f.raw = type_boolean) && {count = 2}} then {
      result := TRUE;
    }
 else {
      ((typ_f.raw.is_block) || {typ_f.raw.subtype_list.count != count}).if {
        lst_typ := TYPES_TMP.new;
        expr.get_type lst_typ;

        /*
        ((typ_f.raw = type_boolean) && {! lst_typ.is_empty}).if {
          expr.debug_display; '\n'.print;
          (lst_typ.first = type_boolean).if {

            crash_with_message "NODE_TYPE : BUG";
          };
          /*
          lst_typ.print;
          '\n'.print;
          warning_error (position,"ICI");
          */
        };
        */
        (! lst_typ.is_empty).if {
          (lst_typ.count = 1).if {
            (first_code = NULL).if {
              first_type := lst_typ.first;
              first_code := data.product first_type with expr self type_self;
            }
;
          }
 else {
            (switch = NULL).if {
              switch := SWITCH.create Self with expr size (lst_typ.count);
            }
;
            list := switch.list;
            (list.count != lst_typ.count).if {
              (lst_typ.lower).to (lst_typ.upper) do { j:INTEGER;
                typ := lst_typ.item j;
                ((j > list.upper) || {typ != list.item j.id}).if {
                  add_stack_type typ;
                  //
                  case := CASE.create typ with (data.product typ with expr self type_self);
                  list.add case to j;
                  //
                  stack_type.remove_last;
                }
;
              }
;
            }
;
          }
;
        }
;
        lst_typ.free;
      }
 else {
        //count_flat := count_flat + 1;
        //"Yes\n".print;
      }
;
    }
;
    result
  )
;

  - update_depth self_type:TYPE_FULL :BOOLEAN <-
  ( + result:BOOLEAN;
    + list:FAST_ARRAY(CASE);
    + new_type_self:TYPE_FULL;

    (switch = NULL).if {
      (first_code != NULL).if {
        (self_type = NULL).if {
          new_type_self := expr.static_type;
          ((! new_type_self.is_expanded) || {new_type_self.raw = type_boolean}).if {
            new_type_self := first_type.default.to_strict;
          }
;
        }
 else {
          new_type_self := self_type;
        }
;

        add_stack_type first_type;
        result := data.update_branch first_code self new_type_self;
        stack_type.remove_last;
      }
;
    }
 else {
      list := switch.list;

      (list.lower).to (list.upper) do { j:INTEGER;
        (self_type = NULL).if {
          new_type_self := list.item j.id.default.to_strict;
        }
 else {
          new_type_self := self_type;
        }
;
        add_stack_type (list.item j.id);
        data.update_branch (list.item j.code) self new_type_self;
        stack_type.remove_last;
      }
;
    }
;
    result
  )
;

Section Private

  - stack_type:FAST_ARRAY(TYPE) := FAST_ARRAY(TYPE).create_with_capacity 16;

  - add_stack_type t:TYPE <-
  (
    stack_type.add_last t;
    ((stack_type.count > 1) && {stack_type.first = t}).if {
      string_tmp.copy "Cyclic inheritance : ";
      (stack_type.lower).to (stack_type.upper) do { j:INTEGER;
        stack_type.item j.append_name_in string_tmp;
        string_tmp.append ", ";
      }
;
      string_tmp.append "...";
      semantic_error (data.position, string_tmp);
    }
;
  )
;