Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт мар 28, 2024 22:05

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Ответить
Имя пользователя:
Заголовок:
Текст сообщения:
Введите текст вашего сообщения. Длина сообщения в символах не более: 60000

Размер шрифта:
Цвет шрифта
Настройки:
BBCode ВКЛЮЧЕН
[img] ВЫКЛЮЧЕН
[flash] ВЫКЛЮЧЕН
[url] ВКЛЮЧЕН
Смайлики ВЫКЛЮЧЕНЫ
Отключить в этом сообщении BBCode
Не преобразовывать адреса URL в ссылки
Вопрос
Теперь гостю придется вводить здесь пароль. Не от своей учетной записи, а ПАРОЛЬ ДЛЯ ГОСТЯ, получить который можно после регистрации на форуме через ЛС.:
Этот вопрос предназначен для выявления и предотвращения автоматических регистраций.
   

Обзор темы - Добавить цифру в строку
Автор Сообщение
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Кстати, есть ведь форматируемый вывод, там есть и форматируемый вывод в строку (и на экран и файл) Я тогда так и не решил, нужно ли и как делать что-то с плавающей запятой, а энтузиазм не был проявлен в смысле интереса, т.о. после этот файл использовался только для отладки - очень удобно

viewtopic.php?p=21429#p21429
Сообщение Добавлено: Пн апр 16, 2012 22:03
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Хищник писал(а):
Так если в описании указано, что это слово немедленного исполнения, то оно и сразу выберет из входного потока? А ' выберет не сразу, а когда до него дойдет очередь выполняться, и заберет оно то, что будет во входном потоке в тот момент.


