Scrivere un nuovo linguaggio di programmazione: quando e come eseguire il bootstrap delle strutture di dati?

6

Sto scrivendo il mio linguaggio di programmazione che, finora, è andato benissimo in termini di ciò che ho deciso di realizzare. Tuttavia, ora, vorrei avviare alcune strutture dati e / o oggetti preesistenti. Il mio problema è che non sono davvero sicuro su come iniziare.

Quando inizia il compilatore, ho unito questi componenti aggiuntivi in modo tale che siano parte della portata dell'applicazione?

Se li faccio in una libreria di base, la mia preoccupazione è come distribuisco la libreria oltre al compilatore - o sono parte di del compilatore?

Ho capito che probabilmente ci sono un certo numero di modi plausibili per avvicinarsi a questo, ma sto avendo problemi con l'impostazione della mia direzione. Se aiuta, la lingua è in cima al core .NET (cioè, compila il codice CLR).

Qualsiasi aiuto o suggerimento è molto apprezzato!

    
posta OnResolve 10.07.2012 - 12:11
fonte

4 risposte

1

When the compiler begins do I splice in these add-ins so their part of the scope of the application?

Dipende da come è progettato il linguaggio. Se esiste una sintassi speciale per definire un elenco, ad esempio, è necessario includere l'elenco. Se non c'è, allora dovrebbe essere parte di una libreria (standard) e seguire le regole di altre librerie.

If I make these in some core library, my concern is how I distribute the library in addition to the compiler--or are they part of the compiler?

Ancora una volta, se la sintassi del linguaggio richiede le strutture per funzionare, allora forse basta includerle nel compilatore. Altrimenti rendili una libreria e impacchetta la libreria con il compilatore, oppure rendila una semplice dipendenza di installazione.

    
risposta data 10.07.2012 - 14:23
fonte
1

Nella libreria core di runtime, che distribuirai con il tuo compilatore.

La tua domanda è un po 'astratta, che penso abbia fuorviato gli altri nel modo in cui hanno cercato di rispondere. Assumerò che il tuo linguaggio abbia un dominio di interesse, e ci sono alcuni oggetti di base (le classi di base, forse) che sono fondamentali per la lingua. Se la tua lingua fosse per la scrittura di giochi, forse potresti avere alcune classi base speciali per giocatori, personaggi non giocanti, oggetti e terreno. Ciò ti consentirebbe di utilizzare parole chiave e costrutti di linguaggio speciali per la creazione di giochi.

Mentre si è tentati di "emettere" quelle classi dall'interno del compilatore, in pratica ha più senso scriverle come una libreria separata con caratteristiche conosciute e fare in modo che il compilatore presuma che esse esisteranno. Oltre alla libreria "core", si costruiscono una o più librerie di "estensione" o "add-on" man mano che il sistema di linguaggio cresce. Il compilatore non sa nulla di questi.

In effetti si scopre che dovresti mettere il meno possibile all'interno del compilatore e del core perché è molto più semplice estendere il sistema del linguaggio dai componenti aggiuntivi che estendendo il compilatore e il core stesso.

Se questo non è il segno, modifica la tua domanda per fornire ulteriori dettagli concreti.

    
risposta data 26.07.2014 - 12:44
fonte
0

.NET Framework e tutti i suoi strumenti formano un sistema in due parti: ha un compilatore che compila un linguaggio come C # in un assembly con codice CIL e un compilatore just-in-time (JIT) che compila il CIL per codice macchina.

Un grande vantaggio del CLR è che puoi specificare qualsiasi tipo tu voglia semplicemente usando il suo nome completo. Inoltre, l'assembly specifica in quali assembly è possibile trovare tali tipi. Quindi, quando arriva il compilatore JIT, guarderà il nome di tipo completo, caricherà l'assembly di riferimento che contiene il tipo e lo userà. Il tipo non deve essere conosciuto in anticipo, e non c'è mai un problema con riferimenti circolari. Quindi, se metti alcuni tipi in una libreria principale, tutto ciò che devi fare è assicurarti che gli assembly CLR generati dalla tua lingua facciano riferimento alla tua libreria principale, e quindi i tipi in essi contenuti sono immediatamente disponibili per l'uso.

Il compilatore JIT include solo la logica per gestire alcuni tipi primitivi (numero intero a 32 bit, numero intero a 64 bit, float, riferimenti gestiti e puntatori gestiti) e conosce alcune classi di oggetti molto speciali ( Object , Enum , ValueType , Delegate , ...). Quasi tutte le altre funzionalità sono simulate con i tipi primitivi (es. Booleano true è qualsiasi intero con un valore diverso da zero) o supportate tramite chiamate di metodi (virtuali o non virtuali) (proprietà, metodi, operatori sovraccaricati, coercizioni e conversioni tutti usano le chiamate di metodo internamente). Solo alcune funzionalità di base che non possono essere espresse (in modo efficiente) in un linguaggio gestito (come l'aggiunta di numeri interi o l'assegnazione di matrici) sono integrate nel compilatore JIT.

    
risposta data 09.08.2012 - 16:01
fonte
0

Dato che stai costruendo una lingua sopra il runtime .NET, penso che quello che vuoi fare è distribuire una DLL che inizializzerà le strutture / l'ambiente ricercato, quindi chiama un punto di ingresso in quella DLL nel tuo MSIL generato dal compilatore codice, prima di eseguire la funzione main () (o comunque il linguaggio di programmazione trova il suo punto di ingresso) del programma dell'utente.

Questo è analogo a come le variabili libc e le dipendenze di runtime sono inizializzate dal codice assembly che viene eseguito prima che la funzione main () dell'utente [o più precisamente il codice assembly generato per il prolog + body di main ()] sia effettivamente chiamato in C.

    
risposta data 29.07.2014 - 08:34
fonte

Leggi altre domande sui tag