Pristine Ack-5.5
[Ack-5.5.git] / doc / pascal / transpem.doc
1 .sp 1.5i
2 .de CL
3 .ft R
4 c\\$1
5 .ft 5
6  \fIcode statement-\\$1
7 .ft 5
8  \fBbra *\fRexit_label
9 .ft 5
10 ..
11 .NH
12 Translation of Pascal to EM code
13 .nh
14 .LP
15 .sp
16 A short description of the translation of Pascal constructs to EM code is
17 given in the following paragraphs. The EM instructions and Pascal terminal
18 symbols are printed in \fBboldface\fR. A sentence in \fIitalics\fR is a
19 description of a group of EM (pseudo)instructions.
20 .sp
21 .NH 2
22 Global Variables
23 .LP
24 .sp
25 For every global variable, a \fBbss\fR block is reserved. To enhance the
26 readability of the EM-code generated, the variable-identifier is used as
27 a data label to address the block.
28 .sp
29 .NH 2
30 Expressions
31 .LP
32 .sp
33 Operands are always evaluated, so the execution of
34 .br
35 .ti +3m
36 \fBif\fR ( p <> nil ) \fBand\fR ( p^.value <> 0 ) \fBthen\fR .....
37 .br
38 might cause a run-time error, if p is equal to nil.
39 .LP
40 The left-hand operand of a dyadic operator is almost always evaluated before
41 the right-hand side. Peculiar evaluations exist for the following cases:
42 .sp
43 the expression:  set1 <= set2, is evaluated as follows :
44 .nf
45 - evaluate set2
46 - evaluate set1
47 - compute set2+set1
48 - test set2 and set2+set1 for equality
49 .fi
50 .sp
51 the expression:  set1 >= set2, is evaluated as follows :
52 .nf
53 - evaluate set1
54 - evaluate set2
55 - compute set1+set2
56 - test set1 and set1+set2 for equality
57 .fi
58 .sp
59 Where allowed, according to the standard, constant integral expressions are
60 compile-time evaluated while an effort is made to report overflow on target
61 machine basis. The integral expressions are evaluated in the type \fIarith\fR.
62 The size of an arith is assumed to be at least the size of the integer type
63 on the target machine. If the target machine's integer size is less than the
64 size of an arith, overflow can be detected at compile-time. However, the
65 following call to the standard procedure new, \fInew(p, 3+5)\fR, is illegal,
66 because the second parameter is not a constant according to the grammar.
67 .sp
68 Constant floating expressions are not compile-time evaluated, because the
69 precision on the target machine and the precision on the machine on which the
70 compiler runs could be different. The boolean expression \fI(1.0 + 1.0) = 2.0\fR
71 could evaluate to false.
72 .sp
73 .NH 2
74 Statements
75 .NH 3
76 Assignment Statement
77
78 \fRPASCAL :
79 .ti +3m
80 \f5(variable-access | function-identifier) \fB:=\f5 expression
81
82 \fREM :
83 .nf
84 .in +3m
85 .ft I
86 evaluate expression
87 store in variable-access or function-identifier
88 .ft R
89 .in -3m
90 .fi
91
92 In case of a function-identifier, a hidden temporary variable is used to
93 keep the function result.
94 .bp
95 .NH 3
96 Goto Statement
97
98 \fRPASCAL :
99 .ti +3m
100 \fBGOTO\f5 label
101
102 \fREM :
103 .in +3m
104 Two cases can be distinguished :
105 .br
106 - local goto,
107 .ti +2m
108 in which a \fBbra\fR is generated.
109
110 - non-local goto,
111 .in +2m
112 .ll -1i
113 a goto_descriptor is build, containing the ProgramCounter of the instruction
114 jumped to and an offset in the target procedure frame which contains the
115 value of the StackPointer after the jump. The code for the jump itself is to
116 load the address of the goto_descriptor, followed by a push of the LocalBase
117 of the target procedure and a \fBcal\fR $_gto. A message is generated to
118 indicate that a procedure or function contains a statement which is the
119 target of a non-local goto.
120 .ll +1i
121 .in -2m
122 .in -3m
123 .sp 2
124 .NH 3
125 If Statement
126
127 \fRPASCAL :
128 .in +3m
129 .ft 5
130 \fBIF\f5 boolean-expression \fBTHEN\f5 statement
131
132 .in -3m
133 \fREM :
134 .nf
135 .in +3m
136  \fIevaluation boolean-expression
137  \fBzeq \fR*exit_label
138  \fIcode statement
139 \fRexit_label
140 .in -3m
141 .fi
142 .sp 2
143 \fRPASCAL :
144 .in +3m
145 .ft 5
146 \fBIF\f5 boolean-expression \fBTHEN\f5 statement-1 \fBELSE\f5 statement-2
147
148 .in -3m
149 \fREM :
150 .nf
151 .in +3m
152  \fIevaluation boolean-expression
153  \fBzeq \fR*else_label
154  \fIcode statement-1
155  \fBbra \fR*exit_label
156 \fRelse_label
157  \fIcode statement-2
158 \fRexit_label
159 .in -3m
160 .fi
161 .sp 2
162 .NH 3
163 Repeat Statement
164
165 \fRPASCAL :
166 .in +3m
167 .ft 5
168 \fBREPEAT\f5 statement-sequence \fBUNTIL\f5 boolean-expression
169
170 .in -3m
171 \fREM :
172 .nf
173 .in +3m
174 \fRrepeat_label
175  \fIcode statement-sequence
176  \fIevaluation boolean-expression
177  \fBzeq\fR *repeat_label
178 .in -3m
179 .fi
180 .bp
181 .NH 3
182 While Statement
183
184 \fRPASCAL :
185 .in +3m
186 .ft 5
187 \fBWHILE\f5 boolean-expression \fBDO\f5 statement
188
189 .in -3m
190 \fREM :
191 .nf
192 .in +3m
193 \fRwhile_label
194  \fIevaluation boolean-expression
195  \fBzeq\fR *exit_label
196  \fIcode statement
197  \fBbra\fR *while_label
198 \fRexit_label
199 .in -3m
200 .fi
201 .sp 2
202 .NH 3
203 Case Statement
204 .LP
205 .sp
206 The case-statement is implemented using the \fBcsa\fR and \fBcsb\fR
207 instructions.
208
209 \fRPASCAL :
210 .in +3m
211 \fBCASE\f5 case-expression \fBOF\f5
212 .in +5m
213 case-constant-list-1 \fB:\f5 statement-1 \fB;\f5
214 .br
215 case-constant-list-2 \fB:\f5 statement-2 \fB;\f5
216 .br
217 \&.
218 .br
219 \&.
220 .br
221 case-constant-list-n \fB:\f5 statement-n [\fB;\f5]
222 .in -5m
223 \fBEND\fR
224 .in -3m
225 .sp 2
226 .LP
227 .ll -1i
228 The \fBcsa\fR instruction is used if the range of the case-expression
229 value is dense, i.e.
230 .br
231 .ti +3m
232 \f5( upperbound \- lowerbound ) / number_of_cases\fR
233 .br
234 is less than the constant DENSITY, defined in the file \fIdensity.h\fR.
235
236 If the range is sparse, a \fBcsb\fR instruction is used.
237
238 .ll +1i
239 \fREM :
240 .nf
241 .in +3m
242  \fIevaluation case-expression
243  \fBbra\fR *l1
244 .CL 1
245 .CL 2
246  .
247  .
248 .CL n
249 .ft R
250 \&.case_descriptor
251 .ft 5
252  \fIgeneration case_descriptor
253 \fRl1
254 .ft 5
255  \fBlae\fR .case_descriptor
256 .ft 5
257  \fBcsa\fR size of (case-expression)
258 \fRexit_label
259 .in -3m
260 .fi
261 .bp
262 .NH 3
263 For Statement
264
265 \fRPASCAL :
266 .in +3m
267 .ft 5
268 \fBFOR\f5 control-variable \fB:=\f5 initial-value (\fBTO\f5 | \fBDOWNTO\f5) final-value \fBDO\f5 statement
269
270 .ft R
271 .in -3m
272 The initial-value and final-value are evaluated at the beginning of the loop.
273 If the values are not constant, they are evaluated once and stored in a
274 temporary.
275
276 EM :
277 .nf
278 .in +3m
279  \fIload initial-value
280  \fIload final-value
281  \fBbgt\fR exit-label            (* DOWNTO : \fBblt\fI exit-label\fR *)
282  \fIload initial-value
283 \fRl1
284  \fIstore in control-variable
285  \fIcode statement
286  \fIload control-variable
287  \fBdup\fI control-variable
288  \fIload final-value
289  \fBbeq\fR exit_label
290  \fBinc\fI control-variable\fR    (* DOWNTO : \fBdec\fI control-variable\fR *)
291  \fBbra *\fRl1
292 \fRexit_label
293 .in -3m
294 .fi
295
296 Note: testing must be done before incrementing(decrementing) the
297 control-variable,
298 .br
299 \h'\w'Note: 'u'because wraparound could occur, which could lead to an infinite
300 loop.
301 .sp 2
302 .NH 3
303 With Statement
304
305 \fRPASCAL :
306 .ti +3m
307 \fBWITH\f5 record-variable-list \fBDO\f5 statement
308
309 .ft R
310 The statement
311 .ti +3m
312 \fBWITH\fR r\s-3\d1\u\s0, r\s-3\d2\u\s0, ..., r\s-3\dn\u\s0 \fBDO\f5 statement
313
314 .ft R
315 is equivalent to
316 .in +3m
317 \fBWITH\fR r\s-3\d1\u\s0 \fBDO\fR
318    \fBWITH\fR r\s-3\d2\u\s0 \fBDO\fR
319       ...
320          \fBWITH\fR r\s-3\dn\u\s0 \fBDO\f5 statement
321
322 .ft R
323 .in -3m
324 The translation of
325 .ti +3m
326 \fBWITH\fR r\s-3\d1\u\s0 \fBDO\f5 statement
327 .br
328 .ft R
329 is
330 .nf
331 .in +3m
332 \fIpush address of r\s-3\d1\u\s0
333 \fIstore address in temporary
334 \fIcode statement
335 .in -3m
336 .fi
337
338 .ft R
339 An occurrence of a field is translated into:
340 .in +3m
341 \fIload temporary
342 .br
343 \fIadd field-offset
344 .in -3m
345 .bp
346 .NH 2
347 Procedure and Function Calls
348
349 .ft R
350 In general, the call
351 .ti +5m
352 p(a\s-3\d1\u\s0, a\s-3\d2\u\s0, ...., a\s-3\dn\u\s0)
353 .br
354 is translated into the sequence:
355
356 .in +5m
357 .nf
358 \fIevaluate a\s-3\dn\u\s0
359 \&.
360 \&.
361 \fIevaluate a\s-3\d2\u\s0
362 \fIevaluate a\s-3\d1\u\s0
363 \fIpush localbase
364 \fBcal\fR $p
365 \fIpop parameters
366 .ft R
367 .fi
368 .in -5m
369
370 i.e. the order of evaluation and binding of the actual-parameters is from
371 right to left. In general, a copy of the actual-parameter is made when the
372 formal-parameter is a value-parameter. If the formal-parameter is a
373 variable-parameter, a pointer to the actual-parameter is pushed.
374
375 In case of a function call, a \fBlfr\fR is generated, which pushes the
376 function result on top of the stack.
377 .sp 2
378 .NH 2
379 Register Messages
380
381 .ft R
382 A register message can be generated to indicate that a local variable is never
383 referenced indirectly. This implies that a register can be used for a variable.
384 We distinguish the following classes, given in decreasing priority:
385
386 \(bu control-variable and final-value of a for-statement
387 .br
388 .ti +5m
389 to speed up testing, and execution of the body of the for-statement
390 .sp
391 \(bu record-variable of a with-statement
392 .br
393 .ti +5m
394 to improve the field selection of a record
395 .sp
396 \(bu remaining local variables and parameters
397 .sp 2
398 .NH 2
399 Compile-time optimizations
400
401 .ft R
402 The only optimization that is performed is the evaluation of constant
403 integral expressions. The optimization of constructs like
404 .ti +5m
405 \fBif\f5 false \fBthen\f5 statement\fR,
406 .br
407 is left to either the peephole optimizer, or a global optimizer.