Bonjour à tous.
Tentative d'explication des 2 macros FORD et NEXTD.
Pour essayer de comprendre les 2 macros FORD et NEXTD commençons par un prototype simple et qui fonctionne au moins sur une seule boucle
Si l’on veut émuler le code ASM en PB (plus concis que ASM) dans une Macro on pourra créer une macro FORD …. NEXTD avec les paramètres suivants.
Comme l’instruction for la macro devra avoir comme paramètres :
1) une variable
2) un début
3) une fin
4) et un pas ou step
On doit tenir compte du pas négatif ou positif
Code : Tout sélectionner
Macro FORD(variable,debut,fin,pas)
; initialisation de la boucle FORD
Variable=debut
Label_boucle_debut:
If pas>0 ; pas positif
If variable<=fin
Goto label_finford
Else
Goto label_finnextd
EndIf
ElseIf pas <0; pas négatif
If variable>=fin
Goto label_finford
Else
Goto label_finnextd
EndIf
ElseIf pas=0 ; ici pas négatif peut être traité de tout autre manière
MessageRequester("erreur","pas égal à zero")
EndIf
label_finford:
EndMacro
; Le principe de la Macro FORD ne pose pas de pb
;
; et NEXTD est assez facile si l’on passe la variable et le pas.
Macro NEXTD(variable,pas)
variable+pas
Goto Label_boucle_debut
label_finnextd:
EndMacro
;********************************************************************
; ; avec pas positif
VA=0
debut=1
fin=10
pas=2
FORD(VA,debut,fin,pas)
Debug va
NEXTD(va,pas)
;*********************************************************************
; ; avec pas négatif
; VA=0
; debut=10
; fin=1
; pas=-2
; FORD(VA,debut,fin,pas)
;
; Debug va
;
; NEXTD(va,pas)
Si l’on dé-commente les instructions du pas négatif et si l’on commente les instructions du pas positf.
Les deux options fonctionnent bien.
Par contre si l’on dé-commente les deux pas, l’on obtient une erreur ( ligne xx label déjà déclaré)
Essayons de résoudre le pb des muti-appels avec cet exemple.
Code : Tout sélectionner
; Macro _q_t_
; "
; EndMacro
; Macro _n(__n)
; _q_t_#__n#=_q_t_+Str(__n)+" "
; EndMacro
Macro essai(var)
; _macexpc=MacroExpandedCount
Debug _n(var)+_n(MacroExpandedCount)
label#var:
label#MacroExpandedCount:
label#var#MacroExpandedCount:
EndMacro
VA=30
VA2=32
va3=33
For jj=0 To 3
essai(va) ; premier appel
essai(va2) ; deuxième appel
essai(vA3) ; troisième appel
va4=34
For i=0 To 5
essai(va4) ; quatrième appel
Next
va5=35
essai(va5) ; cinquième appel
Next
; par contre si l'on appel avec une variable déjà utilisée on a une erreur. Supprimer le commentaire de l'appel essai suivant pour avoir une erreur de label déjà déclaré
; pour faire un essai sans erreur vous devez mettre en commentaire le label label#var de la macro commentez dans la macro label#var: et dé-commentez l'appel essai(va) ci-dessous.
; essai(va) ;; sixième appel
; le nombre défini par MacroExpandedCount est le nombre d'appel physique et non logique. C'est le nombre de fois que l'on voit l'appel de la macro.
Passons aux macros FORD et NEXTD
Code : Tout sélectionner
Macro _q_t_
"
EndMacro
Macro _n(__n)
_q_t_#__n#=_q_t_+Str(__n)+" "
EndMacro
Macro ford(FORD_variable,FORD_debut,FORD_fin,FORD_pas)
; initialisation de la boucle FORD
FORD_variable=FORD_debut
Label_boucle_FORD_debut#macroexpandedcount:
If FORD_pas>0 ; FORD_pas positif
If FORD_variable<=FORD_fin
Goto label_finford#macroexpandedcount
Else
Goto label_finnextd#macroexpandedcount
EndIf
ElseIf FORD_pas<0; FORD_pas négatif
If FORD_variable>=FORD_fin
Goto label_finford#macroexpandedcount
Else
Goto label_finnextd#macroexpandedcount
EndIf
ElseIf FORD_pas=0 ; ici FORD_pas négatif peut être traité de tout autre manière
MessageRequester("erreur","pas égal à zero")
EndIf
; MacroExpandedCount
label_finford#macroexpandedcount:
macroexpandedcount1=MacroExpandedCount
EndMacro
; Le principe de la Macro FORD ne pose pas de pb
;
; Par contre le principe de la Macro NEXTDO en pose un si l’on ne veut pas passer ni la variable ni le pas (ce problème sera résolu plus tard).
; Si dans la macro NEXTDO on passe la variable et le pas, c’est assez facile
Macro NEXTDO(NEXTD_variable,NEXTD_pas)
NEXTD_variable+NEXTD_pas
Goto Label_boucle_FORD_debut#macroexpandedcount
label_finnextd#macroexpandedcount:
EndMacro
;********************************************************************
; ; ; avec pas positif
VA=0
debut=1
fin=10
pas=2
FORD(VA,debut,fin,pas)
Debug _N(va)+_N(MacroExpandedCount1)
nextdo(va,pas)
; ;*********************************************************************
; ; ; avec pas négatif
Debug "********* Changement de pas mais avec la même variable (2 boucles indépendantes)"
VA=0
debut=10
fin=1
pas=-2
FORD(VA,debut,fin,pas)
Debug _N(va)+_N(MacroExpandedCount1)
nextdo(va,pas)
;;**************************
On a résolu le pb des multi-appels de la même macro et en plus on peu garder la même variable dans plusieurs boucles indépendantes.
Pour les boucles imbriquées nous allons avoir un nouveau petit bp à résoudre.
Car en numérotant les macros dans l’ordre physique qui se présente nous avons.
Vous pouvez essayer les instructions suivantes avec les Macros précédentes
Code : Tout sélectionner
VA=0
debut=1
fin=10
pas=2
VA2=0
debut2=8
fin2=0
pas2=-2
FORD(VA,debut,fin,pas) ;;;;; macroexpandedcount=1
FORD(VA2,debut2,fin2,pas2) ;;;;; macroexpandedcount=2
Debug _n(va2)+_n(va)
nextdO(va2,pas2) ;;;;; Goto Label_boucle_debut#macroexpandedcount
;; MacroExpandedCount=1 Or il faut se brancher après incrémentation avec une valeur de 2 et non de 1
nextdo(va,pas) ;;;;; Goto Label_boucle_debut#macroexpandedcount
;; MacroExpandedCount=2 et ici il faut il faut se brancher après incrémentation avec une valeur de 1 et non de 2
; Le programme va bouclé à l’infini puisque le FORD niveau 1 et NEXRDO niveau 1 ne sont pas associés.
Le programme va bouclé à l’infini puisque le FORD niveau 1 et NEXTD niveau 1 ne sont pas associés.
On ne peut résoudre ce pb qu’avec une pile push pop ou une gestion de pile car si ici il n’y a que 2 boucles , il peut y avoir 4 ,5 ou plusieurs boucles imbriquées.
Lorsque nous aurons résolu le pb de la pile il faudra s’attaquer au passage des 2 paramètres (variable et pas) en les supprimant dans la Macro NEXTD et en les passant par MAP ou table.
Il y a un effet pervers à garder les variables car on peut obtenir la structure d’appel suivante.
VA=0
debut=1
fin=10
pas=2
VA2=0
debut2=8
fin2=0
pas2=-2
FORD(VA,debut,fin,pas)
FORD(VA2,debut2,fin2,pas2)
Debug _n(va2)+_n(va)
NEXTD(va,pas)
NEXTD(va2,pas2) ;; inversion des NEXTD donne des résultats surprenants
alors que
FORD(VA,debut,fin,pas)
FORD(VA2,debut2,fin2,pas2)
Debug _n(va2)+_n(va)
NEXTD
NEXTD)
Lève immédiatement l’ambigüité car le NEXTD le plus prés de l’instruction FORD lui est associée.et le le dernier NEXTD est associé à l’instruction FORD la plus éloignée.
Comment résoudre le pb des boucles imbriquées et en même temps celui de la suppression des paramètres (variable et pas) de la macro NEXTD
Ici le pb devient plus délicat à résoudre en effet :
Comme il va falloir stocker certaines infos de chaque boucle physique on doit pouvoir supprimer les paramètres (variable et pas) dans la micro NEXTD
Pour garder une présentation à peu près correcte le texte suivant est entre code et /code.
Code : Tout sélectionner
1) stocker le N° de macroexpandedcount dans une table en incrémentant un index
la table sera varpushpop() et l’index _nbpushpop_ on devra aussi mémoriser toutes les informations relative à la boucle
(valeur de la variable,valeur du pas,valeur max de fin, adresse de branchement du commencement de boucle dans FORD,
l’adresse de débranchement de boucle dans NEXTD)
la table de la pile ne devra gérer que les boucles imbriquées (nombre d’imbrications) les infos de chaque boucle doivent être stockées or ces deux
ensembles n’ont pas les mêmes dimensions.
2) Nous aurons donc 1 table servant à la gestion de pile et une table ou une MAp pour toutes les infos de chacune des boucles.
Mais comme nous ne connaissons pas le nb de boucle nous utiliserons une MAP avec comme identifiant le N° de macroexpandedcount
comme celui-ci est numérique nous prendrons str(macroexpandedcount)
3) Nos aurons donc 3 niveaux d’initialisation
31) Un niveau général et unique pour le prg ou nous définirons la table varpushpop() la MAP
et l’index _nbpushpop_
32) un niveau de chaque définition d’une boucle physique définie par FORD(var1,deb1,fin1,pas1)
pour mémoriser dans la MAP :
les infos va1,deb1,fin1,pas1 mêmes si ses infos ne sont pas nécessaires ainsi que les adresses :
l’adresse du label de la fin de NEXTD label_finnextd#macroexpandedcount pour chaque boucle
l’adresse du label de début de FORD Label_boucle_debut#macroexpandedcount
33) Au niveau de chaque boucle logique :
La gestion de la pile par incrémentation de l’index
La mémorisation dans la table varpushpop(_nbpushpop_) du N° de la boucle en train d’être exécuté ce N° est le N° de macroexpandedcount
La gestion de la pile se fera avec l'index _nbpushpop_ associée à la table varpushpop()
qui contient les N° MacroExpandedCount propre à chaque boucle.
_nbpushpop_ sera indexé en prévision de rencontrer un autre FORD avant de le décrémenter dans NEXTD (gestion classique d'une pile).
Lorsque _nbpushpop_ est à zero nous ne sommes pas dans une boucle imbriquée la valeur contenu dans varpushpop(0) est le dernier N° MacroExpandedCount initialiser dans FORD au début de cette boucle dons il ne peut y avoir de confusion dans les infos recherchées à partir de cette valeur dans la MAP puisqu'au début de chaque boucle il y a une initialisation dans FORD.
FORD(A1,D1,F1,PAS1) ;;; _nbpushpop_ =0 pour exploitation et +1 donc 1 en prévision du prochain FORD
FORD(A2,D2,F2,pas2) ;;; _nbpushpop_ =1 pour exploitation et +1 donc 2 en prévision du prochain FORD
FORD(A3,D3,F3,pas3) ;;; _nbpushpop_ =2 pour exploitation et +1 donc 3 en prévision du prochain FORD
Ici instructions avec A1 A2, A3
NEXTD ;;; _nbpushpop_=3 et -1 donc 2 pour l’exploitation correspond parfaitement à FORD(A3.)
NEXTD;;; _nbpushpop_=2 et -1 donc 1 pour l’exploitation correspond parfaitement à FORD(A2..)
NEXTD;;; _nbpushpop_=1 et -1 donc 0 pour l’exploitation correspond parfaitement à FORD(A1.)
On peut vérifier sur toute autre structure d’appel on aura une correspondance parfaite entre FORD et NEXTD
Exemple soit les boucles suivantes 2 boucles indépendantes suivi d’une structure de boucle complexe (2 boucles indépendantes imbriquées dans une boucle)
FORD(A1,DEB1,FIN1,PAS1) _nbpushpop_=0 pour stoker str( MacroExpandedCount) dans varpushpop(0) puis incrémentation en prévision d’un nouveau FORD
.........
NEXTD ;;_nbpushpop_-1 décrémentation donc =0 extraction de l’identificateur du varpushpop(_nbpushpop_) donc de varpushpop(0) Sortie de la boucle avec _nbpushpop_=0
FORD(A2,DEB2,FIN2,PAS2) _nbpushpop_=0 pour stoker str( MacroExpandedCount) dans varpushpop(0) puis incrémentation en prévision d’un nouveau FORD
….
NEXTD ;;_nbpushpop_-1 décrémentation donc =0 extraction de l’identificateur du varpushpop(_nbpushpop_) donc de varpushpop(0)
FORD(B1,D1,F1,P1) ;; _nbpushpop_=0 pour stoker str( MacroExpandedCount) dans varpushpop(0) puis incrémentation en prévision d’un nouveau FORD
;; Maintenant 2 boucles indépendantes imbriquées dans une autre boucle
FORD(C2,D2,F2,P2) ;; _nbpushpop_=1 pour stoker str( MacroExpandedCount) dans varpushpop(1) puis incrémentation en prévision d’un nouveau FORD
…
NEXTD;;_nbpushpop_-1 décrémentation donc =1 extraction de l’identificateur du varpushpop(_nbpushpop_) donc de varpushpop(1) Sortie de la boucle avec _nbpushpop_=1
FORD(C3,D3,F3,P3) ;; _nbpushpop_=1 pour stoker str( MacroExpandedCount) dans varpushpop(1) puis incrémentation en prévision d’un nouveau FORD
…
NEXTD;;_nbpushpop_-1 décrémentation donc =1 extraction de l’identificateur du varpushpop(_nbpushpop_) donc de varpushpop(1) Sortie de la boucle avec _nbpushpop_=1
NEXTD;;_nbpushpop_-1 décrémentation donc =0 extraction de l’identificateur du varpushpop(_nbpushpop_) donc de varpushpop(0) Sortie de la boucle avec _nbpushpop_=0
A la fin des boucles imbriquées _nbpushpop_ doit être =0 ce qui est le cas ici
Ainsi avec la MAP associée à la table varpushpop() laquelle est indexée par _nbpushpop_ on résout le pb des boucles imbriquées et la suppression des paramètres (variable et pas) dans NEXTD.
Pour éviter l'erreur Ligne xx le label est déjà déclaré.
Nous pouvons donc prendre comme type de label :
soit la forme label#variable#MacroExpandedCount: (ceinture bretelle)
soit la forme label#MacroExpandedCount: (plus simple et unique)
Maintenant il ne doit plus rester de pb important pour comprendre les 2 macros.
Voici quelques précisions sur les infos utilisées.
La macro FORD commence par 2 zones d’initialisation
La première pour initialiser une seule fois le programme
Code : Tout sélectionner
;************************* initialisation générale une seule fois pour ce PRG **********************
If FORDflag_=0
Define NEXTDPOP,_nbpushpop_=0
NewMap ADR_ford.ADR()
Dim varpushpop.s(256) ; ici limitation à 256 (boucles avec str(MacroExpandedCount)) vous pouvez augmenter cette valeur
Dim varpushpopB.s(256)
FORDflag_=1
EndIff
la deuxième pour initialiser chaque boucle physique.
Code : Tout sélectionner
;******** initialisation pour le début de chaque boucle une seule fois par le N° d’appel physique de la macro associée au n° de macroexpandedcount *************
;********************* initialisation pour chaque boucle une seule fois par boucle *************
If flagford_#MacroExpandedCount#FORD_variable=0
FORD_identification$=Str(MacroExpandedCount);+_q_t_#FORD_variable#_q_t_
varpushpop(_nbpushpop_)=FORD_identification$
ADR_ford(FORD_identification$)\ADR_var=_q_t_#FORD_variable#_q_t_
ADR_ford()\ADR_macexpc=Str(MacroExpandedCount)
ADR_ford()\ADR_valvar=FORD_variable
ADR_ford()\ADR_deb=?Label_boucle_FORD_debut#macroexpandedcount
ADR_ford()\ADR_fin=?label_finnextd#macroexpandedcount
ADR_ford()\ADR_valpas=FORD_pas
ADR_ford()\ADR_valdeb=FORD_debut
ADR_ford()\ADR_valfin=FORD_fin
flagford_#MacroExpandedCount#FORD_variable=1
EndIf
;************************** Initialisation de la boucle pour chaque appel *************************
;******** initialisation pour le début de chaque boucle de la variable par la valeur début *************
FORD_variable=FORD_debut
ADR_ford(Str(MacroExpandedCount))\ADR_valvar=FORD_variable
et ensuite le début de boucle proprement dite
Code : Tout sélectionner
;********************************************* debut boucle *****************************************
DEBlab_#MacroExpandedCount: ; ***************** début de la boucle
;************************** gestion PUSH POP *******************************
_FORD_identification_$=Str(MacroExpandedCount);+_q_t_#FORD_variable#_q_t_
varpushpop(_nbpushpop_)=_FORD_identification_$
_nbpushpop_+1 ;; incrémentation de l’index de pile placé ici avant les multiples branches
;;; on incrémente en prévision de rencontrer une nouvelle boucle FORD avant la décrémentation dans NEXTD
;;; avec FORD on incrémente _nbpushpop_
;;; avec NEXTD on décrémente _nbpushpop_
FORD_variable=ADR_ford(_FORD_identification_$)\ADR_valvar
If FORD_pas>0 ;;; avec pas positif
;******** While émulation FORD_variable <=fin test pas >0 ************
If FORD_variable<=FORD_fin
Goto FINlab_#Macroexpandedcount
Else
FORDlabfin=ADR_ford(_FORD_identification_$)\ADR_fin
!mov eax,[v_FORDlabfin]
!jmp eax;;; Branchement à la fin de macro NEXTD
EndIf
ElseIf FORD_pas<0 ;;; avec pas négatif
;******** While émulation FORD_variable >=fin test pas <0 ************
If FORD_variable>=FORD_fin
Goto FINlab_#Macroexpandedcount
Else
FORDlabfin=ADR_ford(_FORD_identification_$)\ADR_fin
!mov eax,[v_FORDlabfin]
!jmp eax;;; Branchement à la fin de macro NEXTD
EndIf
ElseIf FORD_pas=0 ;;; Ici pas =0 risque s’il reste à cette valeur de créer une boucle infinie
MessageRequester("Erreur ","le pas ne peut être égal à 0")
End
EndIf
FINlab_#Macroexpandedcount:
EndMacro
L’analyse de la macro FORD est terminée
Passons à l’analyse de la macro NEXTD
Code : Tout sélectionner
Macro Nextd ;(NEXTD_variable)
;************************** gestion PUSH POP *******************************
_nbpushpop_-1 ;;; index de la pile qui permet dans des boucles imbriquées de retrouver la bonne boucle associée à la bonne variable
;; la décrémentation nous amène dans la boucle de niveau inférieure voire à zero au niveau des boucles indépendantes de base.
NEXTDlabdeb=ADR_ford(varpushpop(_nbpushpop_))\ADR_deb ; recherché en function de l’index de la pile de retrouver la valeur de MacroExpandedCount donc de la boucle consernée dans MAP
NEXTD_fin=ADR_ford()\ADR_fin ; recherché de l’adresse de fin
; NEXTD_valfin=ADR_ford()\ADR_valfin
; ******************* incrémentation de la variable par le pas *************************
ADR_ford()\ADR_valvar+ADR_ford()\ADR_valpas ;; incrémentation par son pas de la variable liée à la boucle.
NEXTDlabdeb=ADR_ford()\ADR_deb ;; recherche de l’adresse début de la boucle qui se trouve dans FORD
If NEXTD_fin<>?nextd_#Macroexpandedcount ; ; un petit pb d’initialisation de (FORD) est résolu ici
ADR_ford()\ADR_fin=?nextd_#Macroexpandedcount
EndIf
!mov eax,[v_NEXTDlabdeb];;; branchement au début de la boucle dans le FORD correspondant
!jmp eax ;;;; branchement au début de la boucle qui se trouve dans FORD
Nextd_#Macroexpandedcount:
;************************** gestion PUSH POP *******************************
_nbpushpop_-1
If _nbpushpop_=0
; ******** on peut ici nettoyer la MAP ADR_ford et les tables varpushpop avec varpushpopB si elles deviennent trop petites *******
; ClearMap(ADR_ford.ADR())
; varpushpop=varpushpopB
EndIf
EndMacro
Les éléments annexes.
Code : Tout sélectionner
; Macro _q_t_ ;; elle sert pour la macro suivante
; "
; EndMacro
; Macro _n(__n) ;; elle sert à débuguer le prg _N(var)=> donne ( VAR=valeur de Var)
; _q_t_#__n#=_q_t_+Str(__n)+" "
; EndMacro
Structure ADR
ADR_VAR.s ; nom de la variable qui ne sert pas à l"exploition mais qui permet lors de la mise au point de savoir à qui appartiennent les information de cet index
ADR_macexpc.s{4} ; Numéro d"identification du nombre d'appel de la macro ne sert que pour l'dentification dans la MAP
ADR_valvar.d
ADR_valdeb.d
ADR_valfin.d
ADR_valpas.d
ADR_deb.l
ADR_fin.l
EndStructure
L’analyse des macros FORD et NEXTD est terminée
L’incrémentation de _nbpushpop_ dans FORD et sa décrémentation dans NEXTD associés à varpushpop(_nbpushpop_) est une entité de la gestion de la pile qu’il faudra manipuler avec précaution.
Par exemple ne pas inverser les 2 instructions et ne les déplacer pas n’importe où.
Voici les 2 macros FORD et NEXTD que nous venons de construire
Code : Tout sélectionner
Macro _q_t_
"
EndMacro
Macro _n(__n)
_q_t_#__n#=_q_t_+Str(__n)+" "
EndMacro
Structure ADR
ADR_VAR.s ; nom de la variable qui ne sert pas à l"exploition mais qui permet lors de la mise au point de savoir à qui appartiennent les information de cet index
ADR_macexpc.s{4} ; Numéro d"identification du nombre d'appel de la macro ne sert que pour l'dentification dans la MAP
ADR_valvar.d
ADR_valdeb.d
ADR_valfin.d
ADR_valpas.d
ADR_deb.l
ADR_fin.l
EndStructure
Macro Nextd
;************************** gestion PUSH POP *******************************
_nbpushpop_-1
NEXTDlabdeb=ADR_ford(varpushpop(_nbpushpop_))\ADR_deb
NEXTD_fin=ADR_ford()\ADR_fin
; NEXTD_valfin=ADR_ford()\ADR_valfin
; ******************* incrémentation de la variable par le pas *************************
ADR_ford()\ADR_valvar+ADR_ford()\ADR_valpas
NEXTDlabdeb=ADR_ford()\ADR_deb
If NEXTD_fin<>?label_finnextd#macroexpandedcount
ADR_ford()\ADR_fin=?label_finnextd#macroexpandedcount
EndIf
!mov eax,[v_NEXTDlabdeb]
!jmp eax
label_finnextd#macroexpandedcount:
;************************** gestion PUSH POP *******************************
_nbpushpop_-1
If _nbpushpop_=0
; ******** on peut ici nettoyer la MAP ADR_ford et les tables varpushpop avec varpushpopB si elles deviennent trop petites *******
; ClearMap(ADR_ford.ADR())
; varpushpop=varpushpopB
EndIf
EndMacro
Macro ford(FORD_variable,FORD_debut,FORD_fin,FORD_pas)
;************************* initialisation générale une seule fois pour ce PRG **********************
If FORDflag_=0
Define NEXTDPOP,_nbpushpop_=0
NewMap ADR_ford.ADR()
Dim varpushpop.s(256) ; ici limitation à 256 (variables+ MacroExpandedCount) vous pouvez augmenter cette valeur
Dim varpushpopB.s(256)
FORDflag_=1
EndIf
;********************* initialisation pour chaque boucle une seule fois par boucle *************
If flagford_#MacroExpandedCount#FORD_variable=0
FORD_identification$=Str(MacroExpandedCount);+_q_t_#FORD_variable#_q_t_
varpushpop(_nbpushpop_)=FORD_identification$
ADR_ford(FORD_identification$)\ADR_var=_q_t_#FORD_variable#_q_t_
ADR_ford()\ADR_macexpc=Str(MacroExpandedCount)
ADR_ford()\ADR_valvar=FORD_variable
ADR_ford()\ADR_deb=?Label_boucle_FORD_debut#macroexpandedcount
ADR_ford()\ADR_fin=?label_finnextd#macroexpandedcount
ADR_ford()\ADR_valpas=FORD_pas
ADR_ford()\ADR_valdeb=FORD_debut
ADR_ford()\ADR_valfin=FORD_fin
flagford_#MacroExpandedCount#FORD_variable=1
EndIf
;************************** Initialisation de la boucle pour une variable *************************
FORD_variable=FORD_debut
ADR_ford(Str(MacroExpandedCount))\ADR_valvar=FORD_variable
;********************************************* debut boucle *****************************************
Label_boucle_FORD_debut#macroexpandedcount: ; ***************** début de la boucle
;************************** gestion PUSH POP *******************************
_FORD_identification_$=Str(MacroExpandedCount);+_q_t_#FORD_variable#_q_t_
varpushpop(_nbpushpop_)=_FORD_identification_$
_nbpushpop_+1
FORD_variable=ADR_ford(_FORD_identification_$)\ADR_valvar
If FORD_pas>0
;******** While émulation FORD_variable <=fin test pas >0 ************
If FORD_variable<=FORD_fin
Goto label_finford#macroexpandedcount
Else
FORDlabfin=ADR_ford(_FORD_identification_$)\ADR_fin
!mov eax,[v_FORDlabfin]
!jmp eax
EndIf
ElseIf FORD_pas<0
;******** While émulation FORD_variable >=fin test pas <0 ************
If FORD_variable>=FORD_fin
Goto label_finford#macroexpandedcount
Else
FORDlabfin=ADR_ford(_FORD_identification_$)\ADR_fin
!mov eax,[v_FORDlabfin]
!jmp eax
EndIf
ElseIf FORD_pas=0
MessageRequester("Erreur ","le pas ne peut être égal à 0")
End
EndIf
label_finford#macroexpandedcount:
EndMacro
Vous pouvez supprimer dans la structure et dans les MACROS les informations et les instructions qui ne sont pas strictement nécessaires au bon fonctionnement.
Si vous avez des questions n'hésitez pas.
A+