--          This file is part of SmartEiffel The GNU Eiffel Compiler.
--       Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE
--          Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr
--                       http://SmartEiffel.loria.fr
-- SmartEiffel 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  2, or (at your option)  any  later
-- version. SmartEiffel 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  SmartEiffel;  see the file COPYING.  If not,
-- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA.
--
class IFTHENLIST

inherit IF_GLOBALS

creation make

feature

   pretty_print is
      local
         i: INTEGER
      do
         from
            i := list.lower
         until
            i > list.upper
         loop
            list.item(i).pretty_print
            i := i + 1
            if i <= list.upper then
               pretty_printer.indent
               pretty_printer.keyword(once "elseif")
            end
         end
      end

   afd_check is
      local
         i: INTEGER
      do
         from
            i := list.upper
         until
            i < list.lower
         loop
            list.item(i).afd_check
            i := i - 1
         end
      end

   safety_check is
      local
         i: INTEGER
      do
         from
            i := list.upper
         until
            i < list.lower
         loop
            list.item(i).safety_check
            i := i - 1
         end
      end

   collect_c_tmp is
      local
         i: INTEGER
      do
         from
            i := list.upper
         until
            i < list.lower
         loop
            list.item(i).collect_c_tmp
            i := i - 1
         end
      end

   compile_to_c: INTEGER is
         -- state 0: no printing done.
         -- state 1: already print `non_static'.
         -- state 2: end of list or previous `static_true'.
      local
         state, previous, i: INTEGER
      do
         from
            i := list.lower
         until
            state = 2
         loop
            inspect
               state
            when 0 then
               if i > list.upper then
                  state := 2
                  Result := previous
               else
                  previous := list.item(i).compile_to_c(false)
                  inspect
                     previous
                  when non_static then
                     state := 1
                  when static_false then
                  when static_true then
                     Result := static_true
                     state := 2
                  end
               end
            else -- 1
               if i > list.upper then
                  state := 2
                  inspect
                     previous
                  when static_true then
                     Result := static_true
                  else
                     Result := non_static
                  end
               else
                  previous := list.item(i).compile_to_c(true)
                  inspect
                     previous
                  when non_static then
                  when static_false then
                  when static_true then
                     state := 2
                     Result := static_true
                  end
               end
            end
            i := i + 1
         end
      ensure
         (<<static_true,static_false,non_static>>).fast_has(Result)
      end

   compile_to_jvm: INTEGER is
      local
         i: INTEGER
      do
         from
            Result := list.first.compile_to_jvm
            i := list.lower + 1
         until
            Result = static_true or else i > list.upper
         loop
            inspect
               list.item(i).compile_to_jvm
            when static_true then
               Result := static_true
            when static_false then
               if Result = static_false then
               else
                  Result := non_static
               end
            else -- non_static :
               Result := non_static
            end
            i := i + 1
         end
      ensure
         (<<static_true,static_false,non_static>>).fast_has(Result)
      end

   use_current: BOOLEAN is
      local
         i: INTEGER
      do
         from
            i := list.upper
         until
            i < list.lower or else Result
         loop
            Result := list.item(i).use_current
            i := i - 1
         end
      end

   stupid_switch(run_time_set: RUN_TIME_SET): BOOLEAN is
      local
         i: INTEGER
      do
         from
            Result := true
            i := list.upper
         until
            not Result or else i < list.lower
         loop
            Result := list.item(i).stupid_switch(run_time_set)
            i := i - 1
         end
      end

   count: INTEGER is
      do
         Result := list.count
      end

   to_runnable(ct: E_TYPE): like Current is
      require
         ct /= Void
      local
         i: INTEGER
      do
         if current_type /= Void then
	    from
	       !!Result.make(list.first)
	       i := list.lower + 1
	    until
	       i > list.upper
	    loop
	       Result.add_last(list.item(i))
	       i := i + 1
	    end
            Result := Result.to_runnable(ct)
         else
            current_type := ct
            from
               i := list.lower
            until
               i > list.upper or else nb_errors > 0
            loop
               list.put(list.item(i).to_runnable(ct),i)
               debug
                  if nb_errors = 0 then
                     check
                        list.item(i) /= Void
                     end
                  end
               end
               i := i + 1
            end
            Result := Current
         end
      end

feature {IFTHENELSE}

   verify_scoop(allowed: FORMAL_ARG_LIST) is
      local
         i: INTEGER
      do
         from
            i := list.upper
         until
            i < list.lower
         loop
            list.item(i).verify_scoop(allowed)
            i := i - 1
         end
      end

feature {IFTHENELSE,IFTHENLIST}

   add_last(it: IFTHEN) is
      require
         it /= Void
      do
         list.add_last(it)
      ensure
         count = old count + 1
      end

feature {IFTHENELSE}

   compile_to_jvm_resolve_branch is
      local
         i, static: INTEGER
      do
         from
            i := list.lower
            static := non_static
         until
            static = static_true or else i > list.upper
         loop
            static := list.item(i).compile_to_jvm_resolve_branch
            i := i + 1
         end
      end

feature {NONE}

   list: FIXED_ARRAY[IFTHEN]

   current_type: E_TYPE

   make(first: IFTHEN) is
      require
         first /= Void
      do
         !!list.with_capacity(4)
	 list.add_last(first)
      ensure
         list.first = first
      end

invariant

   list.count >= 1

end -- IFTHENLIST
