home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / c_pretty_printer.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  65.6 KB  |  2,750 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://www.loria.fr/SmallEiffel
  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.    -- Handling of C code pretty printing.
  19.    -- Also known as `cpp'.
  20.    --
  21.    
  22. inherit CODE_PRINTER;
  23.    
  24. creation make
  25.  
  26. feature
  27.  
  28. feature {NONE}
  29.    
  30.    out_c: STD_FILE_WRITE is
  31.      -- The current *.c output file.
  32.       once
  33.      !!Result.make;
  34.       end;
  35.    
  36.    out_h: STD_FILE_WRITE;
  37.      -- The *.h output file.
  38.    
  39.    current_out: STD_FILE_WRITE;
  40.      -- Is `out_c' or `out_h'.
  41.    
  42.    out_make: STD_FILE_WRITE is
  43.      -- The *.make output file.
  44.       once
  45.      !!Result.make;
  46.       end;
  47.    
  48. feature 
  49.    
  50.    make is do end;
  51.  
  52. feature    
  53.    
  54.    get_started is
  55.       require
  56.      small_eiffel.is_ready
  57.       local
  58.      no_check: BOOLEAN;
  59.      body: STRING;
  60.       do
  61.      echo.file_removing(path_make);
  62.      no_check := run_control.no_check;
  63.      top := -1;
  64.      backup_sfw_connect(out_c,path_c);
  65.      current_out := out_c;
  66.      add_first_include;
  67.      !!out_h.make;
  68.      sfw_connect(out_h,path_h);
  69.      current_out := out_h;
  70.      put_banner(out_h);
  71.      -- Global struct :
  72.      out_h.put_string(
  73.             "%N%
  74.         %#include <stdio.h>%N%
  75.         %#include <string.h>%N%
  76.         %#include <math.h>%N%
  77.         %#include <stdlib.h>%N%
  78.         %#include <signal.h>%N%
  79.         %#include <stddef.h>%N%
  80.         %#include <stdarg.h>%N%
  81.         %#include <limits.h>%N%
  82.         %#include <float.h>%N%
  83.         %#include <setjmp.h>%N%
  84.         %#include <sys/types.h>%N%
  85.         %#include <sys/stat.h>%N%
  86.         %#include <fcntl.h>%N%
  87.         %#ifndef O_RDONLY%N%
  88.         %#include <sys/file.h>%N%
  89.         %#endif%N%
  90.         %#ifndef O_RDONLY%N%
  91.         %#define O_RDONLY 0000%N%
  92.         %#endif%N%
  93.         %typedef struct S0 T0;%N%
  94.         %struct S0{int id;};%N");
  95.      cdef_id(us_integer,2);
  96.      cdef_id(us_character,3);
  97.      cdef_id(us_real,4);
  98.      cdef_id(us_double,5);
  99.      cdef_id(us_boolean,6);
  100.      cdef_id(us_pointer,8);
  101.      cdef_id(fz_expanded,10);
  102.      cdef_id("REF",11);
  103.      cdef_id("LINK",12);
  104.      cdef_id("FTAG",13);
  105.      cdef_id("NAME",14);
  106.      cdef_id("COLUMN",15);
  107.      cdef_id("LINE",16);
  108.      cdef_id("PATH",17);
  109.      cdef_id("DOING",18);
  110.      cdef_id("INV",19);
  111.      cdef_id(us_bit,20);
  112.      if no_check then
  113.         put_extern3("tag_pos_1","assignment");
  114.         put_extern3("tag_pos_2","boolean exp.");
  115.         put_extern3("tag_pos_3","instruction");
  116.         put_extern3("tag_pos_4","assertion");
  117.         put_extern3("tag_pos_5","creation call");
  118.         put_extern3("tag_pos_6","variant exp.");
  119.         put_extern3(us_current,us_current);
  120.         put_extern3(us_result,us_result);
  121.         put_extern1("double*rs_bot");
  122.         put_extern1("double*rs");
  123.         put_extern1("double*rs_lb");
  124.         put_extern1("double*rs_top");
  125.         put_c_function("void se_rsg(int sz)",
  126.            "if(rs+sz<rs_top)return;%N%
  127.            %{int osz=(rs_top-rs_bot+1);%N%
  128.                %int nsz;%N%
  129.                %double*nrs_bot;%N%
  130.                %int msz=262144;%N%
  131.                %nsz=osz*2;%N%
  132.                %nrs_bot=(void*)malloc(nsz*sizeof(double));%N%
  133.                %if((osz>msz)||(nrs_bot==NULL)){%N%
  134.                %printf(%"Stack Overflow (limit = %%d).\n%",msz);%N%
  135.                %rsp();if(!se_rspf)exit(0);}%N%
  136.                %((void)memcpy(nrs_bot,rs_bot,osz*sizeof(double)));%N%
  137.                %rs_lb=nrs_bot+(rs_lb-rs_bot);%N%
  138.                %rs=nrs_bot+(rs-rs_bot);%N%
  139.                %rs_top=nrs_bot+(nsz-1);%N%
  140.                %free(rs_bot);%N%
  141.                %rs_bot=nrs_bot;%N%
  142.                %return;}");
  143.         put_c_function("void rs_link(char*tag)",
  144.            "se_rsg(1024);%N%
  145.            %*((int*)rs++)=LINKid;%N%
  146.            %*((int*)rs)=(rs-rs_lb);%N%
  147.            %rs_lb=rs++;%N%
  148.            %*((int*)rs++)=FTAGid;%N%
  149.            %*((char**)rs++)=tag;");
  150.         put_c_function("void rs_unlink(void)",
  151.            "rs=rs_lb-1;%N%
  152.            %rs_lb=rs_lb-(*((int*)rs_lb));");
  153.         body :=
  154.             "*((int*)rs++)=LINEid;%N%
  155.            %*((int*)rs++)=l;%N%
  156.            %*((int*)rs++)=COLUMNid;%N%
  157.            %*((int*)rs++)=c;%N%
  158.            %*((int*)rs++)=PATHid;%N%
  159.            %*((int*)rs++)=f;%N%
  160.            %*((int*)rs++)=DOINGid;%N%
  161.            %*((char**)rs++)=tp;";
  162.         if run_control.trace then
  163.            body.append(
  164.                "if (se_trace_flag){%N%
  165.            %fprintf(se_trace_file,%"line %%d column %%d in %
  166.                %%%s\n%",l,c,p[f]);%N%
  167.                %fflush(se_trace_file);}");
  168.         end;
  169.         put_c_function("void rs_pPOS(char* tp,int l,int c,int f)",
  170.                body);
  171.         put_c_function("int rs_pop_int(int e)",
  172.            "rs-=8;%N%
  173.            %return e;");
  174.         put_c_function("void rs_pINT(int*i,char*n)",
  175.            "*((int*)rs++)=NAMEid;%N%
  176.            %*((char**)rs++)=n;%N%
  177.            %*((int*)rs++)=INTEGERid;%N%
  178.            %*((int**)rs++)=i;");
  179.         put_c_function("void rs_pCHA(char*c,char*n)",
  180.            "*((int*)rs++)=NAMEid;%N%
  181.            %*((char**)rs++)=n;%N%
  182.            %*((int*)rs++)=CHARACTERid;%N%
  183.            %*((char**)rs++)=c;");
  184.         put_c_function("void rs_pBOO(int*b,char*n)",
  185.            "*((int*)rs++)=NAMEid;%N%
  186.            %*((char**)rs++)=n;%N%
  187.            %*((int*)rs++)=BOOLEANid;%N%
  188.            %*((int**)rs++)=b;");
  189.         put_c_function("void rs_pREA(float*r,char*n)",
  190.            "*((int*)rs++)=NAMEid;%N%
  191.            %*((char**)rs++)=n;%N%
  192.            %*((int*)rs++)=REALid;%N%
  193.            %*((float**)rs++)=r;");
  194.         put_c_function("void rs_pDOU(double*d,char*n)",
  195.            "*((int*)rs++)=NAMEid;%N%
  196.            %*((char**)rs++)=n;%N%
  197.            %*((int*)rs++)=DOUBLEid;%N%
  198.            %*((double**)rs++)=d;");
  199.         put_c_function("void rs_pPOI(void*p,char*n)",
  200.            "*((int*)rs++)=NAMEid;%N%
  201.            %*((char**)rs++)=n;%N%
  202.            %*((int*)rs++)=POINTERid;%N%
  203.            %*((void**)rs++)=p;");
  204.         put_c_function("void rs_pBIT(void*p,char*n)",
  205.            "*((int*)rs++)=NAMEid;%N%
  206.            %*((char**)rs++)=n;%N%
  207.            %*((int*)rs++)=BITid;%N%
  208.            %*((void**)rs++)=p;");
  209.         put_c_function("void rs_pREF(void**r,char*n)",
  210.            "*((int*)rs++)=NAMEid;%N%
  211.            %*((char**)rs++)=n;%N%
  212.            %*((int*)rs++)=REFid;%N%
  213.            %*((void***)rs++)=r;");
  214.         put_c_function("void rs_pEXP(void*e,char*n)",
  215.            "*((int*)rs++)=NAMEid;%N%
  216.            %*((char**)rs++)=n;%N%
  217.            %*((int*)rs++)=expandedid;%N%
  218.            %*((void**)rs++)=e;");
  219.         put_extern2("int se_af",'0');
  220.         put_extern2("int se_rspf",'0');
  221.         put_extern1("int se_af_rlc");
  222.         put_extern1("int se_af_rlr");
  223.      end;
  224.      if run_control.require_check then
  225.         put_c_function("void ac_req(int v)",
  226.            "if (!v && se_af_rlc)%N% 
  227.            %error0(%"Require Assertion Violated.%");%N%
  228.            %se_af_rlr=se_af_rlr&&v;%N%
  229.            %rs-=8;");
  230.      end;
  231.      if run_control.ensure_check then
  232.         put_c_function("void ac_ens(int v)",
  233.            "if (!v) error0(%"Ensure Assertion Violated.%");%N%
  234.            %rs-=8;");
  235.      end;
  236.      if run_control.invariant_check then
  237.         put_c_function("void ac_inv(int v)",
  238.            "if (!v) error0(%"Class Invariant Violation.%");%N%
  239.            %rs-=8;");
  240.         put_c_function("int se_rciaux(double* sp)",
  241.            "if((*((char**)sp))!=Current) return 0;%
  242.                %sp++; if((*((int*)sp))!=REFid) return 0;%
  243.            %return 1;");
  244.         put_c_function("int se_rci(void*C)",
  245.            "double*lb=rs_lb;%N%
  246.                %double*sp;%N%
  247.            %if(se_af)return 0;%N%
  248.            %if(se_rspf)return 0;%N%
  249.                %while(1){%N%
  250.                %if(lb==rs_bot)return 0;%N%
  251.            %sp=lb+4;%N%
  252.                %if(se_rciaux(sp)){%N%
  253.                %sp+=2;%N%
  254.                %if((**((void***)sp))==C)break;}%N%
  255.            %lb=lb-(*((int*)lb));}%N%
  256.                %while(1){%N%
  257.            %lb=lb-(*((int*)lb));%N%
  258.                %if(lb==rs_bot)return 1;%N%
  259.            %sp=lb+4;%N%
  260.                %if(se_rciaux(sp)){%N%
  261.                %sp+=2;%N%
  262.                %if((**((void***)sp))==C)return 0;}}");
  263.      end;
  264.      if run_control.loop_check then
  265.         put_c_function("void ac_liv(int v)",
  266.            "if (!v) error0(%"Loop Invariant Violation.%");%N%
  267.            %rs-=8;");
  268.         put_c_function("int lvc(int lc,int lv1,int lv2)",
  269.            "if (lc==0){if (lv2 < 0){%N% 
  270.            %rsp();%N%
  271.            %printf(%"Bad First Variant Value = %%d\n%",lv2);}%N%
  272.            %else {rs-=8;return lv2;}}%N%
  273.            %else if ((lv2 < 0)||(lv2 >= lv1)){%N% 
  274.            %rsp();%N%
  275.            %printf(%"Loop Body Count = %%d (done)\n%
  276.            %New Variant = %%d\n%
  277.            %Previous Variant = %%d\n%",lc,lv2,lv1);}%N%
  278.            %else {rs-=8;return lv2;}%N%
  279.            %printf(%"*** Error at Run Time *** : Bad Loop Variant.\n%");%N%
  280.            %if(!se_rspf)exit(1);");
  281.      end;
  282.      if run_control.all_check then
  283.         put_c_function("void ac_civ(int v)",
  284.            "if (!v) error0(%"Check Assertion Violated.%");%N%
  285.            %rs-=8;");
  286.      end;
  287.      current_out := out_c;
  288.       ensure
  289.      on_c
  290.       end;
  291.    
  292.    swap_on_c is
  293.       do
  294.      current_out := out_c;
  295.       ensure
  296.      on_c;
  297.       end;
  298.    
  299.    swap_on_h is
  300.       do
  301.      current_out := out_h;
  302.       ensure
  303.      on_h;
  304.       end;
  305.    
  306.    on_h: BOOLEAN is
  307.       require
  308.      small_eiffel.is_ready
  309.       do
  310.      Result := current_out = out_h;
  311.       end;
  312.    
  313.    on_c: BOOLEAN is
  314.       require
  315.      small_eiffel.is_ready
  316.       do
  317.      Result := current_out = out_c;
  318.       end;
  319.    
  320. feature {SWITCH_COLLECTION}
  321.  
  322.    incr_elt_c_count(i: INTEGER) is
  323.       do
  324.      check
  325.         out_c.is_connected;
  326.      end;
  327.      if no_split then
  328.      else
  329.         elt_c_count := elt_c_count + i;
  330.         if elt_c_count > elt_c_count_max then
  331.            elt_c_count := 0;
  332.            out_c.put_character('%N');
  333.            out_c.disconnect;
  334.            split_count := split_count + 1;
  335.            path_c_copy_in(path_c,split_count);
  336.            backup_sfw_connect(out_c,path_c);
  337.            add_first_include;
  338.            if current_out /= out_h then
  339.           current_out := out_c;
  340.            end;
  341.         end;
  342.      end;
  343.       end;
  344.  
  345. feature -- Printing C code :
  346.    
  347.    put_extern1(decl: STRING) is
  348.       do
  349.      incr_elt_c_count(1);
  350.      out_h.put_string(fz_extern);
  351.      out_h.put_string(decl);
  352.      out_h.put_string(fz_00);
  353.      out_c.put_string(decl);
  354.      out_c.put_string(fz_00);
  355.       end;
  356.    
  357.    put_extern2(decl: STRING; init: CHARACTER) is
  358.       do
  359.      incr_elt_c_count(1);
  360.      out_h.put_string(fz_extern);
  361.      out_h.put_string(decl);
  362.      out_h.put_string(fz_00);
  363.      out_c.put_string(decl);
  364.      out_c.put_character('=');
  365.      out_c.put_character(init);
  366.      out_c.put_string(fz_00);
  367.       end;
  368.    
  369.    put_extern3(var, value: STRING) is
  370.       do
  371.      incr_elt_c_count(1);
  372.      out_c.put_string("char ");
  373.      out_c.put_string(var);
  374.      out_c.put_string("[]=%"");
  375.      out_c.put_string(value);
  376.      out_c.put_string("%";%N");
  377.      out_h.put_string("extern char ");
  378.      out_h.put_string(var);
  379.      out_h.put_character('[');
  380.      out_h.put_character(']');
  381.      out_h.put_string(fz_00);
  382.       end;
  383.    
  384.    put_extern4(t, var: STRING; value: INTEGER) is
  385.       do
  386.      incr_elt_c_count(1);
  387.      out_c.put_string(t);
  388.      out_c.put_character(' ');
  389.      out_c.put_string(var);
  390.      out_c.put_character('[');
  391.      out_c.put_integer(value);
  392.      out_c.put_string("];%N");
  393.      out_h.put_string(fz_extern);
  394.      out_h.put_string(t);
  395.      out_h.put_character(' ');
  396.      out_h.put_string(var);
  397.      out_h.put_character('[');
  398.      out_h.put_character(']');
  399.      out_h.put_string(fz_00);
  400.       end;
  401.    
  402.    put_extern5(decl: STRING; init: STRING) is
  403.       do
  404.      incr_elt_c_count(1);
  405.      out_h.put_string(fz_extern);
  406.      out_h.put_string(decl);
  407.      out_h.put_string(fz_00);
  408.      out_c.put_string(decl);
  409.      out_c.put_character('=');
  410.      out_c.put_string(init);
  411.      out_c.put_string(fz_00);
  412.       end;
  413.    
  414.    put_c_heading(heading: STRING) is
  415.       do
  416.      incr_elt_c_count(15);
  417.      out_h.put_string(heading);
  418.      out_h.put_string(fz_00);
  419.      out_c.put_string(heading);
  420.      out_c.put_string(fz_11);
  421.       end;
  422.    
  423.    put_c_function(heading, body:STRING) is
  424.       require
  425.      not heading.empty;
  426.      not body.empty
  427.       do
  428.      incr_elt_c_count(15);
  429.      put_c_heading(heading);
  430.      out_c.put_string(body);
  431.      out_c.put_string(fz_12);
  432.       end;
  433.    
  434.    put_string(c: STRING) is
  435.       require
  436.      small_eiffel.is_ready
  437.       do
  438.      current_out.put_string(c);
  439.       end;
  440.    
  441.    put_string_c(s: STRING) is
  442.       require
  443.      small_eiffel.is_ready;
  444.      on_c
  445.       do
  446.      tmp_string.clear;
  447.      manifest_string_pool.string_to_c_code(s,tmp_string);
  448.      out_c.put_string(tmp_string);
  449.       end;
  450.    
  451.    put_character(c: CHARACTER) is
  452.       require
  453.      small_eiffel.is_ready
  454.       do
  455.      current_out.put_character(c);
  456.       end;
  457.    
  458.    put_integer(i: INTEGER) is
  459.       require
  460.      small_eiffel.is_ready
  461.       do
  462.      current_out.put_integer(i);
  463.       end;
  464.    
  465.    put_real(r: REAL) is
  466.       require
  467.      small_eiffel.is_ready
  468.       do
  469.      current_out.put_real(r);
  470.       end;
  471.    
  472.    put_position(p: POSITION) is
  473.       require
  474.      small_eiffel.is_ready
  475.       do
  476.      if p = Void then
  477.         put_string("0,0,0");
  478.      else
  479.         put_integer(p.line);
  480.         put_character(',');
  481.         put_integer(p.column);
  482.         put_character(',');
  483.         put_integer(p.base_class.id);
  484.      end;
  485.       end;
  486.    
  487.    put_target_as_target is
  488.      -- Produce C code to pass the current stacked target as
  489.      -- a target of a new call : user expanded are passed with
  490.      -- a pointer and class invariant code is produced.
  491.       require
  492.      small_eiffel.is_ready
  493.       local
  494.      code: INTEGER;
  495.      rf: RUN_FEATURE;
  496.      target: EXPRESSION;
  497.      args: EFFECTIVE_ARG_LIST;
  498.      tt: TYPE;
  499.      ivt_flag: BOOLEAN;
  500.       do
  501.      code := stack_code.item(top); 
  502.      inspect
  503.         code
  504.      when C_direct_call then 
  505.         target := stack_target.item(top);
  506.         tt := stack_rf.item(top).current_type;
  507.         target.mapping_c_target(tt);
  508.      when C_check_id then 
  509.         target := stack_target.item(top);
  510.         rf := stack_rf.item(top);
  511.         tt := rf.current_type;
  512.         check 
  513.            tt.is_reference; 
  514.         end;
  515.         if run_control.boost then
  516.            target.mapping_c_target(tt);
  517.         else
  518.            ivt_flag := call_invariant_start(tt);
  519.            check_id(target,rf.id);
  520.            if ivt_flag then
  521.           call_invariant_end;
  522.            end;
  523.         end;
  524.      when C_inline_dca then 
  525.         put_character('(');
  526.         stack_rf.item(top).current_type.mapping_cast;
  527.         put_character('(');
  528.         put_target_as_value;
  529.         put_string(fz_13);
  530.      when C_same_target then 
  531.         rf := stack_rf.item(top);
  532.         args := stack_args.item(top);
  533.         top := top - 1;
  534.         put_target_as_target;
  535.         top := top + 1;
  536.         stack_code.put(code,top);
  537.         stack_rf.put(rf,top);
  538.         stack_args.put(args,top);
  539.      else
  540.         common_put_target;
  541.      end;
  542.       end;
  543.    
  544.    put_target_as_value is
  545.      -- Produce C code for a simple access to the stacked target.
  546.      -- User's expanded values are not given using a pointer.
  547.      -- There is no C code to check the class invariant.
  548.       require
  549.      small_eiffel.is_ready
  550.       local
  551.      code: INTEGER;
  552.      rf, static_rf: RUN_FEATURE;
  553.      target: EXPRESSION;
  554.      args: EFFECTIVE_ARG_LIST;
  555.      c0c: CALL_0_C;
  556.      direct_rf: RUN_FEATURE;
  557.       do
  558.      code := stack_code.item(top);
  559.      inspect
  560.         code
  561.      when C_direct_call then 
  562.         stack_target.item(top).compile_to_c;
  563.      when C_check_id then 
  564.         stack_rf.item(top).current_type.mapping_cast;
  565.         stack_target.item(top).compile_to_c;
  566.      when C_inline_dca then 
  567.         rf := stack_rf.item(top);
  568.         target := stack_target.item(top);
  569.         args := stack_args.item(top);
  570.         static_rf := stack_static_rf.item(top);
  571.         top := top - 1;
  572.         c0c ?= target;
  573.         direct_rf := c0c.run_feature;
  574.         direct_rf.mapping_c;
  575.         top := top + 1;
  576.         stack_code.put(code,top);
  577.         stack_rf.put(rf,top);
  578.         stack_target.put(target,top);
  579.         stack_args.put(args,top);
  580.         stack_static_rf.put(static_rf,top);
  581.      when C_same_target then 
  582.         rf := stack_rf.item(top);
  583.         args := stack_args.item(top);
  584.         top := top - 1;
  585.         put_target_as_value;
  586.         top := top + 1;
  587.         stack_code.put(code,top);
  588.         stack_rf.put(rf,top);
  589.         stack_args.put(args,top);
  590.      else
  591.         common_put_target;
  592.      end;
  593.       end;
  594.    
  595.    target_cannot_be_dropped: BOOLEAN is
  596.      -- True when top target cannot be dropped because we are 
  597.      -- not sure that target is non Void or that target has 
  598.      -- no side effects. When Result is true, printed 
  599.      -- C code is : "(((void)(<target>))"
  600.       require
  601.      small_eiffel.is_ready
  602.       do
  603.      inspect
  604.         stack_code.item(top)
  605.      when C_direct_call, C_check_id then
  606.         Result := not stack_target.item(top).can_be_dropped;
  607.      when C_inline_dca then
  608.         Result := true;
  609.      when C_same_target then 
  610.         top := top - 1;
  611.         Result := target_cannot_be_dropped;
  612.         top := top + 1;
  613.      else
  614.      end;
  615.      if Result then
  616.         put_string("((/*UT*/(void)(");
  617.         put_target_as_target;
  618.         put_string(fz_13);
  619.      end;
  620.       end;
  621.  
  622.    arguments_cannot_be_dropped: BOOLEAN is
  623.      -- True when arguments cannot be dropped.
  624.      -- Printed C code is like :
  625.      --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  626.       do
  627.      if not no_args_to_eval then
  628.         Result := true;
  629.         put_string("((/*UA*/(void)(");
  630.         put_arguments;
  631.         put_string(fz_13);
  632.      end;
  633.       end;
  634.  
  635.    cannot_drop_all: BOOLEAN is
  636.      -- Result is true when something (target or one argument)
  637.      -- cannot be dropped. Thus when something cannot be dropped,
  638.      -- Result is true and C code is printed : 
  639.      --  "(((void)<exp1>),((void)<exp2>),...((void)<expN>)"
  640.       do
  641.      if target_cannot_be_dropped then
  642.         Result := true;
  643.         put_character(',');
  644.         if arguments_cannot_be_dropped then
  645.            put_character(')');
  646.         else
  647.            put_character('0');
  648.         end;
  649.      else
  650.         Result := arguments_cannot_be_dropped;
  651.      end;
  652.       end;
  653.  
  654.    no_args_to_eval: BOOLEAN is
  655.      -- True if there is no C code to produce to eval arguments.
  656.      -- For example because there are  no arguments or because
  657.      -- we are inside a switching function for example.
  658.       require
  659.      small_eiffel.is_ready
  660.       local
  661.      code: INTEGER;
  662.      args: EFFECTIVE_ARG_LIST;
  663.       do
  664.      code := stack_code.item(top);
  665.      inspect 
  666.         code
  667.      when C_direct_call, 
  668.               C_check_id, 
  669.               C_inside_new,
  670.           C_same_target
  671.       then
  672.         args := stack_args.item(top);
  673.         if args = Void then
  674.            Result := true;
  675.         else
  676.            Result := args.can_be_dropped;
  677.         end;
  678.      when C_inline_dca then
  679.         top := top - 1;
  680.         Result := no_args_to_eval;
  681.         top := top + 1;
  682.      else
  683.         Result := true;
  684.      end;
  685.       end;
  686.  
  687.    put_arguments is
  688.       -- Produce code to access effective arguments list.
  689.       require
  690.      small_eiffel.is_ready
  691.       local
  692.      code: INTEGER;
  693.      rf, static_rf: RUN_FEATURE;
  694.      target: EXPRESSION;
  695.      args: EFFECTIVE_ARG_LIST;
  696.      fal: FORMAL_ARG_LIST;
  697.      switch: SWITCH;
  698.       do
  699.      code := stack_code.item(top);
  700.      inspect 
  701.         code
  702.      when C_expanded_initialize then
  703.      when C_inside_twin then
  704.         put_ith_argument(1);
  705.      when C_direct_call then
  706.         fal := stack_rf.item(top).arguments;
  707.         stack_args.item(top).compile_to_c(fal);
  708.      when C_check_id then
  709.         fal := stack_rf.item(top).arguments;
  710.         stack_args.item(top).compile_to_c(fal);
  711.      when C_switch then
  712.         fal := stack_rf.item(top).arguments;
  713.         static_rf := stack_static_rf.item(top);
  714.         switch.put_arguments(static_rf,fal);
  715.      when C_inside_new then
  716.         fal := stack_rf.item(top).arguments;
  717.         stack_args.item(top).compile_to_c(fal);
  718.      when C_inline_dca then
  719.         rf := stack_rf.item(top);
  720.         target := stack_target.item(top);
  721.         args := stack_args.item(top);
  722.         static_rf := stack_static_rf.item(top);
  723.         top := top - 1;
  724.         args.dca_inline(rf.arguments);
  725.         top := top + 1;
  726.         stack_code.put(code,top);
  727.         stack_rf.put(rf,top);
  728.         stack_target.put(target,top);
  729.         stack_args.put(args,top);
  730.         stack_static_rf.put(static_rf,top);
  731.      when C_same_target then
  732.         fal := stack_rf.item(top).arguments;
  733.         stack_args.item(top).compile_to_c(fal);
  734.      when C_inline_one_pc then
  735.      end;
  736.       end;
  737.    
  738.    put_ith_argument(index: INTEGER) is
  739.       -- Produce code to access to the ith argument.
  740.       require
  741.      small_eiffel.is_ready
  742.      index >= 1
  743.       local
  744.      code: INTEGER;
  745.      rf, static_rf: RUN_FEATURE;
  746.      target: EXPRESSION;
  747.      args: EFFECTIVE_ARG_LIST;
  748.      fal: FORMAL_ARG_LIST;
  749.      switch: SWITCH;
  750.       do
  751.      code := stack_code.item(top);
  752.      inspect 
  753.         code
  754.      when C_direct_call then
  755.         fal := stack_rf.item(top).arguments;
  756.         stack_args.item(top).compile_to_c_ith(fal,index);
  757.      when C_check_id then
  758.         fal := stack_rf.item(top).arguments;
  759.         stack_args.item(top).compile_to_c_ith(fal,index);
  760.      when C_switch then
  761.         fal := stack_rf.item(top).arguments;
  762.         static_rf := stack_static_rf.item(top);
  763.         switch.put_ith_argument(static_rf,fal,index);
  764.      when C_inside_new then
  765.         fal := stack_rf.item(top).arguments;
  766.         stack_args.item(top).compile_to_c_ith(fal,index);
  767.      when C_inline_dca then
  768.         rf := stack_rf.item(top);
  769.         target := stack_target.item(top);
  770.         args := stack_args.item(top);
  771.         static_rf := stack_static_rf.item(top);
  772.         top := top - 1;
  773.         if rf /= Void then
  774.            args.dca_inline_ith(rf.arguments,index);
  775.         else
  776.            -- No rf for "=" and "/=".
  777.            args.dca_inline_ith(static_rf.arguments,index);
  778.         end;
  779.         top := top + 1;
  780.         stack_code.put(code,top);
  781.         stack_rf.put(rf,top);
  782.         stack_target.put(target,top);
  783.         stack_args.put(args,top);
  784.         stack_static_rf.put(static_rf,top);
  785.      when C_same_target then
  786.         fal := stack_rf.item(top).arguments;
  787.         stack_args.item(top).compile_to_c_ith(fal,index);
  788.      when C_inline_one_pc then
  789.         print_argument(index);
  790.      when C_inside_twin then
  791.         check
  792.            index = 1
  793.         end;
  794.         if stack_rf.item(top).current_type.is_reference then
  795.            put_string("((T0*)C)");
  796.         else
  797.            put_string("*C");
  798.         end;
  799.      end;
  800.       end;
  801.    
  802. feature {NATIVE_SMALL_EIFFEL}
  803.  
  804.    put_c_inline_h is
  805.       local
  806.      c_code: MANIFEST_STRING;
  807.       do
  808.      c_code := get_inline_ms;
  809.      if c_inline_h_mem.has(c_code) then
  810.      else
  811.         c_inline_h_mem.add_last(c_code);
  812.         out_h.put_string(c_code.to_string);
  813.         out_h.put_character('%N');
  814.      end;
  815.       end;
  816.  
  817.    put_c_inline_c is
  818.       local
  819.      c_code: MANIFEST_STRING;
  820.       do
  821.      c_code := get_inline_ms;
  822.      out_c.put_string(c_code.to_string);
  823.       end;
  824.  
  825.    put_trace_switch is
  826.       do
  827.      if run_control.trace then
  828.         put_string("se_trace_flag=(");
  829.         put_ith_argument(1);
  830.         put_string(fz_14);
  831.      end;
  832.       end;
  833.  
  834. feature {NATIVE_SMALL_EIFFEL}
  835.  
  836.    put_generating_type(t: TYPE) is 
  837.       local
  838.      rc: RUN_CLASS;
  839.       do
  840.      generator_used := true;
  841.      generating_type_used := true;
  842.      put_string(fz_cast_t0_star);
  843.      put_character('(');
  844.      put_character('t');
  845.      put_character('[');
  846.      if t.is_reference then
  847.         rc := t.run_class;
  848.         if rc.is_tagged then
  849.            put_character('(');
  850.            put_target_as_value;
  851.            put_character(')');
  852.            put_string(fz_arrow_id);
  853.         else
  854.            put_integer(rc.id);
  855.         end;
  856.      else
  857.         put_integer(t.id);
  858.      end;
  859.      put_character(']');
  860.      put_character(')');
  861.       end;
  862.  
  863.    put_generator(t: TYPE) is 
  864.       require
  865.      t.is_run_type;
  866.       local
  867.      rc: RUN_CLASS;
  868.       do
  869.      generator_used := true;
  870.      put_string(fz_cast_t0_star);
  871.      put_character('(');
  872.      put_character('g');
  873.      put_character('[');
  874.      if t.is_reference then
  875.         rc := t.run_class;
  876.         if rc.is_tagged then
  877.            put_character('(');
  878.            put_target_as_value;
  879.            put_character(')');
  880.            put_string(fz_arrow_id);
  881.         else
  882.            put_integer(rc.id);
  883.         end;
  884.      else
  885.         put_integer(t.id);
  886.      end;
  887.      put_character(']');
  888.      put_character(')');
  889.       end;   
  890.    
  891.    put_to_pointer is 
  892.       do
  893.      put_string("((void*)");
  894.      put_target_as_value;
  895.      put_character(')');
  896.       end;
  897.  
  898.    put_object_size(t: TYPE) is 
  899.       require
  900.      t.is_run_type;
  901.       local
  902.      tcbd: BOOLEAN;
  903.       do
  904.      tcbd := target_cannot_be_dropped;
  905.      if tcbd then
  906.         out_c.put_character(',');
  907.      end;
  908.      out_c.put_string("sizeof(T");
  909.      out_c.put_integer(t.id);
  910.      out_c.put_character(')');
  911.      if tcbd then
  912.         out_c.put_character(')');
  913.      end;
  914.       end;   
  915.    
  916. feature {NONE}
  917.  
  918.    c_inline_h_mem: FIXED_ARRAY[MANIFEST_STRING] is
  919.       once
  920.      !!Result.with_capacity(4);
  921.       end;
  922.  
  923. feature {SMALL_EIFFEL}
  924.  
  925.    cecil_define is
  926.       local
  927.      save_out_h: like out_h;
  928.       do
  929.      cecil_pool.c_define_internals;
  930.      save_out_h := out_h;
  931.      cecil_pool.c_define_users;
  932.      out_h := save_out_h;
  933.       end;
  934.  
  935. feature {CECIL_POOL}
  936.  
  937.    connect_cecil_out_h(user_path_h: STRING) is
  938.       require
  939.      out_h = Void
  940.       do
  941.      !!out_h.make;
  942.      sfw_connect(out_h,user_path_h);
  943.       end;
  944.  
  945.    disconnect_cecil_out_h is
  946.       do
  947.      out_h.disconnect;
  948.       end;
  949.  
  950. feature {TYPE}
  951.    
  952.    to_reference(src, dest: TYPE) is
  953.      -- Put the name of the corresponding conversion 
  954.      -- fonction. Memorize arguments for later definition 
  955.      -- of the function.
  956.       require
  957.      small_eiffel.is_ready;
  958.      src.is_expanded;
  959.      dest.is_reference;
  960.       local
  961.      src_rc, dest_rc: RUN_CLASS;
  962.       do
  963.      src_rc := src.run_class;
  964.      dest_rc := dest.run_class;
  965.      check
  966.         src_rc.at_run_time;
  967.         dest_rc.at_run_time;
  968.      end;
  969.      if to_reference_mem = Void then
  970.         to_reference_mem := <<src_rc,dest_rc>>;
  971.      elseif not to_reference_mem.fast_has(src_rc) then
  972.         to_reference_mem.add_last(src_rc);
  973.         to_reference_mem.add_last(dest_rc);
  974.      end;
  975.      tmp_string.clear;
  976.      conversion_name(dest_rc.id);
  977.      put_string(tmp_string);
  978.       end;
  979.  
  980.    to_expanded(src, dest: TYPE) is
  981.      -- Put the name of the corresponding conversion 
  982.      -- fonction. Memorize arguments for later definition 
  983.      -- of the function.
  984.       require
  985.      small_eiffel.is_ready;
  986.      src.is_reference;
  987.      dest.is_expanded;
  988.       local
  989.      src_rc, dest_rc: RUN_CLASS;
  990.       do
  991.      src_rc := src.run_class;
  992.      dest_rc := dest.run_class;
  993.      check
  994.         src_rc.at_run_time;
  995.         dest_rc.at_run_time;
  996.      end;
  997.      if to_expanded_mem = Void then
  998.         to_expanded_mem := <<src_rc,dest_rc>>;
  999.      elseif not to_expanded_mem.fast_has(src_rc) then
  1000.         to_expanded_mem.add_last(src_rc);
  1001.         to_expanded_mem.add_last(dest_rc);
  1002.      end;
  1003.      tmp_string.clear;
  1004.      conversion_name(dest_rc.id);
  1005.      put_string(tmp_string);
  1006.       end;
  1007.    
  1008. feature {NONE} -- Automatic Type Conversion stuff :
  1009.    
  1010.    to_expanded_mem, to_reference_mem: ARRAY[RUN_CLASS];
  1011.       
  1012.    conversion_name(dest_id: INTEGER) is
  1013.       do
  1014.      tmp_string.append(fz_to_t);
  1015.      dest_id.append_in(tmp_string);
  1016.       end; 
  1017.    
  1018.    define_to_reference is 
  1019.       local
  1020.      i: INTEGER;
  1021.      src_rc, dest_rc: RUN_CLASS;
  1022.      src_type, dest_type: TYPE;
  1023.       do
  1024.      from
  1025.         i := 1;
  1026.      until
  1027.         i > to_reference_mem.upper
  1028.      loop
  1029.         src_rc := to_reference_mem.item(i);
  1030.         i := i + 1;
  1031.         dest_rc := to_reference_mem.item(i);
  1032.         i := i + 1;
  1033.         src_type := src_rc.current_type;
  1034.         dest_type := dest_rc.current_type;
  1035.         echo.put_string(msg2);
  1036.         echo.put_string(src_type.run_time_mark);
  1037.         echo.put_string(" to ");
  1038.         echo.put_string(dest_type.run_time_mark);
  1039.         echo.put_string(msg1);
  1040.         tmp_string.copy(fz_t0_star);
  1041.         conversion_name(dest_rc.id);
  1042.         tmp_string.extend('(');
  1043.         src_type.c_type_for_target_in(tmp_string);
  1044.         tmp_string.append(" s)");
  1045.         put_c_heading(tmp_string);
  1046.         swap_on_c;
  1047.         tmp_string.clear;
  1048.         dest_type.c_type_for_target_in(tmp_string);
  1049.         tmp_string.append("d;%Nd=((void*)malloc(sizeof(*d)));%N");
  1050.         if dest_rc.is_tagged then
  1051.            tmp_string.extend('d');
  1052.            tmp_string.append(fz_arrow_id);
  1053.            tmp_string.extend('=');
  1054.            dest_rc.id.append_in(tmp_string);
  1055.            tmp_string.extend(';');
  1056.         end;
  1057.         tmp_string.append("%Nd->_item=s;%Nreturn (T0*)d;}%N");
  1058.         out_c.put_string(tmp_string);
  1059.      end;
  1060.       end;
  1061.    
  1062.    define_to_expanded is 
  1063.       local
  1064.      i: INTEGER;
  1065.      src_rc, dest_rc: RUN_CLASS;
  1066.      src_type, dest_type: TYPE;
  1067.       do
  1068.      from
  1069.         i := 1;
  1070.      until
  1071.         i > to_expanded_mem.upper
  1072.      loop
  1073.         src_rc := to_expanded_mem.item(i);
  1074.         i := i + 1;
  1075.         dest_rc := to_expanded_mem.item(i);
  1076.         i := i + 1;
  1077.         src_type := src_rc.current_type;
  1078.         dest_type := dest_rc.current_type;
  1079.         echo.put_string(msg2);
  1080.         echo.put_string(src_type.run_time_mark);
  1081.         echo.put_string(" to ");
  1082.         echo.put_string(dest_type.run_time_mark);
  1083.         echo.put_string(msg1);
  1084.         tmp_string.clear;
  1085.         dest_type.c_type_for_result_in(tmp_string);
  1086.         tmp_string.extend(' ');
  1087.         conversion_name(dest_rc.id);
  1088.         tmp_string.append("(T0*s)");
  1089.         out_h.put_string(tmp_string);
  1090.         out_h.put_string(fz_00);
  1091.         out_c.put_string(tmp_string);
  1092.         tmp_string.copy(fz_11);
  1093.  
  1094.         -- NYI ...
  1095.  
  1096.         tmp_string.append(fz_12);
  1097.         out_c.put_string(tmp_string);
  1098.      end;
  1099.       end;
  1100.    
  1101. feature {NONE}
  1102.    
  1103.    push_void(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1104.       require
  1105.      rf /= Void;
  1106.      t /= Void
  1107.       do
  1108.      error_void_or_bad_type(t);
  1109.      push_direct(rf,t,args);
  1110.      sure_void_count := sure_void_count + 1;
  1111.       end;
  1112.    
  1113. feature {CECIL_POOL,RUN_FEATURE}
  1114.  
  1115.    push_direct(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1116.       require
  1117.      rf /= Void;
  1118.      t /= Void
  1119.       do
  1120.      stack_push(C_direct_call);
  1121.      stack_rf.put(rf,top);
  1122.      stack_target.put(t,top);
  1123.      stack_args.put(args,top);
  1124.      direct_call_count := direct_call_count + 1;
  1125.       end;
  1126.  
  1127. feature {RUN_FEATURE_3}
  1128.  
  1129.    push_inline_one_pc is
  1130.       do
  1131.      stack_push(C_inline_one_pc);
  1132.       end;
  1133.  
  1134. feature {RUN_FEATURE_3,RUN_FEATURE_4}
  1135.    
  1136.    push_inline_dca(relay_rf: RUN_FEATURE; dpca: CALL_PROC_CALL) is
  1137.       -- Where `dpca' is inside `relay_rf'.
  1138.       require
  1139.      relay_rf /= Void;
  1140.      dpca /= Void
  1141.       do
  1142.      stack_push(C_inline_dca);
  1143.      stack_rf.put(dpca.run_feature,top);
  1144.      stack_static_rf.put(relay_rf,top);
  1145.      stack_target.put(dpca.target,top);
  1146.      stack_args.put(dpca.arguments,top);
  1147.      direct_call_count := direct_call_count + 1;
  1148.       end;
  1149.  
  1150.    push_same_target(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  1151.       require
  1152.      rf /= Void
  1153.       do
  1154.      stack_push(C_same_target);
  1155.      stack_rf.put(rf,top);
  1156.      stack_args.put(args,top);
  1157.       end;
  1158.    
  1159. feature {CECIL_POOL}
  1160.  
  1161.    push_cpc(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]; 
  1162.         t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1163.       local
  1164.      dyn_rf: RUN_FEATURE;
  1165.       do
  1166.      if r = Void then
  1167.         push_void(up_rf,t,args);
  1168.         up_rf.mapping_c;
  1169.         pop;
  1170.      elseif r.count = 1 then
  1171.         dyn_rf := r.first.dynamic(up_rf);
  1172.         push_check(dyn_rf,t,args);
  1173.         dyn_rf.mapping_c;
  1174.         pop;
  1175.      else
  1176.         use_switch(up_rf,r,t,args);
  1177.      end;
  1178.       end;
  1179.  
  1180. feature {NONE}
  1181.    
  1182.    push_check(rf: RUN_FEATURE; t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1183.       require
  1184.      rf /= Void;
  1185.      t /= Void;
  1186.       do
  1187.      stack_push(C_check_id);
  1188.      stack_rf.put(rf,top);
  1189.      stack_target.put(t,top);
  1190.      stack_args.put(args,top);
  1191.       end;
  1192.    
  1193. feature {SWITCH}
  1194.    
  1195.    push_switch(rf, static_rf: RUN_FEATURE) is
  1196.       require
  1197.      rf /= Void;
  1198.      static_rf /= Void;
  1199.      rf.run_class.dynamic(static_rf) = rf
  1200.       do
  1201.      stack_push(C_switch);
  1202.      stack_rf.put(rf,top);
  1203.      stack_static_rf.put(static_rf,top);
  1204.      stack_args.put(Void,top); -- *** ?????? ****
  1205.       end;
  1206.       
  1207. feature {NONE}
  1208.  
  1209.    expanded_initializer(t: TYPE; a: RUN_FEATURE) is
  1210.      -- ***** CHANGE THIS ******
  1211.      -- Call the expanded initializer for type `t' if any.
  1212.      -- The result is assigned in writable `w' or to attribute 
  1213.      -- `a' of the brand new created object in "n".
  1214.       require 
  1215.      t.is_expanded;
  1216.      a /= Void
  1217.       local
  1218.      rf: RUN_FEATURE;
  1219.       do
  1220.      rf := t.expanded_initializer;
  1221.      if rf /= Void then
  1222.         stack_push(C_expanded_initialize);
  1223.         stack_target.put(Void,top);
  1224.         stack_rf.put(a,top);
  1225.         direct_call_count := direct_call_count + 1;
  1226.         rf.mapping_c;
  1227.         pop;
  1228. --***        if call_invariant_start(rf.current_type) then
  1229. --***           put_character('&');
  1230. --***           w.compile_to_c;
  1231. --***           call_invariant_end;
  1232. --***           put_string(fz_00);
  1233. --***        end;
  1234.      end;
  1235.       end;
  1236.  
  1237. feature {CREATION_CALL_3_4,LOCAL_VAR_LIST}
  1238.  
  1239.    expanded_writable(rf3: RUN_FEATURE_3; writable: EXPRESSION) is
  1240.      -- Call the expanded initializer `rf3' using `writable'
  1241.      -- as target.
  1242.       require 
  1243.      rf3.current_type.is_expanded;
  1244.      writable /= Void 
  1245.       do
  1246.      stack_push(C_expanded_initialize);
  1247.      stack_target.put(writable,top);
  1248.      stack_rf.put(Void,top); -- *** UNNEEDED ???
  1249.      direct_call_count := direct_call_count + 1;
  1250.      rf3.mapping_c;
  1251.      pop;
  1252.      if call_invariant_start(rf3.current_type) then
  1253.         put_character('&');
  1254.         writable.compile_to_c;
  1255.         call_invariant_end;
  1256.         put_string(fz_00);
  1257.      end;
  1258.       end;
  1259.  
  1260. feature {CREATION_CALL}   
  1261.    
  1262.    push_new(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
  1263.       --    *************** 3 ???
  1264.       require
  1265.      rf /= Void;
  1266.       do
  1267.      stack_push(C_inside_new);
  1268.      stack_rf.put(rf,top);
  1269.      stack_args.put(args,top);
  1270.      direct_call_count := direct_call_count + 1;
  1271.       end;
  1272.  
  1273. feature {NATIVE}
  1274.  
  1275.    inside_twin(cpy: RUN_FEATURE) is
  1276.       do
  1277.      stack_push(C_inside_twin);
  1278.      stack_rf.put(cpy,top);
  1279.      cpy.mapping_c;
  1280.      pop;
  1281.       end;
  1282.    
  1283. feature {NONE}
  1284.    
  1285.    use_switch(up_rf: RUN_FEATURE; r: ARRAY[RUN_CLASS]; 
  1286.           t: EXPRESSION; args: EFFECTIVE_ARG_LIST) is
  1287.       require
  1288.      up_rf /= Void;
  1289.      r.count > 1
  1290.      t /= Void;
  1291.      on_c;
  1292.       local
  1293.      rt, target_type: TYPE;
  1294.      rc: RUN_CLASS;
  1295.      rf: RUN_FEATURE;
  1296.      switch: SWITCH;
  1297.       do
  1298.      if run_control.boost and then 
  1299.         stupid_switch(up_rf) 
  1300.       then
  1301.         direct_call_count := direct_call_count + 1;
  1302.         switch_collection.remove(up_rf);
  1303.         put_string(fz_open_c_comment);
  1304.         put_character('X');
  1305.         put_integer(up_rf.current_type.id);
  1306.         put_string(fz_close_c_comment);
  1307.         rt := up_rf.result_type;
  1308.         if rt /= Void then
  1309.            tmp_string.copy(fz_17);
  1310.            rt.c_type_for_result_in(tmp_string);
  1311.            tmp_string.extend(')');
  1312.            put_string(tmp_string);
  1313.         end;
  1314.         rc := r.item(1);
  1315.         rf := rc.dynamic(up_rf);
  1316.         push_direct(rf,t,args);
  1317.         rf.mapping_c;
  1318.         pop;
  1319.         if rt /= Void then
  1320.            put_character(')');
  1321.         end;
  1322.      else
  1323.         switch_count := switch_count + 1;
  1324.         out_c.put_string(switch.name(up_rf));
  1325.         out_c.put_character('(');
  1326.         if run_control.no_check then
  1327.            put_position(t.start_position)
  1328.            out_c.put_character(',');
  1329.         end;
  1330.         t.compile_to_c;
  1331.         if args /= Void then
  1332.            out_c.put_character(',');
  1333.            args.compile_to_c(up_rf.arguments);
  1334.         end;
  1335.         put_character(')');
  1336.         if up_rf.result_type = Void then
  1337.            out_c.put_string(fz_00);
  1338.         end;
  1339.      end;
  1340.       end;
  1341.    
  1342. feature {E_FEATURE}
  1343.  
  1344.    stupid_switch(up_rf: RUN_FEATURE): BOOLEAN is
  1345.       require
  1346.      small_eiffel.is_ready;
  1347.      up_rf.run_class.running /= Void
  1348.       local
  1349.      r: ARRAY[RUN_CLASS];
  1350.      i: INTEGER;
  1351.      f1, f2: E_FEATURE;
  1352.      rc: RUN_CLASS;
  1353.       do
  1354.      from
  1355.         r := up_rf.run_class.running;
  1356.         Result := true;
  1357.         i := r.upper;
  1358.         f1 := up_rf.base_feature;
  1359.      until
  1360.         not Result or else i = 0
  1361.      loop
  1362.         rc := r.item(i);
  1363.         f2 := rc.dynamic(up_rf).base_feature;
  1364.         Result := f1 = f2;
  1365.         i := i - 1;
  1366.      end;
  1367.      if Result then
  1368.         Result := f1.stupid_switch(up_rf,r);
  1369.      end;
  1370.       end;
  1371.  
  1372. feature  -- Handling errors at run time :
  1373.    
  1374.    put_error0(msg: STRING) is
  1375.      -- Print `msg' and then stop execution. 
  1376.      -- Also print stack when not -boost.
  1377.       do
  1378.      put_string("error0(");
  1379.      put_string_c(msg);
  1380.      put_string(fz_14);
  1381.       end;
  1382.  
  1383.    put_error1(msg: STRING; p: POSITION) is
  1384.      -- Print `msg' for position `p' and then stop execution. 
  1385.      -- Also print stack when not -boost.
  1386.       do
  1387.      put_string("error1(");
  1388.      put_string_c(msg);
  1389.      put_character(',');
  1390.      put_position(p)
  1391.      put_string(fz_14);
  1392.       end;
  1393.    
  1394.    put_comment(str: STRING) is
  1395.       do
  1396.      put_string(fz_open_c_comment);
  1397.      put_string(str);
  1398.      put_string(fz_close_c_comment);
  1399.       end;
  1400.  
  1401.    put_comment_line(str: STRING) is
  1402.       do
  1403.      put_character('%N');
  1404.      put_comment(str);
  1405.      put_character('%N');
  1406.       end;
  1407.  
  1408.    define_main(rf3: RUN_FEATURE_3) is
  1409.       local
  1410.      id: INTEGER;
  1411.      rc: RUN_CLASS;
  1412.      ct: TYPE;
  1413.       do
  1414.      echo.put_string("Define main function.%N");
  1415.      ct := rf3.current_type;
  1416.      id := ct.id;
  1417.      rc := rf3.run_class;
  1418.      swap_on_c;
  1419.      split_c_now;
  1420.      put_extern1("int se_argc");
  1421.      put_extern1("char**se_argv");
  1422.      if run_control.trace then
  1423.         put_extern1("FILE *se_trace_file");
  1424.         put_extern2("int se_trace_flag",'0');
  1425.      end;
  1426.      if vms_system = system_name then
  1427.         put_string(fz_void);
  1428.      else
  1429.         put_string(fz_int);
  1430.      end;
  1431.      put_string(" main(int argc,char*argv[]){%N");
  1432.      if gc_handler.is_on then
  1433.         gc_handler.initialize;
  1434.      end;
  1435.      put_string("se_initialize();%N{%N");
  1436.      if gc_handler.is_on then
  1437.         put_string("jmp_buf env;%N");
  1438.      end;
  1439.      gc_handler.put_new(rc);
  1440.      if gc_handler.is_on then
  1441.         put_string("(void)setjmp(env);%N%
  1442.                %gc_root_main=((void**)(&env));%N");
  1443.      end;
  1444.      put_string(
  1445.             "se_argc=argc; se_argv=argv;%N%
  1446.         %#ifdef SIGINT%Nsignal(SIGINT,sigrsp);%N#endif%N%
  1447.         %#ifdef SIGQUIT%Nsignal(SIGQUIT,sigrsp);%N#endif%N%
  1448.         %#ifdef SIGTERM%Nsignal(SIGTERM,sigrsp);%N#endif%N%
  1449.         %#ifdef SIGBREAK%Nsignal(SIGBREAK,sigrsp);%N#endif%N%
  1450.         %#ifdef SIGKILL%Nsignal(SIGKILL,sigrsp);%N#endif%N");
  1451.      manifest_string_pool.c_call_initialize;
  1452.      if run_control.no_check then
  1453.         put_string(
  1454.            "#define rs_isz 4096%N%
  1455.            %rs_bot=(void*)malloc(rs_isz*sizeof(double));%N%
  1456.            %rs=rs_bot;%N%
  1457.            %rs_top=rs_bot+(rs_isz-1);%N%
  1458.            %rs_lb=rs_bot;%N");
  1459.      end;
  1460.      expanded_attributes(ct);
  1461.      if sprintf_double_flag then
  1462.         put_string("_spfd=malloc(32);%N%
  1463.                %_spfd[0]='%%';%N%
  1464.                %_spfd[1]='.';%N");
  1465.      end;
  1466.      once_pre_computing;
  1467.      if run_control.trace then
  1468.         put_string(
  1469.             "printf(%"Writing \%"trace.se\%" file.\n%");%N%
  1470.         %se_trace_file=fopen(%"trace.se%",%"w%");%N%
  1471.             %se_trace_flag=1;%N");
  1472.      end;
  1473.      push_new(rf3,Void);
  1474.      rf3.mapping_c;
  1475.      pop;
  1476.      if run_control.invariant_check then
  1477.         if rc.invariant_assertion /= Void then
  1478.            put_character('i');
  1479.            put_integer(id);
  1480.            put_character('(');
  1481.            put_character('n');
  1482.            put_character(')');
  1483.            put_string(fz_00);
  1484.         end;
  1485.      end;
  1486.      if run_control.no_check then
  1487.         put_string(
  1488.                "if (rs != rs_bot){%N%
  1489.            %printf(%"\n***Internal SmallEiffel Stack Error.\n%");%N%
  1490.            %rsp();}");
  1491.      end;
  1492.      if gc_handler.info_flag then
  1493.         put_string(fz_gc_info);
  1494.         put_string(fz_c_no_args_procedure);
  1495.      end;
  1496.      put_string("exit(0);}}%N");
  1497.      incr_elt_c_count(10);
  1498.      echo.put_string("Symbols used: ");
  1499.      echo.put_integer(unique_string.count);
  1500.      echo.put_string(fz_b6);
  1501.      manifest_string_pool.c_define;
  1502.       end;
  1503.  
  1504.    define_used_basics is
  1505.      -- Produce C code only when used.
  1506.       local
  1507.      no_check: BOOLEAN;
  1508.       do
  1509.      no_check := run_control.no_check;
  1510.      echo.put_string("Define used basics.%N");
  1511.      if sprintf_double_flag then
  1512.         put_extern1("char*_spfd");
  1513.      end;
  1514.      if small_eiffel.string_at_run_time then
  1515.         manifest_string_pool.define_se_ms;
  1516.      end;
  1517.      manifest_array_pool.c_define;
  1518.      if no_check then
  1519.         put_c_function("void rsp(void)",
  1520.           "if(se_rspf)return;se_rspf=1;%N%
  1521.                %printf(%"Eiffel program crash at run time.\n%");%N%
  1522.            %printf(%"Final Run Stack :\n%");%N%
  1523.            %{double*sp=(rs_bot-1);%N%
  1524.            %while (1) {se_af=1;%N%
  1525.            %sp++;%N%
  1526.            %if (sp >= rs) break;%N%
  1527.            %if (sp > rs_top) break;%N%
  1528.            %switch (*((int*)sp++)){%N%
  1529.            %case LINKid: continue;%N%
  1530.            %case FTAGid:{%N%
  1531.            %printf(%"=====================================%
  1532.            %=========================\n%");%N%
  1533.            %printf(%"------ %%s\n%",*((char**)sp));%N%
  1534.            %continue;}%N%
  1535.            %case NAMEid:{%N%
  1536.            %printf(%"%%s = %",*((char**)sp));%N%
  1537.            %continue;}%N%
  1538.            %case POINTERid:{%N%
  1539.            %printf(%"External POINTER `%%p'.\n%",**(void***)sp);%N%
  1540.                %continue;}%N%
  1541.            %case BITid:{%N%
  1542.            %printf(%"BIT_N\n%");%N%
  1543.                %continue;}%N%
  1544.            %case REFid:{void*o=(**(T0***)sp);%N%
  1545.            %if (o) {se_print(o,o); printf(%"\n%");}%N%
  1546.            %else printf(%"Void\n%");continue;}%N%
  1547.            %case expandedid:{%N%
  1548.            %printf(%"expanded object\n%");continue;}%N%
  1549.            %case INTEGERid:{%N%
  1550.            %printf(%"%%d\n%",**(int**)sp);continue;}%N%
  1551.            %case CHARACTERid:{%N%
  1552.            %printf(%"'%%c'\n%",**(char**)sp);continue;}%N%
  1553.            %case BOOLEANid:{%N%
  1554.            %if (**(int**)sp) printf(%"true\n%");%N%
  1555.            %else printf(%"false\n%");continue;}%N%
  1556.            %case REALid:{%N%
  1557.            %printf(%"%%f\n%",(double)**(float**)sp);%N%
  1558.            %continue;}%N%
  1559.            %case DOUBLEid:{%N%
  1560.            %printf(%"%%f\n%",**(double**)sp);continue;}%N%
  1561.            %case LINEid:{%N%
  1562.            %printf(%"line %%d %",*(int*)sp);%N%
  1563.            %continue;}%N%
  1564.            %case COLUMNid:{%N%
  1565.            %printf(%"column %%d %",*(int*)sp);%N%
  1566.            %continue;}%N%
  1567.            %case PATHid:{%N%
  1568.            %printf(%"file %%s %",p[*(int*)sp]);%N%
  1569.            %continue;}%N%
  1570.            %case DOINGid:{%N%
  1571.            %printf(%"(%%s)\n%",*(char**)sp);continue;}%N%
  1572.            %case INVid:{%N%
  1573.            %printf(%"Class Invariant of %%s\n%",*(char**)sp);%N%
  1574.            %continue;}%N%
  1575.            %default:{%N% 
  1576.            %printf(%"Stack Damaged ... Sorry.\n%");%N%
  1577.            %exit(1);}}}%N%
  1578.            %printf(%"===================== End of Run Stack %
  1579.            %==========================\n\n%");se_af=0;se_rspf=0;%N}");
  1580.      else
  1581.         put_c_function("void rsp(void)",
  1582.            "printf(%"Eiffel program crash at run time.\n%");%N%
  1583.            %printf(%"No trace when using option \%"-boost\%"\n%");");
  1584.      end;
  1585.      if no_check then 
  1586.         put_c_function("void error0(char*m)",
  1587.            "rsp();%N%
  1588.            %printf(%"*** Error at Run Time *** : %%s\n%",m);%N%
  1589.            %if(!se_rspf)exit(1);");
  1590.         put_c_function("void error1(char*m,int l,int c,int f)",
  1591.            "rsp();%N%
  1592.            %printf(%"Line : %%d column %%d in %%s.\n%",%
  1593.            %l,c,p[f]);%N%
  1594.            %printf(%"*** Error at Run Time *** : %%s\n%",m);%N%
  1595.            %if(!se_rspf)exit(1);");
  1596.         put_c_function("void error2(T0*o,int l,int c,int f)",
  1597.            "printf(%"Target Type %%s not legal.\n%",s2e(t[o->id]));%N%
  1598.            %error1(%"Bad target.%",l,c,f);");
  1599.         put_c_function("T0*vc(void*o,int l,int c,int f)",
  1600.            "if (!o) error1(%"Call with a Void target.%",l,c,f);%N%
  1601.            %return o;");
  1602.         put_c_function("T0*ci(int id,void*o,int l,int c,int f)",
  1603.            "if (id == (vc(o,l,c,f)->id)) return o;%N%
  1604.            %rsp();%N%
  1605.            %printf(%"Line : %%d column %%d in %%s.\n%",%
  1606.            %l,c,p[f]);%N%
  1607.            %printf(%"*** Error at Run Time *** : %");%N%
  1608.            %printf(%"Target is not valid (not the good type).\n%");%N%
  1609.            %printf(%"Expected :%%s, Actual :%%s.\n%",%N%
  1610.            %s2e(t[id]),s2e(t[((T0*)o)->id]));%N%
  1611.            %if(!se_rspf)exit(1);");
  1612.         put_c_function("void evobt(void*o,int l,int c,int f)",
  1613.            "if (!o) error1(%"Target is Void.%",l,c,f);%N%
  1614.            %else error2(o,l,c,f);");
  1615.      end;
  1616.      put_c_function("void sigrsp(int sig)",
  1617.         "printf(%"Received signal %%d (man signal).\n%",sig);%N%
  1618.             %rsp();%N%
  1619.         %exit(1);");
  1620.      switch_collection.c_define;
  1621.      if to_expanded_mem /= Void then   
  1622.         define_to_expanded;
  1623.      end;
  1624.      if to_reference_mem /= Void then   
  1625.         define_to_reference;
  1626.      end;
  1627.      if sure_void_count > 0 then
  1628.         echo.put_string("Calls with a Void target : ");
  1629.         echo.put_integer(sure_void_count);
  1630.         echo.put_string(" (yes it is dangerous).%N");
  1631.      end;
  1632.      echo.print_count("Direct Call",direct_call_count);
  1633.      echo.print_count("Check Id Call",check_id_count);
  1634.      echo.print_count("Switched Call",switch_count);
  1635.      echo.print_count("Inlined Procedure",inlined_procedure_count);
  1636.      echo.print_count("Inlined Function",inlined_function_count);
  1637.      echo.print_count("Static Expression",static_expression_count);
  1638.      echo.print_count("Real Procedure",real_procedure_count);
  1639.      echo.print_count("Real Function",real_function_count);
  1640.      echo.print_count("Procedure",procedure_count);
  1641.      echo.print_count("Function",function_count);
  1642.      if pre_computed_once /= Void then
  1643.         echo.print_count("Pre-Computed Once Function Call",
  1644.                  pre_computed_once.count);
  1645.      end;
  1646.      echo.put_string("Internal stacks size used : ");
  1647.      echo.put_integer(stack_code.count);
  1648.      echo.put_character('%N');
  1649.      define_initialize;
  1650.       end;
  1651.  
  1652. feature {NONE}
  1653.    
  1654.    define_is_equal_prototype(id: INTEGER) is
  1655.       do
  1656.      tmp_string.copy(fz_int);
  1657.      tmp_string.extend(' ');
  1658.      tmp_string.extend('r');
  1659.      (id).append_in(tmp_string);
  1660.      tmp_string.append(us_is_equal);
  1661.      tmp_string.append("(T");
  1662.      (id).append_in(tmp_string);
  1663.      tmp_string.append("*C, T0*a1)");
  1664.      out_h.put_string(tmp_string);
  1665.      out_c.put_string(tmp_string);
  1666.       end;
  1667.  
  1668. feature 
  1669.    
  1670.    trace_boolean_expression(e: EXPRESSION) is
  1671.      -- Produce a C boolean expression including trace code.
  1672.       require
  1673.      e.result_type.is_boolean;
  1674.      run_control.no_check;
  1675.       do
  1676.      rs_push_position('2',e.start_position);
  1677.      put_string(",rs_pop_int(");
  1678.      e.compile_to_c;
  1679.      put_character(')');
  1680.       end;
  1681.    
  1682. feature {ASSERTION}
  1683.    
  1684.    check_assertion(e: EXPRESSION) is
  1685.      -- Produce a C boolean expression including trace code
  1686.      -- and assertion check.
  1687.       require
  1688.      e.result_type.is_boolean
  1689.       local
  1690.      static: BOOLEAN;
  1691.       do
  1692.      static := e.is_static; 
  1693.      if not static or else e.static_value = 0 then
  1694.         rs_push_position('4',e.start_position);
  1695.         put_string("ac_");
  1696.         put_string(check_assertion_mode);
  1697.         put_character('(');
  1698.         if static then
  1699.            static_expression_count := static_expression_count + 1;
  1700.            put_character('0');
  1701.         else
  1702.            e.compile_to_c;
  1703.         end;
  1704.         put_string(fz_14);
  1705.      end;
  1706.       end;
  1707.    
  1708. feature {NONE}
  1709.    
  1710.    check_assertion_mode: STRING;
  1711.  
  1712. feature {ASSERTION_LIST}
  1713.    
  1714.    set_check_assertion_mode(s: STRING) is
  1715.       require
  1716.      s /= Void
  1717.       do
  1718.      check_assertion_mode := s;
  1719.       ensure
  1720.      check_assertion_mode = s
  1721.       end;   
  1722.    
  1723. feature {NONE}
  1724.    
  1725.    error_void_or_bad_type(e: EXPRESSION) is
  1726.       require
  1727.      e /= Void;
  1728.      e.result_type.is_run_type;
  1729.       do
  1730.      eh.add_position(e.start_position);
  1731.      eh.append("Call on a Void or a bad target. Dynamic ");
  1732.      eh.add_type(e.result_type.run_type," is concerned. ")
  1733.      eh.print_as_warning;
  1734.      if run_control.boost then
  1735.         put_string("(rsp();exit(1);)");
  1736.      else
  1737.         put_string("evobt(");
  1738.         e.compile_to_c;
  1739.         put_character(',');
  1740.         put_position(e.start_position);
  1741.         put_character(')');
  1742.      end;
  1743.       end;
  1744.    
  1745. feature {RUN_FEATURE} -- Run stack link/push/unlink :
  1746.    
  1747.    rs_link(rf: RUN_FEATURE) is
  1748.       do
  1749.      put_string("rs_link(");
  1750.      rf.put_tag;     
  1751.      put_string(fz_14);
  1752.       end;
  1753.    
  1754.    rs_unlink is
  1755.       do
  1756.      put_string("rs_unlink();%N");
  1757.       end;
  1758.    
  1759.    rs_push_current(t: TYPE) is
  1760.       require
  1761.      t.run_type = t;
  1762.       do
  1763.      rs_push(us_current,"C",t);
  1764.       end;
  1765.    
  1766.    rs_push_result(t: TYPE) is
  1767.       require
  1768.      t.run_type = t;
  1769.       do
  1770.      rs_push(us_result,"R",t);
  1771.       end;
  1772.    
  1773.    rs_push_argument(src_name: STRING; rank: INTEGER; t: TYPE) is
  1774.       require
  1775.      src_name /= Void;
  1776.      t.run_type = t;
  1777.      rank > 0;
  1778.       do
  1779.      tmp_string.clear;
  1780.      tmp_string.extend('a');
  1781.      rank.append_in(tmp_string);
  1782.      rs_push(src_name,tmp_string,t);
  1783.       end;
  1784.  
  1785. feature {LOCAL_NAME1}
  1786.    
  1787.    rs_push_local(src_name: STRING; t: TYPE) is
  1788.       require
  1789.      src_name /= Void;
  1790.      t.run_type = t;
  1791.       do
  1792.      tmp_string.clear;
  1793.      tmp_string.extend('_');
  1794.      tmp_string.append(src_name);
  1795.      rs_push(src_name,tmp_string,t);
  1796.       end;
  1797.    
  1798. feature {INSTRUCTION,IFTHEN}
  1799.    
  1800.    rs_push_position(msg_nb: CHARACTER; p: POSITION) is
  1801.       do
  1802.      if run_control.no_check then
  1803.         put_string("rs_pPOS(tag_pos_");
  1804.         put_character(msg_nb);
  1805.         put_character(',');
  1806.         put_position(p);
  1807.         put_character(')');
  1808.         if msg_nb /= '2' then
  1809.            put_string(fz_00);
  1810.         end;
  1811.      end;
  1812.       end;
  1813.    
  1814.    rs_pop_position is
  1815.       do
  1816.      if run_control.no_check then
  1817.         put_string("rs-=8;%N");
  1818.      end;
  1819.       end;
  1820.          
  1821. feature  -- Numbering of inspect variables :
  1822.    
  1823.    inspect_incr is
  1824.       do
  1825.      inspect_level := inspect_level + 1;
  1826.       end;
  1827.    
  1828.    inspect_decr is
  1829.       do
  1830.      inspect_level := inspect_level - 1;
  1831.       end;
  1832.  
  1833.    put_inspect is
  1834.       do
  1835.      put_character('z');
  1836.      put_integer(inspect_level);
  1837.       end;
  1838.  
  1839. feature {NONE}
  1840.    
  1841.    inspect_level: INTEGER;
  1842.  
  1843. feature -- Printing Current, local or argument :
  1844.  
  1845.    inline_level_incr is
  1846.       do
  1847.      inline_level := inline_level + 1;
  1848.       end;
  1849.  
  1850.    inline_level_decr is
  1851.       do
  1852.      inline_level := inline_level - 1;
  1853.       end;
  1854.  
  1855.    print_current is
  1856.       local
  1857.      level: INTEGER;
  1858.       do
  1859.      put_character('C');
  1860.      level := inline_level;
  1861.      if level > 0 then
  1862.         put_integer(level);
  1863.      end;
  1864.       end;
  1865.  
  1866.    print_argument(rank: INTEGER) is
  1867.       local
  1868.      code: INTEGER;
  1869.       do
  1870.      code := ('a').code + inline_level;
  1871.      put_character(code.to_character);
  1872.      put_integer(rank);
  1873.       end;
  1874.  
  1875.    print_local(name: STRING) is
  1876.       local
  1877.      level: INTEGER;
  1878.       do
  1879.      from
  1880.         level := inline_level + 1;
  1881.      until
  1882.         level = 0
  1883.      loop
  1884.         put_character('_');
  1885.         level := level - 1;
  1886.      end;
  1887.      put_string(name);
  1888.       end;
  1889.  
  1890. feature {NONE}
  1891.    
  1892.    inline_level: INTEGER;
  1893.    
  1894. feature {NONE}
  1895.  
  1896.    check_id(e: EXPRESSION; id: INTEGER) is
  1897.      -- Produce a C expression checking that `e' is not void and 
  1898.      -- that `e' is really of type `id'.
  1899.      -- The result of the C expression is the pointer to the
  1900.      -- corresponding Object.
  1901.       require
  1902.      e.result_type.run_type.is_reference;
  1903.      id > 0;
  1904.       do
  1905.      if run_control.no_check then
  1906.         put_character('(');
  1907.         put_character('(');
  1908.         put_character('T');
  1909.         put_integer(id);
  1910.         put_string("*)ci(");
  1911.         put_integer(id);
  1912.         put_character(',');
  1913.         e.compile_to_c;
  1914.         put_character(',');
  1915.         put_position(e.start_position);
  1916.         put_string(fz_13);
  1917.         check_id_count := check_id_count + 1;
  1918.      else
  1919.         e.compile_to_c;
  1920.         direct_call_count := direct_call_count + 1;
  1921.      end;
  1922.       end;
  1923.    
  1924.    same_base_feature(r: ARRAY[RUN_CLASS]; up_rf: RUN_FEATURE): BOOLEAN is 
  1925.       -- True if all have the same final name and the same base_feature.
  1926.       require
  1927.      not r.empty;
  1928.      up_rf /= Void
  1929.       local
  1930.      i: INTEGER;
  1931.      up_bf, bf: E_FEATURE;
  1932.      up_name, name: FEATURE_NAME;
  1933.      rf: RUN_FEATURE;
  1934.       do
  1935.      from
  1936.         up_bf := up_rf.base_feature;
  1937.         up_name := up_rf.name;
  1938.         i := r.lower;
  1939.         Result := true;
  1940.      until
  1941.         not Result or else i > r.upper
  1942.      loop
  1943.         rf := r.item(i).dynamic(up_rf);
  1944.         bf := rf.base_feature;
  1945.         name := rf.name;
  1946.         Result := name.is_equal(up_name) and then bf = up_bf;
  1947.         i := i + 1;
  1948.      end;
  1949.       end;
  1950.  
  1951. feature {SMALL_EIFFEL}
  1952.  
  1953.    generating_type_used: BOOLEAN;
  1954.    
  1955.    generator_used: BOOLEAN;
  1956.    
  1957. feature {E_LOOP}
  1958.    
  1959.    variant_check(e: EXPRESSION) is
  1960.       do
  1961.      rs_push_position('6',e.start_position);
  1962.      put_string("v=lvc(c++,v,");
  1963.      e.compile_to_c;
  1964.      put_string(fz_14);
  1965.       end;
  1966.    
  1967. feature {NONE}
  1968.    
  1969.    rs_push(src_name, c_name: STRING; t: TYPE) is
  1970.       require
  1971.      src_name /= Void;
  1972.      c_name /= Void;
  1973.      t.run_type = t;
  1974.      run_control.no_check
  1975.       local
  1976.      str: STRING;
  1977.       do
  1978.      put_string("rs_p")
  1979.      if t.is_reference then
  1980.         put_string("REF((void**)");
  1981.      else
  1982.         if t.is_basic_eiffel_expanded then
  1983.            str := t.written_mark;
  1984.            put_character(str.item(1));
  1985.            put_character(str.item(2));
  1986.            put_character(str.item(3));
  1987.         elseif t.is_bit then
  1988.            put_string("BIT");
  1989.         else 
  1990.            put_string("EXP");
  1991.         end;
  1992.         put_character('(');
  1993.      end;
  1994.      put_character('&');
  1995.      put_string(c_name);
  1996.      put_character(',');
  1997.      if src_name = us_current then
  1998.         put_string(us_current);
  1999.      elseif src_name = us_result then
  2000.         put_string(us_result);
  2001.      else
  2002.         put_string_c(src_name);
  2003.      end;
  2004.      put_string(fz_14);
  2005.       end;
  2006.    
  2007. feature {NONE}
  2008.    
  2009.    tmp_string: STRING is
  2010.       once
  2011.      !!Result.make(256);
  2012.       end;
  2013.    
  2014.    tmp_string2: STRING is
  2015.       once
  2016.      !!Result.make(128);
  2017.       end;
  2018.    
  2019.    tmp_string3: STRING is
  2020.       once
  2021.      !!Result.make(128);
  2022.       end;
  2023.    
  2024. feature {NONE}
  2025.    
  2026.    once_pre_computing is
  2027.       local
  2028.      i: INTEGER;
  2029.      of_array: ARRAY[E_FEATURE];
  2030.      rf6: RUN_FEATURE_6;
  2031.      of: ONCE_FUNCTION;
  2032.       do
  2033.      if pre_computed_once /= Void then
  2034.         echo.put_string(fz_04);
  2035.         echo.put_string(fz_05);
  2036.         from  
  2037.            i := pre_computed_once.upper;
  2038.            !!of_array.with_capacity(1 + i // 2,1);
  2039.         until
  2040.            i = 0
  2041.         loop
  2042.            rf6 := pre_computed_once.item(i);
  2043.            of := rf6.base_feature;
  2044.            if not of_array.fast_has(of) then
  2045.           of_array.add_last(of);
  2046.           rf6.c_pre_computing;
  2047.            end;
  2048.            i := i - 1;
  2049.         end;
  2050.         echo.print_count(fz_04,of_array.count);
  2051.      end;
  2052.       end;
  2053.    
  2054. feature {NONE}
  2055.    
  2056.    need_invariant(target_type: TYPE): RUN_CLASS is
  2057.      -- Give the good RUN_CLASS when `target_type' need some 
  2058.      -- class invariant checking.
  2059.       require
  2060.      target_type.is_run_type
  2061.       do
  2062.      if run_control.invariant_check then
  2063.         Result := target_type.run_type.run_class;
  2064.         if Result.at_run_time and then
  2065.            Result.invariant_assertion /= Void then
  2066.         else
  2067.            Result := Void;
  2068.         end;
  2069.      end;
  2070.       end;
  2071.  
  2072. feature {RUN_FEATURE}
  2073.  
  2074.    current_class_invariant(current_type: TYPE) is
  2075.      -- Add some C code to check class invariant with Current at 
  2076.      -- the end of a routine.
  2077.       require
  2078.      current_type.is_run_type
  2079.       local
  2080.      rc: RUN_CLASS;
  2081.       do
  2082.      rc := need_invariant(current_type);
  2083.      if rc /= Void then
  2084.         if rc.current_type.is_reference then
  2085.            put_string("if(se_rci(C))");
  2086.         end;
  2087.         put_character('i');
  2088.         put_integer(rc.id);
  2089.         put_character('(');
  2090.         put_character('C');
  2091.         put_character(')');
  2092.         put_string(fz_00);
  2093.      end;
  2094.       end;
  2095.    
  2096. feature 
  2097.    
  2098.    call_invariant_start(target_type: TYPE): BOOLEAN is
  2099.      -- Start printing call of invariant only when it is needed 
  2100.      -- (`target_type' really has an invariant and when mode is 
  2101.      -- `-invariant_check').  
  2102.      -- When Result is true, `call_invariant_end' must be called to 
  2103.      -- finish the job.
  2104.       require
  2105.      target_type.is_run_type;
  2106.       local
  2107.      rc: RUN_CLASS;
  2108.       do
  2109.      rc := need_invariant(target_type);
  2110.      if rc /= Void then
  2111.         out_c.put_character('i');
  2112.         out_c.put_integer(rc.id);
  2113.         out_c.put_character('(');
  2114.         Result := true;
  2115.      end;
  2116.       end;
  2117.  
  2118.    call_invariant_end is
  2119.       do
  2120.      out_c.put_character(')');
  2121.       end;
  2122.    
  2123. feature {NONE}
  2124.    
  2125.    define_initialize is
  2126.      -- Very very last definitions ;-);
  2127.       local
  2128.      no_check: BOOLEAN;
  2129.       do
  2130.      no_check := run_control.no_check;
  2131.      echo.put_string("Define initialize stuff.%N");
  2132.      small_eiffel.define_extern_tables;
  2133.      if no_check then
  2134.         split_c_now;
  2135.      end;
  2136.      put_c_heading("void se_initialize(void)");
  2137.      swap_on_c;
  2138.      if no_check then
  2139.         small_eiffel.initialize_path_table;
  2140.      end;
  2141.      if generator_used then
  2142.         small_eiffel.initialize_generator;
  2143.      end;
  2144.      if generating_type_used then
  2145.         small_eiffel.initialize_generating_type;
  2146.      end;
  2147.      put_string(fz_12);
  2148.      if no_check then
  2149.         split_c_now;
  2150.      end;
  2151.       end;
  2152.    
  2153. feature {NONE}
  2154.    
  2155.    cdef_id(str: STRING; id: INTEGER) is
  2156.       do
  2157.      tmp_string.clear;
  2158.      tmp_string.extend('#');
  2159.      tmp_string.append(fz_define);
  2160.      tmp_string.extend(' ');
  2161.      tmp_string.append(str);
  2162.      tmp_string.append("id ");
  2163.      id.append_in(tmp_string);
  2164.      tmp_string.extend('%N');
  2165.      out_h.put_string(tmp_string);
  2166.       end;
  2167.  
  2168. feature {CREATION_CALL}
  2169.    
  2170.    expanded_attributes(rt: TYPE) is
  2171.      -- Produce C code to initialize expanded attribute
  2172.      -- of the new object juste created in variable "n".
  2173.       require
  2174.      small_eiffel.is_ready;
  2175.      rt.is_run_type
  2176.       local
  2177.      wa: ARRAY[RUN_FEATURE];
  2178.      a: RUN_FEATURE;
  2179.      at: TYPE;
  2180.      i: INTEGER;
  2181.      rf3: RUN_FEATURE_3;
  2182.       do
  2183.      wa := rt.run_class.writable_attributes;
  2184.      if wa /= Void then
  2185.         from  
  2186.            i := wa.upper;
  2187.         until
  2188.            i = 0
  2189.         loop
  2190.            a := wa.item(i);
  2191.            at := a.result_type.run_type;
  2192.  
  2193.            rf3 := at.expanded_initializer;
  2194.            if rf3 /= Void then
  2195.           stack_push(C_expanded_initialize);
  2196.           stack_target.put(Void,top);
  2197.           stack_rf.put(a,top);
  2198.           direct_call_count := direct_call_count + 1;
  2199.           rf3.mapping_c;
  2200.           pop;
  2201. --***              if call_invariant_start(rf.current_type) then
  2202. --***                 put_character('&');
  2203. --***                 w.compile_to_c;
  2204. --***                 call_invariant_end;
  2205. --***                 put_string(fz_00);
  2206. --***              end;
  2207.            end;
  2208.            i := i - 1;
  2209.         end;
  2210.      end;
  2211.       end;
  2212.    
  2213. feature {NONE} -- Splitting of the C code:
  2214.    
  2215.    split_count: INTEGER;
  2216.      -- Number of *.c files.
  2217.    
  2218.    elt_c_count: INTEGER;
  2219.      -- Number of elements already in current *.c file.
  2220.    
  2221.    elt_c_count_max: INTEGER is 1960;
  2222.      -- One unit is about 1 source line.
  2223.    
  2224.    path_h: STRING is
  2225.       once
  2226.      Result := run_control.root_class;
  2227.      if Result = Void then
  2228.         fatal_error("No <root class>.");
  2229.      else
  2230.         Result := to_bcn(Result);
  2231.         Result.to_lower;
  2232.         if dos_system = system_name then
  2233.            from
  2234.            until
  2235.           Result.count <= 4
  2236.            loop
  2237.           Result.remove_last(1);
  2238.            end;
  2239.         end;
  2240.         Result.append(h_suffix);
  2241.      end;
  2242.       ensure
  2243.      Result.has_suffix(h_suffix);
  2244.       end;
  2245.    
  2246.    path_c: STRING is
  2247.       once
  2248.      if no_split then
  2249.         Result := path_h.twin;
  2250.         Result.remove_suffix(h_suffix);
  2251.         Result.append(c_suffix);
  2252.      else
  2253.         split_count := 1;
  2254.         !!Result.make(path_h.count + 2);
  2255.         path_c_copy_in(Result,split_count);
  2256.      end;
  2257.       ensure
  2258.      Result.has_suffix(c_suffix);
  2259.       end;
  2260.    
  2261.    path_make: STRING is
  2262.       once
  2263.      Result := path_h.twin;
  2264.      Result.remove_last(h_suffix.count);
  2265.      Result.append(make_suffix);
  2266.       end;
  2267.    
  2268. feature {NONE}
  2269.  
  2270.    output_name: STRING;
  2271.      -- Void means default "a.out".
  2272.    
  2273.    add_first_include is
  2274.       do
  2275.      put_banner(out_c);
  2276.      out_c.put_string("#include %"");
  2277.      out_c.put_string(path_h);
  2278.      out_c.put_string(fz_18);
  2279.       end;
  2280.    
  2281. feature {RUN_CLASS}
  2282.  
  2283.    split_c_start_run_class is
  2284.      -- May split here to add some padding space.
  2285.       do
  2286.      if no_split then
  2287.      elseif split_rc_count >= 9 then
  2288.         split_c_now;
  2289.         split_rc_count := 0;
  2290.      else
  2291.         split_rc_count := split_rc_count + 1;
  2292.      end;
  2293.       end;
  2294.  
  2295.    split_rc_count: INTEGER;
  2296.  
  2297. feature {SWITCH_COLLECTION}
  2298.    
  2299.    split_c_now is
  2300.      -- Assume `out_c' has finished current C function (or current
  2301.      -- C entity).
  2302.       do
  2303.      incr_elt_c_count(elt_c_count_max + 1);
  2304.       end;
  2305.  
  2306. feature {NONE}
  2307.  
  2308.    put_banner(output: STD_FILE_WRITE) is
  2309.       require
  2310.      output /= Void;
  2311.      output.is_connected;
  2312.       do
  2313.      output.put_string(fz_open_c_comment);
  2314.      output.put_string(
  2315.             "%N-- ANSI C code generated by :%N");
  2316.      output.put_string(small_eiffel.copyright);
  2317.      output.put_string(fz_close_c_comment);
  2318.      output.put_character('%N');
  2319.       end;
  2320.    
  2321. feature  
  2322.  
  2323.    c_compiler: STRING is 
  2324.       once
  2325.      !!Result.make(12);
  2326.      tmp_string.copy(small_eiffel_directory);
  2327.      add_directory(tmp_string,fz_sys);
  2328.      tmp_string.append("compiler.");
  2329.      tmp_string.append(system_name);
  2330.      echo.sfr_connect(tmp_file_read,tmp_string);
  2331.      tmp_file_read.read_line_in(Result);
  2332.      tmp_file_read.disconnect;
  2333.       end;
  2334.  
  2335.    c_linker: STRING is 
  2336.       once
  2337.      !!Result.make(12);
  2338.      tmp_string.copy(small_eiffel_directory);
  2339.      add_directory(tmp_string,fz_sys);
  2340.      tmp_string.append("linker.");
  2341.      tmp_string.append(system_name);
  2342.      echo.sfr_connect(tmp_file_read,tmp_string);
  2343.      tmp_file_read.read_line_in(Result);
  2344.      tmp_file_read.disconnect;
  2345.       end;
  2346.  
  2347.    set_no_strip is
  2348.       do
  2349.      no_strip := true;
  2350.       end;
  2351.       
  2352.    set_no_split is
  2353.       do
  2354.      no_split := true;
  2355.       end;
  2356.       
  2357.    add_c_library(lib: STRING) is
  2358.       require
  2359.      lib.has_prefix("-l");
  2360.       do
  2361.      if c_library_list = Void then
  2362.         c_library_list := <<lib>>;
  2363.      elseif c_library_list.has(lib) then
  2364.      else
  2365.         c_library_list.add_last(lib);
  2366.      end;
  2367.       end;
  2368.    
  2369.    add_c_compiler_option(op: STRING) is
  2370.       require
  2371.      op /= Void
  2372.       do
  2373.      if c_compiler_options = Void then
  2374.         !!c_compiler_options.make(10);
  2375.      end;
  2376.      c_compiler_options.append(op);
  2377.      c_compiler_options.extend(' ');
  2378.       end;
  2379.    
  2380.    add_c_object(file_o: STRING) is
  2381.       require
  2382.      file_o.has_suffix(o_suffix) or file_o.has_suffix(c_suffix); 
  2383.       do
  2384.      if c_object_list = Void then
  2385.         c_object_list := <<file_o>>;
  2386.      elseif c_object_list.has(file_o) then
  2387.      else
  2388.         c_object_list.add_last(file_o);
  2389.      end;
  2390.       end;
  2391.    
  2392.    set_output_name(on: like output_name) is
  2393.       require
  2394.      on /= Void
  2395.       do
  2396.      output_name := on;
  2397.       ensure     
  2398.      output_name = on;
  2399.       end;
  2400.    
  2401.    write_make_file is 
  2402.       local
  2403.      score: DOUBLE;
  2404.       do
  2405.      out_h.put_character('%N');
  2406.      out_h.disconnect;
  2407.      out_c.put_character('%N');
  2408.      out_c.disconnect;
  2409.      sfw_connect(out_make,path_make);
  2410.      if no_split then
  2411.         write_make_file_no_split;
  2412.      else
  2413.         write_make_file_split;
  2414.      end;
  2415.      if not no_strip then
  2416.         print_strip;
  2417.      end;
  2418.      out_make.disconnect;
  2419.      if nb_errors > 0 then
  2420.         echo.file_removing(path_make);
  2421.      else
  2422.         echo.put_string("Type inference score : ");
  2423.         score := direct_call_count + check_id_count; 
  2424.         score := (score / (score + switch_count)) * 100.0;
  2425.         echo.put_double_format(score,2);
  2426.         echo.put_character('%%');
  2427.         echo.put_character('%N');
  2428.      end;
  2429.      eiffel_parser.show_nb_warnings;
  2430.      eiffel_parser.show_nb_errors;
  2431.      echo.put_string(fz_02);
  2432.       end;
  2433.    
  2434. feature {NONE}
  2435.  
  2436.    oflag: STRING;
  2437.  
  2438.    add_oflag is
  2439.       do
  2440.      if output_name /= Void then
  2441.         if oflag = Void then
  2442.            tmp_string.append("-o ");
  2443.         else
  2444.            tmp_string.append(oflag);
  2445.         end;
  2446.         tmp_string.append(output_name);
  2447.         tmp_string.extend(' ');
  2448.      end;
  2449.       end;
  2450.  
  2451. feature 
  2452.  
  2453.    set_oflag(str: STRING) is
  2454.       do
  2455.      oflag := str;
  2456.       end;
  2457.    
  2458. feature {NONE}
  2459.    
  2460.    print_strip is
  2461.       require
  2462.      not no_strip;
  2463.       do
  2464.      if os2_system = system_name or else 
  2465.         unix_system = system_name
  2466.       then
  2467.         tmp_string.clear;
  2468.         if os2_system = system_name then
  2469.            tmp_string.append("emxbind -qs ");
  2470.         else
  2471.            tmp_string.append("strip ");
  2472.         end;
  2473.         if output_name = Void then
  2474.            tmp_string.append("a.out");
  2475.         else
  2476.            tmp_string.append(output_name);
  2477.         end;
  2478.         echo_make;
  2479.      end;     
  2480.       end;
  2481.       
  2482.    call_c_compiler is
  2483.       do
  2484.      tmp_string.copy(c_compiler);
  2485.      tmp_string.extend(' ');
  2486.      if c_compiler_options /= Void then
  2487.         tmp_string.append(c_compiler_options);
  2488.      end;
  2489.       end;
  2490.    
  2491.    call_c_linker is
  2492.       do
  2493.      tmp_string.copy(c_linker);
  2494.      tmp_string.extend(' ');
  2495.      if c_compiler_options /= Void then
  2496.         tmp_string.append(c_compiler_options);
  2497.      end;
  2498.       end;
  2499.    
  2500.    tmp_string_object_library is
  2501.       local
  2502.      i: INTEGER;
  2503.       do
  2504.      if c_object_list /= Void then
  2505.         from  
  2506.            i := c_object_list.lower;
  2507.         until
  2508.            i > c_object_list.upper
  2509.         loop
  2510.            tmp_string.extend(' ');
  2511.            tmp_string.append(c_object_list.item(i));
  2512.            i := i + 1;
  2513.         end;        
  2514.      end;
  2515.      if c_library_list /= Void then
  2516.         from  
  2517.            i := c_library_list.lower;
  2518.         until
  2519.            i > c_library_list.upper
  2520.         loop
  2521.            tmp_string.extend(' ');
  2522.            tmp_string.append(c_library_list.item(i));
  2523.            i := i + 1;
  2524.         end;        
  2525.      end;
  2526.       end;
  2527.    
  2528.    echo_make is
  2529.       do
  2530.      out_make.put_string(tmp_string);
  2531.      out_make.put_character('%N');
  2532.       end;
  2533.    
  2534.    no_strip: BOOLEAN; 
  2535.    
  2536.    no_split: BOOLEAN; 
  2537.  
  2538.    c_compiler_options: STRING;
  2539.    
  2540.    c_object_list, c_library_list: ARRAY[STRING];
  2541.    
  2542.    c_code_saved: BOOLEAN;
  2543.  
  2544. feature {NONE}
  2545.  
  2546.    get_inline_ms: MANIFEST_STRING is
  2547.       local
  2548.      e: EXPRESSION;
  2549.       do
  2550.      e := stack_args.item(top).expression(1);
  2551.      Result ?= e;
  2552.      if Result = Void then
  2553.         eh.add_position(e.start_position);
  2554.         fatal_error("Bad usage of C inlining.");
  2555.      end;
  2556.      manifest_string_pool.used_for_inline(Result);
  2557.       end;
  2558.  
  2559. feature {NONE}
  2560.  
  2561.    backup_sfw_connect(sfw: STD_FILE_WRITE; c_path: STRING) is
  2562.       do
  2563.      tmp_string3.copy(c_path);
  2564.      tmp_string3.extend('~');
  2565.      echo_rename_file(c_path,tmp_string3);
  2566.      sfw_connect(sfw,c_path);
  2567.       end;
  2568.  
  2569.    path_c_copy_in(str: STRING; number: INTEGER) is
  2570.       do
  2571.      str.clear;
  2572.      str.append(path_h);
  2573.      str.remove_last(h_suffix.count);
  2574.      number.append_in(str);
  2575.      str.append(c_suffix);
  2576.       end;
  2577.  
  2578.    path_o_in(str: STRING; number: INTEGER) is
  2579.       do
  2580.      str.append(path_h);
  2581.      str.remove_last(h_suffix.count);
  2582.      number.append_in(str);
  2583.      str.append(o_suffix);
  2584.       end;
  2585.  
  2586. feature {NONE}
  2587.  
  2588.    write_make_file_split is 
  2589.       require
  2590.      not no_split
  2591.       local
  2592.      i: INTEGER;
  2593.       do
  2594.      from  
  2595.         i := split_count;
  2596.      until
  2597.         i = 0
  2598.      loop
  2599.         path_c_copy_in(tmp_string,i);
  2600.         tmp_string2.copy(tmp_string);
  2601.         tmp_string2.extend('~');
  2602.         tmp_string3.clear;
  2603.         path_o_in(tmp_string3,i);
  2604.         if file_exists(tmp_string3) and then
  2605.            file_tools.same_files(tmp_string,tmp_string2) then
  2606.            echo.put_string(fz_01);
  2607.            echo.put_string(tmp_string3);
  2608.            echo.put_string("%" saved.%N");
  2609.         else
  2610.            echo.file_removing(tmp_string3);
  2611.            call_c_compiler;
  2612.            tmp_string.append("-c ");
  2613.            tmp_string.append(tmp_string2);
  2614.            tmp_string.remove_last(1);
  2615.            echo_make;
  2616.         end;
  2617.         i := i - 1;
  2618.         echo.file_removing(tmp_string2);
  2619.      end;
  2620.      call_c_linker;
  2621.      add_oflag;
  2622.      from
  2623.         i := 1;
  2624.      until
  2625.         i > split_count
  2626.      loop
  2627.         path_o_in(tmp_string,i);
  2628.         tmp_string.extend(' ');
  2629.         i := i + 1;
  2630.      end;
  2631.      tmp_string_object_library;
  2632.      echo_make;
  2633.       end;
  2634.  
  2635.    write_make_file_no_split is 
  2636.       require
  2637.      no_split
  2638.       do
  2639.      call_c_compiler;
  2640.      add_oflag;
  2641.      tmp_string.append(path_c);
  2642.      tmp_string_object_library;
  2643.      echo_make;
  2644.       end;
  2645.  
  2646. feature {NONE}
  2647.  
  2648.    common_put_target is
  2649.       local
  2650.      rf: RUN_FEATURE;
  2651.      flag: BOOLEAN;
  2652.      e: EXPRESSION;
  2653.      ct: TYPE;
  2654.       do
  2655.      inspect
  2656.         stack_code.item(top)
  2657.      when C_inside_twin then 
  2658.         rf := stack_rf.item(top);
  2659.         ct := rf.current_type;
  2660.         if ct.is_reference then
  2661.            put_character('(');
  2662.            ct.mapping_cast;
  2663.            put_character('R');
  2664.            put_character(')');
  2665.         else
  2666.            put_character('&');
  2667.            put_character('R');
  2668.         end;
  2669.      when C_inside_new then 
  2670.         put_character('n');
  2671.      when C_switch then 
  2672.         rf := stack_rf.item(top);
  2673.         flag := call_invariant_start(rf.current_type);
  2674.         put_character('(');
  2675.         put_character('(');
  2676.         put_character('T');
  2677.         put_integer(rf.id);
  2678.         put_character('*');
  2679.         put_character(')');
  2680.         put_character('C');
  2681.         put_character(')');
  2682.         if flag then
  2683.            call_invariant_end;
  2684.         end;
  2685.      when C_expanded_initialize then
  2686.         e := stack_target.item(top);
  2687.         if e /= Void then
  2688.            put_character('&');
  2689.            e.compile_to_c;
  2690.         else
  2691.            out_c.put_string("&n->_");
  2692.            out_c.put_string(stack_rf.item(top).name.to_string);
  2693.         end;
  2694.      when C_inline_one_pc then
  2695.         print_current;
  2696.      end;
  2697.       end;
  2698.  
  2699. feature {NONE}
  2700.  
  2701.    msg1: STRING is " type conversion.%N";
  2702.    msg2: STRING is "Automatic ";
  2703.  
  2704.  
  2705. feature {CALL_PROC_CALL}
  2706.  
  2707.    put_cpc(cpc: CALL_PROC_CALL) is
  2708.       local
  2709.      target: EXPRESSION;
  2710.      target_type: TYPE;
  2711.      running: ARRAY[RUN_CLASS];
  2712.      run_feature: RUN_FEATURE;
  2713.       do
  2714.      target := cpc.target;
  2715.      target_type := target.result_type.run_type;
  2716.      run_feature := cpc.run_feature;
  2717.      if target_type.is_expanded then
  2718.         push_direct(run_feature,target,cpc.arguments);
  2719.         run_feature.mapping_c;
  2720.         pop;
  2721.      elseif target.is_current then
  2722.         push_direct(run_feature,target,cpc.arguments);
  2723.         run_feature.mapping_c;
  2724.         pop;
  2725.      elseif target.is_manifest_string then
  2726.         push_direct(run_feature,target,cpc.arguments);
  2727.         run_feature.mapping_c;
  2728.         pop;
  2729.      else
  2730.         push_cpc(run_feature,
  2731.              target_type.run_class.running,
  2732.              target,
  2733.              cpc.arguments);
  2734.      end;
  2735.       end;
  2736.  
  2737. feature {NATIVE_SMALL_EIFFEL}
  2738.  
  2739.    sprintf_double_is_used is
  2740.       do
  2741.      sprintf_double_flag := true;
  2742.       end;
  2743.  
  2744. feature {NONE}
  2745.  
  2746.    sprintf_double_flag: BOOLEAN;
  2747.  
  2748. end -- C_PRETTY_PRINTER
  2749.  
  2750.