Actualmente estoy implementando un evaluador de expresiones (expresiones de línea única, como fórmulas) basado en lo siguiente:
- la expresión ingresada se tokeniza para separar booleanos literales, enteros, decimales, cadenas, funciones, identificadores (variables)
- Implementé el algoritmo Shunting-yard (ligeramente modificado para manejar funciones con un número variable de argumentos) para deshacer el paréntesis y ordenar a los operadores con una precedencia decente en un orden pospuesto
- mi patio de maniobras simplemente produce una cola (simulada) de tokens (por medio de una matriz, mi lenguaje Powerbuilder Classic puede definir objetos, pero solo tiene matrices dinámicas como almacenamiento nativo, no una lista verdadera, ningún diccionario) que evalúo secuencialmente con un máquina de pila simple
Mi evaluador está funcionando bien, pero todavía me falta un if()
y me pregunto cómo proceder.
Con mi evaluación de desviación fijada y basada en la pila, si agrego if()
como otra función con partes verdaderas y falsas, un solo if(true, msgbox("ok"), msgbox("not ok"))
mostrará ambos mensajes, mientras que me gustaría mostrar solo uno. Esto se debe a que cuando necesito evaluar una función, todos sus argumentos ya han sido evaluados y colocados en la pila.
¿Podría darme alguna forma de implementar if()
de manera perezosa?
Pensé en procesarlos como una especie de macro, pero al principio aún no tengo la evaluación de la condición. ¿Quizás necesito usar otro tipo de estructura que no sea una cola para mantener por separado la condición y las expresiones verdadero / falso? Por ahora, la expresión se analiza antes de la evaluación, pero también planeo almacenar la representación intermedia como una especie de expresión precompilada para una evaluación futura.
Editar : después de un poco sobre el problema, creo que podría construir una representación en árbol de mi expresión (un AST en lugar de una secuencia de token lineal), desde la cual podría ignorar fácilmente una u otra rama de mi if()
.