home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / declaration_list.e < prev    next >
Text File  |  1999-06-05  |  7KB  |  282 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. deferred class DECLARATION_LIST
  17.    --
  18.    -- For a formal arguments list (FORMAL_ARG_LIST) or for a local
  19.    -- variable list (LOCAL_VAR_LIST).
  20.    --
  21.    -- Exemple :
  22.    --
  23.    --   foo, bar : ZOO; x : INTEGER
  24.    --
  25.  
  26. inherit GLOBALS;
  27.  
  28. feature {DECLARATION_LIST}
  29.  
  30.    list: ARRAY[DECLARATION];
  31.          -- Really written list including declaration groups.
  32.  
  33.    flat_list: ARRAY[like name];
  34.          -- The same contents as `list' but flat.
  35.  
  36. feature {NONE}
  37.  
  38.    declaration_list_make(l: like list) is
  39.          -- Common part of creation.
  40.       require
  41.          l.lower = 1;
  42.          not l.empty
  43.       local
  44.          il, actual_count: INTEGER;
  45.       do
  46.          list := l;
  47.          from
  48.             il := list.upper;
  49.          until
  50.             il = 0
  51.          loop
  52.             actual_count := actual_count + list.item(il).count;
  53.             il := il - 1;
  54.          end;
  55.          from
  56.             !!flat_list.make(1,actual_count);
  57.             il := 1;
  58.          until
  59.             il > list.upper
  60.          loop
  61.             list.item(il).append_in(Current);
  62.             il := il + 1;
  63.          end;
  64.       ensure
  65.          list = l;
  66.          flat_list /= Void
  67.       end;
  68.  
  69. feature
  70.  
  71.    start_position: POSITION is
  72.       do
  73.          Result := flat_list.first.start_position;
  74.       end;
  75.  
  76.    pretty_print is
  77.       require
  78.          fmt.indent_level >= 2;
  79.       deferred
  80.       ensure
  81.          fmt.indent_level = old fmt.indent_level;
  82.       end;
  83.  
  84.    count: INTEGER is
  85.       do
  86.          Result := flat_list.upper;
  87.       end;
  88.  
  89.    rank_of(n: STRING): INTEGER is
  90.          -- Result is greater than 0 when `n' is in the list.
  91.       require
  92.          string_aliaser.item(n) = n
  93.       do
  94.          from
  95.             Result := count
  96.          until
  97.             Result = 0 or else n = name(Result).to_string
  98.          loop
  99.             Result := Result - 1;
  100.          end;
  101.       ensure
  102.          0 <= Result;
  103.          Result <= count;
  104.       end;
  105.  
  106.    name(i: INTEGER): LOCAL_ARGUMENT1 is
  107.       require
  108.          1 <= i;
  109.          i <= count
  110.       deferred
  111.       ensure
  112.          Result /= Void
  113.       end;
  114.  
  115.    type(i: INTEGER): TYPE is
  116.       require
  117.          1 <= i;
  118.          i <= count;
  119.       do
  120.          Result := name(i).result_type;
  121.       ensure
  122.          Result /= Void
  123.       end;
  124.  
  125. feature {DECLARATION}
  126.  
  127.    add_last(n: like name) is
  128.       local
  129.          i: INTEGER;
  130.          n2: like name;
  131.       do
  132.          from
  133.             i := 1;
  134.          until
  135.             flat_list.item(i) = Void
  136.          loop
  137.             n2 := flat_list.item(i);
  138.             if n2.to_string = n.to_string then
  139.                eh.add_position(n.start_position);
  140.                eh.add_position(n2.start_position);
  141.                fatal_error("Same name appears twice.");
  142.             end;
  143.             i := i + 1;
  144.          end;
  145.          flat_list.put(n,i);
  146.          n.set_rank(i);
  147.       end;
  148.  
  149. feature {RUN_FEATURE}
  150.  
  151.    frozen jvm_stack_space: INTEGER is
  152.          -- Number of needed words in the JVM stack.
  153.       local
  154.          i: INTEGER;
  155.       do
  156.          from
  157.             i := count;
  158.          until
  159.             i = 0
  160.          loop
  161.             Result := Result + type(i).run_type.jvm_stack_space;
  162.             i := i - 1;
  163.          end;
  164.       end;
  165.  
  166. feature {RUN_FEATURE}
  167.  
  168.    frozen jvm_offset_of(la: LOCAL_ARGUMENT): INTEGER is
  169.       local
  170.          i, rank: INTEGER;
  171.       do
  172.          from
  173.             rank := la.rank;
  174.             i := 1;
  175.          variant
  176.             count - i
  177.          until
  178.             i = rank
  179.          loop
  180.             Result := Result + type(i).run_type.jvm_stack_space;
  181.             i := i + 1;
  182.          end;
  183.       end;
  184.  
  185. feature {NONE}
  186.  
  187.    em1: STRING is "Bad declaration.";
  188.  
  189. feature
  190.  
  191.    frozen is_runnable(ct: TYPE): BOOLEAN is
  192.       local
  193.          i: INTEGER;
  194.          n1, n2: like name;
  195.          t: TYPE;
  196.       do
  197.          from
  198.             Result := true;
  199.             i := flat_list.upper;
  200.          until
  201.             not Result or else i = 0
  202.          loop
  203.             t := type(i);
  204.             if t.is_run_type then
  205.                if t.run_type /= t then
  206.                   Result := false;
  207.                end;
  208.             else
  209.                Result := false;
  210.             end;
  211.             i := i - 1;
  212.          end;
  213.          if Result then
  214.             from
  215.                i := flat_list.upper;
  216.             until
  217.                i = 0
  218.             loop
  219.                n1 := flat_list.item(i);
  220.                n2 := n1.to_runnable(ct);
  221.                if n2 = Void then
  222.                   error(n1.start_position,em1);
  223.                   i := 0;
  224.                else
  225.                   i := i - 1;
  226.                end;
  227.             end;
  228.             check_name_clash(ct);
  229.          end;
  230.       end;
  231.  
  232. feature {DECLARATION_LIST}
  233.  
  234.    frozen check_name_clash(ct: TYPE) is
  235.       local
  236.          i: INTEGER;
  237.       do
  238.          from
  239.             i := flat_list.upper;
  240.          until
  241.             i = 0
  242.          loop
  243.             name(i).name_clash(ct);
  244.             i := i - 1;
  245.          end;
  246.       end;
  247.  
  248.    frozen dynamic_runnable(ct: TYPE) is
  249.       local
  250.          i: INTEGER;
  251.          n1, n2: like name;
  252.       do
  253.          flat_list := flat_list.twin;
  254.          from
  255.             i := flat_list.upper;
  256.          until
  257.             i = 0
  258.          loop
  259.             n1 := flat_list.item(i);
  260.             n2 := n1.to_runnable(ct);
  261.             if n2 = Void then
  262.                error(n1.start_position,em1);
  263.             else
  264.                flat_list.put(n2,i);
  265.             end;
  266.             i := i - 1;
  267.          end;
  268.       end;
  269.  
  270. invariant
  271.  
  272.    count > 0;
  273.  
  274.    flat_list.lower = 1;
  275.  
  276.    count = flat_list.count;
  277.  
  278.    list.count <= count;
  279.  
  280. end -- DECLARATION_LIST
  281.  
  282.