Ci sono tre modalità generali di esecuzione per i moderni linguaggi di alto livello:
Interpretato Quando il codice scritto in un linguaggio è interpretato, la sua sintassi viene letta e poi eseguita direttamente, senza fase di compilazione. Un programma chiamato interprete legge ogni dichiarazione del programma, seguendo il flusso del programma, poi decide cosa fare e lo fa. Un ibrido tra un interprete e un compilatore compila l’istruzione in codice macchina e la esegue; il codice macchina viene poi scartato, per essere interpretato di nuovo se la linea viene eseguita di nuovo. Gli interpreti sono comunemente le implementazioni più semplici del comportamento di un linguaggio, rispetto alle altre due varianti elencate qui. Compilato Quando il codice scritto in un linguaggio viene compilato, la sua sintassi viene trasformata in una forma eseguibile prima dell’esecuzione. Ci sono due tipi di compilazione: Generazione di codice macchina Alcuni compilatori compilano il codice sorgente direttamente in codice macchina. Questo è il modo originale di compilazione, e i linguaggi che sono direttamente e completamente trasformati in codice macchina in questo modo possono essere chiamati linguaggi veramente compilati. Vedi linguaggio assembly. Rappresentazioni intermedie Quando il codice scritto in un linguaggio viene compilato in una rappresentazione intermedia, tale rappresentazione può essere ottimizzata o salvata per una successiva esecuzione senza la necessità di rileggere il file sorgente. Quando la rappresentazione intermedia viene salvata, può essere in una forma come il bytecode. La rappresentazione intermedia deve poi essere interpretata o ulteriormente compilata per eseguirla. Le macchine virtuali che eseguono direttamente il bytecode o lo trasformano ulteriormente in codice macchina hanno offuscato la distinzione una volta chiara tra rappresentazioni intermedie e linguaggi veramente compilati. Tradotto o transcompilato da sorgente a sorgente Il codice scritto in un linguaggio può essere tradotto in termini di un linguaggio di livello inferiore per il quale i compilatori di codice nativo sono già comuni. JavaScript e il linguaggio C sono obiettivi comuni per tali traduttori. Vedi CoffeeScript, Chicken Scheme e Eiffel come esempi. In particolare, il codice C e C++ generato può essere visto (come generato dal linguaggio Eiffel quando si usa l’IDE EiffelStudio) nella directory EIFGENs di qualsiasi progetto Eiffel compilato. In Eiffel, il processo di traduzione è indicato come transcompilazione o transcompilazione, e il compilatore Eiffel come transcompilatore o compilatore source-to-source.
Nota che i linguaggi non sono strettamente interpretati o compilati. Piuttosto, le implementazioni del comportamento del linguaggio usano l’interpretazione o la compilazione. Per esempio, ALGOL 60 e Fortran sono stati entrambi interpretati (anche se erano più tipicamente compilati). Allo stesso modo, Java mostra la difficoltà di cercare di applicare queste etichette ai linguaggi, piuttosto che alle implementazioni; Java è compilato in bytecode che viene poi eseguito o interpretando (in una macchina virtuale Java (JVM)) o compilando (tipicamente con un compilatore just-in-time come HotSpot, sempre in una JVM). Inoltre, la compilazione, la transcompilazione e l’interpretazione non sono strettamente limitate alla sola descrizione dell’artefatto del compilatore (eseguibile binario o assembly IL).
Architettura del computer del linguaggio di alto livelloModifica
In alternativa, è possibile per un linguaggio di alto livello essere implementato direttamente da un computer – il computer esegue direttamente il codice HLL. Questo è noto come un’architettura per computer con linguaggio di alto livello – l’architettura stessa del computer è progettata per essere indirizzata da uno specifico linguaggio di alto livello. I grandi sistemi Burroughs erano macchine target per ALGOL 60, per esempio.