La plupart des compilateurs modernes mettent en oeuvre deux concepts qui vont de pair : - la notion de variables locales Un "sous programme", déclare ses propres variables, ne voit qu'elles. les seules informations communes sont les paramètres. Nous fonctionnons déja comme cela avec les programmes indépendants (exécutés par CALL) - la notion de fonction (ou de procédure) c'est la possibilité d'utiliser un sous-programme comme élément du langage (donc d'enrichir le langage de ses propres codes). ET, ces fonctions peuvent renvoyer une valeur. La fonction peut alors être utilisée à la place d'une valeur si l'argument retourné est compatible. |
Exemple : je crée une fonction FINDEMOIS qui accepte un argument de type date, et qui retourne un chiffre qui correspond au N° du dernier jour du mois. - la fonction peut déclarer une variable nommée "DATE", elle n'aura aucun lien avec une variable de même nom dans le programme principal ou dans une autre fonction. - l'appel peut se faire sous la forme : + numjour = findemois(datcde) mais aussi sous la forme implicite suivante : + if findemois(datcde) > 30 ---------------- | |--> cette partie de l'expression est remplacée par la valeur retournée lors la réalisation du test. |
Ces possibilités sont arrivées en ILE/RPG-IV avec la V3R60 : - support des variables locales - Sous-programmes de type fonction, utilisables avec la nouvelle spécif C - Ces fonctions peuvent être dans le même source ou compilées séparément (modules ou programmes de service) puis liées. - un source peut ne contenir que des fonctions (sous-programmes) afin de servir de base à la création d'un programme de service. Définition d'une fonction : =========================== A/ déclaration du prototype, c'est à dire: du type de valeur retournée et des paramètres attendus. cette déclaration doit se faire dans le programme qui UTILISE la fonction par le biais de spécifs D |
Exemple, Pour notre fonction FINDEMOIS : * Définition du prototype pour la procédure FINDEMOIS D FINDEMOIS PR 2P 0 D Dateenv D Ce prototype ce déclare avec les spécifs D du pgm principal. Il indique que la fonction retourne une valeur Packée 2 dont 0 et attend une variable DATE. B/ définition de la fonction : Deux nouvelles spécifs "P" pour définir le début et la fin de la fonction Des Spécifs D pour définir les variables locales Les spécifs C de traitement, avec sur le code-opération RETURN un facteur 2 qui indique la valeur à retourner (vous pouvez coder plusieurs RETURN). |
structure générale d'un pgm RPG-IV : H Spécif H générale |contient NOMAIN s'il n'y a pas de pgm principal F Déclaration de fichiers |(ouvertures globales) D variables globales | D proc1 PR | prototype procédure 1 D proc2 PR | prototype procédure 2 I variables des fichiers | (globales) C traitement | programme principal O sorties | sorties du programme principal P proc1 B -| D PI | définition de l'interface (= *ENTRY PLIST) D | variables locales C | traitement P E -| P proc2 B -| D PI | 2ème procédure (idem) D | C | P E -| **CTDATA |
P Findemois B * Définition de l'Interface de procédure (PI) * doit être conforme avec le prototype (vérifié à la compilation) D PI 2P 0 D Datein D * variables locales DDATEDS DS D Wdate D DATFMT(*DMY) D Wjour 2S 0 OVERLAY(wdate) D slash1 1 OVERLAY(wdate:3) D Wmois 2S 0 OVERLAY(wdate:4) D slash2 1 OVERLAY(wdate:6) D Wan 2S 0 OVERLAY(wdate:7) * traitement C eval wdate = datein C eval wjour = 1 C ADDDUR 1:*M WDATE C SUBDUR 1:*D WDATE C RETURN Wjour P Findemois E |
Le source de cette fonction peut être un source à part et produire un module ne contenant que des fonctions. Il faut alors spécifier NOMAIN en spécif H du programme. Il y a autant de procédures dans le module qu'il y a de procédures dans le source (programme principal compris) L'appel d'une procédure qui ne retourne pas de valeur peut se faire par CALLB. Un programme sans programme principal peut utiliser des fichiers, déclarer des variables globales (spécifs D hors procédure) Les ouvertures de fichiers et les indicateurs sont communs à une unité de compilation (déclaration obligatoirement globale au sein d'un même source) Si vous ne voulez pas partager les fichiers ouverts ou les indicateurs, placez vos procédures dans des sources séparés. (le résultat système est le même ,il y a une phase de liage) |
Le but d'une telle nouveauté est clair : l'écriture de routines standards qui pourront être utilisées : 1/ facilement (comme des fonctions intégrées) 2/ sans risque (variables globales) 3/ sans dégradation de performances (liage ILE) Ce sont des concepts très orientés OBJET . ILE RPG-IV n'est PAS un compilateur OBJET. mais, - Syntaxiquement tout est prêt, y compris le support du C, C++. - Techniquement c'était nécessaire pour supporter SOM/DSOM il n'y a pas encore de FRAMEWORK sur le marché, mais peut-être trouverons-nous bientôt des programmes de service prêts à l'emploi. |
Le Prototypage en détail : Les prototypes servent à définir un appelà venir, qui pourra se faire : 1/ en format libre (procédures de type fonction) 2/ avec le code opération CALLP (Programmes ou procédures) Sont définis : + le nom du programme/de la procédure (nom externe pouvant être différent) + le type d'appel à réaliser EXTPROC(nom) = Appel d'une procédure->CALLB EXTPGM(nom) = Appel d'un programme ->CALL Les appels de programmes et de procédures liées peuvent ainsi se faire avec la même syntaxe. La transformation d'un programme en procédure indépendante, ou bien l'attribution d'un nouveau nom, en seront simplifiés. |
+ le nombre et la nature des paramètres - type et longueur - obligatoire (dft) ou optionnel (OPTIONS().) + la transmission (OPDESC) ou non du descripteur de paramètres. + la définition de la valeur de retour pour une fonction Syntaxe : D nom PR lg!type mots-clés Mots-clés admis : DATFMT, DIM, LIKE, PROCPTR, TIMFMT Il définissent tous la valeur reçue. Nouveau : OPDESC demande à ce que le descripteur soit transmis (équivalent à CALLB(D).) |
Définition des paramètres : Spécif D de définition de variable Mots-clés admis : ASCEND, DATFMT, DIM, LIKE, PROCPTR, TIMFMT. Nouveaux mots-clés : CONST Ce paramètre est non-modifiable (conseillé) Cette information doit être indiquée aussi bien dans le prototype que dans l'interface de procèdure (PI) Il s'agit d'un contrôle réalisé par le compilateur VALUE passage d'un paramètre par valeur (et non par adresse) Ces deux mots-clé autorisent l'utilisation d'expressions lors de l'appel. NOOPT pas d'optimisation pour cette variable (OPTIMIZE(*FULL).) |
STATIC cette variable est stockée en mémoire statique: elle est initialisée lors du PREMIER appel, toutes les autres fois elle retrouve sa valeur précédente. les variables globales sont forcément statiques. OPTIONS(*NOPASS *OMIT *VARSIZE) *NOPASS le paramètre est facultatif, tous les paramètres suivants du prototype doivent être définis OPTION(*NOPASS). *OMIT la valeur *OMIT (pointeur nul) est admise. *VARSIZE paramètre à longueur variable . Utilisable avec l'API CEEDOD qui décrit les paramètres reçus pour la procédure appelée, mais aussi avec QCMDEXC par exemple. la nouvelle fonction %PARMS() retourne le nombre de paramètres reçus dans une procédure. |
Pour une procédure (spécif P) le seul mot-clé est : EXPORT autorise l'utilisation de cette procédure par des modules externes (sinon cette procédure est privée c'est à dire utilisable uniquement dans le même source) L'utilisation d'une fonction se fait sous la forme : X = F(y), F étant une procédure interne ou liée L'utilisation d'une procédure (ou d'un programme) se fait par : CALLP qui est un ordre en format libre, CALLP procédure (p1 : p2: p3) p1, p2, p3 peuvent être : des variables, des constantes (alpha ou numériques), des expressions, d'autres procédures de type fonction. Vous avez ici les mêmes possibilités que pour EVAL !! |
V3R60 / V3R20 : Autres nouveautés. en spécif H : NOMAIN indique qu'il n'y a que des procédures COPYRIGHT('votre signature') place un copyright dans le module en spécif F : le mot-clé PREFIX a une nouvelle syntaxe possible : PREFIX(chaîne : nbr) nbr = nombre de caractères à remplacer ainsi PREFIX('Z' : 3) remplace ABCQTE par ZQTE. en spécif D : deux nouveaux types de variable I = INTEGER -> Binaire U = UNSIGNED -> B non signé. (de 0 à 65535) en spécif C : le format *CYMD est reconnu en gestion de date (MOVE) nouveaux mots réservés : *START et *END valides avec SETLL |