# GRASS (linguaggio di programmazione)

Il GRASS (acronimo di GRAphics Symbiosis System) era un linguaggio di programmazione creato da Thomas A. DeFanti per realizzare animazioni in grafica vettoriale. Il GRASS aveva una sintassi molto simile a quella del BASIC ma aggiungeva numerose istruzioni specifiche per l'animazione quali quelle per scalare, traslare, ruotare e modificare di colore gli oggetti, divenendo ben presto diffuso fra gli artisti della grafica computerizzata.
Resta famoso per essere stato utilizzato da Larry Cuba per creare la sequenza animata dell'attacco alla Morte Nera mostrata ai piloti dell'Alleanza Ribelle nel film Guerre stellari.
Una versione più recente, adattata per supportare la grafica raster, fu denominata Zgrass.

## Storia

La versione originale del GRASS fu sviluppata nel 1973 da Tom DeFanti come tesi per il suo dottorato all'Ohio State University su un PDP-11/45 che pilotava un display Vector General 3DR che, come si evince dal nome, gestiva solo grafica vettoriale. Il GRASS includeva un certo numero di comandi per il disegno vettoriale e poteva organizzare delle collezioni di comandi in una gerarchia (memorizzate in vettori) così da applicare i vari effetti animati agli interi "alberi" dell'immagine in una sola volta. Fu questa la versione utilizzata da Larry Cuba per creare la famosa animazione dell'attacco alla Morte Nera presente nel film Guerre stellari: osservando lo scorrere delle immagini, si possono vedere gli alberi degli oggetti "saltare" nell'immagine in diversi momenti.
Dopo la laurea, DeFanti si trasferì all'Università dell'Illinois dove formò, con Dan Sandin, il gruppo di ricerca Circle Graphics Habitat (oggi noto come Electronic Visualization Laboratory, EVL). Sandin era giunto all'università nel 1971 ed aveva iniziato a costruire l'equivalente video del sintetizzatore audio Moog: il suo progetto era noto come Sandin Image Processor, o IP. L'IP era un computer analogico che accettava in ingresso 2 segnali video, li miscelava, colorava il risultato e poi ricreava in uscita il segnale TV.

### GRASS3

DeFanti aggiunse il sistema GRASS come sorgente dell'IP creando così il GRASS/Image Processor, che fu utilizzato fino alla metà degli anni settanta. Per rendere il sistema più potente DeFanti e Sandin aggiunsero al sistema GRASS ogni sorta di comando, rendendo però il linguaggio idiosincratico. Nel 1977 Nola Donato, che si era aggiunta da poco al gruppo, ridisegnò molte delle strutture di controllo del GRASS riducendole in forme più generali: il risultato fu un linguaggio molto più chiaro che fu denominato GRASS3.

### Z Box e Zgrass

Nello stesso anno DeFanti fu presentato a Jeff Frederiksen, un progettista di chip che lavorava presso la Dave Nutting Associates. Nutting era stata contattata da Midway, la divisione videogiochi di Bally Technologies, per creare un sistema grafico generalizzato da utilizzare sui loro futuri arcade ma anche su una console di nuova concezione, quella che in seguito sarebbe stata nota come Astrocade. Midway si dimostrò interessata alla possibilità di far girare il linguaggio GRASS sui loro sistemi e contattò DeFanti per poterlo adattare alla loro piattaforma. I membri dell'Habitat si misero quindi al lavoro insieme agli ingegneri di Nutting a questo progetto, che fu denominato Z Box. Il linguaggio GRASS3 fu rivisto per adattarlo alla nuova piattaforma divenendo lo Zgrass.
Il sistema creato non fu però mai distribuito da Midway perché la controllante Bally perse l'interesse a seguire il mercato dei videogiochi e decise di vendere tutte le attività del settore prima che lo Z Box fosse completo. DeFanti ed i suoi colleghi ne continuarono lo sviluppo in modo indipendente e produssero alcune macchine basate su quella tecnologia, che furono poi commercializzate con il nome di Datamax UV-1.
A differenza del sistema GRASS originale, lo Z Box era un dispositivo basato su grafica raster: per questo motivo lo Zgrass, pur mantenendo gran parte dei comandi del GRASS3, ne vedeva aggiunti molti di nuovi, espressamente dedicati alla manipolazione di immagini di tipo raster. I nuovi comandi includevano un discreto insieme di comandi per il trasferimento di blocchi di bit così da simulare gli sprite, che l'hardware non includeva.

### RT/1

