.sp 1.5i .de CL .ft R c\\$1 .ft 5 \fIcode statement-\\$1 .ft 5 \fBbra *\fRexit_label .ft 5 .. .NH Translation of Pascal to EM code .nh .LP .sp A short description of the translation of Pascal constructs to EM code is given in the following paragraphs. The EM instructions and Pascal terminal symbols are printed in \fBboldface\fR. A sentence in \fIitalics\fR is a description of a group of EM (pseudo)instructions. .sp .NH 2 Global Variables .LP .sp For every global variable, a \fBbss\fR block is reserved. To enhance the readability of the EM-code generated, the variable-identifier is used as a data label to address the block. .sp .NH 2 Expressions .LP .sp Operands are always evaluated, so the execution of .br .ti +3m \fBif\fR ( p <> nil ) \fBand\fR ( p^.value <> 0 ) \fBthen\fR ..... .br might cause a run-time error, if p is equal to nil. .LP The left-hand operand of a dyadic operator is almost always evaluated before the right-hand side. Peculiar evaluations exist for the following cases: .sp the expression: set1 <= set2, is evaluated as follows : .nf - evaluate set2 - evaluate set1 - compute set2+set1 - test set2 and set2+set1 for equality .fi .sp the expression: set1 >= set2, is evaluated as follows : .nf - evaluate set1 - evaluate set2 - compute set1+set2 - test set1 and set1+set2 for equality .fi .sp Where allowed, according to the standard, constant integral expressions are compile-time evaluated while an effort is made to report overflow on target machine basis. The integral expressions are evaluated in the type \fIarith\fR. The size of an arith is assumed to be at least the size of the integer type on the target machine. If the target machine's integer size is less than the size of an arith, overflow can be detected at compile-time. However, the following call to the standard procedure new, \fInew(p, 3+5)\fR, is illegal, because the second parameter is not a constant according to the grammar. .sp Constant floating expressions are not compile-time evaluated, because the precision on the target machine and the precision on the machine on which the compiler runs could be different. The boolean expression \fI(1.0 + 1.0) = 2.0\fR could evaluate to false. .sp .NH 2 Statements .NH 3 Assignment Statement \fRPASCAL : .ti +3m \f5(variable-access | function-identifier) \fB:=\f5 expression \fREM : .nf .in +3m .ft I evaluate expression store in variable-access or function-identifier .ft R .in -3m .fi In case of a function-identifier, a hidden temporary variable is used to keep the function result. .bp .NH 3 Goto Statement \fRPASCAL : .ti +3m \fBGOTO\f5 label \fREM : .in +3m Two cases can be distinguished : .br - local goto, .ti +2m in which a \fBbra\fR is generated. - non-local goto, .in +2m .ll -1i a goto_descriptor is build, containing the ProgramCounter of the instruction jumped to and an offset in the target procedure frame which contains the value of the StackPointer after the jump. The code for the jump itself is to load the address of the goto_descriptor, followed by a push of the LocalBase of the target procedure and a \fBcal\fR $_gto. A message is generated to indicate that a procedure or function contains a statement which is the target of a non-local goto. .ll +1i .in -2m .in -3m .sp 2 .NH 3 If Statement \fRPASCAL : .in +3m .ft 5 \fBIF\f5 boolean-expression \fBTHEN\f5 statement .in -3m \fREM : .nf .in +3m \fIevaluation boolean-expression \fBzeq \fR*exit_label \fIcode statement \fRexit_label .in -3m .fi .sp 2 \fRPASCAL : .in +3m .ft 5 \fBIF\f5 boolean-expression \fBTHEN\f5 statement-1 \fBELSE\f5 statement-2 .in -3m \fREM : .nf .in +3m \fIevaluation boolean-expression \fBzeq \fR*else_label \fIcode statement-1 \fBbra \fR*exit_label \fRelse_label \fIcode statement-2 \fRexit_label .in -3m .fi .sp 2 .NH 3 Repeat Statement \fRPASCAL : .in +3m .ft 5 \fBREPEAT\f5 statement-sequence \fBUNTIL\f5 boolean-expression .in -3m \fREM : .nf .in +3m \fRrepeat_label \fIcode statement-sequence \fIevaluation boolean-expression \fBzeq\fR *repeat_label .in -3m .fi .bp .NH 3 While Statement \fRPASCAL : .in +3m .ft 5 \fBWHILE\f5 boolean-expression \fBDO\f5 statement .in -3m \fREM : .nf .in +3m \fRwhile_label \fIevaluation boolean-expression \fBzeq\fR *exit_label \fIcode statement \fBbra\fR *while_label \fRexit_label .in -3m .fi .sp 2 .NH 3 Case Statement .LP .sp The case-statement is implemented using the \fBcsa\fR and \fBcsb\fR instructions. \fRPASCAL : .in +3m \fBCASE\f5 case-expression \fBOF\f5 .in +5m case-constant-list-1 \fB:\f5 statement-1 \fB;\f5 .br case-constant-list-2 \fB:\f5 statement-2 \fB;\f5 .br \&. .br \&. .br case-constant-list-n \fB:\f5 statement-n [\fB;\f5] .in -5m \fBEND\fR .in -3m .sp 2 .LP .ll -1i The \fBcsa\fR instruction is used if the range of the case-expression value is dense, i.e. .br .ti +3m \f5( upperbound \- lowerbound ) / number_of_cases\fR .br is less than the constant DENSITY, defined in the file \fIdensity.h\fR. If the range is sparse, a \fBcsb\fR instruction is used. .ll +1i \fREM : .nf .in +3m \fIevaluation case-expression \fBbra\fR *l1 .CL 1 .CL 2 . . .CL n .ft R \&.case_descriptor .ft 5 \fIgeneration case_descriptor \fRl1 .ft 5 \fBlae\fR .case_descriptor .ft 5 \fBcsa\fR size of (case-expression) \fRexit_label .in -3m .fi .bp .NH 3 For Statement \fRPASCAL : .in +3m .ft 5 \fBFOR\f5 control-variable \fB:=\f5 initial-value (\fBTO\f5 | \fBDOWNTO\f5) final-value \fBDO\f5 statement .ft R .in -3m The initial-value and final-value are evaluated at the beginning of the loop. If the values are not constant, they are evaluated once and stored in a temporary. EM : .nf .in +3m \fIload initial-value \fIload final-value \fBbgt\fR exit-label (* DOWNTO : \fBblt\fI exit-label\fR *) \fIload initial-value \fRl1 \fIstore in control-variable \fIcode statement \fIload control-variable \fBdup\fI control-variable \fIload final-value \fBbeq\fR exit_label \fBinc\fI control-variable\fR (* DOWNTO : \fBdec\fI control-variable\fR *) \fBbra *\fRl1 \fRexit_label .in -3m .fi Note: testing must be done before incrementing(decrementing) the control-variable, .br \h'\w'Note: 'u'because wraparound could occur, which could lead to an infinite loop. .sp 2 .NH 3 With Statement \fRPASCAL : .ti +3m \fBWITH\f5 record-variable-list \fBDO\f5 statement .ft R The statement .ti +3m \fBWITH\fR r\s-3\d1\u\s0, r\s-3\d2\u\s0, ..., r\s-3\dn\u\s0 \fBDO\f5 statement .ft R is equivalent to .in +3m \fBWITH\fR r\s-3\d1\u\s0 \fBDO\fR \fBWITH\fR r\s-3\d2\u\s0 \fBDO\fR ... \fBWITH\fR r\s-3\dn\u\s0 \fBDO\f5 statement .ft R .in -3m The translation of .ti +3m \fBWITH\fR r\s-3\d1\u\s0 \fBDO\f5 statement .br .ft R is .nf .in +3m \fIpush address of r\s-3\d1\u\s0 \fIstore address in temporary \fIcode statement .in -3m .fi .ft R An occurrence of a field is translated into: .in +3m \fIload temporary .br \fIadd field-offset .in -3m .bp .NH 2 Procedure and Function Calls .ft R In general, the call .ti +5m p(a\s-3\d1\u\s0, a\s-3\d2\u\s0, ...., a\s-3\dn\u\s0) .br is translated into the sequence: .in +5m .nf \fIevaluate a\s-3\dn\u\s0 \&. \&. \fIevaluate a\s-3\d2\u\s0 \fIevaluate a\s-3\d1\u\s0 \fIpush localbase \fBcal\fR $p \fIpop parameters .ft R .fi .in -5m i.e. the order of evaluation and binding of the actual-parameters is from right to left. In general, a copy of the actual-parameter is made when the formal-parameter is a value-parameter. If the formal-parameter is a variable-parameter, a pointer to the actual-parameter is pushed. In case of a function call, a \fBlfr\fR is generated, which pushes the function result on top of the stack. .sp 2 .NH 2 Register Messages .ft R A register message can be generated to indicate that a local variable is never referenced indirectly. This implies that a register can be used for a variable. We distinguish the following classes, given in decreasing priority: \(bu control-variable and final-value of a for-statement .br .ti +5m to speed up testing, and execution of the body of the for-statement .sp \(bu record-variable of a with-statement .br .ti +5m to improve the field selection of a record .sp \(bu remaining local variables and parameters .sp 2 .NH 2 Compile-time optimizations .ft R The only optimization that is performed is the evaluation of constant integral expressions. The optimization of constructs like .ti +5m \fBif\f5 false \fBthen\f5 statement\fR, .br is left to either the peephole optimizer, or a global optimizer.