Lim

Lim

Qu’est-ce que Lim ?
Lim est un langage de programmation que je développe de A à Z. C’est un projet qui n’est pas voué à répondre à un besoin autre que celui d’assouvir ma curiosité. J’aime apprendre par moi-même et « réinventer la roue » pour la comprendre. Je n’utilise d’ailleurs aucune IA générative pour le développement : je tiens à résoudre chaque problème de logique par mes propres moyens, car c’est là que réside tout l’intérêt de la démarche.

Dans cet article, je vais principalement parler de limc, le compilateur de Lim. Plus précisément, il s’agit d’un transpileur : le code source Lim est converti en code C, lequel est ensuite compilé par un outil externe comme GCC. C’est une approche éprouvée, utilisée par des langages comme Nim.

Pipeline de compilation d'un programme Lim


Le langage Lim
Après des années d’expérimentations, la syntaxe de Lim arrive enfin à maturité. C’est un langage compilé à typage statique fort, inspiré par la clarté de Python. Mon constat était le suivant : j’apprécie l’aspect concis de Python, mais j'aime le cadre qu’offre un langage typé et l'aspect « terre à terre » du C ou du Rust. J’aime avoir l’impression de programmer plus près de ce que la machine va exécuter, tout en gardant une syntaxe moderne.

Caractéristiques techniques :
Exemple de syntaxe Lim :
record point(x:int, y:int)

func create_random_point:point
    return point{ math::random(1, 10), math::random(1, 10) }

func main
    let points = new list<point>
    for i from 0 to 50
        points.add(create_random_point())

La Codebase : Pourquoi Visual Basic ?
Le choix de Visual Basic (VB.NET) pour écrire le compilateur peut sembler désuet, mais il est simple : c'est le langage avec lequel je suis le plus à l'aise. Comme il compile en CIL (Common Intermediate Language), il est totalement compatible avec l'écosystème .NET (C#, F#). Ce qui compte ici, c’est l’implémentation de la logique de compilation, pas le langage en lui-même.

Une architecture « Lazy »
L’architecture de limc repose sur un chargement paresseux (lazy). C’est l’approche que j’ai utilisée par défaut car c’est la plus intuitive :

  1. Le compilateur charge le fichier source principal.
  2. Il le convertit en tokens, puis génère un AST (Abstract Syntax Tree).
  3. Les fichiers importés sont analysés récursivement.
  4. Une fois l'arbre complet, Lim compile le point d’entrée : la fonction main.

Ainsi, la fonction main va faire appel à d’autres fonctions, à leur tour compilées via récurrence. De cette manière, seules les dépendances réellement utilisées sont résolues et compilées, ce qui permet d'optimiser le résultat final.

Gestion de projet
Mon tout premier programme a été une simple application WinForms générant des scripts Batch. J'ai toujours été fasciné par les outils qui servent à créer d'autres outils. Lim existe sous sa forme actuelle depuis 2022, mais mes premiers essais remontent à bien plus loin.

Pendant toutes ces années, j’ai fait bon nombre d’erreurs. J’ai recommencé de zéro un nombre incommensurable de fois. Mais surtout, j’ai appris. J’ai appris à définir ce que je pouvais garder ou non, ce qui relevait d’une bonne ou d’une fausse bonne idée. J’ai appris à prévoir, à réfléchir en amont. J’ai appris que le plus compliqué n’était pas tellement de coder, mais plutôt de conceptualiser un système qui fonctionne, et qui fonctionne pour tout. J’ai appris à réellement tester les cas extrêmes, à refactoriser, à m'organiser. Et surtout, j’ai appris à me définir des objectifs et à ne pas m’éparpiller. C’est un vrai théâtre d’entraînement et de persévérance que rien ne peut remplacer.