Да, но так же получается, что оно сразу и адрес слова на стек положит...
И не сказано, что оно скомпилирует литерал с этим адресом.
Сообщение Добавлено: Вс апр 15, 2012 14:13
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Так если в описании указано, что это слово немедленного исполнения, то оно и сразу выберет из входного потока? А ' выберет не сразу, а когда до него дойдет очередь выполняться, и заберет оно то, что будет во входном потоке в тот момент.
Сообщение Добавлено: Вс апр 15, 2012 14:08
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
VoidVolker писал(а):
Омг. У слова ['] стандартное поведение: оно компилирует исполнимый токен слова из входного потока.


Я знал! Я знал! (c)...

Стандартное поведение, но не стандартное описание...

Или это "КлюГ" в описании!
Сообщение Добавлено: Вс апр 15, 2012 14:04
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
['] EMIT-TO-NAME TO EMIT внутри определения действительно решает проблему. USE - полная копия ['] (приятнее выглядит, проще читать).
Сообщение Добавлено: Вс апр 15, 2012 14:03
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Омг. У слова ['] стандартное поведение: оно компилирует исполнимый токен слова из входного потока.
Сообщение Добавлено: Вс апр 15, 2012 13:58
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
VoidVolker писал(а):
Зачем же так все усложнять? Есть же ['] и USE:



Описание Кварка писал(а):
['] -- Выбрать имя слова из входного потока. Положить
на стек адрес начала кода этого слова. Слово
немедленного исполнения.


немедленное исполнение, значит, адрес на стек попал в момент компиляции... А кто его оттуда в код скомпилировал, да еще и литералом? значит, надо LIT, и его надо исполнить, а не компилировать, а значит, [ LIT, ]

И тогда запись
[ ' EMIT-TO-NAME LIT, ]

оказывается короче, чем

['] EMIT-TO-NAME [ LIT, ]
Сообщение Добавлено: Вс апр 15, 2012 13:51
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Зачем же так все усложнять? Есть же ['] и USE:
Код:
: File
FROM EMIT
['] EMIT-TO-NAME TO EMIT
" File-" PRINT STEP @ . " .txt" PRINT
TO EMIT
0 FILENAME[] SYM-COUNTER @ + C!
FILENAME[] NEWFILE CLOSE
FILENAME[] OPENRW TO HF-OUT ;


Код:
: File
FROM EMIT
USE EMIT-TO-NAME TO EMIT
" File-" PRINT STEP @ . " .txt" PRINT
TO EMIT
0 FILENAME[] SYM-COUNTER @ + C!
FILENAME[] NEWFILE CLOSE
FILENAME[] OPENRW TO HF-OUT ;
Сообщение Добавлено: Вс апр 15, 2012 13:40
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Проблема в слове '

При компиляции - компилируется его исполнение, в результате, оно ищет слово, которое будет после file в момент его исполнения.

Чтобы такого не было, надо делать примерно так:

Код:
: File
FROM EMIT
[ \ здесь вернулись в режим интерпретации
' EMIT-TO-NAME  LIT, \  'хитро' скомпилитровали адрес
\ исполнения слова EMIT-TO-NAME  как литерал
] \ вернулись к компиляции
\ скомпилированный литерал
TO EMIT \ и запишется здесь в EMIT как надо
" File-" PRINT STEP @ . " .txt" PRINT
TO EMIT
0 FILENAME[] SYM-COUNTER @ + C!
FILENAME[] NEWFILE CLOSE
FILENAME[] OPENRW TO HF-OUT ;


А дело в том, что ' получает адрес следующего слова не в момент компиляции, а в момент исполнения.
Сообщение Добавлено: Вс апр 15, 2012 13:17
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Возникли проблемы

Код:
0 ?.SPACE !

VARIABLE STEP
VARIABLE SYM-COUNTER
CREATE FILENAME[] 256 ALLOT

: EMIT-TO-NAME 
  FILENAME[] SYM-COUNTER @ + C!
  1 SYM-COUNTER +!
;

: File
FROM EMIT
' EMIT-TO-NAME TO EMIT
" File-" PRINT STEP @ . " .txt" PRINT
TO EMIT
0 FILENAME[] SYM-COUNTER @ + C!
FILENAME[] NEWFILE CLOSE
FILENAME[] OPENRW TO HF-OUT ;

File


Слово file не выполняется в режиме компиляции

Если его тело выполнить в обычном режиме

Код:
FROM EMIT
' EMIT-TO-NAME TO EMIT
" File-" PRINT STEP @ . " .txt" PRINT
TO EMIT
0 FILENAME[] SYM-COUNTER @ + C!
FILENAME[] NEWFILE CLOSE
FILENAME[] OPENRW TO HF-OUT


работает без проблем. Почему?
Сообщение Добавлено: Вс апр 15, 2012 12:45
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Ну, в ядре нет. Понятно, что сделать можно без проблем.
Сообщение Добавлено: Сб апр 14, 2012 21:34
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Хищник писал(а):
S>D <# HOLDS #> S" - ничего из этого в кварке нет.

Есть же давно. Разве я не выкладывал?
Код:
1 CELLS CONSTANT CELL

: DEFED  \ ( str -- )  \ Синоним двоеточия для строки со стека
  [C]HERE
  CURRENT @ @ [C],    \ LFA  \ записываем адрес начала предыдущего слова
  CURRENT @ [C]!
  BEGIN               \ NFA  \ Пишем имя слова
    DUP C@ [C]C,
    1+
    DUP C@ 0 =
  UNTIL
  DROP 0 [C]C,
  0 [C]C,             \ FFA  \ Один байт для флагов
  ]                   \ CFA  \ А дальше уже код
;

: RET,  \ ( -- ) \ Скомпилировать возврат
  0xC3 [C]C,
;

: :NONAME   \ ( -- xt )  \ Начать определение нового слова без имени, на стеке останется указатель на начало кода(исполнимый токен).
  [C]HERE ]
;

: PROC:   \ ( " name" --> ) \ Начать определение нового слова с именем, взятым из входного потока. Во время выполнения слово оставит на стеке указатель на свой код.
  QUAN [C]HERE [C]HERE 0xA - ! ]
;

: CHAR   \ ( " char" --> ) \ Взять из входного потока следующее слово и оставить на стеке числовой код(ASCII) его первого символа.
  PARSE C@
;

: [CHAR]   \ ( " char" --> ) \ Взять из входного потока следующее слово и скомпилировать числовой код(ASCII) его первого символа. Слово немедленного исполнения.
  PARSE C@ LIT,
; IMMEDIATE

: --   \ ( offset size -- offset+size ) ( " name" --> ) ( addr -- addr+offset )
  CREATE
  OVER , + DOES> @ +
;

: [:]   \ Определить еще одну "точку входа" в слово
  0xE9 [C]C, [C]HERE 0 [C], [C]HERE   \ addr \ адрес, куда записывать переход; "точка" отсчета
  :
  [C]HERE - ABS SWAP !
; IMMEDIATE

\ Пример:
\ : w1
  \ 1
\ [:] w2
  \ 2
\ ;
\ w1 w2  \ --> 2 1 2

\ Вот еще одна дешевая альтернатива локальным переменным
: L1   LOCALSTACK LOCALDEPTH 1-  -FTH ;
: L2   LOCALSTACK LOCALDEPTH 2 - -FTH ;
: L3   LOCALSTACK LOCALDEPTH 3 - -FTH ;
: L4   LOCALSTACK LOCALDEPTH 4 - -FTH ;
: L5   LOCALSTACK LOCALDEPTH 5 - -FTH ;
: L6   LOCALSTACK LOCALDEPTH 6 - -FTH ;
: L7   LOCALSTACK LOCALDEPTH 7 - -FTH ;
: L8   LOCALSTACK LOCALDEPTH 8 - -FTH ;
: L9   LOCALSTACK LOCALDEPTH 9 - -FTH ;


0 , CREATE fpad 256 ALLOT
: -CNT 4 - ;

: char>fpad   \ ( char -- )
  fpad fpad -CNT @ + C!
  CHAR fpad -CNT +!
;

: F>STR   \ ( F: D -- str ) \ Преобразовать флоат-число в строку
  ['] char>fpad TO EMIT  \ Перенаправляем печать в буфер и печатаем в него флоат-число
  0 fpad -CNT !
  F.
  ['] EMIT1 TO EMIT
  0 fpad fpad -CNT @ + C!
  fpad
;

: STR>F   \ ( str -- F: D ) \ Преобразовать строку во флоат-число
  EVALUATE
;


: str>float   \ ( str -- F: D )
  1 >R
  DUP 0
  BEGIN OVER C@ WHILE
    DUP IF R> 10 * >R THEN
    OVER C@  \ Заменяем в строке разделитель на пробел
    [CHAR] , OVER = SWAP [CHAR] . = OR
      IF OVER 32 SWAP C! DROP 1 THEN
    SWAP 1+ SWAP
  REPEAT
  2DROP
  EVALUATE
  SWAP S>F S>F R> S>F F/ F+
;

: /STRING   \ ( a u n -- a+n u-n ) \ Обрезать au-строку слева на n символов
  DUP NEGATE SWAP D-
;

: EXIT RDROP ;

: 2SWAP  ROT >R ROT R> ;
: 2>L   >L >L ;
: 2L>   L> L> ;

: ZLEN
  >R 0 BEGIN R@ OVER + C@ WHILE 1+ REPEAT  RDROP
;

: Z>AU  DUP ZLEN ;


: ERASE  \ ( a len -- )
  0 ROT ROT CFILL
;

: UNLOOP   \ ( -- ) \ Выйти из цикла DO LOOP
  LSTACKI @ 1+ LSTACKIMAX !
;

: UNNEXT   \ ( -- ) \ Выйти из цикла FOR NEXT
  LSTACKI @ LSTACKIMAX !
;

: GET-WORDS
  " words.txt" NEWFILE TO HF-OUT
  CONTEXT @ BEGIN @ DUP WHILE
    HF-OUT OVER CELL +  Z>AU  \ lfa nfa u
    WRITEFILE
    "   " 1 OVER 4 - ! 0 OVER 1+ C! PRINTF
    CRF
  REPEAT
  HF-OUT CLOSE
  DROP
;


256 ARRAY formats
VARIABLE str-posx

: FPRINT   \ ( str -- ) \ Печать с форматированием
  WHEREX str-posx !
  BEGIN DUP C@ DUP WHILE
    formats OVER -TH @ DUP
      IF
        NIP EXECUTE
      ELSE
        DROP EMIT
      THEN
    1+
  REPEAT
  2DROP
;

: StrFormat  \ ( char -- )
  formats SWAP -TH
  [C]HERE SWAP !
  ]
;

: StrFormat:  \ ( char -> )
  CHAR StrFormat
;

: ;StrFormat [COMPILE] ; ; IMMEDIATE

CREATE abc-nums 256 ALLOT
0xFF abc-nums 256 CFILL

HEX
0 abc-nums CHAR 0 + C!  8 abc-nums CHAR 8 + C!
1 abc-nums CHAR 1 + C!  9 abc-nums CHAR 9 + C!
2 abc-nums CHAR 2 + C!  A abc-nums CHAR A + C!
3 abc-nums CHAR 3 + C!  B abc-nums CHAR B + C!
4 abc-nums CHAR 4 + C!  C abc-nums CHAR C + C!
5 abc-nums CHAR 5 + C!  D abc-nums CHAR D + C!
6 abc-nums CHAR 6 + C!  E abc-nums CHAR E + C!
7 abc-nums CHAR 7 + C!  F abc-nums CHAR F + C!
DECIMAL

: gethex   \ ( addr -- addr1 num )
  0
  BEGIN  OVER C@ abc-nums + C@ DUP 0xFF = NOT WHILE
    SWAP 4 LSHIFT +
    SWAP 1+ SWAP
  REPEAT
  DROP
;

StrFormat: \  \ ( addr -- addr1 ) \ Экранирование символов (всех)
  1+ DUP C@ EMIT
;StrFormat

StrFormat: #  \ ( addr -- addr1 )
  DUP 1+ C@ [CHAR] / =
    IF
      1+ SWAP SETCOLOR
    ELSE
      DUP C@ EMIT
    THEN
;StrFormat

StrFormat: $  \ ( addr -- addr1 )
  DUP 1+ C@ [CHAR] / =
    IF
      1+ SWAP SETBGCOLOR
    ELSE
      DUP C@ EMIT
    THEN
;StrFormat

StrFormat: /  \ ( addr -- addr1 )
  DUP 1+ C@
  [CHAR] # OVER =
    IF
      DROP 2 +
      GETCOLOR SWAP
      gethex SETCOLOR
      1-
    ELSE
      [CHAR] $ =
        IF
          2 +
          GETBGCOLOR SWAP
          gethex SETBGCOLOR
          1-
        ELSE
          DUP C@ EMIT
        THEN
    THEN
;StrFormat

0xA StrFormat
  WHEREXY 1+ GOTOXY
;StrFormat

0xD StrFormat
  str-posx @ WHEREY GOTOXY
;StrFormat


256 ALLOT HERE 4 - VALUE PAD   \ Растет вниз. \ «4 -» - строка оканчивается нулем
VARIABLE PAD#

" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" VALUE nums-abc


: HOLD   \ ( char -- ) \ Вставить символ с кодом char в буфер форматного преобразования чисел.
  PAD PAD# @ - C!
  1 PAD# +!
;

: #   \ ( base num -- base num ) \ Выделить одну цифру с конца и добавить ее в буфер форматного преобразования чисел, оставив частное на стеке.
  OVER /MOD
  nums-abc + C@
  HOLD
;

: HOLDS   \ ( str -- ) \ Вставить строку в буфер форматного преобразования чисел.
  DUP ZLEN DUP ROT    \ len len str
  OVER PAD SWAP PAD# @ + - 1+  \ len len str addr
  ROT CMOVE                \ len str addr len
  PAD# +!
;

: #S   \ ( base num -- base num ) \ Преобразовать оставшуюся часть числа.
  BEGIN  OVER /MOD 2DUP OR  WHILE
    nums-abc + C@ HOLD
  REPEAT
  DROP
;

: {#   \ ( num base -- ? base num ) \ Начать форматное преобразование числа в системе счисления base
  OVER 0 MIN -1 MAX
  ROT ABS ROT SWAP
;

: #}   \ ( ? base num -- ) \ Закончить форматное преобразование числа.
  3DROP
  PAD PAD# @ - 1+
  PAD# OFF
;

: <#   \ ( num -- ? base num ) \ Начать форматное преобразование числа в текущей системе счисления.
  DUP 0 MIN -1 MAX SWAP
  ABS
  BASE @ SWAP
;

: #>   \ ( ? base num -- ) \ Закончить форматное преобразование числа.
  3DROP
  PAD PAD# @ - 1+
  PAD# OFF
;

: SIGN   \ ( ? base num -- ? base num ) \ Если число отрицательное, то вставить знак минуса в буфер форматного преобразования чисел.
  2 PICK IF [CHAR] - HOLD THEN
;
Сообщение Добавлено: Сб апр 14, 2012 21:19
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
mOleg писал(а):
А вообще кварк со строками работать умеет?

Не, у него там блокировки на уровне ядра :))

В чем проблема-то? Что в кои-то веки одноразовые <# # #> пригодились для частной задачки, и то, если вовремя про них вспомнить? А векторизованная словарная статья работает в куче алгоритмов и даже не требует специального обдумывания, как, зачем и для чего оно могло бы пригодиться.
Сообщение Добавлено: Сб апр 14, 2012 20:27
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
WingLion писал(а):
incubus370 писал(а):
теперь FILENAME[] содержит следующую строку но без завершающего нуля "File-0.txt".


добавить код 0 EMIT-TO-NAME, и нолик появится.


Надо будет подправить.
Сообщение Добавлено: Сб апр 14, 2012 20:00
  Заголовок сообщения:  Re: Добавить цифру в строку  Ответить с цитатой
Хищник писал(а):
S>D <# HOLDS #> S" - ничего из этого в кварке нет.

В СПФе будет работать,
А вообще кварк со строками работать умеет?

Хищник писал(а):
Речь идет о другом алгоритме.

(я конечно не смотрел, но осуждаю)
Сообщение Добавлено: Сб апр 14, 2012 19:59

Часовой пояс: UTC + 3 часа [ Летнее время ]


cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB