File: switch_collection.e

package info (click to toggle)
smarteiffel 1.1-11
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 12,288 kB
  • ctags: 40,785
  • sloc: ansic: 35,791; lisp: 4,036; sh: 1,783; java: 895; ruby: 613; python: 209; makefile: 115; csh: 78; cpp: 50
file content (207 lines) | stat: -rw-r--r-- 6,568 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
-- This file is part of SmartEiffel The GNU Eiffel Compiler Tools and Libraries
--
-- SmartEiffel is  free software;  you can redistribute it and/or  modify it
-- under  the terms of the  GNU General Public License, as published by  the
-- Free Software Foundation; either version 2, or (at your option) any later
-- version.
-- SmartEiffel is distributed in the hope that it will be useful but WITHOUT 
-- ANY WARRANTY;  without  even the implied warranty  of MERCHANTABILITY  or
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-- more details.  You should have received a copy of  the GNU General Public
-- License along with SmartEiffel;  see the file COPYING.  If not,  write to
-- the Free Software Foundation,  Inc., 59 Temple Place - Suite 330,  Boston, 
-- MA 02111-1307, USA.
--
-- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P.
--			   - University of Nancy 1 - FRANCE
-- Copyright(C) 2003:      INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne
--			   - University of Nancy 2 - FRANCE
--
--		 Dominique COLNET, Suzanne COLLIN, Olivier ZENDRA,
--			   Philippe RIBET, Cyril ADRIAN
--
-- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
--
expanded class SWITCH_COLLECTION
   --
   -- Unique Global Object in charge of the `switch_collection'.
   --

inherit
   GLOBALS
   VISITABLE

feature {CALL_PROC_CALL, E_AGENT}

   update(target: EXPRESSION; run_feature: RUN_FEATURE) is
	 -- Update the switch_collection such that `run_feature' can be
	 -- applied with `target'.
      require
	 not smart_eiffel.is_ready
         target /= Void
	 run_feature /= Void
      local
         current_type: E_TYPE; type_of_agent: TYPE_OF_AGENT
      do
	 if target.is_current then
         elseif target.is_manifest_string then
         else
	    current_type := run_feature.current_type
	    check current_type = current_type.run_type end
	    type_of_agent ?= current_type
	    if type_of_agent /= Void then
	    elseif current_type.is_reference then
	       update_with(run_feature)
            end
         end
      end
   
feature {SMART_EIFFEL}

   c_define is
         -- Produce C code for switches.
      local
         dictionary2: DICTIONARY[RUN_FEATURE,FEATURE_NAME]
         count1, count2, total: INTEGER; switch: SWITCH
      do
	 echo.put_string(
            once "Late binding support (X* switch definition).%N")
         if not dictionary.is_empty then
            cpp.swap_on_c
            from
               count1 := 1
            until
               count1 > dictionary.count
            loop
               dictionary2 := dictionary.item(count1)
               from
                  count2 := 1
               until
                  count2 > dictionary2.count
               loop
		  cpp.next_bunch_size(3)
                  switch.c_define(dictionary2.item(count2))
                  total := total + 1
                  count2 := count2 + 1
               end
               count1 := count1 + 1
            end
         end
         echo.print_count(once "Defined Switche",total)
      end

feature {CECIL_FILE, ADDRESS_OF_POOL, E_AGENT, RUN_CLASS}

   update_with(run_feature: RUN_FEATURE) is
      require
	 not smart_eiffel.is_ready
	 not run_feature.current_type.is_type_of_agent
      local
         current_type: E_TYPE; key1: STRING; key2: FEATURE_NAME
         dictionary2: DICTIONARY[RUN_FEATURE,FEATURE_NAME]
         run_time_set: RUN_TIME_SET; dyn_rf: RUN_FEATURE; i: INTEGER
      do
         current_type := run_feature.current_type
         run_time_set := run_feature.run_class.run_time_set
         if run_time_set.count > 1 then
            key1 := current_type.run_time_mark
            key2 := run_feature.name
	    dictionary2 := dictionary.reference_at(key1)
            if dictionary2 /= Void then
               if not dictionary2.has(key2) then
                  dictionary2.add(run_feature, key2)
                  smart_eiffel.magic_count_increment
               end
            else
               create dictionary2.make
               dictionary2.put(run_feature, key2)
               dictionary.put(dictionary2, key1)
               smart_eiffel.magic_count_increment
            end
            check
               dictionary.at(key1).at(key2) = run_feature
            end
	    if smart_eiffel.status >= 2 then
	       -- To make dynamic possibilities live:
	       from
		  i := run_time_set.count
	       until
		  i = 0
	       loop
		  dyn_rf := run_time_set.item(i).dynamic(run_feature)
		  i := i - 1;
	       end
	    end
         end
      end

feature {C_PRETTY_PRINTER}

   remove(run_feature: RUN_FEATURE) is
      require
         run_feature /= Void
      local
         key1: STRING; key2: FEATURE_NAME
         dictionary2: DICTIONARY[RUN_FEATURE,FEATURE_NAME]
      do
         key1 := run_feature.run_class.run_time_mark
	 dictionary2 := dictionary.reference_at(key1)
         if dictionary2 /= Void then
            key2 := run_feature.name
            dictionary2.remove(key2)
            check
               not dictionary.at(key1).has(key2)
            end
         end
      end

feature {JVM}

   jvm_define is
         -- Produce Java byte code for switches.
      local
         dictionary2: DICTIONARY[RUN_FEATURE,FEATURE_NAME]
         count1, count2, total: INTEGER; switch: SWITCH
         up_rf: RUN_FEATURE
      do
         if not dictionary.is_empty then
            from
               count1 := 1
            until
               count1 > dictionary.count
            loop
               dictionary2 := dictionary.item(count1)
               from
                  count2 := 1
               until
                  count2 > dictionary2.count
               loop
                  up_rf := dictionary2.item(count2)
                  jvm.set_current_frame(up_rf)
                  switch.jvm_define(up_rf)
                  total := total + 1
                  count2 := count2 + 1
               end
               count1 := count1 + 1
            end
         end
         echo.print_count(once "Defined Switche",total)
      end

feature {SWITCH_COLLECTION_VISITOR}

   accept(visitor: SWITCH_COLLECTION_VISITOR) is
      do
         visitor.visit_switch_collection(Current)
      end

feature {NONE}

   dictionary: DICTIONARY[DICTIONARY[RUN_FEATURE,FEATURE_NAME],STRING] is
         -- First STRING key is the name of a run type corresponding
         -- to a RUN_CLASS. Embedded dictionary gives all switching points.
      once
         create Result.with_capacity(1024)
      end

end -- SWITCH_COLLECTION