Precedenza degli operatori
La valutazione di un'espressione viene eseguita dall'interprete REXX da
sinistra a destra, ma alcuni operatori hanno una maggior precedenza
(priorità) di altri e vengono perciò elaborati prima indipendentemente
dalla loro posizione.
L'ordine completo di precedenza degli operatori, iniziando da quelli
con più alta priorità è:
operatori prefissi
|
\ - +
|
operatore di elevazione a potenza
|
**
|
operatori di moltiplicazione e divisione
|
* / % //
|
operatori di somma e sottrazione
|
+ -
|
operatori di concatenazione
|
" " || abuttal
|
oparatori di comparazione
|
== = \== \= > < >> << >< <> >= \< >>= \<< <= \> <<= \>>
|
AND logico
|
&
|
OR e OR esclusivo
|
| &&
|
Secondo tali regole si può determinare il risultato di una sequenza di
operazioni come:
Say 3 + 2 * 5 /* mostra '13' */
Dato che la moltiplicazione (*) ha una priorità superiore alla somma
(+), viene prima calcolato il risultato di 2 * 5 e poi viene
sommato a 3.
Allo stesso modo, avendo l'operazione di somma (+) una priorità
superiore a quella di concatenazione, nell'esempio successivo la somma
sarà eseguita prima della concatenazione:
Say 3 2 + 2 5 /* mostra '3 4 5' */
Le parentesi possono essere usate per forzare la valutazione dell'espressione
in un ordine differente da quello causato dalla precedenza degli operatori
in quanto le espressioni racchiuse entro le parentesi vengono valutate
per prime:
say 6 - 4 + 1 /* mostra '3' */
say 6 -(4 + 1) /* mostra '1' */
say 3 + 2||2 + 3 /* mostra '55' */
say 3 +(2||2)+ 3 /* mostra '28' */
Numeri
Per l'interprete del REXX un programma non è che un insieme di stringhe
da valutare. Se una stringa soddisfa le seguenti condizioni il REXX
la considera un numero valido:
- La stringa inizia con un numero, un punto decimale o un segno (+ o -).
- Le potenze di 10 (numeri in notazione scentifica) sono indicati da
E. Questi sono anche detti numeri in virgola mobile.
- I numeri possono essere racchiusi tra virgolette semplici (') o
doppie (") e sono ammessi spazi tra il numero e il segno.
L'argomento dei numeri verrà ulteriormente approfondito in uno dei prossimi
capitoli.
Concatenazione
L'operazione di concatenazione può essere eseguita:
- lasciando uno o più spazi tra i termini. L'interprete del REXX unisce
i termini con un solo spazio di separazione.
- unendo i termini senza lasciare spazi, purché il REXX sia in grado
di riconoscerli come separati.
- usando l'operatore ||.
La funzione substring()
La funzione SUBSTR permette di isolare una parte di una stringa.
SUBSTR può essere invocata con 2 o 3 argomenti:
substr(string,n)
substr(string,n,length)
dove:
string
|
è la stringa di cui si vuole isolare una porzione
|
n
|
è la posizione del primo carattere della substringa che si vuole
estrarre da string. I caratteri in string sono contati a partire
dal numero 1.
|
length
|
è opzionale e rappresenta il numero di caratteri della substringa. Se
viene omesso tutta la parte di string successiva al carattere n
sarà inclusa nella substringa.
|
Esempi:
say substr("rivelando", 1, 4) /* mostra "rive" */
verbo = "rivelare" /* assegna "rivelare" alla variabile */
say substr(verbo, 3) /* mostra "velare" */
say substr(verb, 3, 4) /* mostra "vela" */
Lunghezza delle stringhe
Per calcolare la lunghezza di una stringa si usa la funzione "LENGTH:
n = length(string)
n, il risultato, rappresenta la lunghezza della stringa.
Esempio:
verbo = "rivelare"
say length(verbo) /* mostra "8" */
Il seguente programma richiede all'utente di immettere il nome di un file,
se la lunghezza di questo supera gli 8 caratteri ammessi nelle
partizioni FAT, il programma mostra un messaggio e accorcia il
nome del file:
/* CHKFNAME.CMD */
say "Scrivi il nome di un file"
pull fname"."ext /* Pull legge il nome del file separandolo */
/* dall'estensione */
if length(fname) > 8
then
do
fname = substr(fname,1,8)
say "Il nome del file introdotto è troppo lungo! ",
"Verrà troncato in "fname
end
L'argomento relativo alle funzioni per la manipolazione delle stringhe
verrà approfondito in uno dei prossimi capitoli.
Comparazione
Ci sono due diversi metodi di comparazione di caratteri e stringhe: la
comparazione normale e la comparazione esatta.
La comparazione normale ignora gli spazi precedenti e successivi alla
stringa e compara carattere per carattere.
La comparazione esatta compara carattere per carattere includendo anche
gli spazi.
Il valore di un carattere nella comparazione è determinato in base al
suo valore in codice ASCII:
valore minore -----------------------------------------> valore maggiore
|
| carattere NULL
| .../ caratteri di controllo, punteggiatura e speciali
| 0...9 numeri
| A...Z caratteri maiuscoli
| [...` alcuni caratteri punteggiatura e speciali
| a...z caratteri minuscoli
| {...þ caratteri speciali, semigrafici, lettere accentate
|
V
valore maggiore
Tutti i caratteri vengono comparati secondo il valore ASCII relatiivo
alla codepage corrente.
Nella comparazione normale, se entrambi i termini non sono numeri,
gli spazi che li precedono o li seguono vengono ignorati, le stringhe
più corte vengono riempite di spazi e poi
vengono comparate da sinistra a destra un carattere per volta.
Se le stringhe non sono uguali i primi due caratteri differenti
determinano il risultato.
Per esempio se compariamo " Formaggio" con "Foro":
gli spazi precedenti vengono ignorati
| |
V V
| | |F|o|r|m|a|g|g|i|o|
| | | |
= = = * -----------------------> "m" < "o"
| | | |
|F|o|r|o| | | | | | <---- alla stringa più corta vengono
aggiunti degli spazi
Tramite la comparazione esatta (strict-comparison) si può
eseguire una comparazione precisa, carattere per carattere, senza
che gli spazi iniziali vengano sottratti o senza che vengano aggiunti
spazi finali.
Per controllare che due stringhe siano esattamente uguali
si usa il doppio segno di uguale (==).
Per esempio:
- il valore di "biscotto" = " biscotto" è 1 (VERO)
- il valore di "biscotto" \= " biscotto" è 0 (FALSO)
- il valore di "biscotto" == " biscotto" è 0 (FALSO)
- il valore di "biscotto" \== " biscotto" è 1 (VERO)
Dato che gli spazi hanno un valore ASCII inferiore a quello dei
caratteri dell'alfabeto, con la comparazione esatta, il valore di
"biscotto" è superiore e a quello di " biscotto".
Per determinare con precisione quale stringa è maggiore o minore,
piuttosto che detrminare solo se le stringhe sono differenti come
negli esempi precedenti si usano gli operatori >> e
<<.
Per esempio:
- il valore di "banana" >> "biscotto" è 1 (VERO)
- il valore di "$10" >> "nove" è 0 (FALSO)
- il valore di "pesce" << "bistecca" è 0
- il valore di " pesce" << "pesce" è 1 dato che il valore del carattere
di spazio è inferiore a quello del carattere "p".
Rappresentando graficamente la comparazione:
gli spazi precedenti non vengono ignorati
| |
V V
| | |p|e|s|c|e|c|a|n|e|
|
*------------------------> " " < "p" quindi " pescecane" << "pesce"
|
|p|e|s|c|e| <--------------- non vegono aggiunti spazi
di solito non si applica la comparazione esatta alle stringhe numeriche
perchè la ragione di tale comparazione e comparare valori piuttosto
che caratteri.
Se x = "2" e y = "+2":
- x = y è VERO
- x \= y è FALSO
- x == y è FALSO
- x \== y è VERO
La comparazione esatta può essere utile nel caso si voglia controllare
la presenza di zeri non significativi o della notazione esponenziale:
- 32.000 = 32 è VERO
- 32.000 == 32 è FALSO
- 000000 = 0E0000 è VERO
- 000000 == 0E0000 è FALSO
Operatori Booleani
Gli operatori logici o operatori Booleani modificano e combianano
le espressioni.
Essi sono:
- L'operatore NOT (\) quando precede un termine cambia
il suo valore da VERO in FALSO o viceversa.
Quando precede un operatore di comparazione ne inverte il risultato.
Per esempio:
say \ 0 /* mostra '1' */
say \ 1 /* mostra '0' */
say \ 2 /* mostra messagio di errore */
say \ (3 = 3) /* mostra '0' */
frutta = "banane"
say frutta = "banane" /* mostra '1' */
say frutta = "mele" /* mostra '0' */
say \(frutta = "mele") /* mostra '1' */
say \(frutta = "banane") /* mostra '0' */
- L'operatore AND (&) dà un risultato di VERO
solo quando entrambi i termini sono veri:
if pronto = "SI" & risultato = GIUSTO"
then say "va!"
La frase "va!" viene mostrata solo quando vengono soddisfatte
entrambe le condizioni.
- L'operatore OR (|) dà un risultato di FALSO solo
quando sono FALSI entrambi i termini:
if pronto = "SI" | risultato = GIUSTO"
then say "va!"
E' sufficiente che una qualsiasi o entrambe le condizioni siano VERE
perché il risultato sia anch'esso VERO.
- L'operatore di OR esclusivo (&&)dà un risultato VERO
solo quando uno e solo uno dei termini è VERO.
if pronto = "SI" & risultato = GIUSTO"
then say "va!"
La frase "va!" viene mostrata solo quando una sola delle due
condizioni è VERA.
Conversione di dati
Il REXX può essere usato per tradurre dati da un set di caratteri ad
uno differente o per elaborare dati in formato binario o esadecimale.
In uno dei prossimi articoli tratteremo più approfonditamente l'argomento
dell'ingresso e uscita dei dati sotto forma di file e queue.
Sistemi numerali
L'OS/2 usa un set di caratteri standard, chiamato ASCII in cui
ad ogni carattere corrisponde un dato codice numerico. Per esempio il
carattere "?" ha il valore di 63.
I computer operano su dati in formato binario, che possono cioè assumere
solo 2 differenti valori cui ci si può riferire come acceso/spento, si/no,
VERO/FALSO o 1/0.
Anche i numeri vengono rappresentati in questo modo. Il numero decimale 63
in un sistema binario viene rappresentato come 00111111.
Ogni cifra indica una potenza di 2 per cui nel precedente esempio
00111111 indica 32 + 16 + 8 + 4 + 2 + 1.
E' questo il modo in cui il carattere di punto interrogativo
viene rappresentato nel computer. Ogni carattere viene considerato come
un byte un insieme di otto cifre binarie aventi ciascuna un valore
di 0 o 1.
Essendo i numeri binari piuttosto scomodi da leggere, i programmatori
usano un sistema numerico in base 16 chiamato esadecimale (spesso
abbreviato in hex). Ogni cifra di un numero esadecimale rappresenta
quattro cifre binarie. Perciò sono sufficienti due sole cifre esadecimali
per rappresentare un byte.
I caratteri usati per rappresentare le 16 cifre esadecimali sono:
valore decimale
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
|
15
|
cifra esadecimale
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
9
|
A
|
B
|
C
|
D
|
E
|
F
|
L'equivalente esadecimale di 63 è 3F, cioè
16 * 3 + 15 * 1 corrispondente al carattere "?".
Oltre ai caratteri in formato ASCCI e ai numeri il REXX è in grado
di elaborare anche numeri in formato binario e esadecimale.
I numeri in formato binario sono rappresentati come una sequenza di cifre
binarie racchiusa da virgolette e seguita immediatamente (senza
separazione di spazi) dal carattere "B" o "b".
Sono ammessi spazi nella stringa binaria, ma solo per separare le cifre
in gruppi di 4 o 8.
Per rappresentare un numero in formato esadecimale, la sequenza di cifre
esadecimali che lo compone deve essere racchiusa tra virgolette ed
immediatamente seguita dal carattere "X" o "x" (senza
separazione di spazi).
Gli spazi nella stringa sono ammessi solo per separare le cifre in
coppie.
Alcuni esempi:
say 37 /* mostra '37' (numero decimale) */
say "%" /* mostra '%' (codice ASCII 37) */
say '25'x /* equivale a '37' decimale. Mostra */
/* il carattere corrispondente: '%' */
say '0010 0101'b /* equivale a '37' decimale. Mostra */
/* il carattere corrispondente: '%' */
Nel caso vengano usati x o b come variabili, in caso di
ambiguità, il REXX dà precedenza al loro significato di indicatori
di base numerica:
x = 'qui' /* assegna la stringa "qui" alla variabile x */
say '3F'x /* mostra il carattere '?' invece di "3Fqui" */
Funzioni di conversione dati
Le seguenti funzioni, incluse nell'interprete REXX, convertono numeri
e caratteri da un formato ad un altro:
conversione di n da a
|
binario
|
ASCII
|
esadecimale
|
decimale
|
binario
|
-
|
X2C(B2X(n))
|
B2X(n)
|
X2D(B2X(n))
|
ASCII
|
X2B(C2X(n))
|
-
|
C2X(n)
|
C2D(n)
|
esadecimale
|
X2B(n)
|
X2C(n)
|
-
|
X2D(n)
|
decimale
|
X2B(D2X(n))
|
D2C(n)
|
D2X(n)
|
-
|
Il nome delle funzioni di conversione è stato creato in base al seguente
significato:
carattere
|
significato
|
2
|
converte in
|
B
|
binario
|
C
|
carattere ASCII
|
X
|
esadecimale
|
D
|
decimale
|
Esempi:
say B2X(0011 1111) /* mostra "3F " */
say X2B(3F) /* mostra "00111111" */
say C2X(?) /* mostra "3F" */
say X2C(3F) /* mostra "?" */
say C2D(?) /* mostra "63" */
say D2C(63) /* mostra "?" */
say D2X(63) /* mostra "3F" */
say X2D(3F) /* mostra "63" */
|