Forth
http://fforum.winglion.ru/

2VALUE
http://fforum.winglion.ru/viewtopic.php?f=18&t=2677
Страница 1 из 2

Автор:  F-MAP [ Вс окт 31, 2010 19:43 ]
Заголовок сообщения:  2VALUE

Нужна помощь! Понадобилось преписать код, обрабатывающий числа двойной длины, конкретно хотелось иметь аналог слова VALUE, как бы 2VALUE, работающее с числами двойной длины, посмотрел исходники, попытался сам написать, но видимо не силен в ассемблере:
Код:
CODE _2CONSTANT-CODE
     LEA  EBP, -4 [EBP]
     MOV  [EBP], EAX
     POP EAX

     MOV EDX, 4 [EAX]
     LEA EBP, -4 [EBP]
     MOV [EBP], EDX
     MOV EAX, [EAX]
    RET
END-CODE

CODE _2TOVALUE-CODE
     POP EBX
     LEA EBX, -9 [EBX]
     MOV [EBX], EAX

     MOV EDX, [EBP]
     MOV [EAX], EDX
     MOV EDX, 4 [EBP]
     MOV 4 [EAX], EDX
     LEA EBP, 0xC [EBP]
     MOV EAX, -4 [EBP]
    RET
END-CODE

: 2VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _2CONSTANT-CODE COMPILE,  , ,
  ['] _2TOVALUE-CODE COMPILE,
;


Не срабатывает слово TO, может кто-то поможет?

Автор:  WingLion [ Вс окт 31, 2010 19:59 ]
Заголовок сообщения:  Re: 2VALUE

а для него не надо писать слово 2TO?
просто TO - для одинарного числа.

Автор:  F-MAP [ Вс окт 31, 2010 20:25 ]
Заголовок сообщения:  Re: 2VALUE

С моей колокольни вроде должно сработать
Код:
: TO \ 94 CORE EXT
\ Интерпретация: ( x "<spaces>name" -- )
\ Пропустить ведущие пробелы и выделить name, ограниченное пробелом.
\ Записать x в name. Неопределенная ситуация возникает, если name не
\ определено через VALUE.
\ Компиляция: ( "<spaces>name" -- )
\ Пропустить ведущие пробелы и выделить name, ограниченное пробелом.
\ Добавить семантику времени выполнения, данную ниже, к текущему определению.
\ Неопределенная ситуация возникает, если name не определено через VALUE.
\ Время выполнения: ( x -- )
\ Записать x в name.
\ Примечание: Неопределенная ситуация возникает, если POSTPONE или [COMPILE]
\ применяются к TO.
  '
  9 + STATE @
  IF COMPILE, ELSE EXECUTE THEN
; IMMEDIATE

Автор:  WingLion [ Вс окт 31, 2010 20:30 ]
Заголовок сообщения:  Re: 2VALUE

A кто и в каком месте вызывает
F-MAP писал(а):
_2TOVALUE-CODE


??
не 2ТO ли должно это делать?

Автор:  rvm [ Вс окт 31, 2010 23:20 ]
Заголовок сообщения:  Re: 2VALUE

Слово TOVALUE вызывается из TO когда делается 9 + @ EXECUTE, но 2TOVALUE так вызываться не может, т.к..
Код:
: VALUE ( x "<spaces>name" -- ) \ 94 CORE EXT
  [T] HEADER [I]
  CONSTANT-CODE COMPILE, ,
  TOVALUE-CODE COMPILE,
;
F-MAP писал(а):
Код:
: 2VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _2CONSTANT-CODE COMPILE,  , ,
  ['] _2TOVALUE-CODE COMPILE,
;

: TO \ 94 CORE EXT
  '
  9 + STATE @
  IF COMPILE, ELSE EXECUTE THEN
; IMMEDIATE

Смещение 9 подойдет только для поля данных размером в одну ячейку. Такая реализация неудачна для поддержки поля данных различной длины.

Решения: либо ввести 2TO для двойных значений; либо усложнить _2CONSTANT и _2TOVALUE (чтобы хранили старшую и младшую часть или раздельно, или вместе после кода _2TOVALUE); либо изменить реализацию (например, использовать смещение -5 вместо +9) и пересобрать SPF4.

Автор:  chess [ Пн ноя 01, 2010 16:26 ]
Заголовок сообщения:  Re: 2VALUE

Все-таки проще реализовать через 2TO:

Код:
: _2CONSTANT-CODE   $ -4 @P=A A=RS $ 4 D=@A $ -8 @P=D A=@A $ -8 Pa  ;
: _2TOVALUE-CODE    B=RS $ -0D @B=A D=@P $ -9 @B=D $ 8 Pa $ -4 A=@P ;

: 2VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _2CONSTANT-CODE COMPILE,  , ,
  ['] _2TOVALUE-CODE COMPILE,  ;

: 2TO
  '
  13 + STATE @
  IF COMPILE, ELSE EXECUTE THEN
; IMMEDIATE

STARTLOG
SEE _2CONSTANT-CODE
SEE _2TOVALUE-CODE


лог
Код:
CODE _2CONSTANT-CODE
5D0647 8945FC           MOV     FC [EBP] , EAX
5D064A 58               POP     EAX
5D064B 8B5004           MOV     EDX , 4 [EAX]
5D064E 8955F8           MOV     F8 [EBP] , EDX
5D0651 8B00             MOV     EAX , [EAX]
5D0653 8D6DF8           LEA     EBP , F8 [EBP]
5D0656 C3               RET     NEAR
END-CODE
( 16 bytes, 7 instructions )


CODE _2TOVALUE-CODE
5D0673 5B               POP     EBX
5D0674 8943F3           MOV     F3 [EBX] , EAX
5D0677 8B5500           MOV     EDX , 0 [EBP]
5D067A 8953F7           MOV     F7 [EBX] , EDX
5D067D 8D6D08           LEA     EBP , 8 [EBP]
5D0680 8B45FC           MOV     EAX , FC [EBP]
5D0683 C3               RET     NEAR
END-CODE
( 17 bytes, 7 instructions )

Ok

Автор:  chess [ Вт ноя 02, 2010 11:24 ]
Заголовок сообщения:  Re: 2VALUE

Ради спортивного интереса переделал VALUE и 2VALUE под одно TO:

Код:
: _CONSTANT-CODE    DUP A=RS $ 5 A=@A ;
: _TOVALUE-CODE     B=RS @B=A DROP ;

: VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _CONSTANT-CODE COMPILE,
  ['] _TOVALUE-CODE COMPILE, , ;

: _2CONSTANT-CODE   $ -4 @P=A $ -8 Pa A=RS $ 9 D=@A @P=D $ 5 A=@A  ;
: _2TOVALUE-CODE    B=RS D=@P @B=A $ 4 @B=D 2DROP ;

: 2VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _2CONSTANT-CODE COMPILE,
  ['] _2TOVALUE-CODE COMPILE, , , ;

: TO
  ' 5 +
  STATE @ IF COMPILE, ELSE EXECUTE THEN ; IMMEDIATE

ps.
1. Тут надо вспомнить о VECT и его тоже переделать под новое TO.
2. Реализация глобальных переменных типа VALUE 2VALUE, кроме
присущего всем структурам данных в SPF, недостатка, а именно, размещения кода и собственно данных в непосредственной близости
(что приводит к замедлению кода из-за переписывания кэша процессора при записи в такие структуры)
еще и не могут использоваться в макросах (из-за читающего из входного потока слова TO).
Этот момент можно обойти путем использования локальных переменых или локально-именованных глобальных переменных,
код которых удален от собственно данных на величину большую объема кэша процессора и использование которых не требует
чтения из входного потока.

Автор:  F-MAP [ Вт ноя 02, 2010 17:27 ]
Заголовок сообщения:  Re: 2VALUE

Спасибо chess, выручил.

Автор:  rvm [ Вт ноя 02, 2010 17:38 ]
Заголовок сообщения:  Re: 2VALUE

chess писал(а):
1. Тут надо вспомнить о VECT и его тоже переделать под новое TO.
А еще вспомнить о USER-VALUE и USER-VECT ;)
И не забыть, что новое TO нельзя применять к старым VALUE (необходима пересборка ядра, или более умный "TO", который к старым будет применять старый "TO").

Избежать заглядывания вперед можно используя синтаксис (и NOTFOUND-обработчик), например
Код:
0 VALUE abc
123 =:ABC
Хотя, какой в этом смысл, если даже само слово VALUE заглядывает вперед? ;)

Автор:  вопрос [ Вт ноя 02, 2010 18:20 ]
Заголовок сообщения:  Re: 2VALUE

Цитата:
ps.
1. Тут надо вспомнить о VECT и его тоже переделать под новое TO.

Вообще, нужно сделать ТО в виде флага и
каждый вектор или разновидность переменной будет видеть только флаг :idea: :?:

Кстати, видимо, можно оставить совместимость со старым ТО

Новое ТО может вызывать Старое ТО, и, если не получилось, что можно, видимо. анализировать, тогда только оставлять флаг. Т.о. флаг будет оставлен только для тех слов, которые не воспринимают старое ТО. а для старых слов ТО будет просто испонено IMHO

Автор:  Mihail [ Вт ноя 02, 2010 22:21 ]
Заголовок сообщения:  Re: 2VALUE

chess писал(а):
Тут надо вспомнить о VECT и его тоже переделать под новое TO.


Код:
[IFNDEF] BREAK
: BREAK POSTPONE EXIT POSTPONE THEN ;  IMMEDIATE
[THEN]


: _2CONSTANT-CODE   R> 2@ ;

: 2VALUE ( x "<spaces>name" -- )
  HEADER
  ['] _2CONSTANT-CODE COMPILE, , , ;

: TO
  >IN @
  ' 1+ DUP REL@  ['] _2CONSTANT-CODE 4 -  =
  IF NIP CELL+ STATE @ IF  LIT, POSTPONE  2! ELSE 2! THEN
  BREAK  DROP
  >IN ! POSTPONE TO  ; IMMEDIATE


Автор:  вопрос [ Ср ноя 03, 2010 17:31 ]
Заголовок сообщения:  Re: 2VALUE

МОжно реализовать ТО через флаг или через чтение строки
ТО может устанавливать флаг, а слово после ТО, читая флаг, производить нужные действия (если ТО - записывать переменную, если нет- читать)

Какая реализация лучше
Изображение
Недостаток первого способа реализации ТО -
несоотвествие стандарту ,
однако он видимо может быть решён с помощью
создания совместимого с другим типом ТО
т.е. немного более сложное ТО, которое анализирует
ситуацию, и решает, будет ли последующее слово читать флаг или
в соответствии со стандартом ждёт прочтения

Недостаток второго способа - необходимость переделывания ТО
всякий раз, когда появляется новый тип данных, видимо не может
решаться с помощью создания совместимого ТО,
т.к. каждый раз придётся переделывать ТО,
распространяя его совместимост дальшe

Автор:  F-MAP [ Ср ноя 03, 2010 23:08 ]
Заголовок сообщения:  Re: 2VALUE

Всем спасибо за совет. Полистал на досуге книгу Л. Броуди и нашел еще такой вариант чисто на форте:
Код:
: 2VALUE CREATE , , DOES> 2@ ;
: 2TO ' >BODY STATE @ IF LIT, POSTPONE  2! ELSE  2! THEN  ;  IMMEDIATE

Может не совсем эффективно и все же, мне кажется, для форта (SPF) универсальный TO не очень подходит, как языка поддерживающего некого стандарта, видимо TO и VALUE надо определять для каждого типа данных, типа как C@, W@, @, 2@ и т.п.

Автор:  mOleg [ Чт ноя 04, 2010 07:47 ]
Заголовок сообщения:  Re: 2VALUE

F-MAP писал(а):
Может не совсем эффективно и все же, мне кажется, для форта (SPF) универсальный TO не очень подходит

Да все подходит. Вообще это лучше всего смотрится в косвенном ШК, когда просто читается адрес следующего фрагмента шитого кода, добавляется смещение в нужное поле кода (у VALUE (бывших QUAN) переменых их три) и туда передается управление. Проблема с СПФом лишь в том, что поля кода размещены не одно за другим, а потом данные, а в перемешку (чего в форке, к примеру, давно уже и нет):

Код:
\ создать инициализированную переменную,
\ возвращающую по-умолчанию собственно значение.
: VALUE ( x / name --> )
        HEADER
          COMPILE (value)
          COMPILE (store)
          COMPILE (CREATE)
          A,
        ;CREATE ;

\ создать неинициализированную переменную
: USER-VALUE ( / name --> )
             HEADER
               COMPILE (uvalue)
               COMPILE (ustore)
               COMPILE (USER)
               ADDR USER-PLACE A,
             ;CREATE ;

\ сохранить значение n в VALUE переменной
: TO ( n / name --> ) ' TOKEN + REGULAR ; IMMEDIATE

\ прочесть содержимое VALUE переменной
: FROM ( / name --> xt ) ' [ 2 TOKEN * LIT, ] + REGULAR ; IMMEDIATE


в таком случае DVALUE выглядит так же:
Код:
\ создать именованую VALUE переменную, хранящую число двойной длины
: DVALUE ( d / name --> )
         NextWord SHEADER
           COMPILE (DVAL)
           COMPILE (DTOV)
           COMPILE (CREATE)
           D,
         ;CREATE ;


\ создать пользовательскую именованую переменную двойной длины
: USER-DVAL ( --> d )
            NextWord SHEADER
              COMPILE (DUVAL)
              COMPILE (DTOUVAL)
              COMPILE (USER)
              CELL USER-PLACE ,
              1 DOUBLES USER-ALLOT
            ;CREATE ;

Автор:  вопрос [ Чт ноя 04, 2010 19:27 ]
Заголовок сообщения:  Re: 2VALUE

mOleg писал(а):
Да все подходит. Вообще это лучше всего смотрится в косвенном ШК, когда просто читается адрес следующего фрагмента шитого кода, добавляется смещение в нужное поле кода (у VALUE (бывших QUAN) переменых их три) и туда передается управление. Проблема с СПФом лишь в том, что поля кода размещены не одно за другим, а потом данные, а в перемешку (чего в форке, к примеру, давно уже и нет):

Если мы захотим заинлайнить этот код?

Страница 1 из 2 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/