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 FJP(L1) code for statement S1 JMP(L2) LAB(L1) code for statement S2 LAB(L2)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) FJP(L1) Statement(S1) JMP(L2) LAB(L1) Statement(S2) LAB(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
MST(CurLev-Level) 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
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).
ParamList
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.
Param
A pair of formal and actual parameters is handled by Param(Formal, Actual, Pos).