Code coverage for local.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        := LOCAL;

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


  - author      := "Sonntag Benoit (bsonntag@loria.fr)";
  - comment     := "Local slot";

Section Inherit

  + parent_variable:Expanded VARIABLE;

Section Public

  // BSBS: Doit pas etre utile.

  + is_result :BOOLEAN := FALSE;

  - set_result r:BOOLEAN <-
  (
    is_result := r;
  );

  //
  // Copy alias manager.
  //

  - is_alias:BOOLEAN;

  - alias_on <-
  (
    is_alias := TRUE;
  );

  - alias_off <-
  (
    (list_alias.lower).to (list_alias.upper) do { j:INTEGER;
      list_alias.item j.set_my_alias NULL;
    };
    list_alias.clear;
    is_alias := FALSE;
  );

  - list_alias:FAST_ARRAY(LOCAL) := FAST_ARRAY(LOCAL).create_with_capacity 64;

  - get_alias:LOCAL <-
  (
    (my_alias = NULL).if {
      my_alias := my_copy;
      my_alias.set_type_set type_set;
      list_alias.add_last Self;
    };
    my_alias
  );

  + my_alias:LOCAL;

  - set_my_alias new_loc:LOCAL <-
  (
    my_alias := new_loc;
  );

  + list_level:INTEGER;

  - set_list_level lev:INTEGER <-
  (
    list_level := lev;
  );

  - write p:POSITION with r:EXPR value val:EXPR :WRITE <-
  ( + result:WRITE;

    (my_alias != NULL).if {
      result := my_alias.write_direct p with NULL value val;
    }.elseif {is_alias} then {
      result := get_alias.write_direct p with NULL value val;
    } else {
      result := write_direct p with NULL value val;
    };
    result
  );

  - read p:POSITION with r:EXPR :READ <-
  ( + result:READ;

    (my_alias != NULL).if {
      result := my_alias.read_direct p with NULL;
    }.elseif {is_alias} then {
      // Case : Argument function (see CALL_SLOT)
      result := get_alias.read_direct p with NULL;
    } else {
      //? {! is_alias};
      result := read_direct p with NULL;
    };
    result
  );

  //
  // Sequence optimizer
  //

  + last_seq:LOCAL_SEQ;

  - reset_last_write w:WRITE <-
  (
    ((last_seq != NULL)    {last_seq.last_write = w}).if {
      last_seq.set_last_write NULL;
    };
  );

  - set_last_seq s:LOCAL_SEQ <-
  (
    last_seq := s;
  );

  - set_write w:WRITE <-
  (
    (last_seq = NULL).if {
      LOCAL_SEQ.new Self;
      //"LOCAL:".print;
      //intern_name.print; '\n'.print;
    };
    (
      (! PROFIL.mode_recursive)   
      {loop_invariant = NULL}   
      {last_seq.last_write != NULL}   
      {last_seq.last_index != -1}   
      {last_seq.last_list_current = list_current}   
      {last_seq.last_index < list_current.index}    
      {last_seq.last_seq_call_local_and_loop = seq_call_local_and_loop}   
      {list_current.item (last_seq.last_index) = last_seq.last_write} // BSBS: Voir pourquoi pas tjrs le cas
    ).if {
      list_current.put (last_seq.last_write.value) to (last_seq.last_index);
      unwrite (last_seq.last_write);
      new_execute_pass;
    };
    // Save context
    last_seq.set_seq w;
  );

  - set_read <-
  (
    (last_seq != NULL).if {
      last_seq.set_last_index (-1);
    };
  );

  - get_last_index:INTEGER <- last_seq.last_index;

  - is_invariant:BOOLEAN <-
  (
    (loop_seq_call_local_and_loop = seq_call_local_and_loop)   
    {
      (
	(last_seq != NULL)    {last_seq.last_write != NULL}   
	{last_seq.last_seq_index <= loop_seq_index}
      ) || {style = ' '}
    }
  );

  - get_last_value rec:EXPR :EXPR <-
  [
    ? {rec = NULL};
  ]
  ( + result:EXPR;
    + val:EXPR;
    + rd:READ;
    + l:LOCAL;
    + g:SLOT_DATA;
    /*
    + bug:BOOLEAN;

    (intern_name == "__tmp__TC").if {
      bug:=TRUE;
      "0\n".print;
      (last_seq = NULL).if {
        "last seq NULL\n".print;
        crash;
      } else {
        (last_seq.last_write = NULL).if {
          "last_write null\n".print;
        };
      };
    };
     */


    (
      (! PROFIL.mode_recursive)    {loop_invariant = NULL}   
      {last_seq != NULL}    {last_seq.last_write != NULL}
    ).if {
      /*
      (bug).if {
        "1\n".print;
      };
      */
      (
	(is_seq_list (last_seq.last_list_current))   
	{
	  (last_seq.last_seq_call_local_and_loop = seq_call_local_and_loop) ||
	  {require_count = 1}
	}
      ).if {
	val := last_seq.last_write.value;
	rd  ?= val;
	(rd != NULL).if {
	  l ?= rd.variable;
	  g ?= rd.variable;
	};
	(
	  ( // Constant propagation.
	    val.is_constant
	  ) ||
	  { // Local propagation.
	    (l != NULL)    {
	      (
		(l.last_seq != NULL)    {l.last_seq.last_write != NULL}   
		{l.last_seq.last_seq_index < last_seq.last_seq_index}   
		{last_seq.last_seq_call_local_and_loop = seq_call_local_and_loop}
	      ) || {l.require_count <= 1} || {l.style = ' '}
	    }
	  } ||
	  { // Global propagation.
	    (g != NULL)    {g.style = '-'}    {
	      (
		(g.last_write != NULL)    {g.last_seq_index < last_seq.last_seq_index}   
		{last_seq.last_seq_call_and_loop = seq_call_and_loop}   
		{is_seq_list (g.last_list_current)}
	      ) || {g.require_count = 1}
	    }
	  }
	).if {
	  result := val.my_copy;
	}.elseif {
	  // Propagation step by step.
	  (last_seq.last_seq_or_and = seq_or_and)   
	  {ensure_count = 1}   
	  {list_current.index > list_current.lower}   
	  {list_current.item (list_current.index - 1) = last_seq.last_write}
	} then {
	  unwrite (last_seq.last_write);
	  last_seq.set_last_write NULL;
	  list_current.put NOP to (list_current.index - 1);
	  result := val;
	};
      };
    };
    result
  );

  - set_type_set t:TYPES <-
  (
    type_set := t;
  );

  //
  //
  //

  - is_local:BOOLEAN <- TRUE;

  //
  // Creation.
  //

  - create p:POSITION name n:STRING_CONSTANT
  style c:CHARACTER type t:TYPE_FULL result r:BOOLEAN :SELF<-
  ( + result:SELF;
    result := clone;
    result.make p name n style c type t result r;
    result
  );

  - create p:POSITION name n:STRING_CONSTANT
  style c:CHARACTER type t:TYPE_FULL :SELF<-
  ( + result:SELF;
    result := clone;
    result.make p name n style c type t result FALSE;
    result
  );

  - make p:POSITION name n:STRING_CONSTANT
  style c:CHARACTER type t:TYPE_FULL result r:BOOLEAN <-
  ( + tmp:TYPES_TMP;
    ? {p.code != 0};
    ? {t != NULL};

    position    := p;
    name        := n;
    is_result   := r;
    intern_name := ALIAS_STR.get_intern n;

    ((t.is_expanded)    {! t.is_expanded_c}).if {
      type := t + TYPE_FULL.expanded_ref_bit;
    } else {
      type := t;
    };
    style := c;

    (is_static).if {
      tmp := TYPES_TMP.new;
      tmp.add (t.raw);
      type_set := tmp.to_types;
    } else {
      type_set := TYPES_TMP.types_empty;
    };
  );

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

    result := LOCAL.create position name name style style type type;
    result
  );

  //
  // Value.
  //

  - init <-
  ( + val:EXPR;
    + i:INSTR;
    + int:INTEGER_CST;

    val := type.default_value position;
    (ALIAS_STR.is_integer (type.raw.name)).if {
      int ?= val;
      (int != NULL).if {
	int.cast_type type;
      };
    } else {
      val := val.check_type type with position;
    };
    i := write position value val;
    list_current.add_last i;
  );

  - set_intern_name n:STRING_CONSTANT <-
  (
    intern_name := n;
  );

Section VARIABLE

  - new_read p:POSITION with r:EXPR :READ <-
  [ -? {r = NULL}; ]
  (
    READ_LOCAL.create p with Self
  );

  - new_write p:POSITION with r:EXPR value v:EXPR :WRITE <-
  [ -? {r = NULL}; ]
  ( + result:WRITE;
    result := WRITE_LOCAL.create p with v in Self;
    result
  );

  /*
  - new_access r:EXPR :ACCESS <-
  (
    ACCESS_LOCAL.create Self
  );
  */