DOMANDA Creazione linguaggio di programmazione

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Infatti so che le uniche cose che hanno in comune un interprete e un compilatore sono il lexer e il parser. Poi come faccia il compilatore a trasformare tutto in codice macchina per me è un mistero. Ha un set di istruzioni in assembly per ogni istruzione pronto all’uso? Boh
Viene generato un codice intermedio, che non è ancora il codice macchina di un'architettura specifica.
Considera che i compilatori attuali ottimizzano anche il codice: non si tratta di "avere in memoria le istruzioni", ma soprattutto di ottimizzare il codice prima dell'emissione. Per fare un esempio stupido:

C:
int sum = 0;
for(int i=0; i<n; i++) {
    int number = 0x12346;
    sum += (number * i);
}

In un codice come questo una delle ottimizzazioni che avviene è sicuramente spostare la variabile "number" prima del ciclo for, in quanto viene inizializzata ripetutamente ma il suo valore rimane costante, non cambia.

Un altro caso "semplice", è identificare quelle variabili alle quali assegni un valore che è costante, ma attraverso alcune operazioni, tipo:
C:
int number = 24 * 60 * 60;

Questa viene identificata in fase di compilazione e viene direttamente emesso il risultato, "assegnandolo" direttamente alla variabile number; quindi nell'assembly vedresti concettualmente tipo:
Codice:
mov   [number], 86400

Tutto il codice macchina viene poi emesso per l'architettura target al termine di tutto il processo di compilazione.

Non mi ricordo più moltissimi "dettagli" sulle varie fasi, è un argomento che avevo affrontato per curiosità, ma che non ho mai approfondito veramente.
Sicuramente una delle cose che dovrai avere, ma questo già con l'interpretato, è una certa "dimestichezza" con alberi e grafi.

Allora, mi sono documentato un po’ (ma ho compreso molto poco). Da quello che ho capito la parte scritta a mano si occupa di creare i token e fare il parsing, poi llvm si occupa della traduzione in asm e poi in binario

LLVM è quello che ho citato sopra: viene utilizzato in svariati progetti, e si, in sostanza ti consente di emettere delle istruzioni nel codice macchina dell'architettua che vuoi. Il compilatore CLang fa da front-end di LLVM, per esempio.
 

pabloski

Utente Èlite
2,868
916
Ha un set di istruzioni in assembly per ogni istruzione pronto all’uso? Boh

si, è come un gigantesco switch che comprende pure le varie ottimizzazioni per ogni singolo caso, cioè una certa istruzione o sequenza di istruzioni ( in realtà viene generato un albero in forma SSA che riporta le operazioni e gli operandi relativi ), viene tradotta in differenti sequenze di istruzioni macchina, a seconda delle ottimizzazioni che ritiene di dover implementare ( che possono dipendere da un modello specifico di processore, dall'uso di particolari istruzioni vettoriali, ecc... )

Allora, mi sono documentato un po’ (ma ho compreso molto poco). Da quello che ho capito la parte scritta a mano si occupa di creare i token e fare il parsing, poi llvm si occupa della traduzione in asm e poi in binario

il compito del frontend ( cioè quello che dovresti scrivere tu ) è quello di tradurre in forma SSA e nell'IR ( l'assembly ) di LLVM il codice sorgente

il resto lo fa lui, comprese attività come l'eliminazione di dead code, ottimizzazioni di varia natura, loop unrolling e altre millemila cose

puoi dare un rapido sguardo qui per capire come funziona


Ho dato anche un’occhiata a questi due progetti. Se zig ho visto il c++ per nim il compilatore (perche mi sembra sia compilato) è scritto in nim. Cosa che ci sta, perché da quanto so anche gcc è scritto in c, però mi servirebbe imparare un altro linguaggio, che non avrebbe altro scopo di fare il compilatore, infatti non ho mai sentito parlare di questo nim

Nim è molto di nicchia ed è un Pascal-like. Si sta in parte diffondendo nell'ambito della cybersecurity, sia per creare malware che tool per il red/blue teaming.

Li ho tirati in ballo perchè, in particolare Zig, sono facili da apprendere.

