Третий подход к for

Надо признаться, что пока не могу найти за какой конец нитки тянуть, чтобы распутать весь этот клубок … В попытке выдерживать единую концептуальную схему, кажется, что её автор сконструировал очень сложную систему, слишком “ажурную архитектуру”, на которую вдобавок навешан непродуманный интерфейс, нагружающий менталитет, к которому сам он, безусловно давно привык, а чтобы привыкать к нему другим, надо иметь какую-то специфическую мотивацию. Уверен, что такой формат конвенциальным никогда не станет и уже даже хочется все это бросить и заняться, на самом деле, более оптимальными подходами к программированию. Да, оригинально, в определенном смысле эффективно, да … все работает … но такова суть любой автоматизации, любых реализованных архитектур и интерфейсов и все они расширяющиеся. Фишка, как раз в минимальном базисе … который никак не прощупывется в PicoLosp, кроме, конечно, ячейки-пары и то, как общий принцип, но который, может не так явно акцентированный, имеет место быть в любой другой системе. Но тем не менее … попробую, по крайней мере, пройтись по функциям из LLVM. Кстати, с ассемблером тоже странно. Казалось бы, что сначала должны быть тупо реализованы обертки существующих функций хоста, что-то типа транспилера, а уже на нем спроектирована база для интерпретатора. Но в PicoLisp это реализовано как-то по-своему и в купе с нативными функцями С, все выглядит очень запутанно. Рекурсия рекурсией, но похоже, что когда смешиваешь “нижний” уровень с “верхним”, то точно можно избавиться от лишних концепций, вместо того, чтобы наоборот их плодить. Конечно, я многому научился за полгода активного исследования системы и надеюсь, что что-то ещё пойму в следующие полгода на её примерах, лучший из которых сама её реализация …
А пока, перед тотальным сканированием функций из файла “map”, пройдемся по циклам и условным переходам, что составляет, собственно, суть любых вычислений. А поскольку тот же for из этой категории, то не смотря на то, что функция акцентировалась уж два раза, при сканировании общей лексики и в связи с особым её выделением автора, теперь, в связи с её определением!
(NIL "for" _For)
src/glob.l
# (for sym 'cnt ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
# (for sym|(sym2 . sym) 'lst ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
# (for (sym|(sym2 . sym) 'any1 'any2 [. prg]) ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
(de _For (Exe)
(let
(X (cdr Exe)
Y (++ X)
R $Nil )
(cond
((atom Y) # (for sym 'cnt|lst ..)
(needChkVar Exe Y)
(let P (set $Bind (push NIL NIL (val $Bind))) # [[sym] sym LINK]
(set P (val Y) 2 P Y)
(let V (eval (++ X))
(if (num? V) # (for sym 'cnt ..)
(unless (sign? V)
(set Y ZERO)
(loop
(? (> (+ (val Y) (hex "10")) V) # Increment
(setq R (& R -2)) )
(set Y @)
(? (=0 (& (setq R (loop1 X)) 1))) ) )
(save V
(loop # (for sym 'lst ..)
(? (atom V) (setq R (& R -2)))
(set Y (car V))
(? (=0 (& (setq R (loop1 X)) 1)))
(safe (shift V)) ) ) ) )
(set Y (val P) $Bind (val 3 P)) ) )
((atom (cdr Y)) # (for (sym2 . sym) 'lst ..)
(let Sym2 (needChkVar Exe @)
(needChkVar Exe (setq Y (car Y)))
(let P (set $Bind (push NIL NIL (val $Bind))) # [[sym] sym LINK]
(set P (val Y) 2 P Y)
(let
(Q (set $Bind (push (val Sym2) Sym2 (val $Bind))) # [[sym] sym LINK]
V (save (eval (++ X))) )
(set Y ONE)
(loop
(? (atom V) (setq R (& R -2)))
(set Sym2 (car V))
(? (=0 (& (setq R (loop1 X)) 1)))
(set Y (+ (val Y) (hex "10")))
(safe (shift V)) )
(set Sym2 (val Q)) )
(set Y (val P) $Bind (val 3 P)) ) ) )
((atom (car Y)) # (for (sym ..) ..)
(let Z (cdr Y)
(needChkVar Exe (setq Y @))
(let P (set $Bind (push NIL NIL (val $Bind))) # [[sym] sym LINK]
(set
P (val Y)
2 P Y
Y (eval (++ Z)) )
(save R
(loop # (any2 . prg)
(? (nil? (eval (car Z))))
(set $At @)
(? (=0 (& (setq R (loop1 X)) 1)))
(safe (setq R (& R -2)))
(when (pair (cdr Z))
(set Y (run @)) ) ) )
(set Y (val P) $Bind (val 3 P)) ) ) )
(T # (for ((sym2 . sym) ..) ..)
(let (Sym2 (cdr @) Z (cdr Y))
(setq Y (car @))
(needChkVar Exe Y)
(needChkVar Exe Sym2)
(let P (set $Bind (push NIL NIL (val $Bind))) # [[sym] sym LINK]
(set P (val Y) 2 P Y)
(save R
(let Q (set $Bind (push (val Sym2) Sym2 (val $Bind))) # [[sym] sym LINK]
(set
Sym2 (save (eval (++ Z)))
Y ONE )
(loop
(? (nil? (eval (car Z))))
(set $At @)
(? (=0 (& (setq R (loop1 X)) 1)))
(safe (setq R (& R -2)))
(when (pair (cdr Z))
(set Sym2 (run @)) )
(set Y (+ (val Y) (hex "10"))) )
(set Sym2 (val Q)) ) )
(set Y (val P) $Bind (val 3 P)) ) ) ) )
R ) )
https://picolisp-manual.tiddlyhost.com/#for
Не правда ли нетривиально? Тот случай, чтобы попросить ИИ-бот прокомментировать каждую строку (содержимое в скобках?!), любой бот справляется с этой задачей “на ура” … каждый может привлечь для этого того бота, к которому привык … я для себя, все-таки, даже вытащу все зависимости … И похоже пока не будут разобраны “по косточкам” подобные вещи, не придет понимание авторских замыслов … Попробуйте просто взять обычный материнский язык и на нем построить скобочную конструкцию какого-нибуть содержания толстой книги (не более четырех-пяти уровней вложенности) и потом осознайте как это воспринимается в сознании … То-то и оно! Вот почему трудно ожидать конвенций в этом направлении. Код должен легко читаться не только машинами и гениями, но и людьми, далекими от всяких algol-ов и posix-ов. А что делать, если Вы хотите развивать эко-систему дальше, привлекая других людей. Что станет с системой через поколение? Тут никакие схемы и “инженерный чертежи“ не помогут, кроме самого кода … или данных … неважно! Дальше и глубже этого уже просто некуда. Системы должны быть самописанными, самоописываться … все должно быть определено и определено через конвенциональный интерфейс.
Subscribe to my newsletter
Read articles from Sergey Shishkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sergey Shishkin
Sergey Shishkin
Всегда чему-то учусь!