Obecnie implementuję ewaluator wyrażeń (wyrażenia jednowierszowe, takie jak formuły) w oparciu o:
- wprowadzone wyrażenie jest tokenizowane w celu oddzielenia literalnych boolanów, liczb całkowitych, dziesiętnych, ciągów, funkcji, identyfikatorów (zmiennych)
- Zaimplementowałem algorytm Shunting-yard (lekko zmodyfikowany do obsługi funkcji o zmiennej liczbie argumentów), aby pozbyć się nawiasów i uporządkować operatorów z przyzwoitym pierwszeństwem w ustalonej kolejności
- moje pole manewrowe po prostu tworzy (symulowaną) kolejkę tokenów (za pomocą tablicy mój język Powerbuilder Classic może definiować obiekty, ale tylko macierze dynamiczne jako pamięć natywną - nie jest to prawdziwa lista, brak słownika), które oceniam sekwencyjnie za pomocą prosta maszyna do układania w stosy
Mój ewaluator działa dobrze, ale wciąż mi brakuje if()
i zastanawiam się, jak postępować.
Z moją postfuntowaną postfunkcją i oceną stosu, jeśli dodam if()
jako inną funkcję z częściami prawdziwą i fałszywą, jeden if(true, msgbox("ok"), msgbox("not ok"))
wyświetli obie wiadomości, podczas gdy chciałbym pokazać tylko jedną. Dzieje się tak, ponieważ gdy muszę ocenić funkcję, wszystkie jej argumenty zostały już ocenione i umieszczone na stosie.
Czy możesz dać mi sposób na wdrożenie if()
w leniwy sposób?
Myślałem o przetwarzaniu ich jako rodzaju makra, ale na początku nie miałem jeszcze oceny stanu. Być może muszę użyć innej struktury niż kolejka, aby oddzielnie zachować warunek i wyrażenia prawda / fałsz? Na razie wyrażenie jest analizowane przed oceną, ale planuję również przechowywać reprezentację pośrednią jako rodzaj wstępnie skompilowanego wyrażenia do przyszłej oceny.
Edycja : po kilku rozważaniach na temat problemu, myślę, że mógłbym zbudować drzewną reprezentację mojego wyrażenia (AST zamiast liniowego strumienia tokena), z którego mógłbym łatwo zignorować jedną lub drugą gałąź mojego if()
.