Рекурсивный eval
Всегда чему-то учусь!
Увидев в списке “примитивов” (см. предыдущий пост) … , конечно, захотелось посмотреть на зависимости eval, мимо которого пройти просто невозможно. Во-первых, код определения.
(NIL "eval" _Eval)
src/glob.l
# (eval 'any ['cnt]) -> any
(de _Eval (Exe)
(let (X (cdr Exe) E (save (eval (car X))))
(when (pair (cdr X))
(let N (needCnt Exe (eval (car @)))
(when (setq N (int N))
(let Bnd (val $Bind)
(loop
(? (=0 Bnd))
(?
(and
(== $At (val 2 Bnd))
(prog
(set $At (val Bnd))
(=0 (dec 'N)) ) ) )
(setq Bnd (val 3 Bnd)) ) ) ) ) )
(eval E) ) )
map:
llvm~_Eval (81 "@src/flow.l" llvm pico)
llvm~eval (443 "@src/dec.l" llvm pico)
llvm~stdEval (2818 "@src/io.l" llvm pico)
pico~eval (81 "@src/flow.l" llvm pico)
Более того … с примером (!?) из src/dec.l
### Primitives ###
(local) (caar cadr cdar cddr int cnt sign sym name memq member length boxNum box64 eval run)
...
(inline eval (X)
(use @
(cond
((num? X) X)
((sym? X) (val X))
(T (evList X)) ) ) )
...
Скорее, всего, по этому списку надо точно пройтись.
А вот список зависимостей - needCnt loop let cdr car save set setq de dec prog pair when val and int ? \=0 \== и получается, что это тоже кандидаты на статус “базовых функций“ … хотя может получится так, что, все функции типа оболочек из с-библиотек, а тем более из таблицы символов LLVM - база. Надо будет привести полный список функций (символов) из base.ll Как правило, в описаниях Forth-ов, сразу выделяют таблицу функций над функциями ассемблера, типа форт-ассемблера, так по крайней мере у Мура. И, видимо, надо что-то делать с тегом “без зависимостей“ … как-то идея не срабатывает. Но окончательное решение будет принято только, после исследования кода функций типа условных переходов.
https://picolisp-manual.tiddlyhost.com/#eval
Но самое главное, что видно из кода - это зависимость функции от самой функции, то есть рекурсия, конечно, за которой под капотом прячется цикл, но становится понятным, что имели ввиду классики, когда формулировали модель вычислений как рекурсивных функции.