FOR NEXT Loop Emulation ....
Posted: Thu Mar 19, 2015 11:12 am
Hello everyone
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
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