L'ultima versione del GRASS fu l'RT/1, una versione del linguaggio slegata dall'hardware su cui girava, adattato a girare su diverse piattaforme: ne furono realizzate versioni per il DOS, per Windows, per la piattaforma SGI (per usare l'OpenGL), per l'HP-UX, per AIX, per il Macintosh e per l'Amiga. Il linguaggio rimase simile a quello delle prime versioni per cui non è chiaro il motivo del cambio di nome.

## Descrizione

Lo Zgrass era basato su un insieme standard di comandi BASIC, di cui utilizzava anche molta della sintassi. A differenza del BASIC, però, lo Zgrass trattava tutti i comandi come funzioni che restituivano un valore, similarmente al linguaggio C. Se non c'era un valore esplicito da restituire, veniva assunto che la funzione restituisse 1 se era stata eseguita con successo, e 0 in caso contrario. Ad esempio, il comando PRINT PRINT 10, che in BASIC non sarebbe lecito, in Zgrass restituiva 10 1, con il valore "1" stampato dal secondo PRINT ad indicare "Ho stampato con successo la stringa '10'".
I programmi in Zgrass erano identificati come "macro" e memorizzati in stringhe. Questo modo di gestire il codice era voluto, dato che lo Zgrass permetteva a qualunque stringa di diventare un programma. Ad esempio, MYBOX="BOX 0,0,100,100,2" definiva una stringa (non era necessario, come nel BASIC, l'uso del carattere "$" nel nome della stringa) contenente una porzione di codice Zgrass. Digitando semplicemente MYBOX, il sistema eseguiva nel punto di chiamata i comandi contenuti nella stringa. Questa caratteristica poteva essere utilizzata al posto del più tradizionale comando GOSUB del BASIC, con il vantaggio di avere un nome ben definito al posto di un generico numero di linea. Un altro vantaggio era dato dal fatto che il comando rimaneva comunque una stringa, potendo quindi essere manipolato in fase di esecuzione con le normali operazioni per le stringhe.
Molti interpreti BASIC dell'epoca convertivano il testo inserito in una speciale versione "tokenizzata" dove ogni singolo comando veniva sostituito da un singolo numero, detto appunto "token" (generalmente lungo un byte). Questo permetteva all'interprete di eseguire il programma più velocemente perché non doveva tutte le volte decodificare i comandi partendo dal testo inserito. Il modo in cui lo Zgrass usava le macro basandole sulle stringhe rendeva però questo metodo difficile da gestire per cui fu scelto di non implementare la tokenizzazione. Fu invece incluso un compilatore che poteva essere utilizzato con qualsiasi macro, velocizzando di molto l'esecuzione dei programmi: questi consistevano spesso di un mix fra macro compilate e non.
I numeri di linea erano facoltativi e, generalmente, apparivano solo nelle linee che erano destinatarie di un GOTO. Molti interpreti BASIC richiedevano che ogni linea di codice fosse numerata perché il loro editor di codice utilizzava tale numero per determinare la linea da modificare. Lo Zgrass utilizzava invece un editor a tutto schermo molto più sofisticato, che eliminava la necessità di ricorrere alla numerazione delle linee (così come accade nel True BASIC). Lo Zgrass permetteva ad ogni stringa di comportarsi come un "numero di linea" per cui i comandi GOTO 10 e GOTO MARKER erano entrambi validi. Lo Zgrass supportava anche i salti con il comando SKIP, che muoveva l'esecuzione del programma indietro o avanti di un certo numero di linee.
Data la sua natura di linguaggio orientato alla grafica, lo Zgrass includeva numerosi comandi di base per il disegno grafico. Il sistema di coordinate dello Zgrass era basato su quello del chip grafico che Nutting aveva progettato, composto da una griglia di 320×204 pixel: invece l'Astrocade, a causa del limitato quantitativo di RAM, supportava una risoluzione di 160×102 pixel. Per evitare potenziali problemi di mappatura, il punto zero del sistema di coordinate era piazzato nel centro dello schermo per cui l'intervallo valido di coordinate spaziava da -160 a 160 per l'asse X e da -102 a 102 per l'asse Y. Sull'Astrocade venivano utilizzati solo i valori positivi mentre sull'UV-1 era disponibile tutto lo spazio di coordinate.
Lo Zgrass integrava un insieme discretamente ricco di funzioni per la manipolazione degli array, un componente ampiamente utilizzato in grafica. Dette funzioni includevano quelle per "catturare" porzioni dello schermo in un array come una bitmap, che poteva poi essere manipolata come un qualunque altro oggetto grafico. Questo permetteva allo Zgrass di simulare le funzionalità offerte dagli sprite, che l'hardware sviluppato da Nutting non includevano, utilizzando le caratteristiche del linguaggio. Un'altra caratteristica che l'hardware, sviluppato per l'Astrocade, non implementava era l'abilità di processare gli array ad una ragiovelo velocità per cui l'unità UV-1 era dotata di una FPU di Zilog per aumentare le prestazioni.
Lo Zgrass includeva i "livelli", 3 diverse priorità dei processi che permettevano alle macro di essere eseguite normalmente, in "background" (con priorità minima) o in "foreground" (con priorità massima). I livelli aggiungevano una semplice forma di multitasking che risultava enormemente utile in un linguaggio pensato per le animazioni: gli sviluppatori di giochi potevano inserire le routine di gestione del joystick nel livello di background consci del fatto che esse venivano eseguite automaticamente mentre le routine principali disegnavano il gioco. Le funzioni inserite nel livello di foreground venivano eseguite prima delle altre ed erano spesso utilizzate per gestire dei timer ed altri compiti a "bassa latenza". Lo Zgrass includeva una funzione denominata TIMEOUT che chiamava le macro ad intervalli di tempo prestabiliti, permettendo di implementare i timer in maniera molto semplice.
Lo Zgrass includeva una serie di comandi mutuati dal CP/M grazie ai quali era possibile accedere al disco senza tornare al prompt dei comandi: l'utente poteva salvare le macro nei file oppure caricarle da questi ultimi, avendo così la possibilità di costruire dei programmi caricando dal disco diverse macro in un unico, grande, programma. Durante il salvataggio, era sempre eseguito automaticamente un salvataggio di backup. Il linguaggio supportava anche gli accessi ai nastri magnetici ma, curiosamente, la sintassi variava: i comandi per il disco iniziavano tutti con la lettera "D", ad esempio DPUT, mentre quelli per il nastro terminavano con il suffisso "TAPE", ad esempio PUTTAPE (non è chiaro il motivo di questa differenza dato che lo stesso comando avrebbe potuto essere indicato come TPUT)
A causa del fatto che i programmi potevano essere costruiti da qualunque tipo di macro caricata dal disco, lo Zgrass necessitava di un controllo sulle variabili migliore rispetto a quello del BASIC: in esso, infatti, tutte le variabili sono "globali" per cui se 2 sub-routine usano entrambe la variabile i (caso molto comune) esse possono impostare ognuna il valore della variabile dell'altra, rendendo molto difficile un'eventuale operazione di debug. Con lo Zgrass, se un programmatore caricava 2 macro entrambe contenenti un ciclo basato su una variabile denominata "i", i problemi potevano essere molto complicati da risolvere. Per porre rimedio a questa situazione gli sviluppatori pensarono di indicare in minuscolo le variabili locali alla sola macro.

## Esempio

Questo codice crea una nuova macro denominata SINCURVE che può essere chiamata semplicemente con SINCURVE, digitanto al prompt dei comandi oppure inserito in altre macro o altri programmi. SINCURVE usa 2 variabili locali, x e angle, ed 1 variabile globale, OFFSET.
Il costrutto PROMPT/INPUT è una modifica dell'originale INPUT del BASIC, che non chiede all'utente di digitare i valori richiesti se questi sono digitati insieme al nome della macro quando essa viene richiamata dal prompt dei comandi. In questo caso digitando semplicemente SINCURVE si otterrà come risultato l'apparizione del messaggio di richiesta del valore, mentre scrivendo SINCURVE 30 l'interprete salterà la richiesta tramite prompt ed il valore 30 sarà automaticamente assegnato a OFFSET. Grazie a ciò una singola macro poteva essere utilizzata sia interattivamente sia all'interno di un programma come una normale funzione.
POINT è un esempio di uno dei numerosi comandi grafici inclusi nel linguaggio Zgrass. POINT richiede come valori le coordinate X e Y in cui disegnare un punto, ed il suo colore. Nell'esempio la coordinata X è costruita applicando ad un valore fisso lo spostamento passato dall'utente mediante il parametro OFFSET mentre la coordinata Y è calcolata con una funzione trigonometrica, il cui valore viene incrementato per essere comodamente visibile sullo schermo (nell'esempio, di 80 volte). Il colore è passato con l'ultimo valore, in questo caso 3. L'UV-1 utilizzava dei registri per i colori, per cui il valore "3" non si riferiva ad un particolare colore ma indicava al sistema di utilizzare la terza tonalità impostata dall'utente.
L'ultima riga è interessante. La struttura di controllo introdotta con IF presenta un incremento, (x=x+1), prima del test vero e proprio, una caratteristica normalmente non disponibile nel BASIC. In questo caso se il test risulta vero (se quindi x, dopo l'incremento, risulta inferiore a 159), allora il flusso di esecuzione torna indietro di 2 linee con il comando SKIP -2, che opera in sostituzione del comando GOTO.