Here are two macros (FORD NEXTD ..) that allow to emulate a FOR ... NEXT.
The main features of these two macros are:
1) all parameters can be passed by variable
2) The step can be an integer or a positive or negative float
Syntax for these macros.
FORD (variable name, value of start, end value, step)
..
...
nextD
Code: Select all
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
; ******************* 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)
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)
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
;************** Pour toutes les boucles imbriquées on ne peut utiliser les mêmes variables ******************
pas1=2
pas2=3
pas3=5
ford(A1,0,8,pas1)
A3=0 ; remise à zero de A3 qui ne sert pas dans la boucle suivante
Debug "__ debut boucle imbriquée A1 avec A2 les valeurs de A3 ne sont pas utiles puisque A3 peut être initialise avant la boucle qui ne concerne que A1 et A2 _________________"
ford(A2,0,9,pas2)
Debug _n(A1)+_n(A2)+_n(A3)
nexTd
A2=0 ; remise à zero de A2 qui ne sert pas dans la boucle suivante
Debug "___debut boucle imbriquée A1 avec A3 les valeurs de A2 ne sont pas utiles puisque A2 peut être initialise avant la boucle qui ne concerne que A1 et A3 _________________"
ford(A3,0,15,pas3)
Debug _n(A1)+_n(A2)+_n(A3)
nextd
nextd
Debug "------boucle indépendante on peut garder la même variable a1 ----------------"
PASd=2
ford(a1,1,6,pasd)
Debug _n(a1)
nextd
Debug "------ on peut garder la même variable a1 ----------------"
ford(a1,0,6,pasd)
Debug _n(a1)
nextd
Debug "-------- possibilité d'avoir des boucles imbriquées 2 variables pas inversé-------------------"
;
pas.d=10
Ford(a3,10.0,50.0,pas) ;
pasb=-10
FORD(a4,50.0,-10.0,pasb)
Debug _n(a3)+_n(a4) ;
Nextd
nextd
; ;
Debug "-------- possibilité d'avoir des boucles imbriquées 3 variables ou plus -------------------"
pas.d=4
Ford(a5,10.0,50.0,pas)
pasb=5
FORD(a6,5.0,15.0,pasb)
FORD(a7,2,8,2)
Debug _n(a5)+_n(a6)+_n(a7); +_n(_nbpushpop_)
Nextd
Nextd
nextd
Debug "---------------------------"
;
pas.d=4
A8=0
Ford(A8,10.0,50.0,pas)
Debug A8
Nextd
Debug "---------------------------"
;
pas=-10.0
A9.d=0
Ford(A9,200.0,10.0,pas)
Debug A9
Nextd
;
Debug "-------- possibilité d'avoir un pas en nombre réel -------------------"
pas=-3.4
A10.d=0
ford(A10,#PI,-30*#PI,pas)
Debug A10
nextd
Debug "------- Pour chaque boucle il faut changer le nom de la variable --------------------"
pas.d=4
Ford(A10,10.0,100.0,pas)
Debug A10
Nextd
End