File: assignment_attempt.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 (365 lines) | stat: -rw-r--r-- 11,149 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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
-- 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
--
class ASSIGNMENT_ATTEMPT
   --
   -- For instructions like :
   --                          foo ?= bar
   --                          foo ?= bar + 1
   --
   
inherit INSTRUCTION
   
creation make

feature

   left_side: EXPRESSION

   right_side: EXPRESSION

   side_effect_free: BOOLEAN is False
      
   end_mark_comment: BOOLEAN is False

   use_current: BOOLEAN is
      do
         if left_side.use_current then
            Result := True
         else
            Result := right_side.use_current
         end
      end

   stupid_switch(run_time_set: RUN_TIME_SET): BOOLEAN is
      do
         if smart_eiffel.stupid_switch(left_side.result_type,
				       run_time_set) 
	  then
            if smart_eiffel.stupid_switch(right_side.result_type,
					  run_time_set)
	     then
               if left_side.stupid_switch(run_time_set) then
                  if right_side.stupid_switch(run_time_set) then
                     Result := True
                  end
               end
            end
         end
      end

   afd_check is
      do
         right_side.afd_check
      end

   safety_check is
      do
         right_side.safety_check
      end

   simplify_2(container: COMPOUND; index: INTEGER) is
      do
	 right_side := right_side.simplify_2
      end
   
   collect_c_tmp is
      do
	 right_side.collect_c_tmp
      end

   compile_to_c is
      local
         run_time_set, run_time_set2: RUN_TIME_SET; i: INTEGER
      do
	 if ace.no_check then
	    cpp.put_trace_or_sedb_instruction(start_position)
	 end
	 cpp.put_string(once "/*AA*/")
         if right_type.run_type.is_expanded then
            error_handler.add_position(start_position)
            fatal_error("Right-hand side expanded Not Yet Implemented.")
         end
         run_time_set := left_type.run_class.run_time_set
         if run_time_set.count = 0 then
            if not right_side.side_effect_free then
               right_side.compile_to_c
               cpp.put_string(fz_00)
            end
            left_side.compile_to_c
            cpp.put_string(fz_30)
         elseif right_side.is_current then
            if run_time_set.has(right_side.result_type.run_class) then
               left_side.compile_to_c
               cpp.put_string(once "=((void*)")
               right_side.compile_to_c
               cpp.put_string(fz_14)
            else
               left_side.compile_to_c
               cpp.put_string(fz_30)
            end
	 elseif run_time_set.count = 1 
	    and then not run_time_set.first.is_tagged 
	  then
	    check
	       ace.boost 
	    end
            left_side.compile_to_c
            cpp.put_character('=')
	    run_time_set2 := right_type.run_class.run_time_set
	    if run_time_set2.count = 1 
	       and then 
	       run_time_set2.first = run_time_set.first
	     then
	       -- Only one and the good one.
	    else
	       cpp.put_string(fz_null)
	       cpp.put_character(';')
	    end
	    right_side.compile_to_c
	    cpp.put_string(fz_00)
         else -- General translation scheme:
            left_side.compile_to_c
            cpp.put_character('=')
            if right_side.is_current then
               cpp.put_string(fz_cast_t0_star)
            end
            right_side.compile_to_c
            cpp.put_string(once ";%Nif(NULL!=(")
            left_side.compile_to_c
            cpp.put_string(once ")){%N")
	    if smart_eiffel.scoop
	       and then not left_side.result_type.is_separate
	       and then right_side.result_type.is_separate
	     then
	       cpp.put_string(once "se_subsystem_t* self = se_current_subsystem_thread();%N")
	       cpp.put_string(once "if (get_subsystem(")
	       left_side.compile_to_c
	       cpp.put_string(once ", NULL) == self) {%N")
	       left_side.compile_to_c
	       cpp.put_string(once "=((sT0*)(")
	       left_side.compile_to_c
	       cpp.put_string(once "))->ref;%N}%N")
	    end
	    cpp.put_string(once "switch(((T0*)")
            left_side.compile_to_c
            cpp.put_string(once ")->")
            cpp.put_string(once "id){%N")
	    from
               i := 1
            until
               i > run_time_set.count
            loop
	       check run_time_set.item(i).is_tagged end
               cpp.put_string(once "case ")
               cpp.put_integer(run_time_set.item(i).id)
               cpp.put_character(':')
               i := i + 1
            end
            cpp.put_string(once "%Nbreak;%Ndefault:%N")
            left_side.compile_to_c
            cpp.put_string(once "=NULL;%N}%N}")
         end
      end

   compile_to_jvm is
      local
         run_time_set: RUN_TIME_SET; rc: RUN_CLASS; point1, i: INTEGER
         ca: like code_attribute; branch_index: INTEGER
      do
         ca := code_attribute
         if right_type.run_type.is_expanded then
            error_handler.add_position(start_position)
            fatal_error("Right-hand side expanded Not Yet Implemented.")
         end
         run_time_set := left_type.run_class.run_time_set
         if run_time_set.count = 0 then
            right_side.compile_to_jvm
            ca.opcode_pop
            ca.opcode_aconst_null
            left_side.jvm_assign
         else
            right_side.compile_to_jvm
            ca.opcode_dup
            point1 := ca.opcode_ifnull
            from
               branch_index := ca.get_branch_array_index
               i := run_time_set.count
            until
               i = 0
            loop
               ca.opcode_dup
               rc := run_time_set.item(i)
               rc.opcode_instanceof
               ca.add_branch(ca.opcode_ifne, branch_index)
               i := i - 1
            end
            ca.opcode_pop
            ca.opcode_aconst_null
            ca.resolve_u2_branch(point1)
            ca.resolve_branches( branch_index )
            ca.release_branch_array_index
            left_side.jvm_assign
         end
      end

   once_pre_computable: BOOLEAN is
      do
	 if left_side.once_pre_computable then
	    Result := right_side.once_pre_computable
	 end
      end

   start_position: POSITION is
      do
         Result := left_side.start_position
      end

   to_runnable(ct: E_TYPE): like Current is
      local
	 e: EXPRESSION; fatal_error_flag, warning_flag: BOOLEAN
      do
	 if current_type = Void then
	    current_type := ct
	    e := left_side.to_runnable(ct)
            if e = Void then
	       error_handler.add_position(left_side.start_position)
	       error_handler.append(fz_blhsoa)
	       error_handler.print_as_fatal_error
            end
	    left_side := e
	    e := right_side.to_runnable(ct)
	    if e = Void then
	       error_handler.add_position(right_side.start_position)
	       error_handler.append(fz_brhsoa)
	       error_handler.print_as_fatal_error
            end
	    right_side := e
            if not left_type.run_type.is_reference then
               error_handler.add_type(left_type.run_type,
				      " is not a reference Type.")
               error_handler.add_position(start_position)
	       error_handler.append(" Invalid reverse assignment (VJRV).")
	       error_handler.print_as_fatal_error
            end
	    if right_side.is_current then
	       -- No check yet :-(
	    elseif not left_type.run_type.is_a(right_type.run_type) then
	       fatal_error_flag := True
	    elseif right_type.run_type.is_a(left_type.run_type) then
	       if not left_type.is_like_current and then
		  not right_type.is_formal_generic and then
		  not left_type.is_formal_generic
                then
		  warning_flag := True
               end
	    else
	       error_handler.cancel
            end
	    if fatal_error_flag then
	       error_handler.add_position(start_position)
	       error_handler.append(
	       "Invalid assignment attempt. The left-hand side expression must %
	       %conforms with the right-hand side. Note: the previous %
	       %constraint is more strict than ETL is, but, the SmartEiffel team %
	       %is convinced that this is better for your safety to enforce %
	       %this extra constraint. If you cannot work around, feel free to %
	       %post your problem in our mailing list. If you agree with us, %
	       %feel free to help us to convince other people %
	       %(Wed Mar 19 2003). D.Colnet.")
	       error_handler.print_as_fatal_error
	    end
	    if warning_flag then
	       error_handler.add_type(right_type," is a ")
	       error_handler.add_type(left_type,
	       ". Simple assignment is allowed (%"?=%" is not necessary).")
	       error_handler.add_position(start_position)
	       error_handler.print_as_warning
	    end
	    assignment_handler.assignment(right_side.start_position,
					  right_side.result_type,
					  left_type)
	    Result := Current
         else
            create Result.make(left_side,right_side)
            Result := Result.to_runnable(ct)
         end
      end

   right_type: E_TYPE is
      do
         Result := right_side.result_type
      ensure
         Result /= Void
      end

   left_type: E_TYPE is
      do
         Result := left_side.result_type
      ensure
         Result /= Void
      end

   pretty_print is
      do
         pretty_print_assignment(left_side,once "?=",right_side)
      end

feature {ASSIGNMENT_ATTEMPT_VISITOR}

   accept(visitor: ASSIGNMENT_ATTEMPT_VISITOR) is
      do
         visitor.visit_assignment_attempt(Current)
      end

feature {COMPOUND,INSTRUCTION_WITH_COMMENT}

   verify_scoop(allowed: FORMAL_ARG_LIST) is
      local
         dummy: BOOLEAN
      do
         dummy := left_side.verify_scoop(allowed)
         dummy := right_side.verify_scoop(allowed)
      end

feature {NONE}

   current_type: E_TYPE

   make(ls: like left_side; rs: like right_side) is
      require
         ls /= Void
         rs /= Void
      do
         left_side := ls
         right_side := rs
      end

invariant

   left_side.is_writable

   right_side /= Void

end -- ASSIGNMENT_ATTEMPT