home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / assertion_list.e < prev    next >
Text File  |  1999-06-05  |  9KB  |  361 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 ASSERTION_LIST
  17.    --
  18.    -- To store a list of assertions (see ASSERTION).
  19.    --
  20.    -- See also : CLASS_INVARIANT, E_REQUIRE, E_ENSURE,
  21.    --            LOOP_INVARIANT and CHECK_INVARIANT.
  22.    --
  23.  
  24. inherit GLOBALS;
  25.  
  26. feature
  27.  
  28.    name: STRING is
  29.          -- "require", "ensure" or "invariant".
  30.       deferred
  31.       end;
  32.  
  33.    start_position: POSITION;
  34.          -- If any, the position of the first letter of `name'.
  35.  
  36.    header_comment: COMMENT;
  37.  
  38. feature {ASSERTION_LIST,E_CHECK,E_FEATURE}
  39.  
  40.    list: ARRAY[ASSERTION];
  41.  
  42. feature
  43.  
  44.    current_type: TYPE;
  45.          -- Not Void when checked in.
  46.  
  47. feature {NONE}
  48.  
  49.    run_feature: RUN_FEATURE;
  50.          -- Corresponding one (if any) when runnable.
  51.          -- Note: class invariant are not inside a RUN_FEATURE.
  52.  
  53. feature
  54.  
  55.    set_current_type(ct: like current_type) is
  56.       do
  57.          current_type := ct;
  58.       end;
  59.  
  60.    afd_check is
  61.       local
  62.          i: INTEGER;
  63.       do
  64.          if list /= Void then
  65.             from
  66.                i := list.upper;
  67.             until
  68.                i = 0
  69.             loop
  70.                list.item(i).afd_check;
  71.                i := i - 1;
  72.             end;
  73.          end;
  74.       end;
  75.  
  76. feature {NONE}
  77.  
  78.    is_always_true: BOOLEAN is
  79.       local
  80.          i: INTEGER;
  81.          assertion: ASSERTION;
  82.       do
  83.          from
  84.             i := list.upper;
  85.             Result := true;
  86.          until
  87.             not Result or else i = 0
  88.          loop
  89.             assertion := list.item(i);
  90.             Result := assertion.is_always_true;
  91.             i := i - 1;
  92.          end;
  93.       end;
  94.  
  95. feature
  96.  
  97.    compile_to_c is
  98.       require
  99.          run_control.require_check
  100.       local
  101.          i: INTEGER;
  102.          need_se_tmp: BOOLEAN;
  103.          assertion: ASSERTION;
  104.       do
  105.          if is_always_true then
  106.             cpp.increment_static_expression_count(list.count);
  107.          else
  108.             if run_feature = Void then
  109.                cpp.put_string("if(ds.fd->assertion_flag){%N%
  110.                               %ds.fd->assertion_flag=0;%N");
  111.             else
  112.                cpp.put_string("if(");
  113.                run_feature.c_assertion_flag;
  114.                cpp.put_string("){%N");
  115.                run_feature.c_assertion_flag;
  116.                cpp.put_string("=0;%N");
  117.             end;
  118.             from
  119.                i := 1;
  120.             until
  121.                i > list.upper
  122.             loop
  123.                assertion := list.item(i);
  124.                if assertion.is_always_true then
  125.                else
  126.                   assertion.collect_c_tmp;
  127.                   need_se_tmp := cpp.se_tmp_open_declaration;
  128.                   cpp.set_check_assertion_mode(check_assertion_mode);
  129.                   assertion.compile_to_c;
  130.                   if need_se_tmp then
  131.                      cpp.se_tmp_close_declaration;
  132.                   end;
  133.                end;
  134.                i := i + 1;
  135.             end;
  136.             if run_feature = Void then
  137.                cpp.put_string("ds.fd->assertion_flag=1;%N}%N");
  138.             else
  139.                run_feature.c_assertion_flag;
  140.                cpp.put_string("=1;%N}%N");
  141.             end;
  142.          end;
  143.       end;
  144.  
  145.    frozen compile_to_jvm(last_chance: BOOLEAN) is
  146.          -- If `last_chance' is true, an error message is printed at
  147.          -- run-time.
  148.          -- The final result is always left a top of stack.
  149.       local
  150.          point_true, i: INTEGER;
  151.          ca: like code_attribute;
  152.       do
  153.          ca := code_attribute;
  154.          ca.check_opening;
  155.          from
  156.             failure.clear;
  157.             i := 1;
  158.          until
  159.             i > list.upper
  160.          loop
  161.             list.item(i).compile_to_jvm(last_chance);
  162.             failure.add_last(ca.opcode_ifeq);
  163.             i := i + 1;
  164.          end;
  165.          ca.opcode_iconst_1;
  166.          point_true := ca.opcode_goto;
  167.          ca.resolve_with(failure);
  168.          ca.opcode_iconst_0;
  169.          ca.resolve_u2_branch(point_true);
  170.          ca.check_closing;
  171.       end;
  172.  
  173.    is_pre_computable: BOOLEAN is
  174.       local
  175.          i: INTEGER;
  176.       do
  177.          if list = Void then
  178.             Result := true;
  179.          else
  180.             from
  181.                i := list.upper;
  182.                Result := true;
  183.             until
  184.                not Result or else i = 0
  185.             loop
  186.                Result := list.item(i).is_pre_computable;
  187.                i := i - 1;
  188.             end;
  189.          end;
  190.       end;
  191.  
  192.    use_current: BOOLEAN is
  193.       local
  194.          i: INTEGER;
  195.       do
  196.          if list /= Void then
  197.             from
  198.                i := list.upper;
  199.             until
  200.                Result or else i = 0
  201.             loop
  202.                Result := list.item(i).use_current;
  203.                i := i - 1;
  204.             end;
  205.          end;
  206.       end;
  207.  
  208. feature {NONE}
  209.  
  210.    make(sp: like start_position; hc: like header_comment; l: like list) is
  211.       require
  212.          l /= Void implies not l.empty;
  213.          hc /= Void or else l /= Void;
  214.       do
  215.          start_position := sp;
  216.          header_comment := hc;
  217.          list := l;
  218.       ensure
  219.          start_position = sp;
  220.          header_comment = hc;
  221.          list = l;
  222.       end;
  223.  
  224. feature {NONE}
  225.  
  226.    make_runnable(sp: like start_position; l: like list;
  227.                  ct: like current_type; rf: like run_feature) is
  228.       require
  229.          not l.empty;
  230.          ct /= Void
  231.       do
  232.          start_position := sp;
  233.          list := l;
  234.          current_type := ct;
  235.          run_feature := rf;
  236.       ensure
  237.          start_position = sp;
  238.          list = l;
  239.          current_type = ct;
  240.          run_feature = rf
  241.       end;
  242.  
  243. feature
  244.  
  245.    empty: BOOLEAN is
  246.       do
  247.          Result := list = Void;
  248.       end;
  249.  
  250.    run_class: RUN_CLASS is
  251.       do
  252.          Result := current_type.run_class;
  253.       end;
  254.  
  255.    frozen to_runnable(ct: TYPE): like Current is
  256.       require
  257.          ct.run_type = ct;
  258.       do
  259.          if current_type = Void then
  260.             current_type := ct;
  261.             run_feature := small_eiffel.top_rf;
  262.             if list /= Void then
  263.                list := assertion_collector.runnable(list,ct,run_feature,'_');
  264.             end;
  265.             if nb_errors = 0 then
  266.                Result := Current;
  267.             end;
  268.          else
  269.             Result := twin;
  270.             Result.set_current_type(Void);
  271.             Result := Result.to_runnable(ct);
  272.          end;
  273.       ensure
  274.          nb_errors = 0 implies Result /= Void
  275.       end;
  276.  
  277.    pretty_print is
  278.       local
  279.          i: INTEGER;
  280.       do
  281.          fmt.indent;
  282.          fmt.keyword(name);
  283.          fmt.level_incr;
  284.          if header_comment /= Void then
  285.             header_comment.pretty_print;
  286.          else
  287.             fmt.indent;
  288.          end;
  289.          if list /= Void then
  290.             from
  291.                i := 1;
  292.             until
  293.                i > list.upper
  294.             loop
  295.                if fmt.zen_mode and i = list.upper then
  296.                   fmt.set_semi_colon_flag(false);
  297.                else
  298.                   fmt.set_semi_colon_flag(true);
  299.                end;
  300.                fmt.indent;
  301.                list.item(i).pretty_print;
  302.                i := i + 1;
  303.             end;
  304.          end;
  305.          fmt.level_decr;
  306.          fmt.indent;
  307.       ensure
  308.          fmt.indent_level = old fmt.indent_level;
  309.       end;
  310.  
  311.    set_header_comment(hc: like header_comment) is
  312.       do
  313.          header_comment := hc;
  314.       end;
  315.  
  316. feature {E_FEATURE,RUN_CLASS,ASSERTION_COLLECTOR}
  317.  
  318.    add_into(collector: ARRAY[ASSERTION]) is
  319.       local
  320.          i: INTEGER;
  321.          a: ASSERTION;
  322.       do
  323.          if list /= Void then
  324.             from
  325.                i := 1;
  326.             until
  327.                i > list.upper
  328.             loop
  329.                a := list.item(i);
  330.                if not collector.fast_has(a) then
  331.                   collector.add_last(a);
  332.                end;
  333.                i := i + 1;
  334.             end;
  335.          end;
  336.       end;
  337.  
  338. feature {NONE}
  339.  
  340.    failure: FIXED_ARRAY[INTEGER] is
  341.       once
  342.          !!Result.with_capacity(12);
  343.       end;
  344.  
  345.    check_assertion_mode: STRING is
  346.       deferred
  347.       end;
  348.  
  349. feature {RUN_FEATURE_6, RUN_REQUIRE}
  350.  
  351.    clear_run_feature is
  352.       do
  353.          run_feature := Void;
  354.       end;
  355.  
  356. invariant
  357.  
  358.    list /= Void implies (list.lower = 1 and not list.empty);
  359.  
  360. end -- ASSERTION_LIST
  361.