Forth http://fforum.winglion.ru/ |
|
расширенные операторами стековые манипуляторы http://fforum.winglion.ru/viewtopic.php?f=2&t=2740 |
Страница 26 из 27 |
Автор: | vikt [ Вс дек 30, 2012 19:14 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Манипуляторы нужны. Только надо определиться с окончательной версией. Или, например, (базовая реализация , документация и проч.) + расширения, которые можно обсуждать, предлагать варианты. А так, глаза разбегаются, трудно решиться реализовывать. |
Автор: | WingLion [ Вс дек 30, 2012 20:06 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
vikt писал(а): Манипуляторы нужны. от терминатора |
Автор: | Alex [ Пн дек 31, 2012 17:17 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Добрый вечер !!! всех с новым годом!!! предлагаю Вашему вниманию версию со встроенным компилятором в манипулятор другие либы не нужны, работает на голом SPF Код: USER-CREATE /d/ 10 CELLS USER-ALLOT USER /cur USER /lim : !, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : @, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : ?? ( a u -- f ) SWAP OVER /cur @ OVER COMPARE 0= IF 1- /cur +! 0 THEN ; : sm, ( -- ) 0 CASE S" 1\" ?? OF 1 !, ENDOF S" 2\" ?? OF 2 !, 1 !, ENDOF S" 3\" ?? OF 3 !, 2 !, 1 !, ENDOF S" 4\" ?? OF 4 !, 3 !, 2 !, 1 !, ENDOF S" 5\" ?? OF 5 !, 4 !, 3 !, 2 !, 1 !, ENDOF S" 6\" ?? OF 6 !, 5 !, 4 !, 3 !, 2 !, 1 !, ENDOF S" 7\" ?? OF 7 !, 6 !, 5 !, 4 !, 3 !, 2 !, 1 !, ENDOF S" 8\" ?? OF 8 !, 7 !, 6 !, 5 !, 4 !, 3 !, 2 !, 1 !, ENDOF S" 9\" ?? OF 9 !, 8 !, 7 !, 6 !, 5 !, 4 !, 3 !, 2 !, 1 !, ENDOF S" 1" ?? OF 1 @, ENDOF S" 2" ?? OF 2 @, ENDOF S" 3" ?? OF 3 @, ENDOF S" 4" ?? OF 4 @, ENDOF S" 5" ?? OF 5 @, ENDOF S" 6" ?? OF 6 @, ENDOF S" 7" ?? OF 7 @, ENDOF S" 8" ?? OF 8 @, ENDOF S" 9" ?? OF 9 @, ENDOF ENDCASE ; : sm.comp ( a u -- ) OVER /cur ! + 1- /lim ! BEGIN sm, /cur @ /lim @ < WHILE /cur 1+! REPEAT ; \ ========================================================================= CREATE buf 640 ALLOT USER wrd USER sym : sym+ ( char -- ) buf C@ 1+ DUP buf C! buf + C! ; : wrd! ( a u -- ) wrd @ 1+ wrd ! buf wrd @ 64 * + 2DUP C! 1+ SWAP CMOVE ; : <..> ( a u -- ) S" .." COMPARE 0= IF wrd @ 1+ 1 ?DO I 48 + sym+ LOOP THEN ; : fnd! ( a u -- ) wrd @ 1+ 1 ?DO 2DUP I 64 * buf + DUP C@ 1 0 D+ COMPARE 0= IF I 48 + sym+ LEAVE THEN LOOP <..> ; : <NextWord> ( -- a u ) BEGIN NextWord DUP 0= WHILE DROP 2DROP REFILL REPEAT ; : { ( === преобразавать текст внутри { ..... } в стековый манипулятор === ) buf 640 BL FILL 0 wrd ! 2 buf C! [CHAR] \ buf 2+ C! BEGIN <NextWord> 2DUP S" -" COMPARE WHILE wrd! REPEAT 2DROP wrd @ 48 + buf 1+ C! BEGIN <NextWord> 2DUP S" }" COMPARE WHILE fnd! REPEAT 2DROP buf COUNT sm.comp ; IMMEDIATE : 2dup { a b - .. .. } ; : test1 1 2 2dup ; \ результат test1 ( 1 2 1 2 ) : 3noop { a b c - .. } ; : test2 1 2 3 3noop ; \ результат test2 ( 1 2 3 ) : test3 1 2 3 { x count element - x } DEPTH .SN CR CR ; \ результат test3 ( 1 ) если добавить еще пару строк, то можно использовать манипуляторы напрямую в словах Код: : sm.test ( a u -- a u f ) 2DUP 1 > SWAP DUP C@ [CHAR] 1 [CHAR] 9 1+ WITHIN SWAP 1+ C@ [CHAR] \ = AND AND ;
: NOTFOUND ( A U -- ) sm.test IF sm.comp ELSE NOTFOUND THEN ; : test4 1 2 3 3\321 ; : test5 3\ ; : test6 1 2 3 4 5 6 { n1 n2 n3 n4 n5 n6 - n5 n2 n1 n4 n1 n2 } 1\ ; |
Автор: | vikt [ Пн дек 31, 2012 18:30 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
С новым годом!!! |
Автор: | Alex [ Ср янв 02, 2013 10:42 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
последняя реализация конструкции true-grue распалась на две независимые части. собственно компиляция без промежуточного представления в манипуляторах: Код: USER-CREATE /d/ 10 CELLS USER-ALLOT USER-CREATE buf 640 USER-ALLOT USER wrd : !, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : @, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : <..> ( a u -- ) S" .." COMPARE 0= IF wrd @ 1+ 1 ?DO I @, LOOP THEN ; : wrd! ( a u -- ) wrd @ 1+ wrd ! buf wrd @ 64 * + 2DUP C! 1+ SWAP CMOVE ; : fnd! ( a u -- ) wrd @ 1+ 1 ?DO 2DUP I 64 * buf + COUNT COMPARE 0= IF I @, LEAVE THEN LOOP <..> ; : <NextWord> ( -- a u ) BEGIN NextWord DUP 0= WHILE DROP 2DROP REFILL REPEAT ; : { buf 640 BL FILL 0 wrd ! BEGIN <NextWord> 2DUP S" -" COMPARE WHILE wrd! REPEAT 2DROP 1 wrd @ DO I !, -1 +LOOP BEGIN <NextWord> 2DUP S" }" COMPARE WHILE fnd! REPEAT 2DROP ; IMMEDIATE Цитата: : 2dup { a b - .. .. } ; : test1 1 2 2dup ; \ результат test1 ( 1 2 1 2 ) : 3noop { a b c - .. } ; : test2 1 2 3 3noop ; \ результат test2 ( 1 2 3 ) : test3 1 2 3 { x count element - x } DEPTH .SN CR CR ; \ результат test3 ( 1 ) : test6 1 2 3 4 5 6 { n1 n2 n3 n4 n5 n6 - n5 n2 n1 n4 } ; \ результат test6 ( 5 2 1 4 ) простейшая реализация манипуляторов: Код: USER-CREATE /d/ 10 CELLS USER-ALLOT USER /cur USER /lim
: !, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : @, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : sm.comp ( a u -- ) OVER C@ 48 - 1 SWAP DO I !, -1 +LOOP OVER 2+ /cur ! + 1- /lim ! BEGIN /cur @ DUP C@ 48 - @, /lim @ < WHILE /cur 1+! REPEAT ; : sm.test ( a u -- a u f ) 2DUP 1 > SWAP DUP C@ [CHAR] 1 [CHAR] 9 1+ WITHIN SWAP 1+ C@ [CHAR] \ = AND AND ; : NOTFOUND ( A U -- ) sm.test IF sm.comp ELSE NOTFOUND THEN ; : test1 1 2 3 3\321 ; |
Автор: | Alex [ Чт янв 03, 2013 11:49 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Сделал еще одну версию с возможностью доопределения. то есть в рамках одного или нескольких смежных определений можно использовать несколько конструкций { - } Интересует Ваше мнение (особенно true-grue) о нужности Вот к примеру этот код компилируется и выдает правильный результат: Код: CREATE arr 9 , 1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 , : /arr/ ( arr -- adr2 adr1 ) DUP CELL+ SWAP @ CELLS OVER + SWAP ; : each: R> { xt - } /arr/ DO I @ {.. - xt } EXECUTE CELL +LOOP ; : sum> {.. sum lev arr - sum arr } each: {.. elem - elem elem lev } > IF + ELSE DROP THEN ; 0 4 arr sum> . ( 14 ) количество слов внутри конструкции увеличено до 31, каждое имя до 31 символа. добавлен контроль синтаксиса: Код: USER-CREATE /d/ 32 CELLS USER-ALLOT USER-CREATE buf 32 32 * USER-ALLOT
: !, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : @, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : <..> ( a u -- ) S" .." COMPARE 0= buf @ buf CELL+ @ <> AND IF buf @ 1+ buf CELL+ @ 1+ 1 MAX ?DO I @, LOOP THEN ; : wrd! ( a u -- ) buf @ 1+ buf ! buf buf @ 32 * + 2DUP C! 1+ SWAP CMOVE ; : fnd! ( a u -- ) buf @ 1+ 1 ?DO 2DUP I 32 * buf + COUNT COMPARE 0= IF I @, 2DROP UNLOOP EXIT THEN LOOP <..> ; : <NextWord> ( -- a u ) BEGIN NextWord DUP 0= WHILE DROP 2DROP REFILL REPEAT ; : check1 ( a u -- a u ) S" } .. ; { " 2OVER SEARCH NIP NIP IF ABORT" not correct syntax { - }" THEN ; : check2 ( a u -- a u ) S" ; { " 2OVER SEARCH NIP NIP IF ABORT" not correct syntax { - }" THEN ; : { buf 32 32 * ERASE /d/ 32 CELLS ERASE BEGIN <NextWord> 2DUP S" -" COMPARE WHILE check1 wrd! REPEAT 2DROP buf @ 0 > IF buf CELL+ @ 1 MAX buf @ DO I !, -1 +LOOP THEN BEGIN <NextWord> 2DUP S" }" COMPARE WHILE check2 fnd! REPEAT 2DROP ; IMMEDIATE : {.. buf @ 0 > IF buf @ buf CELL+ ! THEN BEGIN <NextWord> 2DUP S" -" COMPARE WHILE check1 wrd! REPEAT 2DROP buf CELL+ @ buf @ < IF buf CELL+ @ 1+ buf @ DO I !, -1 +LOOP THEN BEGIN <NextWord> 2DUP S" }" COMPARE WHILE check2 fnd! REPEAT 2DROP ; IMMEDIATE |
Автор: | вопрос [ Пт янв 04, 2013 22:12 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Опять доопределения внутри определений. Позволю себе пошутить, надеюсь необидно Ловушка неограниченной гибкости форта подстерегает даже тех, кто пользуется ею для создания новых ловушек неограниченной гибкости |
Автор: | ArtemKAD [ Сб янв 05, 2013 00:30 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Alex писал(а): Сделал еще одну версию с возможностью доопределения. то есть в рамках одного или нескольких смежных определений можно использовать несколько конструкций { - } Интересует Ваше мнение (особенно true-grue) о нужности Вот к примеру этот код компилируется и выдает правильный результат: Код: CREATE arr 9 , 1 , -1 , -3 , 4 , 0 , 5 , -6 , -7 , 9 , : /arr/ ( arr -- adr2 adr1 ) DUP CELL+ SWAP @ CELLS OVER + SWAP ; : each: R> { xt - } /arr/ DO I @ {.. - xt } EXECUTE CELL +LOOP ; : sum> {.. sum lev arr - sum arr } each: {.. elem - elem elem lev } > IF + ELSE DROP THEN ; 0 4 arr sum> . ( 14 ) А грабли с одним общим буфером не появятся? К примеру если конструкция { } будет использоваться в слове /arr/ которое располагается между двумя { } { } ... |
Автор: | Alex [ Сб янв 05, 2013 14:00 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Эх наверно неудачный пример привел, замесил несколько идей в кучу. давайте поговорим о конструкции { - } я ее не зря так написал, Она состоит из двух частей: { ... - это часть определительная (записывающая) здесь вершина и элементы стека ассоциируются (соотносятся) с некими наборами символов - словами (не путаем! это не слова форт системы, их нет в словаре) здесь главное дать элементу на стеке метку, желательно осмысленную чтобы служить не только для идентификации но и для понимания смысла обьектов (самодокументирование) и так мы удаляем элементы со стека в массив (хранилище) и даем им метки. далее начинает работать вторая часть конструкции: - ... } ее задача очень проста - взять слово, найти его среди меток и положить на стек соответствующее значение (извлекающаяся часть). Слова-метки имеют смысл только внутри конструкции (ограничены фигурными скобками). Все это очень здорово напоминает стековые манипуляторы (там метки есть символы 0..9) И мне как человеку написавшему собственный вариант стековых манипуляторов естественным показался путь компиляции обсуждаемой конструкции в манипулятор. Но реализация может быть и иной, например непосредственная генерация примитивов форта для необходимого стекового эффекта. ссылку уже давали. И так здесь для временного хранения используются глобальные массивы /d/ и buf, они очищаются словом { и нет никаких проблем, если мы в одном или нескольких определениях используем конструкцию { - }. Но мы можем использовать глобальность массивов /d/ и buf и в полезных и порой необходимых нам задачах. например Код: : sum> ( sum lev arr - sum ) SWAP { level - } each: DUP {.. - level } > IF + ELSE DROP THEN ; здесь метка level ведет себя как VALUE, но мы не создавали словарной статьи.вот здесь { level - } мы сохранили значение в массиве /d/ и связали с меткой в массиве buf, а вот здесь {.. - level } мы не инициализировали наши глобальные массивы, а добрались до значения по метке. В этом примере видно, что мы используя глобальность избежали необходимость обертки кода между итератором each: и ; это пример использования записывающей части конструкции в одном определении и использование читающей части в другом определении. Но можно ведь и дописать в другой конструкции дополнительные метки и это тоже может быть полезно. Ну а антиглобалисты вообще могут не использовать слово {.. как будто его не существует Цитата: А грабли с одним общим буфером не появятся? К примеру если конструкция { } будет использоваться в слове /arr/ которое располагается между двумя { } { } ... нет каждая конструкция { - } автономна и независима, побочный эффект дает и использует вариант {.. - } , по любому нужно понимать, что делаешь Всех с наступающим рождеством! |
Автор: | diver [ Сб янв 05, 2013 15:03 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
вариант с "{ }" не вызовет ли конфликтов с локальными переменными? в spf в одной из библиотек именно такой синтаксис ? |
Автор: | ArtemKAD [ Сб янв 05, 2013 15:49 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Alex писал(а): побочный эффект дает и использует вариант {.. - } , по любому нужно понимать, что делаешь Вот и я о нем говорил. Если между } и {.. будет хоть одно слово использующее буфер \d\ результат будет весьма и весьма непредсказуемым. Причем хорошо если это слово определено в том-же файле. А если нет.... Такие грабли очень опасны. И их опасность ростет с ростом популярности. |
Автор: | Alex [ Сб янв 05, 2013 17:05 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Да есть конфликт с locals.f можно конечно для новой конструкции придумать новые имена. например {: и ;} Я делал прикидку для 5-6 параметров на стеке - код от forthwiz получался длиной 18-20 команд ассемблера, а в этой реализации порядка 60-80 команд. Данную реализацию еще можно пофакторизировать, свести два глобальных массива в один. Но пределы уже не далеко, Небольшая библиотека в 6-8 определений вполне пойдет как модель, посмотреть как конструкция влияет на код и мозг. |
Автор: | ArtemKAD [ Сб янв 05, 2013 19:39 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Alex писал(а): простейшая реализация манипуляторов: Код: USER-CREATE /d/ 10 CELLS USER-ALLOT USER /cur USER /lim : !, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : @, ( n -- ) 1- CELLS LIT, ['] /d/ COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : sm.comp ( a u -- ) OVER C@ 48 - 1 SWAP DO I !, -1 +LOOP OVER 2+ /cur ! + 1- /lim ! BEGIN /cur @ DUP C@ 48 - @, /lim @ < WHILE /cur 1+! REPEAT ; : sm.test ( a u -- a u f ) 2DUP 1 > SWAP DUP C@ [CHAR] 1 [CHAR] 9 1+ WITHIN SWAP 1+ C@ [CHAR] \ = AND AND ; : NOTFOUND ( A U -- ) sm.test IF sm.comp ELSE NOTFOUND THEN ; : test1 1 2 3 3\321 ; Слегка эту реализацию причесал и привел к почти готовому для SPF виду. Единственное - все-же надо изменить разделитель на что-то более узнаваемое. Пока испытывал несколько раз путался между \ и / . Да и проверку стоит усилить - проверять на допустимость чисел во второй половине манипулятора. Код: MODULE: vocSM USER-CREATE bufer 10 CELLS USER-ALLOT : char->num [CHAR] 0 - ; : n+!, ( n -- ) 1- CELLS LIT, ['] bufer COMPILE, ['] + COMPILE, ['] ! COMPILE, ; : n+@, ( n -- ) 1- CELLS LIT, ['] bufer COMPILE, ['] + COMPILE, ['] @ COMPILE, ; : sm.comp ( a u -- ) OVER C@ char->num 1 SWAP \ от n до 1 DO I n+!, -1 +LOOP \ компилится код который n ячеек стека кладет в буфер OVER + SWAP 2+ \ остаток строки после разделителя ?DO I C@ char->num n+@, LOOP \ компилится код который из буфера ячейки снова раскладывает в стек ; : n+! ( n -- ) 1- CELLS bufer + ! ; : n+@ ( n -- bn ) 1- CELLS bufer + @ ; : sm.run ( a u -- ) 2DUP 2>R \ что-бы не болтался адрес на стеке мешая снимать значения. \ использую предположение, что у интерпретатора при выполнении \ NOTFOUND ничего лишнего на стеке не болтается DROP C@ char->num 1 SWAP \ от n до 1 DO I n+! -1 +LOOP \ n ячеек стека кладет в буфер 2R> OVER + SWAP 2+ \ остаток строки после разделителя ?DO I C@ char->num n+@ LOOP \ из буфера ячейки снова раскладывает в стек ; : test_digit ( c -- f ) \ проверка на допустимость символов цифр (от 1 до 9) [CHAR] 1 [CHAR] 9 1+ WITHIN ; : sm.test ( a u -- a u f ) 2DUP 1 > \ два и больше символов в строке SWAP DUP C@ test_digit \ первая цифра от 1 до 9 SWAP 1+ C@ [CHAR] \ = \ второй символ \ AND AND ; \ ===================================================================== EXPORT WARNING @ WARNING 0! : NOTFOUND ( A U -- ) sm.test IF STATE @ IF sm.comp ELSE sm.run THEN ELSE NOTFOUND THEN ; WARNING ! ;MODULE Ну и добавить Код: : 1\11 DUP ; : 1\ DROP ; : 2\21 SWAP ; : 2\121 OVER ; : 2\2 NIP ; не помешает (хотя оптимизатор в SPF рулит ). |
Автор: | Alex [ Вс янв 06, 2013 11:01 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Молодца! правильно заметили, что в sm.comp основной цикл парсинга лучше сделать через ?DO Цитата: Единственное - все-же надо изменить разделитель на что-то более узнаваемое. Пока испытывал несколько раз путался между \ и / не, нормальный разделитель, быстро к нему привыкаешь, тем более что в расширенныхстековыми операциями манипуляторах еще есть разделитель / и | 1..9| - означает что загружаются ячейки и не трогается состояние стека 1..9/ - использовать буфер номер 1..9 из-за того что есть два варианта загрузки со снятием со стека (1..9\ ) и без ( 1..9| ) используются два ассемблерных слова SPDROP ( p*n n --) и SPMOVE ( p*n addr n --) SPMOVE копирует данные со стека в массив, SPDOP - сдвигает указатель стека. ну и чтобы эти слова были проще и быстрее, ячейки в массиве (bufer) идут в обратном порядке. то есть сейчас в простейшей реализации bufer[ячейка0][ячейка1][ячейка2]..[ячейка9] а в продвинутых версиях bufer[ячейка9][ячейка8][ячейка7]..[ячейка0] |
Автор: | ArtemKAD [ Вс янв 06, 2013 13:37 ] |
Заголовок сообщения: | Re: расширенные операторами стековые манипуляторы |
Alex писал(а): , тем более что в расширенных стековыми операциями манипуляторах Каждый раз когда я смотрю в сторону расширенных стековых манипуляторов вспоминаю Броуди: Вложение: Сложность или простота.JPG [ 18.71 Кб | Просмотров: 22571 ] |
Страница 26 из 27 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |