Strutture condizionali
    Il "Quarto" fuso ] The 4th Time Zone ]   


 

Introduzione
OperazioniInput/Output
TheOperatori matematici
Operatori dello stack
Altri operatori
Colon definition
Strutture di controllo
Strutture condizionali
Costanti e variabili
Altre parole
Uso dell'editor
Messaggi di errore


                                   

[ Indice ][ Indietro ][ Avanti ]

Anche le parole decisionali (conditional-branching) possono essere usati solo entro una colon-definition e usano la forma:

IF  (parte vera) … Parole-Forth … THEN

IF  (parte vera) … Parole-Forth … ELSE (parte falsa) … Forth-words … THEN

Queste istruzioni condizionali si basano sul test del numero in cima allo stack per decidere se eseguire la parte vera o la parte falsa della condizione. Se l'elemento in cima allo stack è vero (non zero) allora verrà eseguita la parte vera. Se l'elemento è falso (zero) la parte verà verrà ignorata e avrà luoco l'esecuzione della parte falsa. Se manca la parte ELSE l'esecuzione prosegue esattamente alla parola dopo il comando THEN. Esiste un sinonimo di THEN cioè ENDIF.  

Esistono numerosi operatori matematici che lasciano sullo stack un flag vero (non zero) o un flag falso (zero) per poterlo testare con l'istruzione IF.

0<

Lascia un flag vero se il numero in cima allo stack è minore di zero, altrimenti lascia un flag falso.

p.es.      -4 0< <CR>

lascia un flag vero (non zero). Per vedere tutto questo prova

. <CR>

per stampare il numero in cima allo stack che rappresenta un flag. Stamperà

-1

ad indicare un flag vero.

914 0< . <CR>

will print a 0 (false flag).

0=

Lascia un flag vero se il numero in cima allo stack è uguale a zero, altrimenti un flag falso.

<

Lascia un flag vero se il secondo numero sullo stack è minore del numero in cima allo stack, altrimenti lascia un flag falso

p.es.      40 25 <  . <CR>

stampa 0 (flag falso).

Se guardiamo lo stack durante questa operazione vediamo

Operazione

TOS

40

40

25

40  25

<

0

.

empty

>

Lascia un flag vero se il secondo numero sullo stack è maggiore del numero in cima allo stack, altrimenti viene lasciato un flag falso.

p.es.      40  25 > . <CR>

stampa -1 (flag vero).

=

Lascia un flag vero se i due numeri in cima allo tack sono uguali, altrimenti lascia un flag falso.

Proviamo alcuni esempi di utilizzo delle strutture condizionali:

: TEST=  <CR>
= IF ." SONO UGUALI " THEN  <CR>
." FINE " ;  <CR>

Ora introduci due numeri seguiti da TEST= e un ritorno a capo

p.es.      11 119  TEST= <CR>

stamperà FINE

119 119  TEST=  <CR>

stamperà SONO UGUALI FINE

Ora digita

:  TEST1=  <CR>
= IF ." UGUALI " ELSE ." DISUGUALI " THEN  <CR>
CR ." FINE " ;  <CR>

e digita

249 249 TEST1=  <CR>

stamperà

UGUALI
FINE

Prova:      249 249  TEST1=  <CR>

stamperà

DISEGUALI
FINE

Nota come la parte dopo il THEN è stata eseguita in entrambi i casi.

Discutiamo ora altre due strutture per ciclo

BEGIN  … parole-Forth…  UNTIL

BEGIN  … parole-Forth…  WHILE … parole-Forth …  REPEAT

Per quanto riguarda BEGIN UNTIL il valore in cima allostack viene testato dopo aver incontrato UNTIL. Se il flag è falso (zero) allora il ciclo che inizia da  BEGIN viene ripetuto. Se il valore è vero (non zero) allora avviene un uscita dal ciclo.

Prova questi esempi:

: COUNT-DOWN DECIMAL  100  <CR>
BEGIN 1 – DUP DUP . CR 0= UNTIL  <CR>
." FATTO " ;  <CR>

Digita ora:

COUNT-DOWN  <CR>

Stamperà

99
98
97

2
1
0
DONE

