[NEXT] [PREV]    HANDBOOK / CASE STUDY / The Compiler /

Translating Statements


Here is the specification for translating statements:


179  'action' Statement(Stmt: STMT) 
180     'rule' Statement(assign(V, E, Pos)) : 
181        Designator(V -> TV) 
182        Expression(E -> TE) 
183        Assign(TV, TE, Pos) 
184     'rule' Statement(read(V, Pos)) : 
185        Designator(V -> T) 
186        CheckSimple(T, Pos) 
187        TypeCode(T -> N) 
188        REA(N) 
189        STI 
190     'rule' Statement(write(E, Pos)) : 
191        Expression(E -> T) 
192        CheckSimple(T, Pos) 
193        TypeCode(T -> N) 
194        WRI(N) 
195     'rule' Statement(call(Ident, Actuals, Pos)) : 
196        Apply(Ident, Pos -> Obj) 
197        CheckProcedure(Obj, Pos -> Formals, Level, Start) 
198        GetCurrentNesting(-> CurLev) 
199        MST(CurLev-Level) 
200        ParamList(Formals, Actuals  -> Size) 
201        JSR(Size, Start) 
202     'rule' Statement(if(E, S1, S2, Pos)) : 
203        Expression(E -> T) 
204        CheckBool(T, Pos) 
205        NewLabel(-> L1) 
206        NewLabel(-> L2) 
207        FJP(L1) 
208        Statement(S1) 
209        JMP(L2) 
210        LAB(L1) 
211        Statement(S2) 
212        LAB(L2) 
213     'rule' Statement(while(E, S, Pos)) : 
214        NewLabel(-> L1) 
215        NewLabel(-> L2) 
216        JMP(L2) 
217        LAB(L1) 
218        Statement(S) 
219        LAB(L2) 
220        Expression(E -> T) 
221        CheckBool(T, Pos) 
222        INV 
223        FJP(L1) 
224     'rule' Statement(seq(S1, S2)) : 
225        Statement(S1) 
226        Statement(S2) 
227  'action' Assign(LhsType: TYPE, RhsType: TYPE, Pos: POS) 
228     'rule' Assign(integer, integer, Pos) : STI 
229     'rule' Assign(real, integer, Pos) : FLT STI 
230     'rule' Assign(real, real, Pos) : STI 
231     'rule' Assign(boolean, boolean, Pos) : STI 
232     'rule' Assign(T1, T2, Pos) : 
233        Error("Invalid types in assignment", Pos) 
234  'action' ParamList(Formals: DECLLIST, Actuals: EXPRLIST 
235           -> Size: INT) 
236     'rule' ParamList(decllist(dcl(Id,D,_), Fs), exprlist(E,Es,Pos) 
237            -> S+1) : 
238        Param(D, E, Pos) 
239        ParamList(Fs, Es -> S) 
240     'rule' ParamList(nil, nil -> 0) 
241     'rule' ParamList(decllist(D, Fs), nil(Pos) -> 0) : 
242        Error("Too few actual parameters", Pos) 
243     'rule' ParamList(nil, exprlist(E, Es, Pos) -> 0) : 
244        Error("Too many actual parameters", Pos) 
245  'action' Param(Formal: DEF, Actual: EXPR, Pos: POS) 
246     'rule' Param(valueparam(FType), Actual, Pos) : 
247        Expression(Actual -> AType) 
248        CheckEquiv(FType, AType, Pos) 
249     'rule' Param(varparam(FType), Actual, Pos) : 
250        CheckDesignator(Actual, Pos -> D) 
251        Designator(D -> AType) 
252        CheckEquiv(FType, AType, Pos) 


The predicate Statement(Stmt) analyzes and translates statements. For each alternative of the abstract syntax, there is a separate rule.

As an example, consider the treatment of if-statements that are represented by

   if(E, S1, S2, Pos)
The code for this construct is

   code for expression E
   code for statement S1
   code for statement S2
where L1 and L2 are two unique labels. First, the expression is evaluated. If this yields false, the FJP instruction jumps to L2. Otherwise, the statement S1 is executed. After that, we jump over the code for S2. The code for S2 is preceded by a label S2, which is the target of FJP.

New labels are created by NewLabel. The predicate Expression not only generates codes for its argument E, but also computes the type T of E. In an if-statement this type must be bool. This is checked by CheckBool.

Hence, the rule for if is

'rule' Statement(if(E, S1, S2, Pos)) :
   Expression(E -> T)
   CheckBool(T, Pos)
   NewLabel(-> L1)
   NewLabel(-> L2)
An assignment

   assign(V, E, Pos)
is compiled into code for the designator V and code for the expression E.

After evaluation of these code sequences, the stack top comprises the address given by V and the value of E. An instruction STI is used to store the value at the given address and to remove the two items from the stack. The types TV and TE of V and E must be equal and scalar. In addition, TV may be real and TE may be int. Then the STI must be preceeded by an FLT instruction. This check and the generation of FLT and STI are expressed by the predicate Assign.

The code for a procedure call is

   code for parameters
   JSR(Size, Start)
where CurLev is the current nesting level and the procedure has been declared at level Level and with start label Start. The code for parameters is generated by ParamList.


Assign(LhsType, RhsType, Pos) checks whether a value of type RhsType can be assigned to a designator of type LhsType. If so, it emits the corresponding instruction(s).


The code for parameter passing is constructed by the predicate ParamList(Formals, Actuals -> Size) which processes the lists of formal and actual parameters in parallel.


A pair of formal and actual parameters is handled by Param(Formal, Actual, Pos).