home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / c_pretty_printer.e < prev    next >
Text File  |  1999-06-17  |  69KB  |  2,451 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 C_PRETTY_PRINTER
  17.    --
  18.    -- Singleton in charge of handling C code pretty printing.
  19.    -- This singleton is shared via the GLOBALS.`cpp' once function.
  20.    --
  21.  
  22. inherit CODE_PRINTER;
  23.  
  24. creation make
  25.  
  26. feature {NONE}
  27.  
  28.    make is
  29.       do
  30.       end;
  31.  
  32. feature
  33.  
  34.    on_h: BOOLEAN is
  35.       require
  36.          small_eiffel.is_ready
  37.       do
  38.          Result := current_out = out_h;
  39.       end;
  40.  
  41.    on_c: BOOLEAN is
  42.       require
  43.          small_eiffel.is_ready
  44.       do
  45.          Result := current_out = out_c;
  46.       end;
  47.  
  48.    swap_on_c is
  49.       do
  50.          current_out := out_c;
  51.       ensure
  52.          on_c;
  53.       end;
  54.  
  55.    swap_on_h is
  56.       do
  57.          current_out := out_h;
  58.       ensure
  59.          on_h;
  60.       end;
  61.  
  62.    put_extern1(decl: STRING) is
  63.       do
  64.          incr_elt_c_count(5);
  65.          out_h.put_string(fz_extern);
  66.          out_h.put_string(decl);
  67.          out_h.put_string(fz_00);
  68.          out_c.put_string(decl);
  69.          out_c.put_string(fz_00);
  70.       end;
  71.  
  72.    put_extern2(decl: STRING; init: CHARACTER) is
  73.       do
  74.          incr_elt_c_count(5);
  75.          out_h.put_string(fz_extern);
  76.          out_h.put_string(decl);
  77.          out_h.put_string(fz_00);
  78.          out_c.put_string(decl);
  79.          out_c.put_character('=');
  80.          out_c.put_character(init);
  81.          out_c.put_string(fz_00);
  82.       end;
  83.  
  84.    put_extern3(var, value: STRING) is
  85.       do
  86.          incr_elt_c_count(5);
  87.          out_c.put_string("char ");
  88.          out_c.put_string(var);
  89.          out_c.put_string("[]=%"");
  90.          out_c.put_string(value);
  91.          out_c.put_string("%";%N");
  92.          out_h.put_string("extern char ");
  93.          out_h.put_string(var);
  94.          out_h.put_character('[');
  95.          out_h.put_character(']');
  96.          out_h.put_string(fz_00);
  97.       end;
  98.  
  99.    put_extern4(t, var: STRING; value: INTEGER) is
  100.       do
  101.          incr_elt_c_count(5);
  102.          out_c.put_string(t);
  103.          out_c.put_character(' ');
  104.          out_c.put_string(var);
  105.          out_c.put_character('[');
  106.          out_c.put_integer(value);
  107.          out_c.put_string("];%N");
  108.          out_h.put_string(fz_extern);
  109.          out_h.put_string(t);
  110.          out_h.put_character(' ');
  111.          out_h.put_string(var);
  112.          out_h.put_character('[');
  113.          out_h.put_character(']');
  114.          out_h.put_string(fz_00);
  115.       end;
  116.  
  117.    put_extern5(decl: STRING; init: STRING) is
  118.       do
  119.          incr_elt_c_count(5);
  120.          out_h.put_string(fz_extern);
  121.          out_h.put_string(decl);
  122.          out_h.put_string(fz_00);
  123.          out_c.put_string(decl);
  124.          out_c.put_character('=');
  125.          out_c.put_string(init);
  126.          out_c.put_string(fz_00);
  127.       end;
  128.  
  129.    put_extern6(decl: STRING; init: INTEGER) is
  130.       do
  131.          incr_elt_c_count(5);
  132.          out_h.put_string(fz_extern);
  133.          out_h.put_string(decl);
  134.          out_h.put_string(fz_00);
  135.          out_c.put_string(decl);
  136.          out_c.put_character('=');
  137.          out_c.put_integer(init);
  138.          out_c.put_string(fz_00);
  139.       end;
  140.  
  141.    put_extern7(decl: STRING) is
  142.       do
  143.          incr_elt_c_count(5);
  144.          out_h.put_string(fz_extern);
  145.          out_h.put_string(decl);
  146.          out_h.put_string(fz_00);
  147.          out_c.put_string(decl);
  148.          out_c.put_character('=');
  149.       end;
  150.  
  151.    put_c_heading(heading: STRING) is
  152.       do
  153.          incr_elt_c_count(50);
  154.          out_h.put_string(heading);
  155.          out_h.put_string(fz_00);
  156.          out_c.put_string("%N%N");
  157.          out_c.put_string(heading);
  158.          out_c.put_string(fz_11);
  159.       end;
  160.  
  161.    put_c_function(heading, body:STRING) is
  162.       require
  163.          not heading.empty;
  164.          body /= Void
  165.       do
  166.          put_c_heading(heading);
  167.          out_c.put_string(body);
  168.          out_c.put_string(fz_12);
  169.       end;
  170.  
  171.    put_string(c: STRING) is
  172.       require
  173.          small_eiffel.is_ready
  174.       do
  175.          current_out.put_string(c);
  176.       end;
  177.  
  178.    put_string_c(s: STRING) is
  179.       require
  180.          small_eiffel.is_ready;
  181.          on_c
  182.       do
  183.          tmp_string.clear;
  184.          manifest_string_pool.string_to_c_code(s,tmp_string);
  185.          out_c.put_string(tmp_string);
  186.       end;
  187.  
  188.    put_character(c: CHARACTER) is
  189.       require
  190.          small_eiffel.is_ready
  191.       do
  192.          current_out.put_character(c);
  193.       end;
  194.  
  195.    put_integer(i: INTEGER) is
  196.       require
  197.          small_eiffel.is_ready
  198.       do
  199.          current_out.put_integer(i);
  200.       end;
  201.  
  202.    put_real(r: REAL) is
  203.       require
  204.          small_eiffel.is_ready
  205.       do
  206.          current_out.put_real(r);
  207.       end;
  208.  
  209.    put_array1(array_name: CHARACTER; value: INTEGER) is
  210.       do
  211.          current_out.put_character(array_name);
  212.          current_out.put_character('[');
  213.          current_out.put_integer(value);
  214.          current_out.put_character(']');
  215.       end;
  216.  
  217.    put_se_string_from_external_copy(c_string: STRING) is
  218.       do
  219.          current_out.put_string("se_string_from_external_copy(");
  220.          put_string_c(c_string);
  221.          current_out.put_character(')');
  222.       end;
  223.  
  224.    put_position(p: POSITION) is
  225.       require
  226.          small_eiffel.is_ready
  227.       do
  228.          if p = Void then
  229.             put_string("0,0,0");
  230.          else
  231.             put_integer(p.line);
  232.             put_character(',');
  233.             put_integer(p.column);
  234.             put_character(',');
  235.             put_integer(p.base_class.id);
  236.          end;
  237.       end;
  238.  
  239.    put_position_in_ds(p: POSITION) is
  240.       require
  241.          small_eiffel.is_ready
  242.       do
  243.          if p = Void then
  244.             out_c.put_string("ds.l=0;%Nds.c=0;%Nds.f=0;%N");
  245.          else
  246.             out_c.put_string("ds.l=");
  247.             out_c.put_integer(p.line);
  248.             out_c.put_string(";%Nds.c=");
  249.             out_c.put_integer(p.column);
  250.             out_c.put_string(";%Nds.f=");
  251.             out_c.put_integer(p.base_class.id);
  252.             out_c.put_string(fz_00);
  253.          end;
  254.       end;
  255.  
  256.    put_target_as_target is
  257.          -- Produce C code to pass the current stacked target as
  258.          -- a target of a new call : user expanded are passed with
  259.          -- a pointer and class invariant code is produced.
  260.       require
  261.          small_eiffel.is_ready
  262.       local
  263.          code: INTEGER;
  264.          rf: RUN_FEATURE;
  265.          target: EXPRESSION;
  266.          args: EFFECTIVE_ARG_LIST;
  267.          ct: TYPE;
  268.          ivt_flag: BOOLEAN;
  269.       do
  270.          code := stack_code.item(top);
  271.          inspect
  272.             code
  273.          when C_direct_call then
  274.             target := stack_target.item(top);
  275.             rf := stack_rf.item(top);
  276.             ct := rf.current_type;
  277.             target.mapping_c_target(ct);
  278.          when C_check_id then
  279.             target := stack_target.item(top);
  280.             rf := stack_rf.item(top);
  281.             ct := rf.current_type;
  282.             check
  283.                ct.is_reference;
  284.             end;
  285.             if run_control.boost then
  286.                target.mapping_c_target(ct);
  287.             else
  288.                ivt_flag := call_invariant_start(ct);
  289.                check_id(target,rf.id);
  290.                if ivt_flag then
  291.                   call_invariant_end;
  292.                end;
  293.             end;
  294.          when C_inline_dca then
  295.             put_character('(');
  296.             stack_rf.item(top).current_type.mapping_cast;
  297.             put_character('(');
  298.             put_target_as_value;
  299.             put_string(fz_13);
  300.          when C_same_target then
  301.             rf := stack_rf.item(top);
  302.             args := stack_args.item(top);
  303.             top := top - 1;
  304.             put_target_as_target;
  305.             top := top + 1;
  306.             stack_code.put(code,top);
  307.             stack_rf.put(rf,top);
  308.             stack_args.put(args,top);
  309.          else
  310.             common_put_target;
  311.          end;
  312.       end;
  313.  
  314.    put_target_as_value is
  315.          -- Produce C code for a simple access to the stacked target.
  316.          -- User's expanded values are not given using a pointer.
  317.          -- There is no C code to check the class invariant.
  318.       require
  319.          small_eiffel.is_ready
  320.       local
  321.          code: INTEGER;
  322.          rf, static_rf: RUN_FEATURE;
  323.          target: EXPRESSION;
  324.          args: EFFECTIVE_ARG_LIST;
  325.          c0c: CALL_0_C;
  326.          direct_rf: RUN_FEATURE;
  327.       do
  328.          code := stack_code.item(top);
  329.          inspect
  330.             code
  331.          when C_direct_call then
  332.             stack_target.item(top).compile_to_c;
  333.          when C_check_id then
  334.             stack_rf.item(top).current_type.mapping_cast;
  335.             stack_target.item(top).compile_to_c;
  336.          when C_inline_dca then
  337.             rf := stack_rf.item(top);
  338.             target := stack_target.item(top);
  339.             args := stack_args.item(top);
  340.             static_rf := stack_static_rf.item(top);
  341.             top := top - 1;
  342.             c0c ?= target;
  343.             direct_rf := c0c.run_feature;
  344.             direct_rf.mapping_c;
  345.             top := top + 1;
  346.             stack_code.put(code,top);
  347.             stack_rf.put(rf,top);
  348.             stack_target.put(target,top);
  349.             stack_args.put(args,top);
  350.             stack_static_rf.put(static_rf,top);
  351.          when C_same_target then
  352.             rf := stack_rf.item(top);
  353.             args := stack_args.item(top);
  354.             top := top - 1;
  355.             put_target_as_value;
  356.             top := top + 1;
  357.             stack_code.put(code,top);
  358.             stack_rf.put(rf,top);
  359.             stack_args.put(args,top);
  360.          else
  361.             common_put_target;
  362.          end;
  363.       end;
  364.  
  365.    put_error0(msg: STRING) is
  366.          -- Print `msg' and then stop execution.
  367.          -- Also print stack when not -boost.
  368.       do
  369.          put_string("error0(");
  370.          put_string_c(msg);
  371.          put_string(",NULL);%N");
  372.       end;
  373.  
  374.    put_comment(str: STRING) is
  375.       do
  376.          put_string(fz_open_c_comment);
  377.          put_string(str);
  378.          put_string(fz_close_c_comment);
  379.       end;
  380.  
  381.    put_comment_line(str: STRING) is
  382.       do
  383.          put_character('%N');
  384.          put_comment(str);
  385.          put_character('%N');
  386.       end;
  387.  
  388.    define_main(rf3: RUN_FEATURE_3) is
  389.       do
  390.          swap_on_c;
  391.          -- Declare eiffel_root_object :
  392.          tmp_string.clear;
  393.          tmp_string.extend('T');
  394.          rf3.run_class.id.append_in(tmp_string);
  395.          tmp_string.append("*eiffel_root_object");
  396.          put_extern5(tmp_string,fz_null);
  397.          --
  398.          put_extern1("int se_argc");
  399.          put_extern1("char**se_argv");
  400.          define_initialize_eiffel_runtime(rf3);
  401.          if not no_main then
  402.             really_define_c_main(rf3);
  403.          end;
  404.          incr_elt_c_count(50);
  405.       end;
  406.  
  407.    trace_boolean_expression(e: EXPRESSION) is
  408.          -- Produce a C boolean expression including trace code.
  409.       require
  410.          e.result_type.is_boolean;
  411.          run_control.no_check;
  412.       do
  413.          put_character('(');
  414.          se_trace_exp(e.start_position);
  415.          put_character(',');
  416.          e.compile_to_c;
  417.          put_character(')');
  418.       end;
  419.  
  420. feature {MANIFEST_STRING_POOL}
  421.  
  422.    starting_manifest_string_definition(count: INTEGER) is
  423.       do
  424.          if count > 500 then
  425.             if elt_c_count > 1000 then
  426.                elt_c_count := elt_c_count_max;
  427.             end;
  428.          end;
  429.       end;
  430.  
  431. feature {SMALL_EIFFEL}
  432.  
  433.    get_started is
  434.       require
  435.          small_eiffel.is_ready
  436.       local
  437.          no_check: BOOLEAN;
  438.       do
  439.          echo.file_removing(path_make);
  440.          no_check := run_control.no_check;
  441.          top := -1;
  442.          if no_split then
  443.             sfw_connect(out_c,path_c);
  444.          else
  445.             backup_sfw_connect(out_c,path_c);
  446.          end;
  447.          current_out := out_c;
  448.          add_first_include;
  449.          !!out_h.make;
  450.          sfw_connect(out_h,path_h);
  451.          current_out := out_h;
  452.          put_banner(out_h);
  453.          out_h.put_character('%N');
  454.          sys_runtime_h(fz_base);
  455.          current_out := out_c;
  456.       ensure
  457.          on_c
  458.       end;
  459.  
  460.    cecil_define is
  461.       local
  462.          save_out_h: like out_h;
  463.       do
  464.          save_out_h := out_h;
  465.          cecil_pool.c_define_users;
  466.          out_h := save_out_h;
  467.       end;
  468.  
  469.    define_used_basics is
  470.          -- Produce C code only when used.
  471.       local
  472.          no_check: BOOLEAN;
  473.       do
  474.          no_check := run_control.no_check;
  475.          echo.put_string("Define used basics.%N");
  476.          if sprintf_double_flag then
  477.             put_extern1("char*_spfd");
  478.          end;
  479.          if to_expanded_mem /= Void then
  480.             define_to_expanded;
  481.          end;
  482.          if to_reference_mem /= Void then
  483.             define_to_reference;
  484.          end;
  485.          bit_constant_definition;
  486.          if sure_void_count > 0 then
  487.             echo.put_string("Calls with a Void target : ");
  488.             echo.put_integer(sure_void_count);
  489.             echo.put_string(" (yes it is dangerous).%N");
  490.          end;
  491.          echo.print_count("Direct Call",direct_call_count);
  492.          echo.print_count("Check Id Call",check_id_count);
  493.          echo.print_count("Switched Call",switch_count);
  494.          echo.print_count("Inlined Procedure",inlined_procedure_count);
  495.          echo.print_count("Inlined Function",inlined_function_count);
  496.          echo.print_count("Static Expression",static_expression_count);
  497.          echo.print_count("Procedure",procedure_count);
  498.          echo.print_count("Function",function_count);
  499.          echo.print_count("Procedure without Current",real_procedure_count);
  500.          echo.print_count("Function without Current",real_function_count);
  501.          echo.print_count("Pre-Computed Once Function Call",
  502.                           pre_computed_once.count);
  503.          echo.put_string("Internal stacks size used : ");
  504.          echo.put_integer(stack_code.count);
  505.          echo.put_character('%N');
  506.       end;
  507.  
  508.    customize_runtime is
  509.       do
  510.          if run_control.no_check then
  511.             sys_runtime_h_and_c("no_check");
  512.             if run_control.trace then
  513.                put_extern2("int se_trace_flag",'0');
  514.                out_c.put_string("#define SE_TRACE 1%N");
  515.             end;
  516.             cpp.sys_runtime_h_and_c("trace");
  517.          else
  518.             cpp.sys_runtime_h_and_c("boost");
  519.          end;
  520.          if basic_directory_used then
  521.             cpp.sys_runtime_h_and_c("basic_directory");
  522.          end;
  523.          exceptions_handler.get_started;
  524.       end;
  525.  
  526. feature {RUN_FEATURE,NATIVE}
  527.  
  528.    target_cannot_be_dropped: BOOLEAN is
  529.          -- True when top target cannot be dropped because we are
  530.          -- not sure that target is non Void or that target has
  531.          -- no side effects. When Result is true, printed
  532.          -- C code is : "(((void)(<target>))"
  533.       require
  534.          small_eiffel.is_ready
  535.       local
  536.          target: EXPRESSION;
  537.          target_type: TYPE;
  538.       do
  539.          inspect
  540.             stack_code.item(top)
  541.          when C_direct_call, C_check_id then
  542.             target := stack_target.item(top);
  543.             target_type := target.result_type;
  544.             Result := not target.can_be_dropped;
  545.          when C_inline_dca then
  546.             Result := true;
  547.          when C_same_target then
  548.             top := top - 1;
  549.             Result := target_cannot_be_dropped;
  550.             top := top + 1;
  551.          else
  552.          end;
  553.          if Result then
  554.             put_string("((/*UT*/(void)(");
  555.             if target_type = Void then
  556.                put_target_as_target;
  557.             elseif target_type.is_user_expanded then
  558.                put_target_as_value;
  559.             else
  560.                put_target_as_target;
  561.             end;
  562.             put_string(fz_13);
  563.          end;
  564.       end;
  565.  
  566.    arguments_cannot_be_dropped: BOOLEAN is
  567.          -- True when arguments cannot be dropped.
  568.          -- Printed C code is like :
  569.          --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  570.       do
  571.          if not no_args_to_eval then
  572.             Result := true;
  573.             put_string("((/*UA*/(void)(");
  574.             put_arguments;
  575.             put_string(fz_13);
  576.          end;
  577.       end;
  578.  
  579.    cannot_drop_all: BOOLEAN is
  580.          -- Result is true when something (target or one argument)
  581.          -- cannot be dropped. Thus when something cannot be dropped,
  582.          -- Result is true and C code is printed :
  583.          --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  584.       do
  585.          if target_cannot_be_dropped then
  586.             Result := true;
  587.             put_character(',');
  588.             if arguments_cannot_be_dropped then
  589.                put_character(')');
  590.             else
  591.                put_character('0');
  592.             end;
  593.          else
  594.             Result := arguments_cannot_be_dropped;
  595.          end;
  596.       end;
  597.  
  598. feature
  599.  
  600.    put_arguments is
  601.       -- Produce code to access effective arguments list.
  602.       require
  603.          small_eiffel.is_ready
  604.       local
  605.          code: INTEGER;
  606.          rf, static_rf: RUN_FEATURE;
  607.          target: EXPRESSION;
  608.          args: EFFECTIVE_ARG_LIST;
  609.          fal: FORMAL_ARG_LIST;
  610.          switch: SWITCH;
  611.       do
  612.          code := stack_code.item(top);
  613.          inspect
  614.             code
  615.          when C_expanded_initialize then
  616.          when C_inside_twin then
  617.             put_ith_argument(1);
  618.          when C_direct_call then
  619.             fal := stack_rf.item(top).arguments;
  620.             stack_args.item(top).compile_to_c(fal);
  621.          when C_check_id then
  622.             fal := stack_rf.item(top).arguments;
  623.             stack_args.item(top).compile_to_c(fal);
  624.          when C_switch then
  625.             fal := stack_rf.item(top).arguments;
  626.             static_rf := stack_static_rf.item(top);
  627.             switch.put_arguments(static_rf,fal);
  628.          when C_inside_new then
  629.             fal := stack_rf.item(top).arguments;
  630.             stack_args.item(top).compile_to_c(fal);
  631.          when C_inline_dca then
  632.             rf := stack_rf.item(top);
  633.             target := stack_target.item(top);
  634.             args := stack_args.item(top);
  635.             static_rf := stack_static_rf.item(top);
  636.             top := top - 1;
  637.             args.dca_inline(rf.arguments);
  638.             top := top + 1;
  639.             stack_code.put(code,top);
  640.             stack_rf.put(rf,top);
  641.             stack_target.put(target,top);
  642.             stack_args.put(args,top);
  643.             stack_static_rf.put(static_rf,top);
  644.          when C_same_target then
  645.             fal := stack_rf.item(top).arguments;
  646.             stack_args.item(top).compile_to_c(fal);
  647.          when C_inline_one_pc then
  648.          when C_precursor then
  649.             fal := stack_rf.item(top).arguments;
  650.             stack_args.item(top).compile_to_c(fal);
  651.          end;
  652.       end;
  653.  
  654.    put_ith_argument(index: INTEGER) is
  655.       -- Produce code to access to the ith argument.
  656.       require
  657.          small_eiffel.is_ready
  658.          index >= 1
  659.       local
  660.          code: INTEGER;
  661.          rf, static_rf: RUN_FEATURE;
  662.          target: EXPRESSION;
  663.          args: EFFECTIVE_ARG_LIST;
  664.          fal: FORMAL_ARG_LIST;
  665.          switch: SWITCH;
  666.       do
  667.          code := stack_code.item(top);
  668.          inspect
  669.             code
  670.          when C_direct_call then
  671.             fal := stack_rf.item(top).arguments;
  672.             stack_args.item(top).compile_to_c_ith(fal,index);
  673.          when C_check_id then
  674.             fal := stack_rf.item(top).arguments;
  675.             stack_args.item(top).compile_to_c_ith(fal,index);
  676.          when C_switch then
  677.             fal := stack_rf.item(top).arguments;
  678.             static_rf := stack_static_rf.item(top);
  679.             switch.put_ith_argument(static_rf,fal,index);
  680.          when C_inside_new then
  681.             fal := stack_rf.item(top).arguments;
  682.             stack_args.item(top).compile_to_c_ith(fal,index);
  683.          when C_inline_dca then
  684.             rf := stack_rf.item(top);
  685.             target := stack_target.item(top);
  686.             args := stack_args.item(top);
  687.             static_rf := stack_static_rf.item(top);
  688.             top := top - 1;
  689.             if rf /= Void then
  690.                args.dca_inline_ith(rf.arguments,index);
  691.             else
  692.                -- No rf for "=" and "/=".
  693.                args.dca_inline_ith(static_rf.arguments,index);
  694.             end;
  695.             top := top + 1;
  696.             stack_code.put(code,top);
  697.             stack_rf.put(rf,top);
  698.             stack_target.put(target,top);
  699.             stack_args.put(args,top);
  700.             stack_static_rf.put(static_rf,top);
  701.          when C_same_target then
  702.             fal := stack_rf.item(top).arguments;
  703.             stack_args.item(top).compile_to_c_ith(fal,index);
  704.          when C_inline_one_pc then
  705.             print_argument(index);
  706.          when C_inside_twin then
  707.             check
  708.                index = 1
  709.             end;
  710.             if stack_rf.item(top).current_type.is_reference then
  711.                put_string("((T0*)C)");
  712.             else
  713.                put_string("*C");
  714.             end;
  715.          end;
  716.       end;
  717.  
  718. feature {NATIVE_SMALL_EIFFEL}
  719.  
  720.    put_c_inline_h is
  721.       local
  722.          c_code: STRING;
  723.       do
  724.          c_code := get_inline_ms.to_string;
  725.          if not c_inline_h_mem.fast_has(c_code) then
  726.             c_inline_h_mem.add_last(c_code);
  727.             out_h.put_string(c_code);
  728.             out_h.put_character('%N');
  729.          end;
  730.       end;
  731.  
  732.    put_c_inline_c is
  733.       local
  734.          c_code: MANIFEST_STRING;
  735.       do
  736.          c_code := get_inline_ms;
  737.          out_c.put_string(c_code.to_string);
  738.       end;
  739.  
  740.    put_trace_switch is
  741.       do
  742.          if run_control.trace then
  743.             put_string("se_trace_flag=(");
  744.             put_ith_argument(1);
  745.             put_string(fz_14);
  746.          end;
  747.       end;
  748.  
  749. feature {NATIVE_SMALL_EIFFEL}
  750.  
  751.    put_generating_type(t: TYPE) is
  752.       local
  753.          rc: RUN_CLASS;
  754.       do
  755.          put_string(fz_cast_t0_star);
  756.          put_character('(');
  757.          put_character('t');
  758.          put_character('[');
  759.          if t.is_reference then
  760.             rc := t.run_class;
  761.             if rc.is_tagged then
  762.                put_character('(');
  763.                put_target_as_value;
  764.                put_character(')');
  765.                put_string(fz_arrow_id);
  766.             else
  767.                put_integer(rc.id);
  768.             end;
  769.          else
  770.             put_integer(t.id);
  771.          end;
  772.          put_character(']');
  773.          put_character(')');
  774.       end;
  775.  
  776.    put_generator(t: TYPE) is
  777.       require
  778.          t.is_run_type;
  779.       local
  780.          rc: RUN_CLASS;
  781.       do
  782.          put_string(fz_cast_t0_star);
  783.          put_character('(');
  784.          put_character('g');
  785.          put_character('[');
  786.          if t.is_reference then
  787.             rc := t.run_class;
  788.             if rc.is_tagged then
  789.                put_character('(');
  790.                put_target_as_value;
  791.                put_character(')');
  792.                put_string(fz_arrow_id);
  793.             else
  794.                put_integer(rc.id);
  795.             end;
  796.          else
  797.             put_integer(t.id);
  798.          end;
  799.          put_character(']');
  800.          put_character(')');
  801.       end;
  802.  
  803.    put_to_pointer is
  804.       do
  805.          put_string("((void*)");
  806.          put_target_as_value;
  807.          put_character(')');
  808.       end;
  809.  
  810.    put_object_size(t: TYPE) is
  811.       require
  812.          t.is_run_type;
  813.       local
  814.          tcbd: BOOLEAN;
  815.       do
  816.          tcbd := target_cannot_be_dropped;
  817.          if tcbd then
  818.             out_c.put_character(',');
  819.          end;
  820.          out_c.put_string("sizeof(T");
  821.          out_c.put_integer(t.id);
  822.          out_c.put_character(')');
  823.          if tcbd then
  824.             out_c.put_character(')');
  825.          end;
  826.       end;
  827.  
  828. feature {CECIL_POOL}
  829.  
  830.    connect_cecil_out_h(user_path_h: STRING) is
  831.       do
  832.          !!out_h.make;
  833.          sfw_connect(out_h,user_path_h);
  834.          sys_runtime_h(fz_base);
  835.          out_h.put_string(
  836.             "extern void*eiffel_root_object;%N%N%
  837.             %typedef char* T9;%N%
  838.             %/* Available Eiffel routines via -cecil:%N*/%N");
  839.       end;
  840.  
  841.    disconnect_cecil_out_h is
  842.       do
  843.          out_h.disconnect;
  844.       end;
  845.  
  846. feature {TYPE}
  847.  
  848.    to_reference(src, dest: TYPE) is
  849.          -- Put the name of the corresponding conversion
  850.          -- fonction. Memorize arguments for later definition
  851.          -- of the function.
  852.       require
  853.          small_eiffel.is_ready;
  854.          src.is_expanded;
  855.          dest.is_reference;
  856.       local
  857.          src_rc, dest_rc: RUN_CLASS;
  858.       do
  859.          src_rc := src.run_class;
  860.          dest_rc := dest.run_class;
  861.          check
  862.             src_rc.at_run_time;
  863.             dest_rc.at_run_time;
  864.          end;
  865.          if to_reference_mem = Void then
  866.             to_reference_mem := <<src_rc,dest_rc>>;
  867.          elseif not to_reference_mem.fast_has(src_rc) then
  868.             to_reference_mem.add_last(src_rc);
  869.             to_reference_mem.add_last(dest_rc);
  870.          end;
  871.          tmp_string.clear;
  872.          conversion_name(dest_rc.id);
  873.          put_string(tmp_string);
  874.       end;
  875.  
  876.    to_expanded(src, dest: TYPE) is
  877.          -- Put the name of the corresponding conversion
  878.          -- fonction. Memorize arguments for later definition
  879.          -- of the function.
  880.       require
  881.          small_eiffel.is_ready;
  882.          src.is_reference;
  883.          dest.is_expanded;
  884.       local
  885.          src_rc, dest_rc: RUN_CLASS;
  886.       do
  887.          src_rc := src.run_class;
  888.          dest_rc := dest.run_class;
  889.          check
  890.             src_rc.at_run_time;
  891.             dest_rc.at_run_time;
  892.          end;
  893.          if to_expanded_mem = Void then
  894.             to_expanded_mem := <<src_rc,dest_rc>>;
  895.          elseif not to_expanded_mem.fast_has(src_rc) then
  896.             to_expanded_mem.add_last(src_rc);
  897.             to_expanded_mem.add_last(dest_rc);
  898.          end;
  899.          tmp_string.clear;
  900.          conversion_name(dest_rc.id);
  901.          put_string(tmp_string);
  902.       end;
  903.  
  904. feature {CECIL_POOL,RUN_FEATURE}
  905.  
  906.    push_direct(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  907.       require
  908.          rf /= Void;
  909.          t /= Void
  910.       do
  911.          stack_push(C_direct_call);
  912.          stack_rf.put(rf,top);
  913.          stack_target.put(t,top);
  914.          stack_args.put(args,top);
  915.          direct_call_count := direct_call_count + 1;
  916.       end;
  917.  
  918. feature {RUN_FEATURE_8}
  919.  
  920.    set_basic_directory_used is
  921.       do
  922.          basic_directory_used := true;
  923.       end;
  924.  
  925. feature {RUN_FEATURE_3}
  926.  
  927.    push_inline_one_pc is
  928.       do
  929.          stack_push(C_inline_one_pc);
  930.       end;
  931.  
  932. feature {RUN_FEATURE_3,RUN_FEATURE_4}
  933.  
  934.    push_inline_dca(relay_rf: RUN_FEATURE; dpca: CALL_PROC_CALL) is
  935.       -- Where `dpca' is inside `relay_rf'.
  936.       require
  937.          relay_rf /= Void;
  938.          dpca /= Void
  939.       do
  940.          stack_push(C_inline_dca);
  941.          stack_rf.put(dpca.run_feature,top);
  942.          stack_static_rf.put(relay_rf,top);
  943.          stack_target.put(dpca.target,top);
  944.          stack_args.put(dpca.arguments,top);
  945.          direct_call_count := direct_call_count + 1;
  946.       end;
  947.  
  948.    push_same_target(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  949.       require
  950.          rf /= Void
  951.       do
  952.          stack_push(C_same_target);
  953.          stack_rf.put(rf,top);
  954.          stack_args.put(args,top);
  955.       end;
  956.  
  957. feature {CECIL_POOL}
  958.  
  959.    push_cpc(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS];
  960.             t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  961.       local
  962.          dyn_rf: RUN_FEATURE;
  963.       do
  964.          if r = Void then
  965.             push_void(up_rf,t,args);
  966.             up_rf.mapping_c;
  967.             pop;
  968.          elseif r.count = 1 then
  969.             dyn_rf := r.first.dynamic(up_rf);
  970.             push_check(dyn_rf,t,args);
  971.             dyn_rf.mapping_c;
  972.             pop;
  973.          else
  974.             use_switch(up_rf,r,t,args);
  975.          end;
  976.       end;
  977.  
  978. feature {SWITCH}
  979.  
  980.    push_switch(rf, static_rf: RUN_FEATURE) is
  981.       require
  982.          rf /= Void;
  983.          static_rf /= Void;
  984.          rf.run_class.dynamic(static_rf) = rf
  985.       do
  986.          stack_push(C_switch);
  987.          stack_rf.put(rf,top);
  988.          stack_static_rf.put(static_rf,top);
  989.       end;
  990.  
  991. feature {CREATION_CALL_3_4,LOCAL_VAR_LIST}
  992.  
  993.    expanded_writable(rf3: RUN_FEATURE_3; writable: EXPRESSION) is
  994.          -- Call the expanded initializer `rf3' using `writable'
  995.          -- as target.
  996.       require
  997.          rf3.current_type.is_expanded;
  998.          writable /= Void
  999.       do
  1000.          stack_push(C_expanded_initialize);
  1001.          stack_target.put(writable,top);
  1002.          stack_rf.put(Void,top); -- *** UNNEEDED ???
  1003.          direct_call_count := direct_call_count + 1;
  1004.          rf3.mapping_c;
  1005.          pop;
  1006.          if call_invariant_start(rf3.current_type) then
  1007.             put_character('&');
  1008.             writable.compile_to_c;
  1009.             call_invariant_end;
  1010.             put_string(fz_00);
  1011.          end;
  1012.       end;
  1013.  
  1014. feature {CREATION_CALL}
  1015.  
  1016.    push_new(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  1017.       require
  1018.          rf /= Void;
  1019.       do
  1020.          stack_push(C_inside_new);
  1021.          stack_rf.put(rf,top);
  1022.          stack_args.put(args,top);
  1023.          direct_call_count := direct_call_count + 1;
  1024.       end;
  1025.  
  1026. feature {NATIVE}
  1027.  
  1028.    inside_twin(cpy: RUN_FEATURE) is
  1029.       do
  1030.          stack_push(C_inside_twin);
  1031.          stack_rf.put(cpy,top);
  1032.          cpy.mapping_c;
  1033.          pop;
  1034.       end;
  1035.  
  1036. feature {E_FEATURE,RUN_FEATURE}
  1037.  
  1038.    stupid_switch(up_rf: RUN_FEATURE): BOOLEAN is
  1039.       require
  1040.          small_eiffel.is_ready;
  1041.          up_rf.run_class.running /= Void
  1042.       local
  1043.          r: ARRAY[RUN_CLASS];
  1044.       do
  1045.          r := up_rf.run_class.running;
  1046.          if r.count > 1 then
  1047.             Result := stupid_switch_n(up_rf,r);
  1048.          else
  1049.             Result := true;
  1050.          end;
  1051.       end;
  1052.  
  1053. feature {ASSERTION}
  1054.  
  1055.    check_assertion(e: EXPRESSION; tag_name: TAG_NAME) is
  1056.          -- Produce a C boolean expression including trace code
  1057.          -- and assertion check.
  1058.       require
  1059.          e.result_type.is_boolean
  1060.       do
  1061.          se_trace_ins(e.start_position);
  1062.          put_string("ac_");
  1063.          put_string(check_assertion_mode);
  1064.          put_character('(');
  1065.          if e.is_static then
  1066.             static_expression_count := static_expression_count + 1;
  1067.          end;
  1068.          e.compile_to_c;
  1069.          put_character(',');
  1070.          if tag_name /= Void then
  1071.             put_string_c(tag_name.to_string);
  1072.          else
  1073.             put_string(fz_null);
  1074.          end;
  1075.          put_string(fz_14);
  1076.       end;
  1077.  
  1078. feature {ASSERTION_LIST}
  1079.  
  1080.    set_check_assertion_mode(s: STRING) is
  1081.       require
  1082.          s /= Void
  1083.       do
  1084.          check_assertion_mode := s;
  1085.       ensure
  1086.          check_assertion_mode = s
  1087.       end;
  1088.  
  1089.    increment_static_expression_count(increment: INTEGER) is
  1090.       do
  1091.          static_expression_count := static_expression_count + increment;
  1092.       end;
  1093.  
  1094. feature
  1095.  
  1096.    se_trace_ins(p: POSITION) is
  1097.       do
  1098.          if run_control.no_check then
  1099.             se_trace_exp(p);
  1100.             out_c.put_string(fz_00);
  1101.          end;
  1102.       end;
  1103.  
  1104.    se_trace_exp(p: POSITION) is
  1105.       do
  1106.          if run_control.no_check then
  1107.             out_c.put_string("se_trace(&ds,");
  1108.             put_position(p);
  1109.             out_c.put_character(')');
  1110.          end;
  1111.       end;
  1112.  
  1113. feature  -- Numbering of inspect variables :
  1114.  
  1115.    inspect_incr is
  1116.       do
  1117.          inspect_level := inspect_level + 1;
  1118.       end;
  1119.  
  1120.    inspect_decr is
  1121.       do
  1122.          inspect_level := inspect_level - 1;
  1123.       end;
  1124.  
  1125.    put_inspect is
  1126.       do
  1127.          put_character('z');
  1128.          put_integer(inspect_level);
  1129.       end;
  1130.  
  1131. feature -- Printing Current, local or argument :
  1132.  
  1133.    inline_level_incr is
  1134.       do
  1135.          inline_level := inline_level + 1;
  1136.       end;
  1137.  
  1138.    inline_level_decr is
  1139.       do
  1140.          inline_level := inline_level - 1;
  1141.       end;
  1142.  
  1143.    print_current is
  1144.       local
  1145.          level: INTEGER;
  1146.       do
  1147.          put_character('C');
  1148.          level := inline_level;
  1149.          if level > 0 then
  1150.             put_integer(level);
  1151.          end;
  1152.       end;
  1153.  
  1154.    print_argument(rank: INTEGER) is
  1155.       local
  1156.          code: INTEGER;
  1157.       do
  1158.          code := ('a').code + inline_level;
  1159.          put_character(code.to_character);
  1160.          put_integer(rank);
  1161.       end;
  1162.  
  1163.    print_local(name: STRING) is
  1164.       local
  1165.          level: INTEGER;
  1166.       do
  1167.          from
  1168.             level := inline_level + 1;
  1169.          until
  1170.             level = 0
  1171.          loop
  1172.             put_character('_');
  1173.             level := level - 1;
  1174.          end;
  1175.          put_string(name);
  1176.       end;
  1177.  
  1178. feature {E_LOOP}
  1179.  
  1180.    variant_check(e: EXPRESSION) is
  1181.       do
  1182.          se_trace_ins(e.start_position);
  1183.          put_string("v=ac_lvc(c++,v,");
  1184.          e.compile_to_c;
  1185.          put_string(fz_14);
  1186.       end;
  1187.  
  1188. feature {RUN_FEATURE}
  1189.  
  1190.    current_class_invariant(current_type: TYPE) is
  1191.          -- Add some C code to check class invariant with Current
  1192.          -- at the end of a routine for `Current'.
  1193.       require
  1194.          current_type.is_run_type
  1195.       local
  1196.          rc: RUN_CLASS;
  1197.       do
  1198.          rc := need_invariant(current_type);
  1199.          if rc /= Void then
  1200.             if rc.current_type.is_reference then
  1201.                out_c.put_string("if(se_rci(C))");
  1202.             end;
  1203.             out_c.put_string(fz_se_i);
  1204.             out_c.put_integer(rc.id);
  1205.             out_c.put_string("(&ds,C);%N");
  1206.          end;
  1207.       end;
  1208.  
  1209. feature
  1210.  
  1211.    call_invariant_start(target_type: TYPE): BOOLEAN is
  1212.          -- Start printing call of invariant only when it is needed
  1213.          -- (`target_type' really has an invariant and when mode is
  1214.          -- `-invariant_check').
  1215.          -- When Result is true, `call_invariant_end' must be called to
  1216.          -- finish the job.
  1217.       require
  1218.          target_type.is_run_type;
  1219.       local
  1220.          rc: RUN_CLASS;
  1221.       do
  1222.          rc := need_invariant(target_type);
  1223.          if rc /= Void then
  1224.             out_c.put_string(fz_se_i);
  1225.             out_c.put_integer(rc.id);
  1226.             out_c.put_string("(&ds,");
  1227.             Result := true;
  1228.          end;
  1229.       end;
  1230.  
  1231.    call_invariant_end is
  1232.       do
  1233.          out_c.put_character(')');
  1234.       end;
  1235.  
  1236. feature
  1237.  
  1238.    macro_def(str: STRING; id: INTEGER) is
  1239.       do
  1240.          tmp_string.clear;
  1241.          tmp_string.extend('#');
  1242.          tmp_string.append(fz_define);
  1243.          tmp_string.extend(' ');
  1244.          tmp_string.append(str);
  1245.          tmp_string.extend(' ');
  1246.          id.append_in(tmp_string);
  1247.          tmp_string.extend('%N');
  1248.          out_h.put_string(tmp_string);
  1249.       end;
  1250.  
  1251. feature {CREATION_CALL}
  1252.  
  1253.    expanded_attributes(rt: TYPE) is
  1254.          -- Produce C code to initialize expanded attribute
  1255.          -- of the new object juste created in variable "n".
  1256.       require
  1257.          small_eiffel.is_ready;
  1258.          rt.is_run_type
  1259.       local
  1260.          wa: ARRAY[RUN_FEATURE];
  1261.          a: RUN_FEATURE;
  1262.          at: TYPE;
  1263.          i: INTEGER;
  1264.          rf3: RUN_FEATURE_3;
  1265.       do
  1266.          wa := rt.run_class.writable_attributes;
  1267.          if wa /= Void then
  1268.             from
  1269.                i := wa.upper;
  1270.             until
  1271.                i = 0
  1272.             loop
  1273.                a := wa.item(i);
  1274.                at := a.result_type.run_type;
  1275.  
  1276.                rf3 := at.expanded_initializer;
  1277.                if rf3 /= Void then
  1278.                   stack_push(C_expanded_initialize);
  1279.                   stack_target.put(Void,top);
  1280.                   stack_rf.put(a,top);
  1281.                   direct_call_count := direct_call_count + 1;
  1282.                   rf3.mapping_c;
  1283.                   pop;
  1284.                end;
  1285.                i := i - 1;
  1286.             end;
  1287.          end;
  1288.       end;
  1289.  
  1290. feature
  1291.  
  1292.    set_no_split is
  1293.       do
  1294.          no_split := true;
  1295.       end;
  1296.  
  1297.    write_make_file is
  1298.       local
  1299.          score: DOUBLE;
  1300.       do
  1301.          out_h.put_character('%N');
  1302.          out_h.disconnect;
  1303.          out_c.put_character('%N');
  1304.          out_c.disconnect;
  1305.          sfw_connect(out_make,path_make);
  1306.          if no_split then
  1307.             write_make_file_no_split;
  1308.          else
  1309.             write_make_file_split;
  1310.          end;
  1311.          if system_tools.strip_executable(tmp_string) then
  1312.             echo_make;
  1313.          end;
  1314.          out_make.disconnect;
  1315.          if nb_errors > 0 then
  1316.             echo.file_removing(path_make);
  1317.          else
  1318.             echo.put_string("Type inference score : ");
  1319.             score := direct_call_count + check_id_count;
  1320.             score := (score / (score + switch_count)) * 100.0;
  1321.             echo.put_double_format(score,2);
  1322.             echo.put_character('%%');
  1323.             echo.put_character('%N');
  1324.          end;
  1325.          eiffel_parser.show_nb_warnings;
  1326.          eiffel_parser.show_nb_errors;
  1327.          echo.put_string(fz_02);
  1328.       end;
  1329.  
  1330. feature {C_PRETTY_PRINTER}
  1331.  
  1332.    no_split: BOOLEAN;
  1333.  
  1334. feature {CALL_PROC_CALL}
  1335.  
  1336.    put_cpc(cpc: CALL_PROC_CALL) is
  1337.       local
  1338.          target: EXPRESSION;
  1339.          target_type: TYPE;
  1340.          run_feature: RUN_FEATURE;
  1341.       do
  1342.          target := cpc.target;
  1343.          target_type := target.result_type.run_type;
  1344.          run_feature := cpc.run_feature;
  1345.          if target_type.is_expanded then
  1346.             push_direct(run_feature,target,cpc.arguments);
  1347.             run_feature.mapping_c;
  1348.             pop;
  1349.          elseif target.is_current then
  1350.             push_direct(run_feature,target,cpc.arguments);
  1351.             run_feature.mapping_c;
  1352.             pop;
  1353.          elseif target.is_manifest_string then
  1354.             push_direct(run_feature,target,cpc.arguments);
  1355.             run_feature.mapping_c;
  1356.             pop;
  1357.          else
  1358.             push_cpc(run_feature,
  1359.                      target_type.run_class.running,
  1360.                      target,
  1361.                      cpc.arguments);
  1362.          end;
  1363.       end;
  1364.  
  1365. feature {NATIVE_SMALL_EIFFEL}
  1366.  
  1367.    sprintf_double_is_used is
  1368.       do
  1369.          sprintf_double_flag := true;
  1370.       end;
  1371.  
  1372. feature
  1373.  
  1374.    sys_runtime_h(name: STRING) is
  1375.          -- Inline corresponding SmallEiffel/sys/runtime/`name'.h file.
  1376.       require
  1377.          name /= Void
  1378.       do
  1379.          system_tools.sys_runtime(name,'h');
  1380.          put_file(tmp_file_read,out_h);
  1381.       end;
  1382.  
  1383.    sys_runtime_c(name: STRING) is
  1384.          -- Inline corresponding SmallEiffel/sys/runtime/`name'.c file.
  1385.       require
  1386.          name /= Void
  1387.       do
  1388.          system_tools.sys_runtime(name,'c');
  1389.          put_file(tmp_file_read,out_c);
  1390.       end;
  1391.  
  1392.    sys_runtime_h_and_c(name: STRING) is
  1393.       do
  1394.          sys_runtime_h(name);
  1395.          sys_runtime_c(name);
  1396.       end;
  1397.  
  1398. feature {SYSTEM_TOOLS}
  1399.  
  1400.    echo_make is
  1401.       do
  1402.          out_make.put_string(tmp_string);
  1403.          out_make.put_character('%N');
  1404.       end;
  1405.  
  1406.    put_c_file(sfr: STD_FILE_READ) is
  1407.       require
  1408.          not sfr.end_of_input
  1409.       do
  1410.          put_file(sfr,out_c);
  1411.       ensure
  1412.          not sfr.is_connected
  1413.       end;
  1414.  
  1415. feature
  1416.  
  1417.    put_recompilation_comment(key: INTEGER) is
  1418.       do
  1419.          out_c.put_string(fz_open_c_comment);
  1420.          out_c.put_integer(key);
  1421.          out_c.put_string(fz_close_c_comment);
  1422.       end;
  1423.  
  1424. feature
  1425.  
  1426.    no_main: BOOLEAN;
  1427.  
  1428.    set_no_main is
  1429.       do
  1430.          no_main := true;
  1431.       ensure
  1432.          no_main
  1433.       end;
  1434.  
  1435.    set_c_size (value: INTEGER) is
  1436.       do
  1437.          elt_c_size := value;
  1438.       end;
  1439.  
  1440.    set_c_count_max (value: INTEGER) is
  1441.       do
  1442.          elt_c_count_max := value;
  1443.       end;
  1444.  
  1445. feature {COMPOUND,ASSERTION_LIST}
  1446.  
  1447.    se_tmp_open_declaration: BOOLEAN is
  1448.          -- True if some `se_tmpXX' is needed.
  1449.       local
  1450.          i: INTEGER;
  1451.          rf: RUN_FEATURE;
  1452.       do
  1453.          from
  1454.             tmp_string.copy(fz_11);
  1455.             i := se_tmp_list.upper;
  1456.          until
  1457.             i < 0
  1458.          loop
  1459.             rf := se_tmp_list.item(i);
  1460.             if rf /= Void then
  1461.                Result := true;
  1462.                rf.result_type.c_type_for_result_in(tmp_string);
  1463.                tmp_string.append(" se_tmp");
  1464.                i.append_in(tmp_string);
  1465.                tmp_string.append(fz_00);
  1466.             end;
  1467.             i := i - 1;
  1468.          end;
  1469.          if Result then
  1470.             se_tmp_level := se_tmp_level + 1;
  1471.             out_c.put_string(tmp_string);
  1472.          end;
  1473.       end;
  1474.  
  1475.    se_tmp_close_declaration is
  1476.       do
  1477.          check
  1478.             se_tmp_level > 0
  1479.          end;
  1480.          se_tmp_level := se_tmp_level - 1;
  1481.          out_c.put_string(fz_12);
  1482.          if se_tmp_level = 0 then
  1483.             se_tmp_list.clear;
  1484.          end;
  1485.       end;
  1486.  
  1487. feature {RUN_FEATURE_4, RUN_FEATURE_11}
  1488.  
  1489.    se_tmp_add(rf: RUN_FEATURE) is
  1490.       do
  1491.          se_tmp_list.add_last(rf);
  1492.       end;
  1493.  
  1494.    se_tmp_open(rf: RUN_FEATURE): INTEGER is
  1495.          -- Result >= 0 implies a temporary variable is used and thus
  1496.          -- `se_tmp_close' must be called.
  1497.          -- Result < 0 indicate that no temporary variable is mandatory.
  1498.       local
  1499.          rt: TYPE;
  1500.       do
  1501.          rt := rf.result_type;
  1502.          if rt.is_user_expanded and then not rt.is_dummy_expanded then
  1503.             Result := se_tmp_list.fast_index_of(rf);
  1504.             check
  1505.                se_tmp_list.valid_index(Result)
  1506.             end;
  1507.             se_tmp_list.put(Void,Result);
  1508.             out_c.put_string("(*(se_tmp");
  1509.             out_c.put_integer(Result);
  1510.             out_c.put_character('=');
  1511.          else
  1512.             Result := -1
  1513.          end;
  1514.       end;
  1515.  
  1516.    se_tmp_close(i: INTEGER) is
  1517.       do
  1518.          check
  1519.             se_tmp_list.item(i) = Void
  1520.          end;
  1521.          out_c.put_string(",&se_tmp");
  1522.          out_c.put_integer(i);
  1523.          out_c.put_string(fz_13);
  1524.       end;
  1525.  
  1526. feature {BIT_CONSTANT}
  1527.  
  1528.    register_bit_constant(bc: BIT_CONSTANT) is
  1529.       require
  1530.          bc.result_type.is_c_unsigned_ptr
  1531.       do
  1532.          if bit_constant_pool = void then
  1533.             !!bit_constant_pool.with_capacity(4);
  1534.          end;
  1535.          bit_constant_pool.add_last(bc);
  1536.          out_c.put_string(fz_se_bit_constant);
  1537.          out_c.put_integer(bit_constant_pool.upper);
  1538.       end;
  1539.  
  1540.    bit_constant_definition is
  1541.       local
  1542.          i: INTEGER;
  1543.          bc: BIT_CONSTANT;
  1544.          type_bit: TYPE_BIT;
  1545.       do
  1546.          if bit_constant_pool /= Void then
  1547.             from
  1548.                i := bit_constant_pool.upper;
  1549.             until
  1550.                i < 0
  1551.             loop
  1552.                tmp_string.clear;
  1553.                bc := bit_constant_pool.item(i)
  1554.                type_bit := bc.result_type;
  1555.                tmp_string.clear;
  1556.                type_bit.c_type_for_target_in(tmp_string);
  1557.                tmp_string.extend(' ');
  1558.                tmp_string.append(fz_se_bit_constant);
  1559.                i.append_in(tmp_string);
  1560.                put_extern7(tmp_string);
  1561.                out_c.put_character('{');
  1562.                bc.c_define;
  1563.                out_c.put_character('}');
  1564.                out_c.put_character(';');
  1565.                out_c.put_character('%N');
  1566.                i := i - 1;
  1567.             end;
  1568.          end;
  1569.       end;
  1570.  
  1571. feature {RUN_CLASS}
  1572.  
  1573.    finished_run_class is
  1574.          -- Add some padding space.
  1575.       do
  1576.          if elt_c_count > elt_c_size then
  1577.             elt_c_count := elt_c_count_max;
  1578.          end;
  1579.       end;
  1580.  
  1581. feature {SWITCH}
  1582.  
  1583.    finished_switch(running_count: INTEGER) is
  1584.          -- Add some padding space.
  1585.       do
  1586.          elt_c_count := elt_c_count + 4 * running_count;
  1587.       end;
  1588.  
  1589. feature {NONE}
  1590.  
  1591.    out_c: STD_FILE_WRITE is
  1592.          -- The current *.c output file.
  1593.       once
  1594.          !!Result.make;
  1595.       end;
  1596.  
  1597.    out_h: STD_FILE_WRITE;
  1598.          -- The *.h output file.
  1599.  
  1600.    current_out: STD_FILE_WRITE;
  1601.          -- Is `out_c' or `out_h'.
  1602.  
  1603.    out_make: STD_FILE_WRITE is
  1604.          -- The *.make output file.
  1605.       once
  1606.          !!Result.make;
  1607.       end;
  1608.  
  1609.    incr_elt_c_count(i: INTEGER) is
  1610.       do
  1611.          check
  1612.             out_c.is_connected;
  1613.          end;
  1614.          if no_split then
  1615.          else
  1616.             elt_c_count := elt_c_count + i;
  1617.             if elt_c_count >= elt_c_count_max then
  1618.                elt_c_count := 0;
  1619.                out_c.put_character('%N');
  1620.                out_c.disconnect;
  1621.                split_count := split_count + 1;
  1622.                path_c_in(path_c,split_count);
  1623.                backup_sfw_connect(out_c,path_c);
  1624.                add_first_include;
  1625.                if current_out /= out_h then
  1626.                   current_out := out_c;
  1627.                end;
  1628.             end;
  1629.          end;
  1630.       end;
  1631.  
  1632.    no_args_to_eval: BOOLEAN is
  1633.          -- True if there is no C code to produce to eval arguments.
  1634.          -- For example because there are  no arguments or because
  1635.          -- we are inside a switching function for example.
  1636.       require
  1637.          small_eiffel.is_ready
  1638.       local
  1639.          code: INTEGER;
  1640.          args: EFFECTIVE_ARG_LIST;
  1641.       do
  1642.          code := stack_code.item(top);
  1643.          inspect
  1644.             code
  1645.          when C_direct_call,
  1646.               C_check_id,
  1647.               C_inside_new,
  1648.               C_same_target
  1649.           then
  1650.             args := stack_args.item(top);
  1651.             if args = Void then
  1652.                Result := true;
  1653.             else
  1654.                Result := args.can_be_dropped;
  1655.             end;
  1656.          when C_inline_dca then
  1657.             top := top - 1;
  1658.             Result := no_args_to_eval;
  1659.             top := top + 1;
  1660.          else
  1661.             Result := true;
  1662.          end;
  1663.       end;
  1664.  
  1665.    c_inline_h_mem: FIXED_ARRAY[STRING] is
  1666.       once
  1667.          !!Result.with_capacity(4);
  1668.       end;
  1669.  
  1670.    to_expanded_mem, to_reference_mem: ARRAY[RUN_CLASS];
  1671.  
  1672.    conversion_name(dest_id: INTEGER) is
  1673.       do
  1674.          tmp_string.append(fz_to_t);
  1675.          dest_id.append_in(tmp_string);
  1676.       end;
  1677.  
  1678.    define_to_reference is
  1679.       local
  1680.          i: INTEGER;
  1681.          src_rc, dest_rc: RUN_CLASS;
  1682.          src_type, dest_type: TYPE;
  1683.       do
  1684.          from
  1685.             i := 1;
  1686.          until
  1687.             i > to_reference_mem.upper
  1688.          loop
  1689.             src_rc := to_reference_mem.item(i);
  1690.             i := i + 1;
  1691.             dest_rc := to_reference_mem.item(i);
  1692.             i := i + 1;
  1693.             src_type := src_rc.current_type;
  1694.             dest_type := dest_rc.current_type;
  1695.             echo.put_string(msg2);
  1696.             echo.put_string(src_type.run_time_mark);
  1697.             echo.put_string(" to ");
  1698.             echo.put_string(dest_type.run_time_mark);
  1699.             echo.put_string(msg1);
  1700.             tmp_string.copy(fz_t0_star);
  1701.             conversion_name(dest_rc.id);
  1702.             tmp_string.extend('(');
  1703.             src_type.c_type_for_result_in(tmp_string);
  1704.             tmp_string.append(" s)");
  1705.             put_c_heading(tmp_string);
  1706.             swap_on_c;
  1707.             gc_handler.allocation(dest_rc);
  1708.             if not src_type.is_dummy_expanded then
  1709.                out_c.put_string("n->_item=s;%N");
  1710.             end;
  1711.             out_c.put_string("return (T0*)n;%N}%N");
  1712.          end;
  1713.       end;
  1714.  
  1715.    define_to_expanded is
  1716.       local
  1717.          i: INTEGER;
  1718.          src_rc, dest_rc: RUN_CLASS;
  1719.          src_type, dest_type: TYPE;
  1720.       do
  1721.          from
  1722.             i := 1;
  1723.          until
  1724.             i > to_expanded_mem.upper
  1725.          loop
  1726.             src_rc := to_expanded_mem.item(i);
  1727.             i := i + 1;
  1728.             dest_rc := to_expanded_mem.item(i);
  1729.             i := i + 1;
  1730.             src_type := src_rc.current_type;
  1731.             dest_type := dest_rc.current_type;
  1732.             echo.put_string(msg2);
  1733.             echo.put_string(src_type.run_time_mark);
  1734.             echo.put_string(" to ");
  1735.             echo.put_string(dest_type.run_time_mark);
  1736.             echo.put_string(msg1);
  1737.             tmp_string.clear;
  1738.             dest_type.c_type_for_result_in(tmp_string);
  1739.             tmp_string.extend(' ');
  1740.             conversion_name(dest_rc.id);
  1741.             tmp_string.append("(T0*s)");
  1742.             out_h.put_string(tmp_string);
  1743.             out_h.put_string(fz_00);
  1744.             out_c.put_string(tmp_string);
  1745.             tmp_string.copy(fz_11);
  1746.  
  1747.             -- NYI ...
  1748.  
  1749.             tmp_string.append(fz_12);
  1750.             out_c.put_string(tmp_string);
  1751.          end;
  1752.       end;
  1753.  
  1754.    push_void(rf: RUN_FEATURE; target: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1755.       require
  1756.          rf /= Void;
  1757.          target /= Void
  1758.       do
  1759.          eh.add_position(target.start_position);
  1760.          eh.append("Call on a Void or a bad target. Dynamic ");
  1761.          eh.add_type(target.result_type.run_type," is concerned. ")
  1762.          eh.print_as_warning;
  1763.          if run_control.boost then
  1764.             exceptions_handler.se_evobt;
  1765.          else
  1766.             put_string("se_evobt(");
  1767.             target.compile_to_c;
  1768.             put_character(',');
  1769.             put_position(target.start_position);
  1770.             put_string(fz_14);
  1771.          end;
  1772.          push_direct(rf,target,args);
  1773.          sure_void_count := sure_void_count + 1;
  1774.       end;
  1775.  
  1776.    push_check(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1777.       require
  1778.          rf /= Void;
  1779.          t /= Void;
  1780.       do
  1781.          stack_push(C_check_id);
  1782.          stack_rf.put(rf,top);
  1783.          stack_target.put(t,top);
  1784.          stack_args.put(args,top);
  1785.       end;
  1786.  
  1787.    expanded_initializer(t: TYPE; a: RUN_FEATURE) is
  1788.          -- ***** CHANGE THIS ******
  1789.          -- Call the expanded initializer for type `t' if any.
  1790.          -- The result is assigned in writable `w' or to attribute
  1791.          -- `a' of the brand new created object in "n".
  1792.       require
  1793.          t.is_expanded;
  1794.          a /= Void
  1795.       local
  1796.          rf: RUN_FEATURE;
  1797.       do
  1798.          rf := t.expanded_initializer;
  1799.          if rf /= Void then
  1800.             stack_push(C_expanded_initialize);
  1801.             stack_target.put(Void,top);
  1802.             stack_rf.put(a,top);
  1803.             direct_call_count := direct_call_count + 1;
  1804.             rf.mapping_c;
  1805.             pop;
  1806.          end;
  1807.       end;
  1808.  
  1809.    use_switch(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS];
  1810.               t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1811.       require
  1812.          up_rf /= Void;
  1813.          r.count > 1
  1814.          t /= Void;
  1815.          on_c;
  1816.       local
  1817.          rt: TYPE;
  1818.          rc: RUN_CLASS;
  1819.          rf: RUN_FEATURE;
  1820.          switch: SWITCH;
  1821.       do
  1822.          if run_control.boost and then stupid_switch(up_rf) then
  1823.             direct_call_count := direct_call_count + 1;
  1824.             switch_collection.remove(up_rf);
  1825.             put_string(fz_open_c_comment);
  1826.             put_character('X');
  1827.             put_integer(up_rf.current_type.id);
  1828.             put_string(up_rf.name.to_string);
  1829.             put_string(fz_close_c_comment);
  1830.             rt := up_rf.result_type;
  1831.             if rt /= Void then
  1832.                tmp_string.copy(fz_17);
  1833.                rt.c_type_for_result_in(tmp_string);
  1834.                tmp_string.extend(')');
  1835.                put_string(tmp_string);
  1836.             end;
  1837.             rc := r.item(1);
  1838.             rf := rc.dynamic(up_rf);
  1839.             push_direct(rf,t,args);
  1840.             rf.mapping_c;
  1841.             pop;
  1842.             if rt /= Void then
  1843.                put_character(')');
  1844.             end;
  1845.          else
  1846.             switch_count := switch_count + 1;
  1847.             out_c.put_string(switch.name(up_rf));
  1848.             out_c.put_character('(');
  1849.             if run_control.no_check then
  1850.                out_c.put_string("&ds,");
  1851.                put_position(t.start_position)
  1852.                out_c.put_character(',');
  1853.             end;
  1854.             t.compile_to_c;
  1855.             if args /= Void then
  1856.                out_c.put_character(',');
  1857.                args.compile_to_c(up_rf.arguments);
  1858.             end;
  1859.             put_character(')');
  1860.             if up_rf.result_type = Void then
  1861.                out_c.put_string(fz_00);
  1862.             end;
  1863.          end;
  1864.       end;
  1865.  
  1866.    stupid_switch_n(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]): BOOLEAN is
  1867.       require
  1868.          small_eiffel.is_ready;
  1869.          r.count > 1
  1870.       local
  1871.          i: INTEGER;
  1872.          up_f: E_FEATURE;
  1873.          dyn_rf: RUN_FEATURE;
  1874.          rc: RUN_CLASS;
  1875.       do
  1876.          from
  1877.             Result := true;
  1878.             i := r.upper;
  1879.             up_f := up_rf.base_feature;
  1880.          until
  1881.             not Result or else i = 0
  1882.          loop
  1883.             rc := r.item(i);
  1884.             dyn_rf := rc.dynamic(up_rf);
  1885.             if up_f = dyn_rf.base_feature then
  1886.                if dyn_rf.name.to_string /= up_rf.name.to_string then
  1887.                   Result := false;
  1888.                end;
  1889.             else
  1890.                Result := false;
  1891.             end;
  1892.             i := i - 1;
  1893.          end;
  1894.          if not Result then
  1895.             Result := attribute_read_removal(up_rf,r);
  1896.             if Result then
  1897.                cpp.put_comment("SSWA2");
  1898.             end;
  1899.          end;
  1900.          if Result then
  1901.             Result := up_f.stupid_switch(up_rf,r);
  1902.          end;
  1903.       end;
  1904.  
  1905.    attribute_read_removal(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]): BOOLEAN is
  1906.       require
  1907.          small_eiffel.is_ready;
  1908.          r.count > 1
  1909.       local
  1910.          rf2a, rf2b: RUN_FEATURE_2;
  1911.          offseta, offsetb: INTEGER;
  1912.          rta, rtb: TYPE;
  1913.          i: INTEGER;
  1914.          rc: RUN_CLASS;
  1915.       do
  1916.          from
  1917.             Result := true;
  1918.             i := r.upper;
  1919.          until
  1920.             not Result or else i = 0
  1921.          loop
  1922.             rc := r.item(i);
  1923.             rf2b ?= rc.dynamic(up_rf);
  1924.             if rf2b /= Void then
  1925.                offsetb := rc.offset_of(rf2b);
  1926.             end;
  1927.             if rf2a = Void then
  1928.                rf2a := rf2b;
  1929.                offseta := offsetb;
  1930.             end;
  1931.             if rf2b = Void then
  1932.                Result := false;
  1933.             else
  1934.                Result := offseta = offsetb;
  1935.                if Result then
  1936.                   rta := rf2a.result_type;
  1937.                   rtb := rf2b.result_type;
  1938.                   if rta.is_reference then
  1939.                      Result := rtb.is_reference;
  1940.                   elseif rta.run_time_mark = rtb.run_time_mark then
  1941.                   elseif rta.is_native_array then
  1942.                      if rta.generic_list.first.is_reference then
  1943.                         Result := rtb.generic_list.first.is_reference;
  1944.                      end;
  1945.                   else
  1946.                      Result := false;
  1947.                   end;
  1948.                end
  1949.             end;
  1950.             i := i - 1;
  1951.          end;
  1952.       end;
  1953.  
  1954.    define_initialize_eiffel_runtime(rf3: RUN_FEATURE_3) is
  1955.       require
  1956.          on_c
  1957.       local
  1958.          no_check: BOOLEAN;
  1959.          rc: RUN_CLASS;
  1960.          ct: TYPE;
  1961.       do
  1962.          no_check := run_control.no_check;
  1963.          ct := rf3.current_type;
  1964.          rc := rf3.run_class;
  1965.          echo.put_string("Define initialize stuff.%N");
  1966.          small_eiffel.define_extern_tables;
  1967.          put_c_heading("void initialize_eiffel_runtime(int argc,char*argv[])");
  1968.          if no_check then
  1969.             out_c.put_string(
  1970.             "se_frame_descriptor irfd={%"Initialysing runtime.%",0,0,%"%",1};%N%
  1971.             %se_dump_stack ds = {NULL,NULL,0,0,0,NULL,NULL};%N%
  1972.             %ds.fd=&irfd;%N%
  1973.             %ds.caller=se_dst;%N");
  1974.          end;
  1975.          out_c.put_string("se_argc=argc;%Nse_argv=argv;%N");
  1976.          gc_handler.initialize_runtime;
  1977.          exceptions_handler.initialize_runtime;
  1978.          if no_check then
  1979.             small_eiffel.initialize_path_table;
  1980.          end;
  1981.          if run_control.generator_used then
  1982.             small_eiffel.initialize_generator;
  1983.          end;
  1984.          if run_control.generating_type_used then
  1985.             small_eiffel.initialize_generating_type;
  1986.          end;
  1987.          if not exceptions_handler.used then
  1988.             out_c.put_string(
  1989.                "#ifdef SIGINT%Nsignal(SIGINT,sigrsp);%N#endif%N%
  1990.                %#ifdef SIGQUIT%Nsignal(SIGQUIT,sigrsp);%N#endif%N%
  1991.                %#ifdef SIGTERM%Nsignal(SIGTERM,sigrsp);%N#endif%N%
  1992.                %#ifdef SIGBREAK%Nsignal(SIGBREAK,sigrsp);%N#endif%N%
  1993.                %#ifdef SIGKILL%Nsignal(SIGKILL,sigrsp);%N#endif%N");
  1994.          end;
  1995.          manifest_string_pool.c_call_initialize;
  1996.          once_pre_computing;
  1997.          if run_control.trace then
  1998.             out_c.put_string("se_trace_flag=1;%N");
  1999.          end;
  2000.          if sprintf_double_flag then
  2001.             out_c.put_string("_spfd=malloc(32);%N%
  2002.                              %_spfd[0]='%%';%N%
  2003.                              %_spfd[1]='.';%N");
  2004.          end;
  2005.          if not gc_handler.is_off then
  2006.             out_c.put_string("gc_is_off=0;%N");
  2007.          end;
  2008.          gc_handler.allocation_of(fz_eiffel_root_object,rc);
  2009.          if run_control.no_check then
  2010.             out_c.put_string("se_dst=NULL;%N");
  2011.          end;
  2012.          out_c.put_string(fz_12);
  2013.       ensure
  2014.          on_c
  2015.       end;
  2016.  
  2017.    define_is_equal_prototype(id: INTEGER) is
  2018.       do
  2019.          tmp_string.copy("T6 r");
  2020.          (id).append_in(tmp_string);
  2021.          tmp_string.append(as_is_equal);
  2022.          tmp_string.append("(T");
  2023.          (id).append_in(tmp_string);
  2024.          tmp_string.append("*C, T0*a1)");
  2025.          out_h.put_string(tmp_string);
  2026.          out_c.put_string(tmp_string);
  2027.       end;
  2028.  
  2029.    check_assertion_mode: STRING;
  2030.  
  2031.    inspect_level: INTEGER;
  2032.  
  2033.    inline_level: INTEGER;
  2034.  
  2035.    check_id(e: EXPRESSION; id: INTEGER) is
  2036.          -- Produce a C expression checking that `e' is not void and
  2037.          -- that `e' is really of type `id'.
  2038.          -- The result of the C expression is the pointer to the
  2039.          -- corresponding Object.
  2040.       require
  2041.          e.result_type.run_type.is_reference;
  2042.          id > 0;
  2043.       do
  2044.          if run_control.no_check then
  2045.             put_string("((T");
  2046.             put_integer(id);
  2047.             put_string("*)ci(");
  2048.             put_integer(id);
  2049.             put_character(',');
  2050.             e.compile_to_c;
  2051.             put_character(',');
  2052.             put_position(e.start_position);
  2053.             put_string(fz_13);
  2054.             check_id_count := check_id_count + 1;
  2055.          else
  2056.             e.compile_to_c;
  2057.             direct_call_count := direct_call_count + 1;
  2058.          end;
  2059.       end;
  2060.  
  2061.    same_base_feature(r: ARRAY[RUN_CLASS]; up_rf: RUN_FEATURE): BOOLEAN is
  2062.       -- True if all have the same final name and the same base_feature.
  2063.       require
  2064.          not r.empty;
  2065.          up_rf /= Void
  2066.       local
  2067.          i: INTEGER;
  2068.          up_bf, bf: E_FEATURE;
  2069.          up_name, name: FEATURE_NAME;
  2070.          rf: RUN_FEATURE;
  2071.       do
  2072.          from
  2073.             up_bf := up_rf.base_feature;
  2074.             up_name := up_rf.name;
  2075.             i := r.lower;
  2076.             Result := true;
  2077.          until
  2078.             not Result or else i > r.upper
  2079.          loop
  2080.             rf := r.item(i).dynamic(up_rf);
  2081.             bf := rf.base_feature;
  2082.             name := rf.name;
  2083.             Result := name.is_equal(up_name) and then bf = up_bf;
  2084.             i := i + 1;
  2085.          end;
  2086.       end;
  2087.  
  2088.    tmp_string: STRING is
  2089.       once
  2090.          !!Result.make(256);
  2091.       end;
  2092.  
  2093.    tmp_string2: STRING is
  2094.       once
  2095.          !!Result.make(128);
  2096.       end;
  2097.  
  2098.    tmp_string3: STRING is
  2099.       once
  2100.          !!Result.make(128);
  2101.       end;
  2102.  
  2103.    once_pre_computing is
  2104.       local
  2105.          i: INTEGER;
  2106.          of_array: FIXED_ARRAY[ONCE_FUNCTION];
  2107.          rf6: RUN_FEATURE_6;
  2108.          of: ONCE_FUNCTION;
  2109.       do
  2110.          if pre_computed_once.upper >= 0 then
  2111.             echo.put_string(fz_04);
  2112.             echo.put_string(fz_05);
  2113.             from
  2114.                i := pre_computed_once.upper;
  2115.                !!of_array.with_capacity(1 + i // 2);
  2116.             until
  2117.                i < 0
  2118.             loop
  2119.                rf6 := pre_computed_once.item(i);
  2120.                of := rf6.base_feature;
  2121.                if not of_array.fast_has(of) then
  2122.                   of_array.add_last(of);
  2123.                   rf6.c_pre_computing;
  2124.                end;
  2125.                i := i - 1;
  2126.             end;
  2127.             echo.print_count(fz_04,of_array.count);
  2128.          end;
  2129.       end;
  2130.  
  2131.    need_invariant(target_type: TYPE): RUN_CLASS is
  2132.          -- Give the good RUN_CLASS when `target_type' need some
  2133.          -- class invariant checking.
  2134.       require
  2135.          target_type.is_run_type
  2136.       do
  2137.          if run_control.invariant_check then
  2138.             Result := target_type.run_type.run_class;
  2139.             if Result.at_run_time and then
  2140.                Result.class_invariant /= Void then
  2141.             else
  2142.                Result := Void;
  2143.             end;
  2144.          end;
  2145.       end;
  2146.  
  2147.    split_count: INTEGER;
  2148.          -- Number of *.c files.
  2149.  
  2150.    elt_c_count: INTEGER;
  2151.          -- Number of elements already in current *.c file.
  2152.  
  2153.    elt_c_size: INTEGER;
  2154.    elt_c_count_max: INTEGER;
  2155.          -- One unit is about 1 source line.
  2156.  
  2157.    path_h: STRING is
  2158.       once
  2159.          Result := system_tools.path_h;
  2160.       ensure
  2161.          Result.has_suffix(h_suffix)
  2162.       end;
  2163.  
  2164.    path_c: STRING is
  2165.       once
  2166.          if no_split then
  2167.             Result := path_h.twin;
  2168.             Result.remove_last(1);
  2169.             Result.extend('c');
  2170.          else
  2171.             split_count := 1;
  2172.             !!Result.make(path_h.count + 4);
  2173.             path_c_in(Result,split_count);
  2174.          end;
  2175.       ensure
  2176.          Result.has_suffix(c_suffix);
  2177.       end;
  2178.  
  2179.    path_make: STRING is
  2180.       once
  2181.          Result := path_h.twin;
  2182.          Result.remove_last(2);
  2183.          Result.append(system_tools.make_suffix);
  2184.       ensure
  2185.          Result.has_suffix(system_tools.make_suffix);
  2186.       end;
  2187.  
  2188.    add_first_include is
  2189.       do
  2190.          put_banner(out_c);
  2191.          out_c.put_string("#include %"");
  2192.          out_c.put_string(path_h);
  2193.          out_c.put_string(fz_18);
  2194.       end;
  2195.  
  2196.    put_banner(output: STD_FILE_WRITE) is
  2197.       require
  2198.          output /= Void;
  2199.          output.is_connected;
  2200.       do
  2201.          output.put_string(fz_open_c_comment);
  2202.          output.put_string(
  2203.             "%N-- ANSI C code generated by :%N");
  2204.          output.put_string(small_eiffel.copyright);
  2205.          output.put_string(fz_close_c_comment);
  2206.          output.put_character('%N');
  2207.       end;
  2208.  
  2209.    c_code_saved: BOOLEAN;
  2210.  
  2211.    get_inline_ms: MANIFEST_STRING is
  2212.       local
  2213.          e: EXPRESSION;
  2214.       do
  2215.          e := stack_args.item(top).expression(1);
  2216.          Result ?= e;
  2217.          if Result = Void then
  2218.             eh.add_position(e.start_position);
  2219.             fatal_error("Bad usage of C inlining (argument%
  2220.                         % is not a manifest string).");
  2221.          end;
  2222.       end;
  2223.  
  2224.    backup_sfw_connect(sfw: STD_FILE_WRITE; c_path: STRING) is
  2225.       require
  2226.          not no_split
  2227.       local
  2228.          object_suffix: STRING;
  2229.       do
  2230.          object_suffix := system_tools.object_suffix;
  2231.          tmp_path.copy(c_path);
  2232.          tmp_path.remove_last(2);
  2233.          tmp_path.append(object_suffix);
  2234.          if file_exists(tmp_path) then
  2235.             if file_exists(c_path) then
  2236.                c_path.put('d',c_path.count);
  2237.             end;
  2238.          end;
  2239.          sfw_connect(sfw,c_path);
  2240.       end;
  2241.  
  2242.    path_c_in(str: STRING; number: INTEGER) is
  2243.       do
  2244.          str.clear;
  2245.          str.append(path_h);
  2246.          str.remove_last(2);
  2247.          number.append_in(str);
  2248.          str.extend('.');
  2249.          str.extend('c');
  2250.       end;
  2251.  
  2252.    write_make_file_split is
  2253.       require
  2254.          not no_split
  2255.       local
  2256.          i: INTEGER;
  2257.          no_change, recompile: BOOLEAN;
  2258.       do
  2259.          no_change := true;
  2260.          from
  2261.             i := split_count;
  2262.          until
  2263.             i = 0
  2264.          loop
  2265.             recompile := true;
  2266.             path_c_in(tmp_path,i);
  2267.             tmp_string.copy(tmp_path);
  2268.             tmp_string.put('d',tmp_string.count);
  2269.             if file_exists(tmp_string) then
  2270.                if file_tools.same_files(tmp_path,tmp_string) then
  2271.                   echo.put_string(fz_01);
  2272.                   echo.put_string(tmp_path);
  2273.                   echo.put_string("%" not changed.%N");
  2274.                   echo.file_removing(tmp_string);
  2275.                   recompile := false;
  2276.                else
  2277.                   echo.file_renaming(tmp_string,tmp_path);
  2278.                end;
  2279.             end;
  2280.             if recompile then
  2281.                tmp_string2.copy(path_h);
  2282.                tmp_string2.remove_last(2);
  2283.                i.append_in(tmp_string2);
  2284.                tmp_string2.extend('.');
  2285.                tmp_string2.extend('c');
  2286.                system_tools.split_mode_c_compiler_command(tmp_string,tmp_string2);
  2287.                echo_make;
  2288.                no_change := false;
  2289.             end;
  2290.             i := i - 1;
  2291.          end;
  2292.          if no_change and then output_name /= Void then
  2293.             no_change := file_exists(output_name)
  2294.          else
  2295.             no_change := false;
  2296.          end;
  2297.          if no_change then
  2298.             echo.put_string("Executable is up-to-date %
  2299.                             %(no C compilation, no linking done).%N");
  2300.          else
  2301.             tmp_string2.copy(path_h);
  2302.             tmp_string2.remove_last(2);
  2303.             system_tools.split_mode_linker_command(tmp_string,
  2304.                                                    tmp_string2,split_count);
  2305.             echo_make;
  2306.          end;
  2307.       end;
  2308.  
  2309.    write_make_file_no_split is
  2310.       require
  2311.          no_split
  2312.       do
  2313.          system_tools.no_split_mode_command(tmp_string,path_c);
  2314.          echo_make;
  2315.       end;
  2316.  
  2317.    common_put_target is
  2318.       local
  2319.          rf: RUN_FEATURE;
  2320.          flag: BOOLEAN;
  2321.          e: EXPRESSION;
  2322.          ct: TYPE;
  2323.       do
  2324.          inspect
  2325.             stack_code.item(top)
  2326.          when C_inside_twin then
  2327.             rf := stack_rf.item(top);
  2328.             ct := rf.current_type;
  2329.             if ct.is_reference then
  2330.                out_c.put_character('(');
  2331.                ct.mapping_cast;
  2332.                out_c.put_character('R');
  2333.                out_c.put_character(')');
  2334.             else
  2335.                out_c.put_character('&');
  2336.                out_c.put_character('R');
  2337.             end;
  2338.          when C_inside_new then
  2339.             out_c.put_character('n');
  2340.          when C_switch then
  2341.             rf := stack_rf.item(top);
  2342.             flag := call_invariant_start(rf.current_type);
  2343.             out_c.put_string("((T");
  2344.             out_c.put_integer(rf.id);
  2345.             out_c.put_string("*)C)");
  2346.             if flag then
  2347.                call_invariant_end;
  2348.             end;
  2349.          when C_expanded_initialize then
  2350.             e := stack_target.item(top);
  2351.             if e /= Void then
  2352.                out_c.put_character('&');
  2353.                e.compile_to_c;
  2354.             else
  2355.                out_c.put_string("&n->_");
  2356.                out_c.put_string(stack_rf.item(top).name.to_string);
  2357.             end;
  2358.          when C_inline_one_pc then
  2359.             print_current;
  2360.          when C_precursor then
  2361.             out_c.put_character('C');
  2362.          end;
  2363.       end;
  2364.  
  2365.    msg1: STRING is " type conversion.%N";
  2366.    msg2: STRING is "Automatic ";
  2367.  
  2368.    sprintf_double_flag: BOOLEAN;
  2369.  
  2370.    put_file(sfr: STD_FILE_READ; output: STD_FILE_WRITE) is
  2371.       require
  2372.          not sfr.end_of_input
  2373.       do
  2374.          from
  2375.             sfr.read_character;
  2376.          until
  2377.             sfr.end_of_input
  2378.          loop
  2379.             output.put_character(sfr.last_character);
  2380.             sfr.read_character;
  2381.          end;
  2382.          sfr.disconnect;
  2383.       ensure
  2384.          not sfr.is_connected
  2385.       end;
  2386.  
  2387.    really_define_c_main(rf3: RUN_FEATURE_3) is
  2388.       require
  2389.          not no_main
  2390.       local
  2391.          id: INTEGER;
  2392.          rc: RUN_CLASS;
  2393.          ct: TYPE;
  2394.       do
  2395.          echo.put_string("Define C main function.%N");
  2396.          ct := rf3.current_type;
  2397.          rc := rf3.run_class;
  2398.          id := rc.id;
  2399.          system_tools.put_c_main_function_type(out_c);
  2400.          out_c.put_string(" main(int argc,char*argv[]){%N%
  2401.                           %initialize_eiffel_runtime(argc,argv);%N");
  2402.          out_c.put_string("{T");
  2403.          out_c.put_integer(id);
  2404.          out_c.put_string("*n=eiffel_root_object;%N");
  2405.          if run_control.no_check then
  2406.             out_c.put_string("se_frame_descriptor root={%"System root.%",1,0,%"");
  2407.             c_frame_descriptor_format.clear;
  2408.             ct.c_frame_descriptor;
  2409.             out_c.put_string(c_frame_descriptor_format);
  2410.             out_c.put_string("%",1};%N%
  2411.                              %se_dump_stack ds;%N%
  2412.                              %ds.fd=&root;%N%
  2413.                              %ds.current=((void**)(&n));%N");
  2414.             put_position_in_ds(rf3.start_position);
  2415.             out_c.put_string("ds.caller=NULL;%Nse_dst=&ds;/*link*/%N");
  2416.          end;
  2417.          expanded_attributes(ct);
  2418.          push_new(rf3,Void);
  2419.          rf3.mapping_c;
  2420.          pop;
  2421.          if run_control.invariant_check then
  2422.             if rc.class_invariant /= Void then
  2423.                out_c.put_string(fz_se_i);
  2424.                out_c.put_integer(id);
  2425.                out_c.put_string("(&ds,n);%N");
  2426.             end;
  2427.          end;
  2428.          gc_handler.gc_info_before_exit;
  2429.          system_tools.put_c_main_function_exit(out_c);
  2430.       end;
  2431.  
  2432.    basic_directory_used: BOOLEAN;
  2433.  
  2434.    bit_constant_pool: FIXED_ARRAY[BIT_CONSTANT];
  2435.  
  2436.    fz_se_bit_constant: STRING is "se_bit_constant";
  2437.  
  2438.    se_tmp_level: INTEGER;
  2439.  
  2440.    se_tmp_list: FIXED_ARRAY[RUN_FEATURE] is
  2441.       once
  2442.          !!Result.with_capacity(4);
  2443.       end;
  2444.  
  2445.    fz_base: STRING is "base";
  2446.  
  2447.    fz_no_check: STRING is "no_check";
  2448.  
  2449. end -- C_PRETTY_PRINTER
  2450.  
  2451.