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

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class SMALL_EIFFEL
  17.    --
  18.    -- Singleton object to handle general purpose information.
  19.    -- This singleton is shared via the GLOBALS.`small_eiffel' once function.
  20.    --
  21.  
  22. inherit GLOBALS;
  23.  
  24. creation make
  25.  
  26. feature
  27.  
  28.    copyright: STRING is
  29.       "-- SmallEiffel The GNU Eiffel Compiler -- Release (- 0.78)      --%N%
  30.       %-- Copyright (C), 1994-98 - LORIA - UHP - CRIN - INRIA - FRANCE --%N%
  31.       %-- Dominique COLNET and Suzanne COLLIN -    colnet@loria.fr     --%N%
  32.       %--                  http://SmallEiffel.loria.fr/                --%N";
  33.  
  34. feature {GC_HANDLER,C_PRETTY_PRINTER}
  35.  
  36.    root_procedure: RUN_FEATURE_3;
  37.  
  38. feature {NONE}
  39.  
  40.    make is
  41.       do
  42.       end;
  43.  
  44. feature
  45.  
  46.    loading_path: ARRAY[STRING] is
  47.       once
  48.          !!Result.with_capacity(16,1);
  49.          system_tools.read_loading_path_in(Result);
  50.       end;
  51.  
  52. feature
  53.  
  54.    is_ready: BOOLEAN;
  55.          -- True when type inference algorithm is done : all
  56.          -- needed classes are loaded, `at_run_time' classes are
  57.          -- known, falling down is done, ...
  58.  
  59. feature
  60.  
  61.    get_class(str: STRING): BASE_CLASS is
  62.       do
  63.          if base_class_dictionary.has(str) then
  64.             Result := base_class_dictionary.at(str);
  65.          else
  66.             tmp_class_name.make(str,Void);
  67.             Result := tmp_class_name.base_class;
  68.          end;
  69.       ensure
  70.          Result /= Void
  71.       end;
  72.  
  73.    base_class(class_name: CLASS_NAME): BASE_CLASS is
  74.       require
  75.          class_name /= Void;
  76.       do
  77.          if base_class_dictionary.has(class_name.to_string) then
  78.             Result := base_class_dictionary.at(class_name.to_string);
  79.          elseif eiffel_parser.is_running then
  80.             fatal_error("Internal Error #1 in SMALL_EIFFEL.");
  81.          else
  82.             if parser_buffer_for(class_name.to_string) then
  83.                Result := eiffel_parser.analyse_class(class_name);
  84.                check
  85.                   Result /= Void
  86.                      implies
  87.                   base_class_dictionary.has(class_name.to_string);
  88.                end;
  89.             end;
  90.             if Result = Void then
  91.                eh.add_position(class_name.start_position);
  92.                fatal_error("Unable to load class.");
  93.             end;
  94.          end;
  95.       end;
  96.  
  97.    load_class(name: STRING): BASE_CLASS is
  98.          -- Try to load the `name' class where `name' is given
  99.          -- in a command line (it can be a class name or a path).
  100.       require
  101.          not eiffel_parser.is_running
  102.       do
  103.          if parser_buffer_for(name) then
  104.             Result := eiffel_parser.analyse_class(Void);
  105.             if Result = Void then
  106.                fatal_error("Cannot load class.");
  107.             end;
  108.          else
  109.             fatal_error("Cannot find class.");
  110.          end;
  111.       end;
  112.  
  113. feature {PRETTY}
  114.  
  115.    re_load_class(e_class: BASE_CLASS): BOOLEAN is
  116.       require
  117.          e_class /= Void;
  118.       local
  119.          name: STRING;
  120.          new_class: like e_class;
  121.       do
  122.          name := e_class.name.to_string;
  123.          check
  124.             base_class_dictionary.has(name);
  125.          end;
  126.          base_class_dictionary.remove(name);
  127.          new_class := load_class(name);
  128.          Result := new_class /= Void;
  129.       end;
  130.  
  131. feature {EIFFEL_PARSER}
  132.  
  133.    add_class(c: BASE_CLASS) is
  134.       require
  135.          c /= Void
  136.       do
  137.          check
  138.             not base_class_dictionary.has(c.name.to_string);
  139.          end;
  140.          base_class_dictionary.put(c,c.name.to_string);
  141.          incr_magic_count;
  142.       ensure
  143.          base_class_dictionary.has(c.name.to_string);
  144.       end;
  145.  
  146. feature {FINDER}
  147.  
  148.    find_path_for(arg: STRING): STRING is
  149.       do
  150.          if parser_buffer_for(arg) then
  151.             Result := parser_buffer.path;
  152.          end;
  153.          parser_buffer.unset_is_ready;
  154.       end;
  155.  
  156. feature {NONE}
  157.  
  158.    parser_buffer_path: STRING is
  159.       once
  160.          !!Result.make(256);
  161.       end;
  162.  
  163.    parser_buffer_for(name: STRING): BOOLEAN is
  164.          -- SmallEiffel algorithm for searching classes on the disk.
  165.          -- When Result, `parser_buffer' is ready to be used.
  166.       require
  167.          name /= Void;
  168.          not parser_buffer.is_ready
  169.       local
  170.          i: INTEGER;
  171.       do
  172.          tmp_tail.copy(name);
  173.          tmp_tail.to_lower;
  174.          if not tmp_tail.has_suffix(eiffel_suffix) then
  175.             tmp_tail.append(eiffel_suffix);
  176.          end;
  177.          from
  178.             i := loading_path.lower;
  179.          until
  180.             i > loading_path.upper or else Result
  181.          loop
  182.             parser_buffer_path.copy(loading_path.item(i));
  183.             parser_buffer_path.append(tmp_tail);
  184.             parser_buffer.load_file(parser_buffer_path);
  185.             Result := parser_buffer.is_ready;
  186.             i := i + 1;
  187.          end;
  188.          if not Result and then rename_dictionary.has(tmp_tail) then
  189.             parser_buffer_path.copy(rename_dictionary.at(tmp_tail));
  190.             parser_buffer.load_file(parser_buffer_path);
  191.             if parser_buffer.is_ready then
  192.                Result := true;
  193.             else
  194.                echo.w_put_string("Bad %"rename.se%" file.%NCannot open %"");
  195.                echo.w_put_string(parser_buffer_path);
  196.                echo.w_put_string(fz_03);
  197.                die_with_code(exit_failure_code);
  198.             end;
  199.          end;
  200.          if not Result then
  201.             tmp_tail.copy(name);
  202.             if not tmp_tail.has_suffix(eiffel_suffix) then
  203.                tmp_tail.append(eiffel_suffix);
  204.             end;
  205.             from
  206.                i := loading_path.lower;
  207.             until
  208.                i > loading_path.upper or else Result
  209.             loop
  210.                parser_buffer_path.copy(loading_path.item(i));
  211.                parser_buffer_path.append(tmp_tail);
  212.                parser_buffer.load_file(parser_buffer_path);
  213.                Result := parser_buffer.is_ready;
  214.                i := i + 1;
  215.             end;
  216.          end;
  217.          if not Result then
  218.             echo.w_put_string("Unable to find file for class %"");
  219.             echo.w_put_string(name);
  220.             echo.w_put_string("%". ");
  221.             parser_buffer_path.clear;
  222.             append_loading_path_in(parser_buffer_path);
  223.             echo.w_put_string(parser_buffer_path);
  224.          end;
  225.       ensure
  226.          Result implies parser_buffer.is_ready
  227.       end;
  228.  
  229.    rename_dictionary: DICTIONARY[STRING,STRING] is
  230.          -- Handling of "rename.se" files.
  231.       local
  232.          i: INTEGER;
  233.          full_name, short_name: STRING;
  234.       once
  235.          from
  236.             !!Result.make;
  237.             i := 1;
  238.          until
  239.             i > loading_path.upper
  240.          loop
  241.             tmp_path.copy(loading_path.item(i));
  242.             tmp_path.append("rename.se");
  243.             echo.sfr_connect(tmp_file_read,tmp_path);
  244.             if tmp_file_read.is_connected then
  245.                from
  246.                until
  247.                   tmp_file_read.end_of_input
  248.                loop
  249.                   tmp_file_read.read_word;
  250.                   full_name := tmp_file_read.last_string.twin;
  251.                   tmp_file_read.read_word;
  252.                   short_name := tmp_file_read.last_string.twin;
  253.                   short_name.prepend(loading_path.item(i));
  254.                   if Result.has(full_name) then
  255.                      echo.w_put_string("Multiple entry for %"");
  256.                      echo.w_put_string(full_name);
  257.                      echo.w_put_string("%" in %"rename.se%" files.%N%
  258.                                            %Clash for %N%"");
  259.                      echo.w_put_string(short_name);
  260.                      echo.w_put_string("%" and %N%"");
  261.                      echo.w_put_string(Result.at(full_name));
  262.                      echo.w_put_string(".%N");
  263.                      die_with_code(exit_failure_code);
  264.                   end;
  265.                   Result.put(short_name,full_name)
  266.                   tmp_file_read.skip_separators;
  267.                end;
  268.                tmp_file_read.disconnect;
  269.             end;
  270.             i := i + 1;
  271.          end;
  272.       end;
  273.  
  274. feature
  275.  
  276.    short_flag: BOOLEAN;
  277.          -- True when command `short' is running.
  278.  
  279.    pretty_flag: BOOLEAN;
  280.          -- True when command `pretty' is running.
  281.  
  282. feature {SHORT}
  283.  
  284.    set_short_flag is
  285.       do
  286.          short_flag := true;
  287.       end;
  288.  
  289. feature {PRETTY}
  290.  
  291.    set_pretty_flag is
  292.       do
  293.          pretty_flag := true;
  294.       end;
  295.  
  296. feature
  297.  
  298.    is_used(cn: STRING): BOOLEAN is
  299.          -- Is the base class `cn' used (loaded) ?
  300.       do
  301.          Result := base_class_dictionary.has(cn);
  302.       end;
  303.  
  304.    run_class(t: TYPE): RUN_CLASS is
  305.       require
  306.          t.run_type = t;
  307.       local
  308.          run_string: STRING;
  309.       do
  310.          run_string := t.run_time_mark;
  311.          if run_class_dictionary.has(run_string) then
  312.             Result := run_class_dictionary.at(run_string);
  313.          else
  314.             !!Result.make(t);
  315.             check
  316.                run_class_dictionary.has(run_string);
  317.             end;
  318.          end;
  319.       ensure
  320.          Result /= Void
  321.       end;
  322.  
  323. feature
  324.  
  325.    base_class_count: INTEGER is
  326.          -- Total number of base class actually loaded.
  327.       do
  328.          Result := base_class_dictionary.count;
  329.       end;
  330.  
  331. feature
  332.  
  333.    compile_to_c is
  334.          -- Produce C code for `root_class'/`procedure'.
  335.       local
  336.          root_class, procedure: STRING;
  337.          rc: RUN_CLASS;
  338.          run_count: INTEGER;
  339.          i: INTEGER;
  340.          gc_flag: BOOLEAN;
  341.       do
  342.          root_class := run_control.root_class;
  343.          procedure := run_control.root_procedure;
  344.          get_started(root_class,procedure);
  345.          if nb_errors = 0 then
  346.             check
  347.                root_procedure /= Void
  348.             end;
  349.             cpp.get_started;
  350.             cpp.swap_on_h;
  351.             gc_flag := not gc_handler.is_off;
  352.             -- ---------------------------------------------------------
  353.             cpp.put_string("%N/* --- Mangling Table Start ---%N");
  354.             from
  355.                i := 1;
  356.             until
  357.                i > run_class_dictionary.count
  358.             loop
  359.                rc := run_class_dictionary.item(i);
  360.                if rc.at_run_time then
  361.                   run_count := run_count + 1;
  362.                end;
  363.                rc.demangling;
  364.                i := i + 1;
  365.             end;
  366.             cpp.put_string(" --- Mangling Table End --- */%N");
  367.             -- ---------------------------------------------------------
  368.             from
  369.                cpp.put_comment_line("C Header Pass 1 :");
  370.                i := 1;
  371.             until
  372.                i > run_class_dictionary.count
  373.             loop
  374.                rc := run_class_dictionary.item(i);
  375.                rc.c_header_pass1;
  376.                i := i + 1;
  377.             end;
  378.             -- ---------------------------------------------------------
  379.             from
  380.                cpp.put_comment_line("C Header Pass 2 :");
  381.                i := 1;
  382.             until
  383.                i > run_class_dictionary.count
  384.             loop
  385.                rc := run_class_dictionary.item(i);
  386.                rc.c_header_pass2;
  387.                i := i + 1;
  388.             end;
  389.             -- ---------------------------------------------------------
  390.             from
  391.                cpp.put_comment_line("C Header Pass 3 :");
  392.                i := 1;
  393.             until
  394.                i > run_class_dictionary.count
  395.             loop
  396.                rc := run_class_dictionary.item(i);
  397.                rc.c_header_pass3;
  398.                i := i + 1;
  399.             end;
  400.             -- ---------------------------------------------------------
  401.             from
  402.                cpp.put_comment_line("C Header Pass 4 :");
  403.                i := 1;
  404.             until
  405.                i > run_class_dictionary.count
  406.             loop
  407.                rc := run_class_dictionary.item(i);
  408.                rc.c_header_pass4;
  409.                i := i + 1;
  410.             end;
  411.             -- Force definition of T9 and T7 :
  412.             if not run_class_dictionary.has(as_native_array_character) then
  413.                cpp.put_string("typedef char* T9;%N");
  414.                if run_control.no_check then
  415.                   cpp.put_c_function("void se_prinT9(T9*o)",
  416.                                      "printf(%"NATIVE_ARRAY[STRING]#%%p\n%",*o);");
  417.                end;
  418.             end;
  419.             manifest_string_pool.c_define1(string_at_run_time);
  420.             cpp.customize_runtime;
  421.             -- ---------------------------------------------------------
  422.             if gc_flag then
  423.                gc_handler.define1;
  424.             end;
  425.             -- ---------------------------------------------------------
  426.             compile_routines;
  427.             cpp.cecil_define;
  428.             -- ---------------------------------------------------------
  429.             cpp.define_main(root_procedure);
  430.             manifest_string_pool.c_define2(string_at_run_time);
  431.             compile_registered_for_c_define;
  432.             address_of_pool.c_define;
  433.             if gc_flag then
  434.                gc_handler.define2;
  435.             end;
  436.             manifest_array_pool.c_define;
  437.             switch_collection.c_define;
  438.             cpp.define_used_basics;
  439.             debug
  440.                echo.put_string("Very Final magic_count : ");
  441.                echo.put_integer(magic_count);
  442.                echo.put_character('%N');
  443.             end;
  444.             cpp.write_make_file;
  445.          else
  446.             eh.append("Cannot produce C code.");
  447.             eh.print_as_error;
  448.          end;
  449.       end;
  450.  
  451.    compile_to_jvm is
  452.          -- Produce Java Byte Code for `root_class'/`procedure'.
  453.       local
  454.          root_class, procedure: STRING;
  455.          rc: RUN_CLASS;
  456.          run_count, i: INTEGER;
  457.       do
  458.          root_class := run_control.root_class;
  459.          procedure := run_control.root_procedure;
  460.          get_started(root_class,procedure);
  461.          if nb_errors = 0 then
  462.             jvm.mkdir;
  463.             from
  464.                i := 1;
  465.             until
  466.                i > run_class_dictionary.count
  467.             loop
  468.                rc := run_class_dictionary.item(i);
  469.                if rc.at_run_time then
  470.                   run_count := run_count + 1;
  471.                   rc.compile_to_jvm;
  472.                end;
  473.                i := i + 1;
  474.             end;
  475.             echo.print_count("Used Type",run_count);
  476.             jvm.write_jvm_root_class;
  477.             jvm.write_main_class(root_procedure);
  478.          else
  479.             eh.append("Cannot produce Java Byte Code.");
  480.             eh.print_as_error;
  481.          end;
  482.       end;
  483.  
  484. feature {NONE}
  485.  
  486.    base_class_dictionary: DICTIONARY[BASE_CLASS,STRING] is
  487.          -- When looking for a BASE_CLASS using the name of
  488.          -- base class (ie FOO[BAR] is stored at key "FOO").
  489.       once
  490.          !!Result.with_capacity(1024);
  491.       end;
  492.  
  493. feature
  494.  
  495.    magic_count: INTEGER;
  496.          -- Grow each time a new run class is added, each time a new
  497.          -- class is loaded, each time a new feature is checked,
  498.          -- each time ...
  499.          -- Thus when `magic_count' stops growing, we are really
  500.          -- ready to run :-).
  501.  
  502. feature {RUN_CLASS,RUN_FEATURE,ASSERTION_COLLECTOR}
  503.  
  504.    incr_magic_count is
  505.       do
  506.          magic_count := magic_count + 1;
  507.       end;
  508.  
  509. feature {BASE_CLASS,RUN_CLASS,GC_HANDLER}
  510.  
  511.    run_class_dictionary: DICTIONARY[RUN_CLASS,STRING] is
  512.       once
  513.          !!Result.with_capacity(1024);
  514.       end;
  515.  
  516. feature {CALL_PROC_CALL}
  517.  
  518.    run_class_with(run_time_mark: STRING): RUN_CLASS is
  519.       do
  520.          if run_class_dictionary.has(run_time_mark) then
  521.             Result := run_class_dictionary.at(run_time_mark);
  522.          end;
  523.       end;
  524.  
  525. feature {RUN_CLASS}
  526.  
  527.    is_tagged(rc: RUN_CLASS): BOOLEAN is
  528.       require
  529.          is_ready;
  530.          rc.at_run_time;
  531.          rc.current_type.is_reference;
  532.          run_control.boost
  533.       local
  534.          i, up: INTEGER;
  535.          r: ARRAY[RUN_CLASS];
  536.          rcd: like run_class_dictionary;
  537.          rc2: RUN_CLASS;
  538.       do
  539.          from
  540.             i := 1;
  541.             rcd := run_class_dictionary;
  542.             up := rcd.count;
  543.          until
  544.             Result or else i > up
  545.          loop
  546.             rc2 := rcd.item(i);
  547.             r := rc2.running;
  548.             if r = Void then
  549.             elseif r.fast_has(rc) then
  550.                Result := r.count > 1;
  551.             end;
  552.             i := i + 1;
  553.          end;
  554.       end;
  555.  
  556.    memory_class_used: BASE_CLASS is
  557.          -- The MEMORY class when used or Void when this class is not
  558.          -- in the live code..
  559.       do
  560.          if base_class_dictionary.has(as_memory) then
  561.             Result := base_class_dictionary.at(as_memory);
  562.          end;
  563.       end;
  564.  
  565. feature {NONE}
  566.  
  567.    get_started(root_class_name, procedure_name: STRING) is
  568.          -- Get started to compile using creation `procedure_name'
  569.          -- of base class `root_class_name'.
  570.       require
  571.          not root_class_name.empty;
  572.          not procedure_name.empty
  573.       local
  574.          root_proc_name: SIMPLE_FEATURE_NAME;
  575.          root: BASE_CLASS;
  576.          root_proc: PROCEDURE;
  577.          root_type: TYPE;
  578.          magic: INTEGER;
  579.       do
  580.          echo.put_string(copyright);
  581.          if run_control.no_check then
  582.             run_control.set_generator_used;
  583.             run_control.set_generating_type_used;
  584.          end;
  585.          echo.put_string("Parsing :%N");
  586.          root := load_class(root_class_name);
  587.          if root = Void then
  588.             eh.append("Cannot load root class ");
  589.             eh.append(root_class_name);
  590.             eh.append(fz_dot);
  591.             eh.print_as_error;
  592.          else
  593.             root_proc_name := root.root_procedure_name(procedure_name);
  594.             root_proc := root.root_procedure(root_proc_name);
  595.          end;
  596.          if nb_errors = 0 then
  597.             if root_proc.arguments /= Void then
  598.                eh.add_position(root_proc.start_position);
  599.                eh.append("Creation procedure ");
  600.                eh.append(procedure_name);
  601.                eh.append(" must not have arguments.");
  602.                eh.print_as_error;
  603.             end;
  604.          end;
  605.          if nb_errors = 0 then
  606.             root_type := root.run_class.current_type;
  607.          end;
  608.          if nb_errors = 0 then
  609.             root_procedure := root_proc.to_run_feature(root_type,root_proc_name);
  610.          end;
  611.          if nb_errors = 0 then
  612.             echo.put_string("Starting Falling Down (");
  613.             echo.put_integer(magic_count);
  614.             echo.put_string(em1);
  615.             from
  616.                falling_down;
  617.                cecil_pool.fill_up;
  618.             until
  619.                magic = magic_count or else nb_errors > 0
  620.             loop
  621.                magic := magic_count;
  622.                falling_down;
  623.             end;
  624.             echo.put_string("End of Falling Down (");
  625.             echo.put_integer(magic_count);
  626.             echo.put_string(em1);
  627.          end;
  628.          if nb_errors = 0 then
  629.             echo.put_string("Starting AFD Check (");
  630.             echo.put_integer(magic_count);
  631.             echo.put_string(em1);
  632.             from
  633.                afd_check;
  634.             until
  635.                magic = magic_count or else nb_errors > 0
  636.             loop
  637.                magic := magic_count;
  638.                falling_down;
  639.                afd_check;
  640.             end;
  641.             echo.put_string("End of AFD Check (");
  642.             echo.put_integer(magic_count);
  643.             echo.put_string(em1);
  644.             check_for_deferred;
  645.             check_generic_formal_arguments;
  646.          end;
  647.          if not eh.empty then
  648.             eh.append("Internal Warning #1 (Error Handler Not Empty) : ");
  649.             eh.print_as_warning;
  650.          end;
  651.          if nb_errors = 0 then
  652.             is_ready := true;
  653.             echo.print_count("Loaded Classe",base_class_dictionary.count);
  654.          end;
  655.       ensure
  656.          nb_errors = 0 implies root_procedure /= Void
  657.       end;
  658.  
  659. feature -- To add more Context for some `to_runnable' :
  660.  
  661.    top_rf: RUN_FEATURE is
  662.       do
  663.          Result := stack_rf.item(top);
  664.       end;
  665.  
  666.    push(rf: RUN_FEATURE) is
  667.       do
  668.          top := top + 1;
  669.          stack_rf.force(rf,top);
  670.       end;
  671.  
  672.    pop is
  673.       do
  674.          check
  675.             1 <= top;
  676.          end;
  677.          top := top - 1;
  678.       ensure
  679.          old(top) = top + 1
  680.       end;
  681.  
  682. feature {NONE}
  683.  
  684.    stack_rf: ARRAY[RUN_FEATURE] is
  685.       once
  686.          !!Result.make(1,50);
  687.       end;
  688.  
  689.    top: INTEGER;
  690.  
  691. feature {NONE}
  692.  
  693.    falling_down is
  694.       local
  695.          rc: RUN_CLASS;
  696.          i: INTEGER;
  697.       do
  698.          if run_control.generator_used then
  699.             type_string.set_at_run_time;
  700.          end;
  701.          manifest_string_pool.falling_down;
  702.          address_of_pool.falling_down;
  703.          switch_collection.falling_down;
  704.          from
  705.             i := 1;
  706.          until
  707.             i > run_class_dictionary.count
  708.          loop
  709.             rc := run_class_dictionary.item(i);
  710.             rc.falling_down;
  711.             i := i + 1;
  712.          end;
  713.       end;
  714.  
  715.    afd_check is
  716.       local
  717.          rc: RUN_CLASS;
  718.          i: INTEGER;
  719.       do
  720.          from
  721.             i := 1;
  722.          until
  723.             i > run_class_dictionary.count
  724.          loop
  725.             rc := run_class_dictionary.item(i);
  726.             rc.afd_check;
  727.             i := i + 1;
  728.          end;
  729.       end;
  730.  
  731. feature {RUN_FEATURE_9}
  732.  
  733.    afd_check_deferred(rf9: RUN_FEATURE_9) is
  734.       do
  735.          if not rf9_memory.fast_has(rf9) then
  736.             rf9_memory.add_last(rf9);
  737.          end;
  738.       end;
  739.  
  740. feature {NONE}
  741.  
  742.    rf9_memory: FIXED_ARRAY[RUN_FEATURE_9] is
  743.       once
  744.          !!Result.with_capacity(256);
  745.       end;
  746.  
  747.    check_for_deferred is
  748.       local
  749.          i: INTEGER;
  750.          rf9: RUN_FEATURE;
  751.          rc: RUN_CLASS;
  752.       do
  753.          from
  754.             i := rf9_memory.upper
  755.             echo.print_count("Deferred Routine",i+1);
  756.          until
  757.             i < 0
  758.          loop
  759.             rf9 := rf9_memory.item(i);
  760.             rc := rf9.current_type.run_class;
  761.             if rc.at_run_time then
  762.                eh.append(rf9.name.to_string);
  763.                eh.append(" is a deferred feature in ");
  764.                eh.append(rf9.current_type.written_mark);
  765.                warning(rf9.start_position,fz_dot);
  766.             end;
  767.             i := i - 1;
  768.          end;
  769.       end;
  770.  
  771.    check_generic_formal_arguments is
  772.       local
  773.          i: INTEGER;
  774.       do
  775.          from
  776.             i := 1;
  777.          until
  778.             i > base_class_dictionary.count
  779.          loop
  780.             base_class_dictionary.item(i).check_generic_formal_arguments;
  781.             i := i + 1;
  782.          end;
  783.       end;
  784.  
  785. feature {C_PRETTY_PRINTER}
  786.  
  787.    define_extern_tables is
  788.       require
  789.          cpp.on_c
  790.       local
  791.          size: INTEGER;
  792.       do
  793.          size := id_provider.max_id + 1;
  794.          cpp.macro_def("SE_MAXID",size);
  795.          if run_control.generator_used then
  796.             cpp.put_extern4(fz_t7_star,"g",size);
  797.          end;
  798.          if run_control.generating_type_used then
  799.             cpp.put_extern4(fz_t7_star,"t",size);
  800.          end;
  801.          if run_control.no_check then
  802.             cpp.put_extern4("char*","p",size);
  803.             c_code.copy("void(*se_prinT[");
  804.             size.append_in(c_code);
  805.             c_code.append("])(void**)");
  806.             cpp.put_extern1(c_code);
  807.          end;
  808.       end;
  809.  
  810.    initialize_path_table is
  811.       require
  812.          run_control.no_check;
  813.          cpp.on_c;
  814.       local
  815.          i: INTEGER;
  816.          bc: BASE_CLASS;
  817.          rc: RUN_CLASS;
  818.       do
  819.          from
  820.             cpp.put_string("p[0]=%"???%";%N");
  821.             i := 1;
  822.          until
  823.             i > base_class_dictionary.count
  824.          loop
  825.             bc := base_class_dictionary.item(i);
  826.             cpp.put_string("p[");
  827.             cpp.put_integer(bc.id);
  828.             cpp.put_string("]=");
  829.             cpp.put_string_c(bc.path);
  830.             cpp.put_string(fz_00);
  831.             i := i + 1;
  832.          end;
  833.          from
  834.             i := 1;
  835.          until
  836.             i > run_class_dictionary.count
  837.          loop
  838.             rc := run_class_dictionary.item(i);
  839.             if rc.at_run_time then
  840.                cpp.put_string("se_prinT[");
  841.                cpp.put_integer(rc.id);
  842.                cpp.put_string("]=((void(*)(void**))se_prinT");
  843.                cpp.put_integer(rc.id);
  844.                cpp.put_string(");%N");
  845.                if rc.current_type.is_generic then
  846.                   cpp.put_string("p[");
  847.                   cpp.put_integer(rc.id);
  848.                   cpp.put_string("]=p[");
  849.                   cpp.put_integer(rc.base_class.id);
  850.                   cpp.put_string("];%N");
  851.                end;
  852.             end;
  853.             i := i + 1;
  854.          end;
  855.       ensure
  856.          cpp.on_c;
  857.       end;
  858.  
  859.    initialize_generator is
  860.       require
  861.          cpp.on_c
  862.       local
  863.          i: INTEGER;
  864.          bc: BASE_CLASS;
  865.          rc: RUN_CLASS;
  866.       do
  867.          from
  868.             i := 1;
  869.          until
  870.             i > base_class_dictionary.count
  871.          loop
  872.             bc := base_class_dictionary.item(i);
  873.             cpp.put_array1('g',bc.id);
  874.             cpp.put_character('=');
  875.             cpp.put_se_string_from_external_copy(bc.name.to_string);
  876.             cpp.put_string(fz_00);
  877.             i := i + 1;
  878.          end;
  879.          from
  880.             i := 1;
  881.          until
  882.             i > run_class_dictionary.count
  883.          loop
  884.             rc := run_class_dictionary.item(i);
  885.             if rc.at_run_time then
  886.                bc := rc.base_class;
  887.                if bc.name.to_string /= rc.current_type.run_time_mark then
  888.                   cpp.put_array1('g',rc.id);
  889.                   cpp.put_character('=');
  890.                   cpp.put_array1('g',bc.id);
  891.                   cpp.put_string(fz_00);
  892.                end;
  893.             end;
  894.             i := i + 1;
  895.          end;
  896.       ensure
  897.          cpp.on_c;
  898.       end;
  899.  
  900.    initialize_generating_type is
  901.       require
  902.          cpp.on_c;
  903.       local
  904.          i: INTEGER;
  905.          rc: RUN_CLASS;
  906.          bc: BASE_CLASS;
  907.          rtm: STRING;
  908.       do
  909.          from
  910.             i := 1;
  911.          until
  912.             i > run_class_dictionary.count
  913.          loop
  914.             rc := run_class_dictionary.item(i);
  915.             if rc.at_run_time then
  916.                cpp.put_array1('t',rc.id);
  917.                cpp.put_character('=');
  918.                bc := rc.base_class;
  919.                rtm := rc.current_type.run_time_mark
  920.                if bc.name.to_string /= rtm then
  921.                   cpp.put_se_string_from_external_copy(rtm);
  922.                else
  923.                   cpp.put_array1('g',rc.id);
  924.                end;
  925.                cpp.put_string(fz_00);
  926.             end;
  927.             i := i + 1;
  928.          end;
  929.       ensure
  930.          cpp.on_c;
  931.       end;
  932.  
  933. feature {NONE}
  934.  
  935.    tmp_class_name: CLASS_NAME is
  936.       once
  937.          !!Result.make(as_any,Void);
  938.       end
  939.  
  940. feature {NONE}
  941.  
  942.    compile_routines is
  943.          -- Try to give the best order to the C output.
  944.       local
  945.          rc, rc_string: RUN_CLASS;
  946.          ct: TYPE;
  947.          deep, i: INTEGER;
  948.          stop: BOOLEAN;
  949.          bcn: STRING;
  950.       do
  951.          echo.put_string("Compiling/Sorting routines for ");
  952.          echo.put_integer(run_class_dictionary.count);
  953.          echo.put_string(" run classes :%N");
  954.          cpp.swap_on_c;
  955.          from
  956.             i := 1;
  957.          until
  958.             i > run_class_dictionary.count
  959.          loop
  960.             rc := run_class_dictionary.item(i);
  961.             ct := rc.current_type;
  962.             if ct.is_basic_eiffel_expanded then
  963.                rc.compile_to_c(0);
  964.             elseif ct.is_string then
  965.                rc_string := rc;
  966.             end;
  967.             i := i + 1;
  968.          end;
  969.          from
  970.             i := 1;
  971.          until
  972.             i > run_class_dictionary.count
  973.          loop
  974.             rc := run_class_dictionary.item(i);
  975.             ct := rc.current_type;
  976.             if ct.is_bit then
  977.                rc.compile_to_c(0);
  978.             end;
  979.             i := i + 1;
  980.          end;
  981.          from
  982.             i := 1;
  983.          until
  984.             i > run_class_dictionary.count
  985.          loop
  986.             rc := run_class_dictionary.item(i);
  987.             bcn := rc.base_class_name.to_string;
  988.             if as_native_array = bcn then
  989.                rc.compile_to_c(0);
  990.             end;
  991.             i := i + 1;
  992.          end;
  993.          if rc_string /= Void then
  994.             rc_string.compile_to_c(0);
  995.          end;
  996.          from
  997.             i := 1;
  998.          until
  999.             i > run_class_dictionary.count
  1000.          loop
  1001.             rc := run_class_dictionary.item(i);
  1002.             ct := rc.current_type;
  1003.             bcn := ct.base_class_name.to_string;
  1004.             if as_array = bcn or else as_fixed_array = bcn then
  1005.                rc.compile_to_c(0);
  1006.             end;
  1007.             i := i + 1;
  1008.          end;
  1009.          from
  1010.             i := 1;
  1011.          until
  1012.             i > run_class_dictionary.count
  1013.          loop
  1014.             rc := run_class_dictionary.item(i);
  1015.             ct := rc.current_type;
  1016.             if ct.is_generic then
  1017.                rc.compile_to_c(0);
  1018.             end;
  1019.             i := i + 1;
  1020.          end;
  1021.          from -- General sorting :
  1022.             deep := 6;
  1023.          until
  1024.             stop
  1025.          loop
  1026.             from
  1027.                stop := true;
  1028.                i := 1;
  1029.             until
  1030.                i > run_class_dictionary.count
  1031.             loop
  1032.                rc := run_class_dictionary.item(i);
  1033.                if not rc.compile_to_c_done then
  1034.                   stop := false;
  1035.                   rc.compile_to_c(deep);
  1036.                end;
  1037.                i := i + 1;
  1038.             end;
  1039.             deep := deep - 1;
  1040.          end;
  1041.       end;
  1042.  
  1043. feature {NONE}
  1044.  
  1045.    tmp_tail: STRING is
  1046.       once
  1047.          !!Result.make(64);
  1048.       end;
  1049.  
  1050. feature {NONE}
  1051.  
  1052.    em1: STRING is " items).%N";
  1053.  
  1054. feature {NONE}
  1055.  
  1056.    append_loading_path_in(str: STRING) is
  1057.       do
  1058.          system_tools.append_lp_in(str,loading_path);
  1059.       end;
  1060.  
  1061. feature {NONE}
  1062.  
  1063.    c_code: STRING is
  1064.       once
  1065.          !!Result.make(128);
  1066.       end;
  1067.  
  1068. feature {NONE}
  1069.  
  1070.    registered_for_c_define: FIXED_ARRAY[RUN_FEATURE_3] is
  1071.       once
  1072.          !!Result.with_capacity(16);
  1073.       end;
  1074.  
  1075.    compile_registered_for_c_define is
  1076.       local
  1077.          i: INTEGER;
  1078.       do
  1079.          from
  1080.             i := registered_for_c_define.upper;
  1081.          until
  1082.             i < 0
  1083.          loop
  1084.             registered_for_c_define.item(i).c_define;
  1085.             i := i - 1;
  1086.          end;
  1087.       end;
  1088.  
  1089. feature {RUN_FEATURE_3}
  1090.  
  1091.    register_for_c_define(rf: RUN_FEATURE_3) is
  1092.       require
  1093.          rf /= Void
  1094.       do
  1095.          registered_for_c_define.add_last(rf);
  1096.       end;
  1097.  
  1098. feature {NONE}
  1099.  
  1100.    string_at_run_time: BOOLEAN is
  1101.       require
  1102.          is_ready
  1103.       local
  1104.          rc: RUN_CLASS;
  1105.       do
  1106.          if run_class_dictionary.has(as_string) then
  1107.             rc := run_class_dictionary.at(as_string);
  1108.             Result := rc.at_run_time;
  1109.          end;
  1110.       end;
  1111.  
  1112.    singleton_memory: SMALL_EIFFEL is
  1113.       once
  1114.          Result := Current;
  1115.       end;
  1116.  
  1117. invariant
  1118.  
  1119.    is_real_singleton: Current = singleton_memory
  1120.  
  1121. end -- SMALL_EIFFEL
  1122.