Spinto dal corso c di Antirez su youtube in cui sta mostrando come si scrive un interprete forth Ho pensato cosi per provare a scriverne uno a modo mio vale dire esasperando tutto.
Il forth è un antico linguaggio di programmazione anzi è in un certo senso anche un sistema operativo. figlio degli anni 60 è sicuramente parecchio alieno per che usa la notazione polacca inversa. Avevo fatto quanche mese fa una serata in compvter su questo linguaggio e sui insospettabili eredi il cui principale è il c nella maniera originale.
Siccome è molto alieno programmare inquesto linguaggio dico sempre scherzosamente che nel rottame dell'astronave aliena di Roosvelt avevano trova un computer con i transistor al germanio che faceva funzinare il forth.
Vediamo un po la notazione:
una somma si fa cosi: 2 2 +
lo spazio o l'invio è il separatore di tutto
il forth usa per tutto un buffer speciale che si chiama stack
La particolarita dello stack è che l'ultimo numero inserito è il primo ad essere estratto.
In realta è un componente previsto direttamente nei processori e solitamente ha i comand push e pop per scrivere leggere in questo buffer
scrivendo 2 metti il numero nello stack
scrivendo un scrivendo un altro 2 lo metti anche lui nello stack
scrivendo piu invece siccome è un comando questo estrae il 2 dallo stack poi estrae il primo 2 dallo stack li somma e il risuiltato vien messo nello stack.
Questa logica è potente e semplice al tempo stesso: i comandi di base sono:
. (nel caso di Antirez ha usato print) stampa l'ultimo numero inserito nello stack
+ - * / sono le operazioni matematiche. il risultato è posto nello stack
> < = operatori di confronto (prendono i 2 numeri li confrontano e se la condizione è vera si mette 1 altrimenti 0)
if else endif preleva dallo stack se è piu di 0 esegue il comando dopo altrimenti cerca else o endif
eccetera....
La versione di forth che ho creato è estrema e minimale. E' scritta in c.
Lo stack non è quello del processore ma un array di int. la matematica va quindi solo a interi. Nel forth di solito la matematica è in virgola fissa.
Il word_exec (le word sono i comandi Forth) fa i confronti di tipo numerico a byte quindi verifica se è un numero altrimenti verifica se è un comando una nuova funzione o una variiabile se non trova nulla emette un errore i comandi aggintivi e molti comandi lunghi tipo dup swap if else fi sono trasformati in numeri con una sorta di hash ma a 32 bit e confrontati quindi non uso strcmp che è piu ttosto pesante.
Per le variabili uso 2 comandi !nome_varibile che assegna alla variabile il valore prendendo dallo stack e @nome_variabile che invece copia nello stack il valore.
Le variabili sono un altro array di una struttura nome ,valore anche qui il nome è cifrato a 32 bit e il valore è un int (quindi su pc a 64 bit). anche qui il findvar è molto veloce perche cerca con il numero cifrato quindi 20X veloce.
Per le stringhe ho usato un array di array di char ( char strings[64][128])
quanod la word inserita inizia con " exec_word mettette tutto il testo nella prima string vuota fino al successivo " quindi inserisce il numero dell'indice delle stringhe nello stack.
il comando $ preleva dallo stack l'indice string e lo stampa. Questo schema è furbo e permette cose strane tipo:
"ciao ciao" !ciao
@ciao $ >stampa ciao ciao.
le funzioni in forth si fanno usando : nome_word comandi.... ; e l'ho implementao uguale solo che nel forth originale il comando viene compilato nel nano forth invece viene caricato in una array cosi come è e quando invocato viene semplicemente iniettato come fosse scritto sul momento. Di fatto sono piu macro che funzioni. Semplice veloce funziona bene ma non offre maggior velocita del codice diretto.
Alla fine è molto limitato ma è un bell'esercizio intelligenza laterale nel cercare soluzioni
estreme ed efficenti e mentre scrivo ho gia un paio di idee insane da aggiungere.
Dimenticavo di dire che funziona sia come terminale sia passando un file.
volete vederlo nei dettagli? https://gist.github.com/vroby65/082f0ffc98bd846b95ab0bac95312574
Nessun commento:
Posta un commento