Interprétation
Le rôle d'un interpréteur est de prendre les quadruplés un à un et de leur associer une portion de programme du langage d'interprétation. Pour notre cas, il s'agit de PASCAL.
La tâche la plus importante d'un interpréteur est de gérer les appels et les retours de modules.
A tout module compilé est associé une zone de données qui contient les variables locales, les paramètres, les variables temporaires créées par le compilateur et certaines informations primordiales pour la gestion des appels et des retours.
Les zones de données sont gérées en pile (Pile) implémentée comme une liste linéaire chaînée.
Donc, à un moment donné, Pile pointe la zone de données courante de l'appelé où figure l'adresse de la zone de données de l'appelant.
Au moment d'un retour Pile prendra cette valeur. ( On initialisera l'adresse de la zone de données de l'appelant à NIL pour le premier appel )
Une zone de données ne contient que des adresses ( vers n'importe quel type d'objet )
Au moment d'un appel, les opérations suivantes sont entreprises :
Vérification sur
le nombre de paramètres
la concordance des types
Allocation d'une zone de données (Empilement) et mise à jour du sommet de pile
Mise à jour des Informations de lien
Mot 0 <-- adresse zone de données de l'appelant
Mot1 <-- adresse vers un entier contenant le numéro de l'appelant
Mot2 <-- adresse vers un entier contenant le numéro du quadruplé du retour (adresse de retour) dans l'appelant
Passage des paramètres
(Transmissions des adresses vers les mots Mot3, Mot4, ...)
Tous les paramètres sont transmis par "nom".
Chargement des tables de l'appelant si elles n'existent pas en mémoire
Donner la main à l'appelé.
Au moment d'un retour, les opérations suivantes sont entreprises.
Récupération du
numéro du quadruplé de retour (adresse de retour)
numéro de l'appelant
Transmission des paramètres (transmission des adresses)
La transmission des paramètres au retour est obligatoire dans notre implémentation à cause des paramètres qui étaient à nil avant l'appel.
Libération de la zone de données ( dépilement ) et mise à jour du sommet de pile.
Si les tables de l'appelant n'existent pas en mémoire, les charger.
Lors d'un retour de module, il n'y a libération que des objets qui ne sont pas des paramètres ayant le statut 'L' ou 'X'.
Donner la main à l'appelant
Remarque
Les procédures récursives sont gérées de la même manière.
Pendant l'exécution
les tables de compilation du module principal existent toujours en mémoire.
Au plus, les tables d'un module secondaire sont présentes en mémoire.
Des opérations de " Swapping " sont alors entreprises comme suit :
lors d'un appel ou d'un retour à un module , si les tables de ce dernier ne sont pas présentes en mémoire centrale alors on les charge
Il est clair que les tables de compilation restent invariantes pendant l'exécution.
Une tâche secondaire consiste à gérer l'espace alloué pour les tableaux et les structures.
Tableaux
Au moment de la compilation, il y a génération du quadruplé 'Dt'.
A l'exécution, à la rencontre du quadruplé' 'Dt', il y a
allocation et initialisation d'une zone pour la caractéristique
allocation d'un espace pour le tableau initialisé à NIL
Dans le cas d'un tableau de structures (simples),l'espace pour ces dernières est alloué à l'exécution.
Structures
Au moment de la compilation, il y a génération du quadruplé 'Ds'.
A l'exécution, à la rencontre du quadruplé' 'Ds', il y a allocation d'un espace pour la structure initialisée à NIL
S'il s'agit d'une structure complexe, cad contenant des tableaux à une dim. de scalaires, il y a aussi allocation de l'espace pour les caractéristiques (initialisé à nil) et pour les tableaux initialisée à NIL.
Implémentation
Nous donnons ci-joint les implémentations PASCAL de tous les objets considéré dans le langage Z.
Constantes
Dimension maximal d'un Tableau
Maxdim = 5
Nombre maxiaml de fichiers ouverts
Maxfich = 5
Longueur maximale d'une chaÎne
Longmax = 255
Types des objets manipulés
{ Entier et Booléen }
Typeentier = ^INTEGER;
{ ChaÎne }
Typechaine = ^STRING;
{ CaractÈre }
Typecar = ^STRING[1];
{ Machine-Nombres }
TYPE Typemnombre = ^Elementmnombre;
Elementmnombre = RECORD
Adrvect : POINTER ;
Nombre : INTEGER;
Indice_courant : INTEGER
END;
{ Machine-Caractères }
TYPE Typemcar = ^Elementmcar;
Elementmcar = RECORD
Adrchaine : Typechaine ;
Nombre : INTEGER;
Indice_courant : INTEGER
END;
{ Listes }
Typeliste = ^Elementliste;
Elementliste = RECORD
Element : POINTER;
Suivant : Typeliste
END;
{ Vecteurs }
TYPE Typevecteur = ^Elementvecteur;
Elementvecteur = RECORD
Adrvect : POINTER ;
Dim : BYTE;
Bornes : ARRAY[1..Maxdim] OF INTEGER
END;
{ Structure }
Pointeur vers une zone de données allouée par Getmem et dont le nombre d'octets est égal au nombre de champs X 4. Chaque élément de cette zone pointe vers un élément de la structure.
{ Fichiers }
TYPE Typefichier = ^Elementfichier;
Elementfichier = RECORD
Num : BYTE; { association }
Ouvert : BOOLEAN; { Ouvert / fermé }
Longueur : INTEGER;{ Longueur d'un article }
Longcaract : BYTE;{ Longueur de la zone des caractéristiques }
Caract : STRING[20]; { types des caractéristiques }
Adrcaract : Pointer;{ adresse vers zone des caractéristiques }
END;
Noter que les champs 'Information' sont dans les premiers champs dans les types. Ceci est fait dans le but de faciliter le calcul d'adresse.
Fragment de l'interpréteur
Voici un fragment de l'interpréteur
{:=} IF Cop = ':='
THEN
BEGIN
IF Bpt3
THEN
IF Tabob^[Pt3].Statut = 'C'
THEN
Affecter_e(Adr1(Pt1, Bpt1), Pteur_cons(Tabob^[Pt3].Adresse))
ELSE { Bpt3=True et Tabob^[Pt3].Statut = 'L'ou 'X'}
Affecter ( Adr1(Pt1, Bpt1), Adr(Pt3, Bpt3), Typeoppp(Pt3, Bpt3), num)
ELSE {'L', 'X'}
Affecter ( Adr1(Pt1, Bpt1), Adr(Pt3, Bpt3), Typeoppp(Pt3, Bpt3), num);
Inc(I);
END
ELSE
{-----------------------------------------------------------------------------}
{aff} IF Cop = 'Aff'
THEN
BEGIN
{ calculabilité }
Typidf := Typeoppp(Pt3, Bpt3);
IF NOT Bpt3 { variable globale }
THEN
IF (Typidf[1] IN ['E', 'B', 'C', 'S', '(', 'V', 'T'])
THEN
IF Adr(Pt3, Bpt3) = NIL
THEN P4 (12, Num);
IF Bpt3 { variable locale }
THEN
IF ( Tabob^[Pt3].Statut <> 'C' ) AND
( Typidf[1] IN ['E', 'B', 'C', 'S', '(', 'V', 'T'] )
THEN
IF Adr(Pt3, Bpt3) = NIL
THEN P4 (12, Num);
IF Bpt3
THEN
IF Tabob^[Pt3].Statut = 'C'
THEN
IF Copy(Tabtyp^, Tabob^[Pt3].Typ, 1) = 'W' { NIL }
THEN
Aff_adr(Pt1, NIL, TRUE)
ELSE
IF Copy(Tabtyp^, Tabob^[Pt3].Typ, 1) = 'B' { Vrai Ou Faux }
THEN
Affecter_e( Adr1(Pt1, Bpt1), Pteur_cons(Tabob^[Pt3].Adresse))
ELSE
IF Copy(Tabtyp^, Tabob^[Pt3].Typ, 1) = 'C'
THEN
Affecter_c (Adr1(Pt1,Bpt1), Pteur_cons(Tabob^[Pt3].Adresse))
ELSE
IF ( Copy(Tabtyp^, Tabob^[Pt3].Typ, 1) = 'S' )
THEN
Affecter_s(Adr1(Pt1, Bpt1), Pteur_conscar(Tabob^[Pt3].Adresse))
ELSE { Cste entiÈre }
Affecter_e (Adr1(Pt1, Bpt1), Pteur_cons(Tabob^[Pt3].Adresse))
ELSE { Bpt3=True et Tabob^[Pt3].Statut = 'L'ou 'X'}
Affecter (Adr1(Pt1, Bpt1), Adr(Pt3, Bpt3), Typeoppp(Pt3, Bpt3), num)
ELSE { Bpt3=False donc 'L', 'X'}
Affecter (Adr1(Pt1, Bpt1), Adr(Pt3, Bpt3), Typeoppp(Pt3, Bpt3), num);
Inc(I);
END
ELSE
{-----------------------------------------------------------------------------}
{b} IF Cop= 'B' { Pt1 Ne Peut ˆtre Global }
THEN
BEGIN
IF Tabob^[Pt1].Statut = 'C'
THEN
IF Const_cons(Tabob^[Pt1].Adresse ) = 'VRAI'
THEN
T1 := 1
ELSE
T1 := 0
ELSE {'L' Ou 'X' }
BEGIN
Ptr_entier := Adr(Pt1, Bpt1);
T1 := Ptr_entier^
END;
IF T1 = 1 THEN I := Pt2 ELSE I := Pt3
END
ELSE
{-----------------------------------------------------------------------------}
{br} IF Cop= 'Br'
THEN
I := Pt1
ELSE
{-----------------------------------------------------------------------------}
{operateur} IF Operateur(Cop) AND ( Typeop( Pt1, Bpt1)='E')
THEN
BEGIN
IF Bpt1
THEN
IF Tabob^[Pt1].Statut = 'C'
THEN
VAL( Const_cons(Tabob^[Pt1].Adresse), T1, Code)
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1) ;
IF Ptr_entier = NIL
THEN P4(12, Num);
T1 := Ptr_entier^;
END
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1) ;
IF Ptr_entier = NIL THEN P4(12, Num);
T1 := Ptr_entier^;
END;
IF ( Cop <> '-U') AND (Cop <> '+U')
THEN
IF Bpt2
THEN
IF Tabob^[Pt2].Statut = 'C'
THEN
VAL( Const_cons(Tabob^[Pt2].Adresse), T2, Code)
ELSE
BEGIN
Ptr_entier := Adr(Pt2, Bpt2) ;
IF Ptr_entier = NIL THEN P4(12, Num);
T2 := Ptr_entier^;
END
ELSE
BEGIN
Ptr_entier := Adr(Pt2, Bpt2) ;
IF Ptr_entier = NIL THEN P4(12, Num);
T2 := Ptr_entier^;
END;
IF (Cop = '/E') AND (T2=0)
THEN P4(9, Num);
Operation( Cop, T1, T2); {t1 <-- T1 Cop T2 }
Empl_e(Adr(Pt3, Bpt3), Ptr_entier);
Ptr_entier^ := T1 ;
Aff_adr(Pt3, Ptr_entier, Bpt3 ) ;
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{operateur} IF Operateur(Cop) AND ( Typeop( Pt1, Bpt1) <>'E') AND
( Typeop( Pt1, Bpt1) <>'C') AND ( Typeop( Pt1, Bpt1) <>'S')
THEN
BEGIN
IF Bpt1
THEN
IF Copy( Tabtyp^, Tabob^[Pt1].Typ, 1) = 'W'
THEN Ptr1 := NIL
ELSE
Ptr1 := Adr(Pt1, Bpt1)
ELSE
IF Copy( Tabpro[1].Tabtyp^, Tabpro[1].Tabob^[Pt1].Typ, 1) = 'W'
THEN Ptr1 := NIL
ELSE
Ptr1 := Adr(Pt1, Bpt1);
IF Bpt2
THEN
IF Copy( Tabtyp^, Tabob^[Pt2].Typ, 1) = 'W'
THEN Ptr2 := NIL
ELSE
Ptr2 := Adr(Pt2, Bpt2)
ELSE
IF Copy( Tabpro[1].Tabtyp^, Tabpro[1].Tabob^[Pt2].Typ, 1) = 'W'
THEN Ptr2 := NIL
ELSE
Ptr2 := Adr(Pt2, Bpt2) ;
Empl_e(Adr(Pt3, Bpt3), Ptr_entier);
IF Cop = '='
THEN
IF Ptr1 = Ptr2
THEN
Ptr_entier^ := 1
ELSE
Ptr_entier^:= 0;
IF (Cop = '^=') OR (Cop='#') OR (Cop='<>')
THEN
IF Ptr1 <> Ptr2
THEN
Ptr_entier^ := 1
ELSE
Ptr_entier^:= 0;
Aff_adr(Pt3, Ptr_entier, Bpt3);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{operateur} IF Operateur(Cop) AND ( ( Typeop( Pt1, Bpt1) ='C')
OR ( Typeop( Pt1, Bpt1) ='S') )
THEN
BEGIN
IF Bpt1
THEN
IF Tabob^[Pt1].Statut = 'C'
THEN
Chaine1 := Const_conscar(Tabob^[Pt1].Adresse)
ELSE
IF Copy(Tabtyp^, Tabob^[Pt1].Typ, 1) = 'C'
THEN { CaractÈre }
BEGIN
Ptr_car := Adr(Pt1, Bpt1);
IF Ptr_car = NIL THEN P4(12, Num);
Chaine1 := Ptr_car^;
END
ELSE { Chaine }
BEGIN
Ptr_chaine := Adr(Pt1, Bpt1) ;
IF Ptr_chaine = NIL THEN P4(12, Num);
Chaine1 := Ptr_chaine^;
END;
IF Bpt2
THEN
IF Tabob^[Pt2].Statut = 'C'
THEN
Chaine2 := Const_conscar(Tabob^[Pt2].Adresse)
ELSE
IF Copy(Tabtyp^, Tabob^[Pt2].Typ, 1) = 'C'
THEN { CaractÈre }
BEGIN
Ptr_car := Adr(Pt2, Bpt2);
IF Ptr_car = NIL THEN P4(12, Num);
Chaine2 := Ptr_car^;
END
ELSE { Chaine }
BEGIN
Ptr_chaine := Adr(Pt2, Bpt2) ;
IF Ptr_chaine = NIL THEN P4(12, Num);
Chaine2 := Ptr_chaine^;
END;
Empl_e(Adr(Pt3, Bpt3), Ptr_entier);
IF Operation_chaine( Cop, Chaine1, Chaine2)
THEN Ptr_entier^ := 1
ELSE Ptr_entier^ := 0;
Aff_adr(Pt3, Ptr_entier, Bpt3);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{+S} IF Cop= '+S'
THEN
BEGIN
IF Bpt1
THEN
IF Tabob^[Pt1].Statut = 'C'
THEN
Chaine1 := Const_conscar(Tabob^[Pt1].Adresse)
ELSE {'L','X'}
IF (Copy(Tabtyp^, Tabob^[Pt1].Typ, 1) = 'S')
THEN
BEGIN
Ptr_chaine := Adr(Pt1, Bpt1) ;
IF Ptr_chaine = NIL THEN P4(12, Num);
Chaine1 := Ptr_chaine^;
END
ELSE
BEGIN
Ptr_car := Adr(Pt1, Bpt1) ;
IF Ptr_car = NIL THEN P4(12, Num);
Chaine1 := Ptr_car^;
END;
IF Bpt2
THEN
IF Tabob^[Pt2].Statut = 'C'
THEN
Chaine2 := Const_conscar(Tabob^[Pt2].Adresse)
ELSE
IF (Copy(Tabtyp^, Tabob^[Pt2].Typ, 1) = 'S')
THEN
BEGIN
Ptr_chaine := Adr(Pt2, Bpt2) ;
IF Ptr_chaine = NIL THEN P4(12, Num);
Chaine2 := Ptr_chaine^;
END
ELSE
BEGIN
Ptr_car := Adr(Pt2, Bpt2) ;
IF Ptr_car = NIL THEN P4(12, Num);
Chaine2 := Ptr_car^;
END;
Empl_s(Adr(Pt3, Bpt3), Ptr_chaine);
Ptr_chaine^:= Chaine1 + Chaine2;
Aff_adr(Pt3, Ptr_chaine, Bpt3);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{et/Ou} IF (Cop ='ET') OR (Cop='OU')
THEN
BEGIN
IF Bpt1
THEN
IF Tabob^[Pt1].Statut = 'C'
THEN
IF Const_cons(Tabob^[Pt1].Adresse) = 'VRAI'
THEN T1 := 1
ELSE T1 := 0
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1);
IF Ptr_entier = NIL THEN P4(12, Num);
T1 := Ptr_entier^;
END
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1);
IF Ptr_entier = NIL THEN P4(12, Num);
T1 := Ptr_entier^;
END;
IF Bpt2
THEN
IF Tabob^[Pt2].Statut = 'C'
THEN
IF Const_cons(Tabob^[Pt2].Adresse) = 'VRAI'
THEN T2 := 1
ELSE T2 := 0
ELSE
BEGIN
Ptr_entier := Adr(Pt2, Bpt2);
IF Ptr_entier = NIL THEN P4(12, Num);
T2 := Ptr_entier^;
END
ELSE
BEGIN
Ptr_entier := Adr(Pt2, Bpt2);
IF Ptr_entier = NIL THEN P4(12, Num);
T2 := Ptr_entier^;
END;
Empl_e(Adr(Pt3, Bpt3), Ptr_entier);
IF Cop='ET'
THEN Ptr_entier^ := T1 * T2
ELSE Ptr_entier^ := Min(T1 + T2, 1);
Aff_adr(Pt3, Ptr_entier, Bpt3);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{non} IF Cop = 'Non'
THEN
BEGIN
IF Bpt1
THEN
IF Tabob^[Pt1].Statut = 'C'
THEN
IF Const_cons(Tabob^[Pt1].Adresse) = 'VRAI'
THEN T1 := 1
ELSE T1 := 0
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1);
IF Ptr_entier = NIL THEN P4(12, Num);
T1 := Ptr_entier^;
END
ELSE
BEGIN
Ptr_entier := Adr(Pt1, Bpt1);
IF Ptr_entier = NIL THEN P4(12, Num);
T1 := Ptr_entier^;
END;
Empl_e(Adr(Pt3, Bpt3), Ptr_entier);
IF T1 = 0
THEN Ptr_entier^ := 1
ELSE Ptr_entier^:= 0;
Aff_adr(Pt3, Ptr_entier, Bpt3);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
{ecrire} IF ( Cop = 'Ecrire') OR
( Cop = 'Lire' )
THEN
BEGIN
Es(I);
Inc(I)
END
ELSE
{-----------------------------------------------------------------------------}
IF Cop = 'Proc'
THEN Inc(I)
ELSE
{-----------------------------------------------------------------------------}
IF Cop ='Appel'
THEN
BEGIN
{ Vérifier Que La PROCEDURE Existe }
J := 2; Trouv := FALSE;
WHILE (J<=Nb_proc) AND NOT Trouv DO
IF Tabpro[J].Nom = Const_conscar(Tabob^[Pt1].Adresse )
THEN Trouv := TRUE
ELSE J := J+1;
{inutile ce test }
IF NOT Trouv
THEN
P4(7, Num);
N_param := Pt3;
{ Récuperer Les Types Des ParamÈtres Et Leur Adresse
Dans Une Liste }
IF N_param <> 0
THEN
BEGIN
Tete := Tabcomp^[Pt2];
Teteliste := NIL;
WHILE Tete <> NIL DO
BEGIN
IF Sizeof( Maillon) > Maxavail
THEN P4(11, Num)
ELSE NEW(Q);
IF Tete^.Local
THEN
BEGIN
Q^.Typ := Copy( Tabtyp^,
Tabob^[Tete^.Indice].Typ,
Tabob^[Tete^.Indice].Nombre );
Q^.Adresse := Tabob^[Tete^.Indice].Adresse
END
ELSE
BEGIN
Q^.Typ := Copy( Tabpro[1].Tabtyp^,
Tabpro[1].Tabob^[Tete^.Indice].Typ,
Tabpro[1].Tabob^[Tete^.Indice].Nombre );
Q^.Adresse := Tabpro[1].Tabob^[Tete^.Indice].Adresse;
END;
Q^.Adr := NIL;
IF Teteliste = NIL
THEN Teteliste := Q
ELSE Liste_type^.Adr := Q;
Liste_type := Q;
Tete := Tete^.Suiv
END;
END;
IF (J <> Proc_courante) AND ( Proc_en_memoire <> J)
THEN
BEGIN
{ liberer les listes occupées par Tabcomp}
for k:=1 to tabpro[proc_en_memoire].pteurtabcomp do
if tabpro[proc_en_memoire].tabcomp^[k] <> nil
then
begin
P_tabcomp := tabpro[proc_en_memoire].tabcomp^[k];
WHILE p_tabcomp <> NIL DO
BEGIN
Q_tabcomp := p_tabcomp^.suiv;
DISPOSE ( p_tabcomp);
p_tabcomp := Q_tabcomp
END;
end;
Liretemp(J, Num);
Proc_en_memoire := J;
END;
{ Vérifier Le Nombre De ParamÈtres }
IF N_param <> Tabpro[J].Quadruplet^[1].Pt1
THEN P4(8, Num);
IF N_param <> 0
THEN
BEGIN
{ Vérifier La Concordance Des Types }
Q := Teteliste;
Tete1 := Tabpro[J].Tabcomp^[1];
WHILE Q <> NIL DO
BEGIN
Typ2 := Copy( Tabpro[J].Tabtyp^,
Tabpro[J].Tabob^[Tete1^.Indice].Typ,
Tabpro[J].Tabob^[Tete1^.Indice].Nombre );
IF ( NOT (Q^.Typ[1] IN ['S', 'C'] ) ) OR
( NOT (Typ2[1] IN ['S', 'C'] ) )
THEN
IF Q^.Typ <> Typ2
THEN P4(6, Num);
Q := Q^.Adr;
Tete1 := Tete1^.Suiv;
END;
END;
{ Allocation De La Zdd Pour La Procédure Appelée }
Seg_zddprec := Seg_zdd;
Depl_zddprec := Depl_zdd;
IF ( Tabpro[J].Longzdd+1 )*4 > Maxavail
THEN P4(11, Num)
ELSE Getmem(Ptr1, (Tabpro[J].Longzdd+1) *4);
FOR K := 1 TO Tabpro[J].Longzdd+1 DO
BEGIN
Adrptr := Ptr1;
Segment := Seg(Adrptr^) ;
Depl := Ofs(Adrptr^);
Depl := Depl + K*4 - 4;
Adrptr := Ptr (Segment, Depl);
Adrptr^ := NIL
END;
Seg_zdd := Seg(Ptr1^);
Depl_zdd := Ofs(Ptr1^);
{ Informations De Lien }
{ Mot 0 <--- Adresse Zdd De L'Appelant }
Adrzdd := Ptr (Seg_zdd, Depl_zdd );
Adrzdd^ := Pile;
{ Mot 1 <--- Numero De La PROCEDURE Appelée }
Adrzdd := Ptr (Seg_zdd, Depl_zdd + 4 );
IF Adrzdd^ = NIL
THEN
BEGIN
Alloc(Ptrx,'E', Erreur);
IF Erreur THEN P4(11, Num)
ELSE Ptr_entier := Ptrx;
END
ELSE Ptr_entier := Adrzdd^;
Ptr_entier^ := Proc_courante;
Adrzdd^ := Ptr_entier;
{ Mot 2 <--- Adresse De Retour }
Adrzdd := Ptr (Seg_zdd, Depl_zdd + 8 );
IF Adrzdd^ = NIL
THEN
BEGIN
Alloc(Ptrx,'E', Erreur);
IF Erreur THEN P4(11, Num)
ELSE Ptr_entier := Ptrx;
END
ELSE Ptr_entier := Adrzdd^;
Ptr_entier^ := I+1;
Adrzdd^ := Ptr_entier;
IF N_param <> 0
THEN
BEGIN
{ Passage Des ParamÈtres }
Q := Teteliste;
K:=1;
WHILE Q <> NIL DO
BEGIN
Cste := Q^.Adresse;
Adrzdd := Ptr (Seg_zddprec, Depl_zddprec + Cste * 4);
{ Adresse K+2 <-- ParamÈtre }
Adrzdd1 := Ptr (Seg_zdd, Depl_zdd + (K+2)*4 );
Adrzdd1^ := Adrzdd^;
Q := Q^.Adr;
K := K + 1
END;
{ Liberer La Liste Teteliste }
WHILE Teteliste <> NIL DO
BEGIN
Q := Teteliste^.adr;
DISPOSE ( Teteliste);
Teteliste := Q
END;
END;
{ Mise à Jour Du Sommet De Pile }
Pile := Ptr1;
{ Interpréter La PROCEDURE J à Partir Du Début }
Proc_courante := J;
I := 1;
END
ELSE
...
...