Я создаю свой собственный Lisp -образный интерпретируемый язык, и я хочу сделать оптимизацию хвостового вызова. Я хочу освободить свой интерпретатор из стека C, чтобы я мог управлять своими собственными переходами от функции к функции и моей собственной магией стека для достижения TCO. (Я действительно не подразумеваю, что у меня нет стека, только тот факт, что вызовы не добавляют фреймы в стек C. Я бы хотел использовать собственный стек, который не растет с помощью хвостовых вызовов). Как и Stackless Python, и в отличие от Ruby или... стандартного Python, я думаю.
Но, поскольку мой язык является производной Lisp, вся оценка s-выражений выполняется в настоящее время рекурсивно (потому что это самый очевидный способ, которым я думал сделать этот нелинейный, высоко иерархический процесс). У меня есть функция eval, которая вызывает функцию Lambda:: apply каждый раз, когда она встречает вызов функции. Затем функция apply вызывает eval для выполнения тела функции и т.д. Взаимная сток-голодная нерегулярная рекурсия. Единственная итеративная часть, которую я сейчас использую, состоит в том, чтобы вычислить тело последовательных s-выражений.
(defun f (x y)
(a x y)) ; tail call! goto instead of call.
; (do not grow the stack, keep return addr)
(defun a (x y)
(+ x y))
; ...
(print (f 1 2)) ; how does the return work here? how does it know it supposed to
; return the value here to be used by print, and how does it know
; how to continue execution here??
Итак, как мне избежать использования рекурсии C? Или я могу использовать какой-то goto, который перескакивает через c-функции? longjmp, возможно? Я действительно не знаю. Пожалуйста, не стесняйтесь, я в основном сам (Интернет), преподаваемый в программировании.