Lisp invece ha un modello di programmazione semplicissimo, basato sulla struttura chiamata cons ( una lista linkata, dove ogni elemento contiene un valore di tipo arbitrario ). E supporta l'omoiconicità, ovvero il codice può essere visto come dati e dunque manipolato a runtime. Pensa all'eval di Python o Javascript, ma molto più potente. In pratica è un vantaggio incredibile per chi realizza propri linguaggi ( o DSL ).

E dimenticavo Brainfuck, che pure ha un modello di programmazione semplicissimo ed è stato creato proprio per insegnare lo sviluppo dei linguaggi.
 
Ultima modifica:
  • Mi piace
Reazioni: DispatchCode

bigendian

Utente Attivo
749
432
OS
Linux
un azienda dove ho lavorato aveva implementato un linguaggio di scripting simil basic, carino, tutti i programmi del dispositivo embedded, a seconda della variante, li scrivevamo in questo simil basic. Il che creava una simpatica portabilita' anche quando abbiamo cambiato hardware. Niente di complesso, un "tokenizer" che trasformava il basic in pseudo opcodes, e un interprete. Mi pare il piu complesso fosse il tokenizer, che diveva effettuare alcuni cicli sul codice. Ma in tutti e due i file, forse 2000 righe in tutto, una cosa fattibile per giocare.
 

giammo82

Utente Attivo
1,210
525
Sinceramente, visto il codice che hai postato in questo forum, ti consiglierei qualche esercizio più facile.
Scrivere un linguaggio di programmazione è un grosso progetto e si studia agli ultimi anni di informatica, in quanto richiede un sacco di nozioni che si imparano con il tempo. Prima di tutto “linguaggio di programmazione” è un termine ormai molto generico, in quanto ne esistono di diversi tipi e quindi prima di iniziare occorre capire bene cosa si voglia fare.
Non ricordo più i libri di testo che usai (e poiché parlo della preistoria ormai sono inutili), ma ti assicuro è un argomento molto complesso, un linguaggio di programmazione è composto da molte parti. Per esempio la prima parte è il “parser” che controlla la sintassi e “rompe” il testo in moduli separati. Ormai nessuno si sogna di scrivere un parser, ne esistono ormai di ottimi come per esempio Lex and Bison che sarebbe la prima cosa che dovresti studiare.

Il mio consiglio, inizia con qualcosa di più semplice.
Per esempio, un programmino che mi aiutò un sacco agli inizi fu un calcolatore che prende come input una formula matematica.
Si inizia con le quattro operazioni tipo

Poi si aggiunge
  • l’ordine delle operazioni
  • l’uso delle parentesi.
  • le operazioni matematiche (tipo seno e coseno)
  • le variabili (assegnare il risultato a una variabile per poi usarla in seguito)
Come vedi ha il vantaggio che si sviluppa a passi, si inizia semplice e mano a mano diventa più complicato.
E vedi bene perché lo ritengo un esercizio utile: è in pratica la base di un linguaggio di programmazione :) ci aggiungi test e cicli e diventa un BASIC su cui poi si basa il Fortran, il Pascal, il C e via dicendo

Fammi sapere.
A davvero si inizia così , pensa che avevo fatto tempo fa un programma che prendeva in input una stringa ossia una espressione matematica e ne ricava il risultato non credevo che fosse la base per scrivere un linguaggio di programmazione...
Post unito automaticamente:

Comunque scrivere un compilatore è più istruttivo di un linguaggio di programmazione...
 
  • Mi piace
Reazioni: Andretti60

Andretti60

Utente Èlite
6,440
5,091
A davvero si inizia così , pensa che avevo fatto tempo fa un programma che prendeva in input una stringa ossia una espressione matematica e ne ricava il risultato non credevo che fosse la base per scrivere un linguaggio di programmazione...
Post unito automaticamente:

Comunque scrivere un compilatore è più istruttivo di un linguaggio di programmazione...
infatti non lo e' :) ma se ne ha bisogno se il linguaggio prevede formule matematiche. Lo ho citato solo come un esempio di programmino interessante da sviluppare (come te ne sarai reso conto)
Beh, certamente scrivere un compilatore e' più' interessante, ma non direi sia più' istruttivo. Un compilatore converte un linguaggio di programmazione in linguaggio macchina, quindi dipende dalla architettura. Beh... non proprio vero, può infatti generare un meta linguaggio che poi viene compilato JIT, o eseguito da un engine specializzato, o simili. Insomma, per "istruttivo" dipende un po' da cosa si voglia poi imparare.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!