| Home / Indice sezione | www.icosaedro.it | ![]() |
|
| |||||||||||||||||||
| Frontespizio Introduzione Caratteristiche Un semplice esempio Moduli Sezione IMPORT Sezione CONST Sezione TYPE Tipo FORWARD Sezione VAR Sezione FUNCTION Sezione BEGIN Stringhe letterali Sottostringhe Commenti Costanti predefinite Variabili predefinite Funzioni predefinite Istruzione di assegnamento Istruzione per la chiamata di funzione Ordine di valutazione degli argomenti attuali Istruzione IF Istruzione SWITCH Istruzione FOR Istruzione WHILE Istruzione REPEAT Istruzione LOOP Istruzione TRY Istruzione RAISE ERROR Istruzione RETURN Espressioni logiche Espressioni intere Espressioni reali Espressioni stringa Espressioni tra tipi strutturati Regole di scope M2 per programmatori C M2 per programmatori Java Rappresentazione dei dati in memoria Keywords Messaggi di errore a runtime Sintassi | M2 per programmatori CIl linguaggio C è versatile e utile. Il compilatore M2 è scritto in C e traduce M2 in C. Il C eccelle in due ambiti: i driver software e i programmi di sistema. Tuttavia, il C mostra dei limiti in altri ambiti: i programmi applicativi, la manipolazione di stringhe, le strutture dati dinamiche, il debugging. Il principio di base di M2 è che i programmi vengono più letti che scritti. Perciò il sorgente deve essere molto chiaro. Per questo le parole chiave di M2 sono scritte in caratteri maiuscoli, in modo da risaltare ed evidenziare la struttura del programma. Il secondo principio di M2 è che deve esistere un solo modo per scrivere una cosa. Un ciclo FOR deve essere impiegato quando è noto a priori l'intervallo della variabile indice. Gli assegnamenti si fanno solo nelle apposite istruzioni di assegnamento. Le parentesi graffe non esistono: le istruzioni di controllo (IF, WHILE, LOOP, ecc.) usano parole chiave obbligatorie che delimitano le istruzioni controllate; in questo modo il programmatore può concentrarsi sulla logica del suo programma e non perde tempo con la formattazione del sorgente.
I file di inclusione
In questo ipotetico modulo, il nome di un file è rappresentato da una array di stringhe che descrivono il path del file. Il FILE è un tipo FORWARD la cui struttura è dichiarata nell'IMPLEMENTATION MODULE e non è nota ai moduli clienti. Il tipo enumerativo ACCESS_MODE è del tutto simile al tipo enum del C. La funzione Open() ritorna un oggetto di tipo FILE da usare nelle successive funzioni per la lettura e la scrittura dei dati. Un modulo cliente potrebbe essere strutturato così:
I nomi dei file sono composti con l'operatore {} che crea un array di stringhe. L'array prodotto è il pathfile che viene passato alla funzione Open(). Il file spiaggia.jpg viene copiato nel file vacanze.jpg. Il ciclo LOOP...END legge blocchi di 4 KB dal file sorgente e li copia nel file destinazione. Quando Read() ritorna NIL la copia è terminata e l'istruzione EXIT termina il ciclo. Ci sono altri fatti importanti da notare in questo breve programma. Spazi e a-capo vengono ignorati dal compilatore, esattamente come in C. La punteggiatura è ridotta al minimo. Le istruzioni non devono essere terminate da ';'. Il simbolo di '=' è un assegnamento quando usato nella istruzione di assegnamento, ed è un operatore di confronto quando usato in una espressione logica. Non si possono eseguire assegnamenti dentro alle espressioni; pertanto il codice C del tipo
deve essere tradotto in qualcosa simile a questo:
In M2 non esistono i puntatori, nè è necessario
manipolare indirizzi di memoria. Le variabili dinamiche vengono
allocate automaticamente quando si assegnano, e vengono rilasciate
automaticamente quando non sono più referenziabili. Le stringhe
hanno lunghezza arbitraria. Gli array hanno lunghezza arbitraria e si
espandono automaticamente. I RECORD, simili alle
Siccome in M2 le stringhe e gli array sono allocati dinamicamente,
le dichiarazioni di stringhe a lunghezza fissa ( Questa struttura dati rappresenta i dati di una automobile:
L'equivalente M2 è:
Un rivenditore di automobili usate decide di usare un array per rappresentare le automobili. Inoltre definisce una funzione Inserisci() per inserire un nuovo modello, e una funzione Cerca() per trovare un modello. Cominciamo con la versione in C della funzione di inserimento:
Lo stesso codice riscritto in M2:
Le chiamate di funzione sono del tutto simili in entrambe le versioni: le stringhe vengono passate come puntatori, mentre i numeri interi sono passati come valori. Ma qui terminano le similitudini. Ora vediamo le differenze.
In M2 gli array sono inizialmente non allocati e si espandono in
modo da ospitare gli elementi che vengono assegnati. La funzione
Il RECORD La differenza più importante tra il C e M2 è il modo in cui vengono trattate le stringhe. In M2 le stringhe sono assimilate a dati di tipo semplice, come i numeri. Nella maggior parte del codice le stringhe vengono "copiate" come puntatori. In effetti nel codice della funzione Inserisci(), M2 non alloca alcuna stringa ma copia solo i puntatori. La conseguenza di questo fatto è che, mentre in C è possibile modificare un carattere di una stringa, in M2 le variabili di tipo stringa non si possono modificare: per cambiare una stringa è necessario copiare nella variabile il puntatore a una nuova stringa. E' per questo motivo che nella implementazione C abbiamo usato strdup().
Vediamo anche il codice della funzione
In questa funzione l'array
M2 produce automaticamente tutto il codice necessario per gestire la
memoria e le strutture dati. In effetti in M2 non esiste un equivalente
delle funzioni
Gli array si possono espandere, ma non si possono contrarre. Per rimuovere
l'automobile
Il garbage collector provvederà a cancellare dalla memoria l'elemento
Quando gli array non sono adeguati per la struttura dati che si deve gestire, in M2 si possono costruire anche liste e alberi. Vediamo per esempio come si rappresenta una lista doppiamente concatenata:
Il record ha adesso due nuovi campi che permettono di spostarsi sul record precedente e sul record seguente della lista. La funzione per cancellare un record si modifica come segue:
Osserviamo attentamente il sorgente, perché ci sono delle
interessanti differenze con il C. Il ciclo WHILE percorre l'elenco
delle automobili. Quando viene individuata l'automobile da cancellare,
il record prededente viene fatto puntare al seguente, mentre il
record seguente viene fatto puntare al precedente. Una volta usciti
dalla funzione, il record da cancellare non ha più riferimenti
all'interno del programma e lo spazio da esso occupato in memoria viene
recuperato. Queste operazioni di cambio indirizzi vengono protette
all'interno di due a[precedente][seguente] = a[seguente]
creerebbe il record Operatori. Il C prevede ben 11 livelli di priorità per gli operatori aritmetici, logici e di confronto. Questo permette di risparmiare in alcuni casi le parentesi tonde, ma induce a commettere qualche errore. In M2 invece esistono solo tre priorità: 1) l'operatore di complemento a uno, 2) gli operatori moltiplicativi, 3) gli operatori additivi e di cambio di segno. Ad esempio, in M2 questa espressione a ^ b + c | dviene calcolata da sinistra verso destra semplicemente come è scritta perché tutti gli operatori che vi compaiono sono di tipo "additivo" e quindi hanno la stessa priorità. In C la stessa espressione viene interpretata in modo meno ovvio: (a ^ (b + c)) | dPer concludere questa panoramica delle differenze tra M2 e C, vediamo come si scrivono nei due linguaggi le istruzioni più comuni:
| |||||||||||||||||||
| ||||||||||||||||||||
| Umberto Salsi | Contatto | Mappa | Home / Indice sezione |