En ce moment je commence un projet de boostraping d’un langage interne a ma Fac avec lequel on a bossé pendant un UE du 1er semestre.
Actuellement le langage est riche et contient pas mal de choses, mais il est pas prêt pour se compiler lui même ( y manque notamment la lecture/ecriture de fichiers)
Sans rentrer dans les détails du langage et de ce qu’il contient, selon vous, que doit contenir un langage pour être apte à se compiler lui même ? De manière générale en faisant aucune hypothèse sur le langage
En terme de fonctionnalités, a par les fichiers et quelques structures de données j’ai pas vraiment d’idées.
Je ne dirais pas qu’il doit nécessairement pouvoir lire et écrire dans des fichiers : s’il gère l’entrée et la sortie standard, c’est suffisant.
À Mes yeux tout langage turing-complet qui gère une entrée et une sortie est capable de « se compiler lui-même ». Mais il est sûrement possible de trouver un sous-ensemble.
On peut trivialement créer un langage à une instruction capable de se compiler lui-même, il suffit que cette instruction produise un compilateur. C’est parfaitement inutile, mais c’est minimal.
Je dirais, intuitivement, que si le langage peut exprimer tout algorithme et gérer des types primitifs (entiers, caractères, …) et permet de définir des nouveaux types composés des types primitifs (par des classes ou des types algébriques ou que sais-je), alors le langage en soi à ce qu’il faut. Par exemple, peux-tu représenter des listes, des arbres, avec ton langage ? Rien que pour faire un AST, ça serait pas mal !
Après, pour ce qui est de lire et écrire des fichiers, c’est pas plutôt une question de bibliothèque du langage ? Certes, le langage devra avoir une bibliothèque standard un tant soit peu fournie pour faire des choses utiles.
La bibliothèque standard est généralement écrite utilisant le langage lui-même, mais… évidemment, il faudra bien une « glue » entre ton langage et l’OS à un moment donné.
Une solution serait que ton langage ait de quoi s’interfacer avec les bibliothèques compilées déjà existantes. À partir de là, tu wrapes la libc est tu auras un strict minimum. Avec tes wrappers de la libc, tu peux ensuite faire une bibliothèque standard aussi riche que tu le souhaites, de façon à rendre le code plus agréable à écrire, utilisant les idiomes de ton langages ainsi que son niveau d’abstraction. Une autre solution serait de rendre built-in quelques fonctions utiles, sur lesquelles le reste va reposer. Ou bien encore, une combinaison des deux.
Mais personne ne veut écrire ça, en Python. Donc la lib standard de Python élève un peu le niveau, pour permettre qu’on écrive cela à la place :
import time
t = time.time()
print(t)
Les deux bouts de code ne sont peut-être pas tout à fait équivalents, j’ai pas testé. Mais c’est pour montrer l’idée.
Sous le capot, ça fait certainement appel aux fonctions bas-niveau de la libc, que ce soit via la FFI ou bien directement en C, dans l’implémentation de Python (CPython).
L’approche la plus logique me semble être d’essayer d’écrire un compilateur, et de faire évoluer le langage si on se rend compte qu’il faut ajouter des choses pour pouvoir compiler facilement, ou au contraire en retirer.
Attention aux problématiques de bootstrap (si la seule implémentation du langage est dans le langage, comment la faire tourner sans une autre implémentation existante ?); si vous avez un interprète, même lent, codé dans un autre langage, c’est une bonne idée de continuer à le maintenir (comme votre langage évolue) pour pouvoir interpréter le compilateur pendant qu’il se compile lui-même.
Merci a tous pour vos réponses, j’me rend compte que vu comment j’énonce le problème c’est difficile de pouvoir me répondre.
cela dit, après avoir eu une réunion avec mes chefs de projet, ils m’ont dit exactement la même chose que gasche
L’approche la plus logique me semble être d’essayer d’écrire un compilateur, et de faire évoluer le langage si on se rend compte qu’il faut ajouter des choses pour pouvoir compiler facilement, ou au contraire en retirer.
C’est à dire que j’ai fait un faux départ en cherchant directement a étendre le langage alors que j’aurais du me concentrer sur la manière de construire mon AST (comme sgble dit plus haut) et d’essayer de commencer a compiler des petites choses, petit a petit, et en paralelle me rendre compte des limitations du langage grace a ça pour savoir quoi étendre et le faire au bon moment.
étant donné que le but ici c’est d’avoir un compilateur pour tout le langage, si j’mamuse a rajouter trop de chose au langage lui-même ce seras juste encore plus dur pour le bootstrap.
Attention aux problématiques de bootstrap (si la seule implémentation du langage est dans le langage, comment la faire tourner sans une autre implémentation existante ?); si vous avez un interprète, même lent, codé dans un autre langage, c’est une bonne idée de continuer à le maintenir (comme votre langage évolue) pour pouvoir interpréter le compilateur pendant qu’il se compile lui-même.
Actuellement, le langage a 4 versions, interprété en java, compilé en java vers du C (avec la bibliothèque d’exécution etc) fournis par les profs (c’était l’objet d’étude d’une UE)
Le but ici, c’est de coder le plus possible dans le langage lui même pour vite avoir un début de structure de compilateur.
C’est assez nouveau pour moi donc la manière d’aborder le projet c’était pas gagné.
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte