FOR NEXT Loop Emulation ....

Just starting out? Need help? Post your questions and find answers here.
PAPIPP
User
User
Posts: 49
Joined: Mon Aug 17, 2009 10:48 pm
Location: France

FOR NEXT Loop Emulation ....

Post by PAPIPP »

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

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


PAPIPP
User
User
Posts: 49
Joined: Mon Aug 17, 2009 10:48 pm
Location: France

Re: FOR NEXT Loop Emulation ....

Post by PAPIPP »

Hello everyone.
For the For .. Next PB instruction can change the start parameter and end of the statement.
with the following example.

Code: Select all

	A1=0
	fin=50
	pas=20
	For deb=0 To 30 Step 10
	  Debug "** debut ** ="+Str(deb)
	  For A1=deb To  fin Step 5
	  Debug _n(deb)+_n(fin)+_n(pas)+_n(A1)
	  Next
	Next  

To achieve the same with FORD ... NEXTtD must be initialized and memorise
FORD_deb FORD_fin FORD_pas and not at the beginning of the physical loop but at the beginning of the logic loop.
By cons ... FORD NEXTD with the possibility to change the logical step for each logic loop.

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   ; ******* initialisation et mémorisation debut boucle physique
; 				ADR_ford()\ADR_valdeb=FORD_debut ; ******* initialisation et mémorisation debut boucle physique
; 				ADR_ford()\ADR_valfin=FORD_fin   ; ******* initialisation et mémorisation debut boucle physique
				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
		;*************** si l'on veut que tous les paramétre puissent être modifier à chaque début d'une boucle logique les 3 instruction suivantes sont nécessaires 
		ADR_ford()\ADR_valpas=FORD_pas   ; ****** pour avoir un pas variable  initialisation et mémorisation debut boucle logique
    ADR_ford()\ADR_valdeb=FORD_debut ; ****** pour avoir un début variable initialisation et mémorisation debut boucle logique
    ADR_ford()\ADR_valfin=FORD_fin  ; ****** pour avoir une fin variable initialisation et mémorisation debut boucle logique

		
		;********************************************* 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
	Debug " **** comparaison entre for next de PB  et FORD NEXTD avec un début variable à chaque boucle logique "
		A1=0
	fin=50
	For deb=0 To 30 Step 10
	  Debug "** debut ** ="+Str(deb)
	  For A1=deb To  fin Step 5
	  Debug _n(deb)+_n(fin)+_n(pas)+_n(A1)
	  Next
	Next  

	Debug " ************** les 3 paramètres début fin et pas peuvent être modifiés à chaque début de boucle logique *************"
	Debug " ************** ci_dessous le début varie à chaque début de boucle logique comme l'instruction for  ci dessus le permet *************"
	A1=0
	fin=50
	pas=5
	For deb=0 To 30 Step 10
	  Debug "** debut ** ="+Str(deb)
	  FORD (A1,deb, fin,pas)
	  Debug _n(deb)+_n(fin)+_n(pas)+_n(A1)
	  NEXTD
	Next  
	Debug " *************** comme pas ou step peut êtr une varaible voici ce que for... next de PB  ne peut pas faire (pas variable à chaque boucle logique) ****************** " 
		Debug " ************** ci_dessous le pas varie à chaque début de boucle logique *************"
	A1=0
	fin=200
	pas=20
	For pas=5 To 30 Step 5
	  Debug "** PAS ** ="+Str(pas)
	  FORD (A1,deb, fin,pas)
	  Debug _n(deb)+_n(fin)+_n(pas)+_n(A1)
	  NEXTD
	Next  


Post Reply