Como implementar uma linguagem interpretada “sem pilha”?
Estou criando minha própria linguagem interpretada do tipo Lisp e quero otimizar a chamada de cauda. Quero liberar meu intérprete da pilha C para que eu possa gerenciar meus próprios saltos de função para função e minha própria mágica de pilha para obter o TCO. (Eu realmente não quero dizer empilhamento propriamente dito, apenas o fato de que as chamadas não adicionam quadros à pilha C. Eu gostaria de usar uma pilha própria que não cresça com chamadas finais). Como Stackless Python, e ao contrário de Ruby ou ... Python padrão, eu ach
Mas, como minha linguagem é um derivado do Lisp, todas as avaliações de expressões s são feitas de forma recursiva (porque é a maneira mais óbvia que pensei em fazer esse processo não-linear e altamente hierárquico). Eu tenho uma função eval, que chama uma função Lambda :: apply toda vez que encontra uma chamada de função. A função apply chama eval para executar o corpo da função e assim por diante. Recursão mútua em C sem cauda, com fome de pilha. A única parte iterativa que atualmente uso é avaliar um corpo de expressões s sequenciai
(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's supposed to
; return the value here to be used by print, and how does it know
; how to continue execution here??
Então, como evito usar a recursão C? Ou posso usar algum tipo de saltar que salte pelas funções c? longjmp, talvez? Eu realmente não sei. Por favor, tenha paciência comigo, eu sou principalmente auto- (Internet-) ensinado em programação.