Interpreteur de langage personnalisable

Description

Bon, voilà un premier résultat d'un interpréteur de langage sans nom.

D'abord, commençons par le plus simple :
Le programme d'exemple montre un petit programme qui effectue quelques commandes du langage.
A l'exécution, il montre l'arbre syntaxique qui permet d'interpréter le programme, et un "écran" montrant la sortie de la fonction "println".
Un ZIP contient un deuxième exemple avec, comme sortie, une image, et les quelques fonctions (cercle, carré, couleur, cos, sin...) pour faire des bôôôôôs dessins...
Pour plus d'info sur le langage, il y a le fichier "syntaxe.txt" dans le ZIP.

Je vais ici vous parler plus en détail de l'interpréteur.
L'unité principale (UInterpreteur.pas) contient la classe TInterpreteur.
C'est le moteur.
Il commence par couper la chaine de caractère en éléments simples du langage via l'unité UToken.pas.
Puis, avec cette suite de token, on crée l'arbre syntaxique via l'unité UParser.pas.
Chaque nœud de cet arbre est un objet dérivé de la classe TNode (UNodes.pas)

La classe Tnode a au minimum deux fonctions :
- Create : crée le nœud et le lie aux sous-branches
- Eval : évalue les sous-branches pour pouvoir s'évaluer lui-même.
Il y a par exemple une classe dérivée pour les nœuds représentant les boucles FOR, ou encore les opérations, les appels de fonctions...

Le type dans le langage étant génériques (nombre, string, boolean..), il existe l'unité UValues.pas et la classe TValue qui représente les valeurs possibles et leurs conversions...

Ensuite, lors de l'interprétation, il y a besoin d'une pile et de tout un tas de trucs comme la sauvegarde des valeurs des variables... C'est l'environnement (UEnvironnement.pas) avec la classe TEnvironnement.

Cette environnement contient la pile (UStack.pas) utilisé lors de l'évaluation des nœuds, la liste des variables globales ou local (UVariables.pas), la liste des fonctions déclarés (UFunctions.pas), pour savoir où elles sont et les appeler, la variable particulière RESULT (de type TValue, qui correspond à l'instruction RETURN du langage), et une bête curieuse, que je vais appeler les fonctions externe (AddFunctionCall, IndexofFunctionCall, OnFunctionCall...)

En fait, dans le langage, il n'y a pas de fonction définit. En dehors de faire des boucles, calculer, assigner, il ne fait rien.
Le développeur doit, via "AddFunctionCall" et l'évènement "OnFunctionCall" ajouter au langage ses propres fonctions.
Dans l'exemple, j'ai définis 3 fonctions externes :
- println qui ajoute le texte en paramètre à l'écran de sortie
- la fonction len qui renvoie la longueur d'une chaine de caractère
- la fonction inc qui ajoute 1 au premier paramètre passé par référence.
Libre au développeur d'en ajouter d'autres.
Avec quelques conditions :
- déclarer la fonction dans l'environnement avec AddFunctionCall
- lier OnFunctionCall avec une fonction f du type TFunctionCallEvent
- ajouter dans la fonction f les choses à faire avec cette fonction.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.