Le problème, c'est que vous mélanger syntaxe infix et prefix dans un dialecte (le lisp) qui a été pensé pour être prefix avant tout notamment avec (x = a)
. Cela peut notamment amener à des misconceptions sur ce qu'on peut imaginer du langage (comme se poser légitimement la question si il est possible d'écrire (5 + 5)
).
Ensuite, je vais reprendre un vieux message qui vient de PdP qui explique succinctement l'idée que vous devriez vous faire de la syntaxe. Le post est très long mais je vous invite vraiment à le lire car c'est un bon début de piste en ce qui concerne le travail en rapport avec la syntaxe.
Je vais te dire pourquoi je n'ai pas regardé la syntaxe du langage - mais ne t'inquiète pas, j'ai fait aussi l'erreur.
Dans le développement d'un langage informatique, quand on est débutant et qu'on lit les ressources tel que le Modern Compiler Implementation in ML ou des livres plus anciens tels que le Dragon Book, le premier chapitre parle de lexique et de syntaxe. Grosso-modo, on commence déjà par décrire la syntaxe d'un langage informatique comme vous le faites ici.
Cette technique d'apprentissage est très bien quand on est supervisé. Elle a l'avantage de produire quelque chose de concret assez rapidement ce qui permet au lecteur d'avoir un résultat de son travail assez rapidement. Aussi, la première phase d'un compilateur/interpréteur est l'analyse lexical et syntaxique (ce qu'on nomme communément le front-end). Pourtant, cela n'en fait pas la partie la plus intéressant. Je dirais même que c'est un piège de commencer par cette partie dans le développement d'un nouveau langage.
Un front-end à la mano ?
J'ai un peu regardé le code disponible et cette remarque convient parfaitement dans le sens où vous vous amusez à faire à la main le front-end. Je juge pas de la qualité de votre code mais surtout de la direction prise dans le développement.
Alors l'analyse lexical et syntaxique, théoriquement c'est ce qu'on nomme un automate à état fini et un automate à pile respectivement. Si vous avez la curiosité de voir les liens, vous verrez que c'est pas super beau à voir dans le sens où ce sont des modèles dont l'explication est, je trouve, complexe pour un néophyte de l'informatique et dont l'implémentation n'est guère intéressant. Ce sont pourtant des modèles basiques que tout informaticien digne doit connaître (dans les grandes lignes). Donc vous devez les apprendre.
Vous pouvez voir une implémentation d'un automate à état fini ici par Russ Cox pour vous faire une idée de ce que c'est. En plus en cadeau, vous avez un tout petit automate à pile dans le lot ici (c'est la fonction re2post
) — mais je vous invite à lire le cours de @nohar sur le sujet qui vous en apprendra toutes les subtilités. Enfin, si vous regardez bien, c'est une implémentation d'un moteur d'expression régulière — en réalité, c'est une application du théorème de Kleene qui dit que pour tout automate à état fini, on peut y associer une expression régulière. Alors, montrer comme ça, ça à l'air chiant. Et ça l'est comme le dénote ce commentaire dans les sources du compilation OCaml sur l'analyse lexical.
En réalité, dans tout langage digne de ce nom, on ne refait plus d'automate à état fini ou d'automate à pile pour créer le lexique et la syntaxe du langage parce que c'est chiant. On utilise des générateurs d'automate à état fini et automate à pile qui sont respectivement pour le C Flex et GNU Bison — tu as les équivalents en OCaml avec ocamllex et menhir ou ocamlyacc (@nohar à la rescousse pour Python). Et ces outils, on les utilise partout comme PHP par exemple ou OCaml avec son propre outil. Il faut savoir que ces outils ont une portée historique, en faite il existe encore aujourd'hui les outils lex
et yacc
qui ont servit à implémenter le premier compilateur C (donc un vieux compilateur), ce sont des outils qui ne viennent pas de nul part. Conventionnellement, lors d'un bootstrap du langage, on lui associe ce genre d'outil portant quasiment le même nom. C'est pour cette raison que vous retrouverez pour la quasi-totalité des langages un équivalent à lex
et yacc
en plus ou moins évolué comme c'est le cas en OCaml.
Ce que je veux dire par là, c'est qu'il faut utiliser ces outils. Non pas parce que c'est moi qui le dit mais parce qu'ils sont fait exactement pour ça, pour créer des langages informatiques. Faire le front-end à la main n'a qu'un intérêt didactique qui reste très limité car vous n'arriverez certainement pas à faire une implémentation équivalente à ce que produit Flex et GNU Bison autant sur la performance que sur la fiabilité, la productivité et surtout la modularité (et si vous voulez rajouter une nouvelle construction au langage ?). C'est factuel. BLABLABLA COURS DE THIZANNE BLABLABLA.
Prendre la bonne direction
Même si la plupart des cours (je dirais même tous) commence par l'implémentation d'un front-end, lors de l'implémentation d'un nouveau langage informatique, ce n'est pas dans cette direction qu'il faut partir. Ce qui fait un langage informatique, ce n'est pas la syntaxe et le lexique, c'est la sémantique.
Pour reprendre un exemple simple, ce qui fait que vous comprenez le mot patate, ce n'est pas la juxtaposition de ses lettres, non plus la liaison entre celle-ci mais la définition du mot patate. C'est cette définition qui est importante, qui délivre l'idée. Tu peux apprendre à un gamin de 2 ans que pour décrire une carotte, il faut dire patate et quand il demandera des carottes, il demandera des patates (en tout cas, le concept lié à ce que nous considérons comme des patates) — ça ne reste qu'un mot, et c'est bien pour cette raison qu'il est différent de la langue française et anglaise quand bien même le concept reste le même.
Ce que je veux dire, c'est qu'importe qu'on est le mot-clé define
ou =
, l'idée derrière reste la même, à savoir l'assignation d'une valeur à une variable.
Ce qui m’amène au centre de l'explication. C'est que ce n'est pas la syntaxe qui dirige ton langage mais la sémantique. Définir d'abord les concepts de ton langage (comme le paradigme impératif) va vous permettre de vous diriger vers une syntaxe spontané (une syntaxe pensé pour vos concepts). Et plus haut, j'ai dit avoir fait la même erreur — et c'est se que vous faites en vérité. Comme vous, j'ai voulu créer mon langage mais dans l'exercice que l'on m'avait proposé, on m'avait imposé une syntaxe proche du lisp — comme vous. Ensuite, au fur et à mesure, je me suis mis à implémenter le concept de programmation fonctionnel. Non pas parce que j'aime la programmation fonctionnelle (je ne la connaissais pas avant) mais parce que la syntaxe du lisp dérive d'une sémantique de langage fonctionnel. Ce n'est pas moi qui est choisi d'en faire un langage fonctionnel, c'est la syntaxe.
Ce que je veux dire au final, c'est que partir sur la syntaxe directement va obligatoirement vous fermer des portes sur des concepts. par exemple, partir sur une syntaxe comme le C exclut la programmation fonctionnelle — ou tout du moins, essayer d'intégrer un tel concept ne donnerais pas une syntaxe spontané — et c'est le cas par exemple avec Python et ses closures. Et de cette expérience, je juge un langage d'abord par les concepts qu'il implémente et ensuite par sa syntaxe (car elle est tout de même importante) et c'est pour cette raison que je n'ai pas regardé la syntaxe de votre langage.
Conclusion
Si vous deviez donc faire un nouveau langage, vous devriez partir sur les concepts qu'il propose avant — et pour le coup, vous commencer à avoir une idée claire. Ensuite, vous éluderez une syntaxe de manière spontané (qui serait proche d'un langage ou non comme le C). C'est pourtant un travail difficile et c'est pour cette raison que les langages syntaxiquement sont proches - on a toujours besoin d'un pied à terre. Mais puisque que syntaxiquement ils sont proches, ils sont aussi sémantiquement proches.
Enfin, j'aimerais que vous portiez votre attention sur un débat sur ce que peut être un langage informatique français (autre lien). Cela présente surtout une extension du débat syntaxe/sémantique visant particulièrement l'idée que l'on peut avoir de la simplicité (toute subjective) d'un langage — et ma conclusion est qu'un langage informatique français n'est pas forcément synonyme d'un langage informatique simple, cette simplicité doit se retrouver dans la sémantique.
EDIT: il doit y avoir des fautes, mais là, je suis très fatigué