From: Ruvim P. <ruv...@gm...> - 2018-12-09 12:02:54
|
On Sun, 9 Dec 2018 at 12:25, ivanov <iv...@ic...> wrote: > Первая трудность с которой столкнулся, обработка пути к подключаемым > файлам. В spf путь начинающийся с "~" отправляет в devel, в gforth, это > естественно не так. Вставил исправляющую "прокладку" между gforth и моей > программой. > Переоределить слова INCLUDE* > Вторая, поведение LITERAL. В gforth оно работает только если значение > появляется на стеке внутри определения: > variable aa > : bb [ aa ] LITERAL ; > а если так: > aa : bb LITERAL ; выдает ошибку "unstructured". > В spf оба случая работают одинаково. В стандарте нет уточнения на этот > счет, так что формально оба поведения "стандартны". > Второй вариант нестандартный. См. спецификацию слова ":" https://forth-standard.org/standard/core/Colon ( C: *"<spaces>name"* -- *colon-sys* ) Т.е. на управляющем стеке (control-flow stack) остается colon-sys произвольного размера. А управляющий стек может быть совмещен со стеком данных. В SPF просто размер colon-sys нулевой, поэтому работает второй вариант. Но, в случае :NONAME уже не работает, т.к. размер colon-sys там ненулевой. Тут несколько вариантов решения. 1) добавить свой отдельный стек управления и переопределить соответствующие слова типа : : ['] : EXECUTE-BALANCE <https://github.com/ruv/forth-design-exp/blob/master/lexeme-translator/lib/stack-effect.fth> N>Z ; : ; NZ> DROP POSTPONE ; [ NZ> DROP ] ; IMMEDIATE (и код оставить нестандартным) 2) использовать переменные или доп-стек, например aa >Z : bb [ Z> ] LITERAL ; 3) использовать свои определяющие слова (прозрачные по стеку данных) Например: `bb def{ lit{ aa } } Я делал подобное <https://github.com/ruv/forth-design-exp/blob/master/lexeme-translator/advanced.example.fth> для noname Третье. > У меня определено много слов так сказать "двойного назначения" или > "прыгающие". > Выглядят они примерно так: > : qq body1 up> body2 ; > При исполнении слова qq выполняется часть body1, а потом, в нужное время и > в нужном месте исполняется вторая часть body2. > С помощью этого нехитрого трюка мои слова могут "перепрыгивать" через свои > параметры. Body1 готовит для них почву, что бы они могли спокойно > появиться, а body2 их употребляет для своих нужд, доделывая работу. > > Слово up> как раз и занимается этим выкрутасом. > В spf это выглядит элегантно : up> R> aa ! ; Подпрограммный шитый > код рулит. > > В gforth - ругань нецензурными словами. > Логично, такое определение "up>" сильно зависит от реализации. > Сначала сделал так: > :NONAME body2 ; > : qq body1 LITERAL aa ! ; - столкнулся с привередливостью LITERAL... > > Ввел доп. переменную специально для передачи параметра, получилось: > :NONAME body2 ; xx ! > : qq body1 [ xx @ ] LITERAL aa ! ; > Это заработало, но потребовало переопределить всю кучу моих слов, явно > разорвать их на две части. > Выполнимо, но некрасиво. > > Сейчас использую вот такой хак: > :NONAME ; DUP @ CONSTANT nonam1 CELL+ @ CONSTANT nonam2 > : qq body1 up> [ noman1 , nonam2 , ] body2 ; > То есть вставляю перед body2 начальный кусок от :NONAME. > То, что это работает, объясняю тем, что видимо в gforth использован прямой > или косвенный шитый код и в этом куске есть что-то нужное адресному > интерпретатору. > Выглядит грязновато, но зато в моем коде ничего менять не нужно (довставку > делаю макросом, а его определяю в "прокладке"). > Для этого лучше использовать quotations (цитаты), которые нетрудно реализовать в любой форт-системе. В SPF они доступны в виде LAMBDA{ ... } <https://github.com/rufig/spf/blob/master/devel/~pinka/lib/lambda.f> . На встрече Forth200x <http://www.forth200x.org/> в 2017 был принят синтаксис [: ;] : qq body1 [: body2 ;] aa ! ; : up{ postpone [: ; immediate : }up postpone ;] postpone aa postpone ! ; immediate : qq body1 up{ body2 }up ; Если переопределить ";" (чтобы проверяло флаг и опционально делало ";] aa !" ) то можно и сделать в виде "up>" Так что, грабли я нашел задолго до многопоточности, с которой пободаюсь > чуть позже. > Сейчас разбираюсь как вызывать С-функции, как их декларировать и > оборачивать. > Это тоже по разному делается в SP-Forth и в Gforth. Последний умеет подключать сишный *.h файлы. См. C Interface <https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/C-Interface.html> > > Мысля переписать ядро spf для ARM меня посетила... посидела и ушла. > Прежде чем этим заняться, решил узнать, а правда ли я первый, кому это > потребовалось. > Видимо правда... > Андрей Черезов делал форт-систему под ARM, но это был встраиваемый вариант (без операционной системы) и вроде как несовместимый с SP-Forth/4 > Что-ж, если плотно сяду на arm, придется этим заняться... самоуверенности > (или наглости?) мне не занимать. > > Когда я об этом думал, то представлял использовать какой-то существующий ассемблер и линкер. Т.е. ассемблером сгенерить объектный файл с низкоуровневыми определениями, из форт-системы сгенерить объектный файл с определениями на форте (подпрограммый код), и слинковать их линкером. -- Ruvim |