Précédent Index Suivant

Chapitre 13 :   Fonctions

On introduit donc ici les fonctions ; l'extension de PP8 ainsi construite se nomme PP9.

13.1   Grammaire et sémantique

La grammaire est modifiée pour accepter les définitions de fonctions. Ces définitions sont distinguées de celles des procédures par l'introduction du mot clé func :
PROCS ::= { PROCTYPE ID PARAMLIST ; CONSTS VARS INSTS ; }
PROCTYPE ::= proc | func
Les fonctions retournent toutes une valeur entière. Cette valeur est celle qui est << affectée >> à l'identificateur de la fonction au sein de celle-ci.

L'appel de fonction se fait par son nom, éventuellement suivi de ses paramètres. On modifie la règle FACT pour ce faire :
FACT ::= ID | NUM | ( EXPR ) | APPEL
Dans cette règle, un ID désigne le nom d'une variable ; les appels de fonctions se font par dérivation du non-terminal APPEL.

13.2   Génération de code

Un appel de fonction laisse sur la pile la valeur retournée par la fonction. Il est donc nécessaire que l'appelant réserve un emplacement sur la pile pour le retour de cette valeur par une instruction INT 1 avant d'empiler les paramètres de la fonction et de faire l'appel.

La pile à l'entrée d'une fonction est bâtie sur le modèle de la figure 13.1




                                    |----------|    
                                    |          |    
                                    |          |<--- variables locales 
                                    |----------|
                            +-------|------    |   
                            |       |----------|
                            |       |    AR    |<--- BASE
                            |       |----------|
                            |       |          |<--- parametres effectifs 
                            |       |          |     de l'appel
                            V       |----------|
                                    |          |<--- retour 
                                    |----------| 
                                    |          |
Figure 13.1 : État de la pile juste après l'appel d'une fonction.


S'il y a N paramètres, le résultat de la fonction est accédé (dans la fonction) par
 LDL -N-2-1

Cette adresse est donc celle dans laquelle il faut ranger le résultat de l'affectation de l'identificateur correspondant au nom de la fonction.

13.3   Exemple

Le P-Code du programme de la figure 13.2 est donné à la figure 13.3.


 program X ; 
 var N ; 
    func F (M) ; 
    begin 
       if M = 1 then F := 1 ; 
       if M > 1 then F := M * F (M-1) 
    end ;
 begin 
    read (N) ;
    write (F(N))
 end . 
Figure 13.2 : Exemple de programme PP9.



0   INT 1   reserve 1 emplacement pour N
1   BRN 27    
#       debut de la fonction F
2   LDL -3   |
3   LDV   | M:=1
4   LDI 1   |
5   EQL   |
6   BZE 10
 
7   LDL -4   |
8   LDI 1   | F:=1
9   STO   |
 
10   LDL -3   |
11   LDV   | M>1
12   LDI 1   |
13   GTR   |
14   BZE 26
 
15   LDL -4   | F
 
16   LDL -3   | M
17   LDV   |
 
18   INT 1   |
19   LDL -3   |
20   LDV   | F (M-1)
21   LDI 1   |
22   SUB   |
23   CAL 2   |
 
24   MUL   | *
 
25   STO   | :=
 
26   RET 1
 
#       programme X
27   LDA 0
28   INN
29   INT 1   |
30   LDA 0   | F (N)
31   LDV   |
32   CAL 1   |
 
33   PRN
34   HLT

Figure 13.3 : P-Code généré pour le programme de la figure 13.2.


13.4   Travaux dirigés et travaux pratiques

  1. En Pascal, la valeur retournée par une fonction est celle << affectée >> au nom de la fonction lors de la fin de celle-ci. Comparer ce choix avec celui de C qui propose une instruction spécifique (return) : du point de vue du programmeur, et du point de vue de l'écriture du compilateur.

  2. Implanter les fonctions telles que décrites dans ce chapitre.

  3. Proposer une syntaxe (ou reprendre celle de Pascal !) pour étendre les fonctions à différents types. Quels problèmes posent l'extension à des types construits (tableaux, structures...) ?

Précédent Index Suivant