J'implémente actuellement un évaluateur d'expressions (expressions sur une seule ligne, comme des formules) basé sur les éléments suivants:
- l'expression entrée est symbolisée pour séparer les booléens littéraux, les entiers, les décimales, les chaînes, les fonctions, les identificateurs (variables)
- J'ai implémenté l'algorithme Shunting-yard (légèrement modifié pour gérer les fonctions avec un nombre variable d'arguments) pour se débarrasser des parenthèses et ordonner les opérateurs avec une priorité décente dans un ordre postfixé
- mon shunting-yard produit simplement une file d'attente (simulée) de jetons (au moyen d'un tableau, mon langage Powerbuilder Classic peut définir des objets, mais n'a que des tableaux dynamiques comme stockage natif - pas une vraie liste, pas de dictionnaire) que j'évalue séquentiellement avec un machine à empiler simple
Mon évaluateur fonctionne bien, mais il me manque encore un if()
et je me demande comment procéder.
Avec mon évaluation shunt-yard postfixée et basée sur la pile, si j'ajoute if()
une autre fonction avec des parties vraies et fausses, un seul if(true, msgbox("ok"), msgbox("not ok"))
affichera les deux messages tandis que je voudrais en afficher un seul. En effet, lorsque j'ai besoin d'évaluer une fonction, tous ses arguments ont déjà été évalués et placés sur la pile.
Pourriez-vous me donner un moyen de mettre if()
en œuvre de manière paresseuse?
J'ai pensé à les traiter comme une sorte de macro, mais au début, je n'ai pas encore évalué l'état. Peut-être que j'ai besoin d'utiliser un autre type de structure qu'une file d'attente pour conserver séparément la condition et les expressions vrai / faux? Pour l'instant, l'expression est analysée avant l'évaluation, mais je prévois également de stocker la représentation intermédiaire comme une sorte d'expression précompilée pour une évaluation future.
Edit : après quelques réflexions sur le problème, je pense que je pourrais construire une représentation arborescente de mon expression (un AST au lieu d'un flux de jeton linéaire), à partir de laquelle je pourrais facilement ignorer l'une ou l'autre branche de ma if()
.