home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / manifest_array.e < prev    next >
Text File  |  1999-06-05  |  12KB  |  497 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. class MANIFEST_ARRAY
  17.    --
  18.    -- Like :  << foo , bar >>
  19.    --
  20.  
  21. inherit EXPRESSION;
  22.  
  23. creation make
  24.  
  25. feature
  26.  
  27.    start_position: POSITION;
  28.          -- Of first character '<'.
  29.  
  30.    list: ARRAY[EXPRESSION];
  31.          -- Void or elements in the array.
  32.  
  33.    result_type: TYPE_ARRAY;
  34.          -- Computed according to the actual `list'.
  35.  
  36. feature {NONE}
  37.  
  38.    current_type: TYPE;
  39.  
  40. feature {NONE}
  41.  
  42.    make(sp: like start_position; l: like list) is
  43.       require
  44.          sp /= Void;
  45.          l /= Void implies not l.empty and l.lower =1;
  46.       do
  47.          start_position := sp;
  48.          list := l;
  49.       ensure
  50.          start_position = sp;
  51.          list = l;
  52.       end;
  53.  
  54. feature
  55.  
  56.    is_current: BOOLEAN is false;
  57.  
  58.    is_writable: BOOLEAN is false;
  59.  
  60.    is_manifest_string: BOOLEAN is false;
  61.  
  62.    is_result: BOOLEAN is false;
  63.  
  64.    is_void: BOOLEAN is false;
  65.  
  66.    is_static: BOOLEAN is false;
  67.  
  68.    precedence: INTEGER is 2;
  69.  
  70.    can_be_dropped: BOOLEAN is false;
  71.  
  72.    c_simple: BOOLEAN is false;
  73.  
  74.    isa_dca_inline_argument: INTEGER is 0;
  75.  
  76.    static_result_base_class: BASE_CLASS is
  77.       do
  78.          Result := small_eiffel.get_class(as_array);
  79.       end;
  80.  
  81.    static_value: INTEGER is
  82.       do
  83.       end;
  84.  
  85.    dca_inline_argument(formal_arg_type: TYPE) is
  86.       do
  87.       end;
  88.  
  89.    is_pre_computable: BOOLEAN is
  90.       local
  91.          i: INTEGER;
  92.          e: EXPRESSION;
  93.       do
  94.          if list = Void then
  95.             Result := true;
  96.          elseif result_type.generic_list.item(1).is_string then
  97.             from
  98.                Result := true;
  99.                i := list.upper;
  100.             until
  101.                not Result or else i = 0
  102.             loop
  103.                e := list.item(i);
  104.                Result := e.is_pre_computable;
  105.                i := i - 1;
  106.             end;
  107.          end;
  108.       end;
  109.  
  110.    assertion_check(tag: CHARACTER) is
  111.       local
  112.          i: INTEGER;
  113.          e: EXPRESSION;
  114.       do
  115.          if list /= Void then
  116.             from
  117.                i := list.upper;
  118.             until
  119.                i = 0
  120.             loop
  121.                e := list.item(i);
  122.                e.assertion_check(tag);
  123.                i := i - 1;
  124.             end;
  125.          end;
  126.       end;
  127.  
  128.    afd_check is
  129.       local
  130.          i: INTEGER;
  131.       do
  132.          if list /= Void then
  133.             from
  134.                i := list.upper;
  135.             until
  136.                i = 0
  137.             loop
  138.                list.item(i).afd_check;
  139.                i := i - 1;
  140.             end;
  141.          end;
  142.       end;
  143.  
  144.    frozen mapping_c_target(target_type: TYPE) is
  145.       do
  146.          cpp.put_string(fz_b7);
  147.          cpp.put_integer(target_type.id);
  148.          cpp.put_string(fz_b8);
  149.          compile_to_c;
  150.          cpp.put_character(')');
  151.       end;
  152.  
  153.    frozen mapping_c_arg(formal_arg_type: TYPE) is
  154.       do
  155.          compile_to_c;
  156.       end;
  157.  
  158.    collect_c_tmp is
  159.       do
  160.       end;
  161.  
  162.    compile_to_c is
  163.       local
  164.          i: INTEGER;
  165.          formal_type, actual_type: TYPE;
  166.          adr: BOOLEAN;
  167.          e: EXPRESSION;
  168.       do
  169.          manifest_array_pool.c_call(result_type);
  170.          formal_type := result_type.generic_list.item(1).run_type;
  171.          cpp.put_character('(');
  172.          if list = Void then
  173.             cpp.put_character('0');
  174.          else
  175.             adr := formal_type.is_user_expanded;
  176.             cpp.put_integer(list.upper);
  177.             from
  178.                i := 1;
  179.             until
  180.                i > list.upper
  181.             loop
  182.                cpp.put_string(fz_b9);
  183.                if adr then
  184.                   cpp.put_character('&');
  185.                end;
  186.                e := list.item(i);
  187.                actual_type := e.result_type.run_type;
  188.                if formal_type.is_reference and then actual_type.is_expanded then
  189.                   actual_type.to_reference;
  190.                   cpp.put_character('(');
  191.                   e.compile_to_c;
  192.                   cpp.put_character(')');
  193.                else
  194.                   e.compile_to_c;
  195.                end;
  196.                i := i + 1;
  197.             end;
  198.          end;
  199.          cpp.put_character(')');
  200.       end;
  201.  
  202.    c_declare_for_old is
  203.       local
  204.          i: INTEGER;
  205.       do
  206.          if list /= Void then
  207.             from
  208.                i := list.upper;
  209.             until
  210.                i = 0
  211.             loop
  212.                list.item(i).c_declare_for_old;
  213.                i := i - 1;
  214.             end;
  215.          end;
  216.       end;
  217.  
  218.    compile_to_c_old is
  219.       local
  220.          i: INTEGER;
  221.       do
  222.          if list /= Void then
  223.             from
  224.                i := list.upper;
  225.             until
  226.                i = 0
  227.             loop
  228.                list.item(i).compile_to_c_old;
  229.                i := i - 1;
  230.             end;
  231.          end;
  232.       end;
  233.  
  234.    compile_to_jvm_old is
  235.       local
  236.          i: INTEGER;
  237.       do
  238.          if list /= Void then
  239.             from
  240.                i := list.upper;
  241.             until
  242.                i = 0
  243.             loop
  244.                list.item(i).compile_to_jvm_old;
  245.                i := i - 1;
  246.             end;
  247.          end;
  248.       end;
  249.  
  250.    compile_target_to_jvm, compile_to_jvm is
  251.       local
  252.          rt, elt_type: TYPE;
  253.          i, idx, space: INTEGER;
  254.          rc: RUN_CLASS;
  255.          idx_rc: INTEGER;
  256.          cp: like constant_pool;
  257.          ca: like code_attribute;
  258.       do
  259.          cp := constant_pool;
  260.          ca := code_attribute;
  261.          rt := result_type.run_type;
  262.          rc := rt.run_class;
  263.          elt_type := rt.generic_list.item(1).run_type;
  264.          idx_rc := rc.jvm_constant_pool_index;
  265.          rc.jvm_basic_new;
  266.          -- Set lower :
  267.          idx := cp.idx_fieldref4(idx_rc,as_lower,fz_i);
  268.          ca.opcode_dup;
  269.          ca.opcode_iconst_1;
  270.          ca.opcode_putfield(idx,-2);
  271.          -- Set upper :
  272.          idx := cp.idx_fieldref4(idx_rc,as_upper,fz_i);
  273.          ca.opcode_dup;
  274.          if list = Void then
  275.             ca.opcode_iconst_0;
  276.          else
  277.             ca.opcode_push_integer(list.count);
  278.          end;
  279.          ca.opcode_putfield(idx,-2);
  280.          -- Set capacity :
  281.          idx := cp.idx_fieldref4(idx_rc,as_capacity,fz_i);
  282.          ca.opcode_dup;
  283.          if list = Void then
  284.             ca.opcode_iconst_0;
  285.          else
  286.             ca.opcode_push_integer(list.count);
  287.          end;
  288.          ca.opcode_putfield(idx,-2);
  289.          -- Set storage :
  290.          idx := cp.idx_fieldref4(idx_rc,as_storage,sd(elt_type));
  291.          ca.opcode_dup;
  292.          if list = Void then
  293.             ca.opcode_aconst_null;
  294.          else
  295.             ca.opcode_push_integer(list.count);
  296.             elt_type.jvm_xnewarray;
  297.             from
  298.                i := 1;
  299.             until
  300.                i > list.upper
  301.             loop
  302.                ca.opcode_dup;
  303.                ca.opcode_push_integer(i - 1);
  304.                space := list.item(i).compile_to_jvm_into(elt_type);
  305.                elt_type.jvm_xastore;
  306.                i := i + 1;
  307.             end;
  308.          end;
  309.          ca.opcode_putfield(idx,-2);
  310.       end;
  311.  
  312.    jvm_branch_if_false: INTEGER is
  313.       do
  314.       end;
  315.  
  316.    jvm_branch_if_true: INTEGER is
  317.       do
  318.       end;
  319.  
  320.    compile_to_jvm_into(dest: TYPE): INTEGER is
  321.       do
  322.          Result := 1;
  323.          compile_to_jvm;
  324.       end;
  325.  
  326.    use_current: BOOLEAN is
  327.       local
  328.          i: INTEGER;
  329.       do
  330.          if list /= Void then
  331.             from
  332.                i := list.upper;
  333.             until
  334.                i = 0 or else Result
  335.             loop
  336.                Result := list.item(i).use_current;
  337.                i := i - 1;
  338.             end;
  339.          end;
  340.       end;
  341.  
  342.    to_runnable(ct: TYPE): like Current is
  343.       local
  344.          i: INTEGER;
  345.          e: EXPRESSION;
  346.          t: TYPE;
  347.       do
  348.          if current_type = Void then
  349.             current_type := ct;
  350.             if list = Void then
  351.                t := type_any;
  352.             else
  353.                from
  354.                   i := list.upper;
  355.                until
  356.                   i = 0
  357.                loop
  358.                   e := list.item(i).to_runnable(ct);
  359.                   if e = Void then
  360.                      eh.add_position(start_position);
  361.                      error(list.item(i).start_position,
  362.                            "Bad expression in manifest array.");
  363.                      i := 0;
  364.                   else
  365.                      list.put(e,i);
  366.                      if t = Void then
  367.                         t := e.result_type;
  368.                      else
  369.                         t := t.smallest_ancestor(e.result_type);
  370.                      end;
  371.                      i := i - 1;
  372.                   end;
  373.                end;
  374.             end;
  375.             if nb_errors = 0 then
  376.                t := t.run_type;
  377.                !!result_type.make(start_position,t);
  378.                result_type.run_class.set_at_run_time;
  379.                result_type.load_basic_features;
  380.                Result := Current;
  381.                if t.is_reference and then list /= Void then
  382.                   from
  383.                      i := list.upper;
  384.                   until
  385.                      i = 0
  386.                   loop
  387.                      t := list.item(i).result_type;
  388.                      if t.is_expanded then
  389.                         t.used_as_reference;
  390.                      end
  391.                      i := i - 1;
  392.                   end;
  393.                end;
  394.                manifest_array_pool.register(result_type);
  395.             end;
  396.          elseif list = Void then
  397.             Result := Current;
  398.          else
  399.             !!Result.make(start_position,list.twin);
  400.             Result := Result.to_runnable(ct);
  401.          end;
  402.       end;
  403.  
  404.    bracketed_pretty_print is
  405.       do
  406.          fmt.put_character('(');
  407.          pretty_print;
  408.          fmt.put_character(')');
  409.       end;
  410.  
  411.    pretty_print is
  412.       local
  413.          i: INTEGER;
  414.       do
  415.          fmt.put_string(fz_c_shift_left);
  416.          fmt.level_incr;
  417.          if list /= Void then
  418.             from
  419.                i := 1;
  420.             until
  421.                i > list.upper
  422.             loop
  423.                list.item(i).pretty_print;
  424.                i := i + 1;
  425.                if i <= list.upper then
  426.                   fmt.put_character(',');
  427.                end;
  428.             end;
  429.          end;
  430.          fmt.put_string(fz_c_shift_right);
  431.          fmt.level_decr;
  432.       end;
  433.  
  434.    print_as_target is
  435.       do
  436.          fmt.put_character('(');
  437.          pretty_print;
  438.          fmt.put_character(')');
  439.          fmt.put_character('.');
  440.       end;
  441.  
  442.    short is
  443.       local
  444.          i: INTEGER;
  445.       do
  446.          short_print.hook_or("op_ma",fz_c_shift_left);
  447.          if list /= Void then
  448.             from
  449.                i := 1;
  450.             until
  451.                i > list.upper
  452.             loop
  453.                list.item(i).short;
  454.                i := i + 1;
  455.                if i <= list.upper then
  456.                   short_print.hook_or("ma_sep",",");
  457.                end;
  458.             end;
  459.          end;
  460.          short_print.hook_or("cl_ma",fz_c_shift_right);
  461.       end;
  462.  
  463.    short_target is
  464.       do
  465.          bracketed_short;
  466.          short_print.a_dot;
  467.       end;
  468.  
  469.    jvm_assign is
  470.       do
  471.       end;
  472.  
  473. feature {NONE}
  474.  
  475.    sd(elt_type: TYPE): STRING is
  476.          -- The JVM descriptor for `storage'.
  477.       do
  478.          tmp_string.clear;
  479.          tmp_string.extend('[');
  480.          elt_type.jvm_descriptor_in(tmp_string);
  481.          Result := tmp_string;
  482.       end;
  483.  
  484.    tmp_string: STRING is
  485.       once
  486.          !!Result.make(16);
  487.       end;
  488.  
  489. invariant
  490.  
  491.    start_position /= Void;
  492.  
  493.    list /= Void implies not list.empty and list.lower = 1;
  494.  
  495. end -- MANIFEST_ARRAY
  496.  
  497.