La struttura BEGIN WHILE REPEAT usa la condizione WHILE per interrompere il ciclo in mezzo tra BEGIN REPEAT. Qui WHILE effettua un test sul flag in cima allo stack e se questo è vero prosegue will continue with the execution of words up to REPEAT which then branches always (unconditionally) back to BEGIN. If the flag is false then WHILE will cause execution to skip the words up to REPEAT and thus exit from the loop.

Costruiamo un programma che stampi i cubi dei numeri da che vanno da 1 in su, finché il cubo non supera 3000. La colon-definition potrebbe essere così

: CUBO  DECIMAL 0  BEGIN 1+  <CR>
DUP DUP DUP DUP * * DUP  <CR>
3000 <  WHILE ." IL CUBO DI "  <CR>
SWAP . ." E' " . CR REPEAT <CR>
DROP DROP DROP ." FATTO "  CR  ;  <CR>

Potresti vedere apparire sullo schermo un messaggio di errore MSG#4: questo significa che la parola che hai appena creato esisteva già. Ma questo non è un problema, semplicemente la nuova parola che sta per essere create nasconderà la vecchia e ogni azione che si riferisce alla parola CUBO verrà diretta all'ultima definizione 

Prova ad eseguire questa parola con:

CUBO <CR>

e osserva il risultato.

Ora, possiamo seguire che cosa succede scrivendo i valori sullo stack a ciascuna iterazione, se ti sembra difficile, i valori sullo stack sono: 

STACK

 

Operazione

Schermo

 

Emtpy

 

DECIMAL

 

 

0

 

0

 

 

0

 

BEGIN

 

 

1

 

1+

 

 

N  N

 

DUP

 

Ci riferiamo al

N  N  N

 

DUP

 

numero sullo stack con N

N  N  N  N

 

DUP

 

 

N  N  N  N  N

 

DUP

 

 

N  N  N  N2

 

*

 

 

N  N  N3

 

*

 

 

N  N  N3  N3

 

DUP

 

 

N  N  N3  N3  3000

 

3000

 

 

N  N  N3  N3  flag

 

<

 

 

IF TRUE:

 

 

 

 

N  N  N3

 

WHILE

 

 

N  N  N3

 

." IL CUBO DI "

IL CUBO DI

 

N  N3  N

 

SWAP

 

 

N  N3   

 

.

N

 

N  N3   

 

." E' "

IS

 

N

 

.

N3

 

N

 

CR

ritorno a capo

 

N

 

REPEAT

 

 

IF FALSE:

 

 

 

 

N  N

 

DROP

 

 

N

 

DROP

 

 

empty

 

DROP

 

 

 

 

." FATTO "

FATTO

 

 

 

CR

 

 

 

 

;

 

 

In effetti, è buona regola controllare il contenuto dello stack durante l'esecuzione di qualunque parola Forth per assicurarsi che tutto funzioni correttamente. (Nota che DROP semplicemente cancella il numero in cima allo stack).

Per concludere, un'altra struttura è stata aggiunta per aggirare il problema di strutture if then molto nidificate. E' la struttura CASE OF. Essa prende la forma generale: forth-words

CASE
n1  OF  parole-forth  ENDOF
n2  OF  parole-forth  ENDOF
 
nk
  OF  parole-forth  ENDOF

ENDCASE

Per esempio:

:  TEST4 CASE  <CR>
1  OF  ." PRIMO CASO " ENDOF  <CR>
2  OF  ."  SECONDO CASO "  ENDOF  <CR>
3  OF  ." TERZO CASO "  ENDOF  <CR>
." ALTRO " <CR>
ENDCASE ;  <CR>

Ora digita:

1 TEST4 CR  2 TEST4 CR 3 TEST4 4 TEST4 CR  <CR>

[ Indice ][ Indietro ][ Avanti ]


Ultimo aggiornamento: 29-11-2002. Copyright (c) 2000-2002 Matteo Vitturi. 
Per problemi o domande relativamente a questo sito contattare il webmaster
Last update: 11.29.2002. Copyright (c) 2000-2002 Matteo Vitturi.
For problems or questions related to this web please contact the webmaster.
1