Qual è l'insieme minimo di operazioni che un'implementazione linguistica deve fornire affinché sia utilizzabile per tutte le applicazioni?

-2

Come divertente progetto per hobby, sto scrivendo una semplice VM bytecode e un compilatore da un linguaggio di alto livello di base al suddetto bytecode.

(Offtopic: il compilatore è ispirato al fantastico tutorial di Jack Crenshaw - Costruiamo un compilatore. Vale davvero la pena leggerlo se non hai familiarità con esso).

Scrivere la VM mi ha fatto riflettere: qual è il set minimo di operazioni che la VM deve supportare per consentire la programmazione di qualsiasi applicazione?

Non sto parlando della completezza di Turing - questo semplicemente ha a che fare con la possibilità di calcolare qualsiasi programma.

Mi riferisco al set di operazioni IO che la VM dovrebbe supportare, tramite opcode dedicati bytecode, attraverso funzioni integrate o attraverso qualche altro meccanismo, per consentire qualsiasi tipo di IO:

Una vera applicazione potrebbe dover leggere un file dal disco, scrivere su un altro, comunicare su TCP o UDP, creare complesse interfacce grafiche sullo schermo, ascoltare l'audio sul microfono, ecc.

Sicuramente gli sviluppatori di, ad esempio, la Java Virtual Machine non hanno creato bytecode dedicati o funzioni built-in per ogni possibile operazione IO. Identico all'interprete Python.

Ora che ci sto pensando - lo stesso si può dire dei compilatori: nessuno scrittore di compilatori per una determinata lingua può supportare ogni possibile operazione di IO.

Quindi come farebbe un progettista VM (o compilatore) per ottenere questo?

    
posta Aviv Cohn 01.10.2018 - 21:26
fonte

1 risposta

3

Passaggio 1: determinare quale piattaforma / sistema operativo si sta utilizzando.

Passaggio 2: offri l'accesso alle funzionalità complete di quella piattaforma.

Ad esempio:

  • Se stai sviluppando un linguaggio che dovrebbe essere eseguito su una JVM, devi solo emettere bytecode JVM ed essere in grado di utilizzare le classi esistenti. (Queste classi potrebbero utilizzare implementazioni native per fornire le loro funzionalità e non sono necessariamente limitate dalla JVM).

  • Se stai sviluppando un linguaggio che dovrebbe funzionare su una variante Unix, allora offri l'accesso all'interfaccia syscall. Quindi puoi chiedere al kernel di fare tutto ciò che desideri, ad es. inviare pacchetti di rete. Go è una delle poche lingue che fa questo.

    In pratica, offriresti un'interfaccia di funzione straniera in modo che i tuoi programmi possano accedere alla libreria standard C e ad altre funzioni C, come quelle di POSIX (che include wrapper per molte syscalls) e altre librerie.

  • Se stai sviluppando un linguaggio che dovrebbe essere usato per scrivere applicazioni web, non hai una scelta a parte la transizione da JavaScript a così puoi accedere a tutte le API Web. Per esempio. tecnologie come WebAssembly consentono di compilare codice che viene eseguito in un browser, ma non offre accesso alle API JS: è necessario scrivere associazioni in JavaScript per rendere le funzioni accessibili a WebAssembly. Ciò rende WebAssembly estremamente poco pratico per lo sviluppo generale del web. Al contrario, TypeScript offre l'accesso a tutte le API Web perché è transpiled in JavaScript e quindi ha pieno accesso alla piattaforma JavaScript.

risposta data 01.10.2018 - 22:05
fonte