File: code_printer.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 (312 lines) | stat: -rw-r--r-- 8,281 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
-- 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
--
deferred class CODE_PRINTER
   --
   -- Common root for C_PRETTY_PRINTER and JVM.
   --

inherit
   GLOBALS
   VISITABLE

feature {CODE_PRINTER_VISITOR}

   accept(visitor: CODE_PRINTER_VISITOR) is
      deferred
      end

feature {NONE}

   inlined_procedure_count: INTEGER

   inlined_function_count: INTEGER

   procedure_count: INTEGER

   function_count: INTEGER

   precursor_routine_count: INTEGER

   real_procedure_count: INTEGER

   real_function_count: INTEGER

   static_expression_count: INTEGER

feature {RUN_FEATURE_3}

   incr_inlined_procedure_count is
      do
         inlined_procedure_count := inlined_procedure_count + 1
      end

   incr_real_procedure_count is
      do
         real_procedure_count := real_procedure_count + 1
      end

   incr_procedure_count is
      do
         procedure_count := procedure_count + 1
      end

feature {RUN_FEATURE_4}

   incr_inlined_function_count is
      do
         inlined_function_count := inlined_function_count + 1
      end

   incr_real_function_count is
      do
         real_function_count := real_function_count + 1
      end

   incr_function_count is
      do
         function_count := function_count + 1
      end

feature {RUN_FEATURE_10, RUN_FEATURE_11}

   incr_precursor_routine_count is
      do
         precursor_routine_count := precursor_routine_count + 1
      end

feature {NONE} -- Context stacks:

   top: INTEGER
         -- Index for top of followings stacks.

   stack_code: FIXED_ARRAY[INTEGER] is
         -- The indicating stack. It contains only one
         -- of the following unique code.
      once
         create Result.make(stack_first_size)
      end

   C_direct_call: INTEGER is unique
         -- Target is sure not to be Void and there is only one possible
         -- type (target is often Current, a manifest string or an expanded).

   C_check_id: INTEGER is unique
         -- Target is a reference type which can be Void but only one type
         -- is the good one.

   C_switch: INTEGER is unique
         -- Target is a reference type with more than one possibility.

   C_create_instruction: INTEGER is unique
         -- Target has been just created with a create instruction and
         -- need to be initialized with some create procedure call.

   C_create_expression: INTEGER is unique
         -- Target has been just created with a create expression and
         -- need to be initialized inside the create function.

   C_expanded_initialize: INTEGER is unique
         -- Target is some expanded to initialize with the default
         -- initialization procedure (ie. without arguments).

   C_inline_dca: INTEGER is unique
         -- Inlining of a direct call applied on attribute of target.
         -- Target is the one given at `top-1' plus the access to
         -- the corresponding attribute stored at level `top'.
         -- Arguments are taken at `top-1' context.

   C_same_target: INTEGER is unique
         -- Target is stored at level top - 1

   C_inline_one_pc: INTEGER is unique
         -- Inlining `one_pc' of RUN_FEATURE_3

   C_inside_twin: INTEGER is unique
         -- In order to call the user's `copy'.

   C_precursor: INTEGER is unique
         -- For Precursor calls.

   C_scoop_unwrapper: INTEGER is unique
         -- For calls into scoop unwrapper.

   C_scoop_wrapper: INTEGER is unique
	 -- For calls into scoop wrapper.

   C_string_inspector: INTEGER is unique
         -- For storage and count string fields generation inside a STRING
         -- inspect.

   C_introspect: INTEGER is unique
         -- For the introspection features

   -- Contents of stacks depends on `stack_code'.
   stack_rf: FIXED_ARRAY[RUN_FEATURE] is
      once
         create Result.make(stack_first_size)
      end

   stack_target: FIXED_ARRAY[EXPRESSION] is
      once
         create Result.make(stack_first_size)
      end

   stack_args: FIXED_ARRAY[EFFECTIVE_ARG_LIST] is
      once
         create Result.make(stack_first_size)
      end

   stack_static_rf: FIXED_ARRAY[RUN_FEATURE] is
      once
         create Result.make(stack_first_size)
      end

   stack_cpc: FIXED_ARRAY[CALL_PROC_CALL] is
      once
         create Result.make(stack_first_size)
      end

   stack_string: FIXED_ARRAY[STRING] is
      once
         create Result.make(stack_first_size)
      end

   stack_first_size: INTEGER is 12

   stack_push(code: INTEGER) is
         -- Push the `code' and resize all stacks if needed.
      local
         new_size: INTEGER
      do
         top := top + 1
         if top > stack_code.upper then
            new_size := stack_code.upper * 2
            stack_code.resize(new_size)
            stack_rf.resize(new_size)
            stack_target.resize(new_size)
            stack_args.resize(new_size)
            stack_static_rf.resize(new_size)
            stack_cpc.resize(new_size)
            stack_string.resize(new_size)
            if new_size > 1024 then
               stack_overflow
            end
         end
         stack_code.put(code,top)
      end

feature {PRECURSOR_CALL}

   push_precursor(rf: RUN_FEATURE; args: EFFECTIVE_ARG_LIST) is
      require
         rf /= Void
      do
         stack_push(C_precursor)
         stack_rf.put(rf,top)
         stack_args.put(args,top)
         direct_call_count := direct_call_count + 1
      end

feature {RUN_FEATURE_3}

   stack_not_full: BOOLEAN is
      do
         Result := top < 50
      end

feature {NONE}

   stack_overflow is
      local
         i: INTEGER
         rf: RUN_FEATURE
         rtm: STRING
         rtma: FIXED_ARRAY[STRING]
      do
         error_handler.append("Infinite inlining loop (bad recursion ??). ")
         from
            i := top - 1
         until
            i < stack_code.lower
         loop
            rf := stack_rf.item(i)
            if rf /= Void then
               error_handler.add_position(rf.start_position)
               rtm := rf.current_type.run_time_mark
               if rtma = Void then
                  create rtma.with_capacity(top)
                  rtma.add_last(rtm)
                  error_handler.append(rtm)
               elseif rtma.fast_has(rtm) then
               else
                  rtma.add_last(rtm)
                  error_handler.append(", ")
                  error_handler.append(rtm)
               end
            end
            i := i - 1
         end
         error_handler.append(",...")
	 error_handler.print_as_fatal_error
      end

feature

   pop is
      do
         check
            stack_code.lower <= top
         end
         top := top - 1
      ensure
         old(top) = top + 1
      end

feature {NONE}

   direct_call_count: INTEGER

   check_id_call_count: INTEGER

   stupid_switch_call_count: INTEGER

   sure_void_count: INTEGER

   switched_call_count: INTEGER

feature {GC_HANDLER}

   incr_direct_call_count is
      do
         direct_call_count := direct_call_count + 1
      end

   incr_switched_call_count is
      do
         switched_call_count := switched_call_count + 1
      end

end -- CODE_PRINTER