lumen
Un linguaggio di scripting a tipizzazione dinamica in Kotlin. Il sorgente viene scansionato, analizzato in AST, compilato in bytecode ed eseguito su una macchina virtuale a stack.
Un linguaggio di scripting a tipizzazione dinamica in Kotlin che esegue davvero il codice: scansione e parsing verso un AST, compilazione in bytecode ed esecuzione su una propria macchina virtuale a stack.
Panoramica
lumen è un linguaggio di scripting a tipizzazione dinamica scritto in Kotlin che esegue davvero il codice. Il sorgente viene scansionato, analizzato in un AST, compilato in bytecode, e infine eseguito su una propria macchina virtuale a stack. Sembra un normale linguaggio di scripting, ma sotto ogni riga percorre tutta la strada dal testo alle istruzioni macchina.
La differenza tra lumen e un tipico esercizio di scrittura di un linguaggio sta in quest'unica parola: bytecode. È facile costruire un interprete che percorre un albero e lo valuta al volo. lumen va un passo oltre e compila, il che è insieme più difficile e molto più interessante.
Un interprete che percorre l'albero sintattico è semplice da scrivere, ma raggiunge in fretta un tetto di prestazioni. Ogni esecuzione dello stesso ciclo significa ripercorrere gli stessi nodi dell'albero, con tutto l'overhead che questo comporta. Per un piccolo script è invisibile, per qualsiasi cosa più grande è percepibile.
lumen sceglie la via più difficile ma migliore: invece di eseguire l'albero, lo compila in bytecode, cioè una lista piatta di istruzioni semplici. Queste istruzioni girano poi su una macchina virtuale che non deve più capire nulla della sintassi - riceve ordini già pronti e li esegue e basta.
Dal testo al bytecode
Tutta la strada si scompone in quattro fasi. Lo scanner taglia il testo in token, il parser li dispone in un albero, il compilatore trasforma l'albero in bytecode, e la macchina virtuale esegue questo bytecode istruzione per istruzione. Sembra codice ordinario, ma ogni riga percorre lo stesso percorso completo.
il testo sorgente diventa token.
i token si dispongono in un albero sintattico (AST).
l'albero si trasforma in bytecode.
il bytecode viene eseguito su uno stack, istruzione per istruzione.
La macchina a stack dall'interno
Una macchina a stack non ha registri come una vera CPU - impila e disimpila gli operandi sullo stack. Un'addizione si riduce a tre mosse: impila due numeri, disimpilali e somma, impila il risultato. Lo stesso modello fa girare tra gli altri Python e Java sotto il cofano, quindi scriverlo da soli è uno sguardo su come funzionano i linguaggi che si usano ogni giorno.
Addizione su una macchina a stack
| Passo | Istruzione | Stack dopo |
|---|---|---|
| 1 | impila 2 | 2 |
| 2 | impila 3 | 2, 3 |
| 3 | somma | 5 |
Una macchina a stack funziona senza registri, eppure sa eseguire qualsiasi programma. Tutta l'aritmetica e il passaggio dei valori avvengono attraverso un solo stack - è sorprendentemente semplice, e allo stesso tempo esattamente l'idea che fa girare i grandi linguaggi di produzione.
Il risultato: la parola "compilato" smette di essere un'astrazione
Ne esce un linguaggio che esegue davvero il codice - non interpreta un albero al volo, ma lo compila e lo esegue su una propria macchina. È un progetto dopo il quale la parola "compilato" smette di essere un'astrazione, perché si è percorsa da soli tutta la strada, da un carattere in un file fino a un'istruzione che fa qualcosa. Un piccolo linguaggio, ma completo fino all'esecuzione.
Altri progetti
Altri lavori della stessa categoria - scopri come affrontiamo sfide simili.
Hai un progetto simile?
Contattaci - il preventivo è gratuito e arriva entro un'ora.



