Forth http://www.fforum.winglion.ru/ |
|
Форматированный вывод http://www.fforum.winglion.ru/viewtopic.php?f=23&t=2021 |
Страница 1 из 1 |
Автор: | VoidVolker [ Пт мар 27, 2009 00:03 ] |
Заголовок сообщения: | Форматированный вывод |
Печать строк: возврат каретки, новая строка, изменение цвета символов и фона(цвет указывается шестнадцатиричным числом в текстовом виде в самой строке), плюс можно и дальше достаточно легко расширять. И почти "стандартное" форматное преобразование чисел - преобразуется одно 32-битное число. Преобразование двойного числа легко делается так: Код: 123 456 <# #S 3DROP <# #S #> Обсудим? Вот код: Код: : ZLEN >R 0 BEGIN R@ OVER + C@ WHILE 1+ REPEAT RDROP ; \ Кстати, может заменить на ASCII ? Как у Броуди? : CHAR PARSE C@ ; : [CHAR] PARSE C@ LIT, ; IMMEDIATE CREATE formats 256 CELLS ALLOT 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 ; Пример: Код: 5 3 GOTOXY
" Использование /#FF00FFнескольких#/cr/#0$/цветов/$0#/n /$0055FFв одной$/ строке" DUP 34 + 0xD OVER C! 1+ 0xA SWAP C! DUP 52 + 0xA SWAP C! FPRINT Результат: |
Автор: | вопрос [ Вс мар 29, 2009 00:08 ] |
Заголовок сообщения: | |
Да, это хорошо, было бы ещё лучше, если доработать и сделать библиотеку с однообразными правилами применения (в частности файловый ввод-вывод также форматированный) |
Автор: | Hishnik [ Вс мар 29, 2009 00:16 ] |
Заголовок сообщения: | |
вопрос писал(а): Да, это хорошо, было бы ещё лучше, если доработать и сделать библиотеку с однообразными правилами применения (в частности файловый ввод-вывод также форматированный)
EMIT - векторное слово. Правда, в FPRINT используется EMIT1 ("классический" EMIT на экран), но если заменить его именно на EMIT, то достаточно будет переопределять этот вектор, чтобы вывод шел в файл. |
Автор: | VoidVolker [ Вс мар 29, 2009 11:35 ] |
Заголовок сообщения: | |
Хищник писал(а): Правда, в FPRINT используется EMIT1 Ой, пардон, там конечно EMIT вопрос писал(а): Да, это хорошо, было бы ещё лучше, если доработать и сделать библиотеку с однообразными правилами применения (в частности файловый ввод-вывод также форматированный)
FPRINT - именно для маленьких строк, раскрашиваемых "вручную": например вывод сообщения или запроса. А вот например для вывода на экран текстового буфера(файла) редактора, да еще и редактируемого в реальном времени, такая техника никак не подходит - слишком большие тормоза будут даже на файлах размеров в десятки килобайт - надо будет постоянно двигать массивы памяти огромные. Т.о. для этого нужен совершенно другой алгоритм форматирования, никак не связанный с содержимым строки, а значит все форматирование строки должно храниться за пределами самой строки. |
Автор: | вопрос [ Вс мар 29, 2009 11:47 ] |
Заголовок сообщения: | |
Цитата: Т.о. для этого нужен совершенно другой алгоритм форматирования, никак не связанный с содержимым строки, а значит все форматирование строки должно храниться за пределами самой строки. не понимаю, во всех языках получается, а тут нет?
|
Автор: | VoidVolker [ Вс мар 29, 2009 13:42 ] |
Заголовок сообщения: | |
вопрос писал(а): не понимаю, во всех языках получается, а тут нет?
А вот не надо подменять понятия - язык тут ни причем. Вот пример: есть у нас строка в 10 мегабайт, и вот чтобы в начале строки вставить /#FF00FF, надо выделить новый буфер для нее размером 10мб+8байт, затем поместить туда /#FF00FF и еще дописать 10мб текста. Даже если строка уже в буфере, в любом случае двигать 10мб данных. Разве это будет быстро? А если нам надо сохранить строку без форматирования? Придется искать по всему буферу символы и группами их записывать в файл. Или произвести поиск текста /#FF00FF? Это усложнит алгоритм поиска. А если мы в реальном времени печатаем в начала текста - при каждом печатаемом символе надо будет двигать 10мб? Разве это будет быстро? Не думаю. Это же сколько работы надо сделать, только чтобы вывести сообщение? А тут 15 минут - и можно не напрягаясь выводить нужным цветом текст. Как любит говорить Хищник: "минимум работы - максимум эффекта". |
Автор: | вопрос [ Вс мар 29, 2009 15:48 ] |
Заголовок сообщения: | |
VoidVolker писал(а): вопрос писал(а): не понимаю, во всех языках получается, а тут нет? А вот не надо подменять понятия - язык тут ни причем. Вот пример: есть у нас строка в 10 мегабайт, и вот чтобы в начале строки вставить /#FF00FF, надо выделить новый буфер для нее размером 10мб+8байт, затем поместить туда /#FF00FF и еще дописать 10мб текста. Даже если строка уже в буфере, в любом случае двигать 10мб данных. Разве это будет быстро? А если нам надо сохранить строку без форматирования? Придется искать по всему буферу символы и группами их записывать в файл. Или произвести поиск текста /#FF00FF? Это усложнит алгоритм поиска. А если мы в реальном времени печатаем в начала текста - при каждом печатаемом символе надо будет двигать 10мб? Разве это будет быстро? Не думаю. Это же сколько работы надо сделать, только чтобы вывести сообщение? А тут 15 минут - и можно не напрягаясь выводить нужным цветом текст. Как любит говорить Хищник: "минимум работы - максимум эффекта". 8) Пример совсем непонятен. Форматирование на уровне исходника осуществляет программист - в исходнике, т.е. случай "чтобы в начале строки вставить /#FF00FF, " неадекватен, это как-раз означало бы, что форматирование осуществляется над неформатированной строкой програмными средствами и только затем передаётся функции форматированного вывода? Форматирование в строку вставляет программист для наглядности, чтобы не подсчитывать символы и не писать "на таком-то символе от начал строки вставить тэг (курсив)", для чего может понадобиться вставлять в исходник строки (а такой вид имеет только исходник строки) дополнительные маркеры форматирования ? ЕСли у нас есть строка, наждающаяся в форматировании, то это никак не предполагает, что её сначала нужно снабдить маркерами, а потом передать слову, которое эти маркеры понимает МОжно (и нужно) сразу помещать результат обработки этих маркеров в строку-результат (строка-результат - это то, что мы выводим) и не пользоваться самими маркерами |
Автор: | VoidVolker [ Вс мар 29, 2009 17:00 ] |
Заголовок сообщения: | |
вопрос писал(а): Зачем строка 10 мБ? Это не строка а база данных, и подход соответствующий.
Воот, я и говорю - для вывода простого сообщения нужного цвета вполне достаточно FPRINT. А для создания и редактирования форматированных текстов нужно уже что-то подобное хтмл. |
Автор: | вопрос [ Пн мар 30, 2009 00:44 ] |
Заголовок сообщения: | |
Цитата: Воот, я и говорю - для вывода простого сообщения нужного цвета вполне достаточно FPRINT. Форматированный вывод и форматированный текст - совсем разные вещи. Форматированный вывод - это преобразование частей строки перед выводом. Форматированный текст - это способ представления текста. Т.е. в первом случае мы говорим о процедуре, а во втором - о результате.
А для создания и редактирования форматированных текстов нужно уже что-то подобное хтмл. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |