Annexe B : Éléments de solutions des exercices
B.1 Procédures
(chapitre 9)
Procédures PROCS
de génération de code pour les procédures.
procedure PROCS ;
begin
while TOKEN = PROC_TOKEN do begin
NEXT_TOKEN ;
TEST_ET_ENTRE (ID_TOKEN, PROCEDURE) ;
TESTE (PT_VIRG_TOKEN) ;
INSTS ;
TESTE (PT_VIRG_TOKEN) ;
GENERER1 (RET) ;
end
end ;
La procédure TEST_ET_ENTRE
est modifiée pour insérer le
numéro de la prochaine instruction P-Code à générer dans le
champ ADRESSE
de la table des symboles.
procedure TESTE_ET_ENTRE (T : TOKENS ; C : CLASSES );
var PCODE_INST
begin
...
CASE C in
...
PROCEDURE : begin
NEXT_INST (PCODE_INST) ;
with TABLEINDEX [DERNIERSYM] do begin
NOM := SYM ;
CLASSE := C ;
ADRESSE := PCODE_INST
end
end ;
...
end ;
B.2 Déclarations locales
(chapitre 10)
Procédure PROCS
d'analyse de déclarations de
procédures avec allocation des variables locales.
procedure PROCS ;
var LIMIT, OLD_OFFSET : integer ;
begin
while TOKEN = PROC_TOKEN do begin
NEXT_TOKEN ;
(* on entre le nom de la procedure en global *)
TEST_ET_ENTRE (ID_TOKEN, PROCEDURE) ;
TESTE (PT_VIRG_TOKEN) ;
(* on memorise le dernier global *)
LIMIT := DERNIERSYM ;
(* on memorise l'offset *)
OLD_OFFSET := OFFSET ;
(* on met l'offset a zero pour les variables locales *)
OFFSET := 0 ;
if TOKEN = CONST_TOKEN then CONSTS ;
if TOKEN = VAR_TOKEN then VARS ;
(* on genere le INT pour les locaux *)
GENERER2 (INT, OFFSET) ;
INSTS ;
TESTE (PT_VIRG_TOKEN) ;
(* on oublie les declarations locales *)
DERNIERSYM := LIMIT ;
OFFSET := OLD_OFFSET ;
GENERER1 (RET)
end
end ;
Les instructions CAL
et RET
de l'interpréteur sont modifiées et l'instruction LDL
est ajoutée :
with INST do
case MNE of
...
CAL : begin
(* on empile l'adresse de retour *)
SP := SP + 1 ;
MEM [SP] := PC ;
(* on empile la base de la zone de l'appelant *)
SP := SP + 1 ;
MEM [SP] := BASE ;
(* mise a jour de BASE *)
BASE := SP -2 ;
PC := SUITE
end ;
RET : begin
(* on recupere l'adresse de retour *)
PC := MEM [BASE] ;
(* on depile toute la zone *)
SP := BASE - 1 ;
(* on recupere l'adresse de la zone de l'appelant *)
BASE := MEM [BASE + 1]
end ;
LDL : begin
(* on empile l'adresse relative au debut de la zone *)
SP := SP + 1 ;
MEM [SP] := BASE + 2 + SUITE
end ;
end
B.3 Procédures imbriquées
(chapitre 11)
Exercice 1
Le code de l'interpréteur pour l'instruction LDL
est le suivant
(cf. BASE
sur la figure B.1)
| |
|----------|
| C |
|----------|
| ------|---------+
|----------| |
+-----------|----- | |
| |----------| |
BASE --------------------->| AR | |
| |==========| |
| | B | |
| |----------| |
| | ------|---------+
| |----------| |
| +---------|----- | |
chainage | | |----------| | chainage
dynamique +-|-------->| AR | | statique
| |==========| |
| | B | |
| |----------| |
| | ------|-----+ |
| |----------| | |
| +-------|----- | | |
| | |----------| | |
+-|------>| AR |<----|---+
| |==========| |
| | A | |
+------>+----------+<----+
Figure B.1 : Liens de chaînage statique et dynamique dans la pile,
positionnement de BASE.
LDL SUITE1 SUITE2
i := SUITE2 ; Z := BASE ;
while i > 0 do begin
Z :== MEM [Z] ;
i := i - 1
end ;
SP := SP + 1 ;
MEM [SP] := Z + 3 + SUITE1 ;
Le + 3
correspond à AR
et aux deux chaînages.