File: create_instruction.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 (299 lines) | stat: -rw-r--r-- 7,687 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
-- 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 CREATE_INSTRUCTION
   --
   -- The new style create instruction.
   --

inherit CREATE_TOOLS; INSTRUCTION

creation {EIFFEL_PARSER,CREATE_INSTRUCTION} make

feature

   side_effect_free: BOOLEAN is False
      
   frozen to_runnable(ct: E_TYPE): like Current is
      local
	 t: E_TYPE
      do
         if current_type = Void then
	    current_type := ct
            check_writable(ct)
	    if type /= Void then
	       check_explicit_type
	       t := type
	    else
	       t := writable.result_type
	    end
            check_created_type(t)
            check_create_clause(t)
            Result := Current
         else
            !!Result.make(start_position,type,writable,call)
            Result := Result.to_runnable(ct)
         end
      end

   frozen once_pre_computable: BOOLEAN is
      local
	 t: like type
      do
         if writable.once_pre_computable then
	    if arguments = Void or else arguments.once_pre_computable then
	       t := type
	       if t = Void then
		  t := writable.result_type
	       end
	       Result := common_once_pre_computable(t)
	    end
	 end
      end

   frozen use_current: BOOLEAN is
      local
	 args: like arguments
      do
	 if writable.use_current then
	    Result := True
	 elseif run_feature /= Void then
	    args := arguments
	    if args /= Void then
	       Result := args.use_current
	    end
	 end
      end

   frozen collect_c_tmp is
      local
         args: like arguments
      do
	 args := arguments
	 if args /= Void then
	    args.collect_c_tmp
	 end
      end

   frozen stupid_switch(run_time_set: RUN_TIME_SET): BOOLEAN is
      local
         t: E_TYPE
      do
         if type /= Void then
            t := type
         else
            t := writable.result_type
         end
         if t.is_anchored then
         elseif t.is_generic then
         else
            if call = Void then
               Result := writable.stupid_switch(run_time_set)
            else
               Result := call.stupid_switch(run_time_set)
            end
         end
      end

   simplify_2(container: COMPOUND; index: INTEGER) is
      do
      end
   
   pretty_print is
      do
         pretty_printer.keyword(fz_create)
	 if type /= Void then
	    pretty_printer.put_character('{')
	    type.pretty_print
	    pretty_printer.put_character('}')
	    pretty_printer.put_character(' ')
	 end
	 if call /= Void then
	    call.pretty_print
	 else
	    writable.pretty_print
	    if pretty_printer.semi_colon_flag then
	       pretty_printer.put_character(';')
	    end
	 end
      end

   frozen compile_to_c is
         -- @TODO: lock till the end of the procedure call
      local
	 t: E_TYPE; rf3: RUN_FEATURE_3; need_se_tmp: BOOLEAN
      do
	 t := type
	 if t = Void then
	    t := writable.result_type.run_type
	 end
         if t.is_reference then
            c2c_opening(t)
	    if run_feature /= Void then
	       cpp.push_create_instruction(run_feature, arguments)
	       -- *** IS IT NECESSARY ***
               -- run_feature.collect_c_tmp
               -- need_se_tmp := cpp.se_tmp_open_declaration
	       -- ***
	       run_feature.mapping_c
               if need_se_tmp then
                  cpp.se_tmp_close_declaration
               end
	       cpp.pop
	    end
            --if smart_eiffel.scoop and then t.is_separate then
            --	 cpp.put_string(once "se_join_subsystem(n->subsystem);%N")
            --end
            c2c_closing(t)
         else
	    writable.compile_to_c
	    cpp.put_character('=')
	    cpp.put_character('M')
	    cpp.put_integer(t.id)
	    cpp.put_string(fz_00)
	    if run_feature /= Void then
	       check
		  run_feature = t.run_class.a_default_create
	       end
	       rf3 ?= run_feature
	       cpp.put_proc_call_0(rf3, writable, Void)
	    end
         end
      end

   frozen compile_to_jvm is
      local
         w: EXPRESSION; t: E_TYPE
      do
         w := writable
	 if type /= Void then
	    t := type
	 else
	    t := writable.result_type
	 end
	 t := t.run_type
         compile_to_jvm0(t)
	 if run_feature /= Void then
	    jvm.inside_create_instruction(run_feature,call)
	 end
         t.jvm_check_class_invariant
         w.jvm_assign_creation
      end

   end_mark_comment: BOOLEAN is False

feature {COMPOUND,INSTRUCTION_WITH_COMMENT}

   verify_scoop(allowed: FORMAL_ARG_LIST) is
      do
      end

feature {CREATE_INSTRUCTION_VISITOR}

   accept(visitor: CREATE_INSTRUCTION_VISITOR) is
      do
         visitor.visit_create_instruction(Current)
      end

feature {NONE}

   check_writable(ct: E_TYPE) is
      require
         ct /= Void
      local
         w: like writable
      do
         w := writable.to_runnable(ct)
         if w = Void then
            error_handler.add_position(writable.start_position)
            fatal_error("Bad writable target for creation.")
         else
            writable := w
         end
      end

   c2c_opening(t: E_TYPE) is
      require
         t.is_reference
      local
         rc: RUN_CLASS; e_result: E_RESULT
      do
         rc := t.run_class
	 if ace.no_check then
	    cpp.put_trace_or_sedb_instruction(start_position)
	 end
         cpp.put_character('{')
         gc_handler.declare_allocate_n(rc)
         cpp.expanded_attributes(t)
         e_result ?= writable
         if e_result /= Void and then e_result.is_once_result then
            cpp.put_string(e_result.c_variable_name)
            cpp.put_string(once "=((T0*)n);%N")
         end
      end

   c2c_closing(t: E_TYPE) is
      require
         t.is_reference
      local
         e_result: E_RESULT
      do
         e_result ?= writable
         if e_result = Void or else not e_result.is_once_result then
            writable.compile_to_c
            cpp.put_string(once "=((T0*)n);%N")
         end
         if cpp.call_invariant_start(t) then
            cpp.put_character('n')
            cpp.call_invariant_end
            cpp.put_character(';')
         end
         cpp.put_character('}')
         cpp.put_character('%N')
      end

   make(sp: like start_position
	t: like type; w: like writable; c: like call) is
      require
         not sp.is_unknown
         w /= Void
      do
         start_position := sp
         type := t
         writable := w
         call := c
      ensure
         start_position = sp
         type = t
         writable = w
         call = c
      end

invariant

   not start_position.is_unknown

   writable.is_writable

end -- CREATE_INSTRUCTION