Forth http://fforum.winglion.ru/ |
|
Список актуальных задач из Rosetta code http://fforum.winglion.ru/viewtopic.php?f=2&t=3263 |
Страница 4 из 5 |
Автор: | Victor__v [ Вт фев 18, 2020 11:06 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Цитата: Given two integers, A and B. Their sum needs to be calculated. Для Nova-forth Код: : CATCH: R> CATCH ; : PLUS: ['] THROW >R 'CR' PARSE FROM ParseBuff.simb KEEP! FROM ParseBuff KEEP! 0 >IN KEEP! CATCH: 0 BEGIN PARSE-NAME DUP WHILE STR>NUM THROW + REPEAT 2DROP . ; Интерпретация строки чисел с перехватом ошибок и восстановлением контекста ФС |
Автор: | Hishnik [ Вт фев 18, 2020 15:55 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Victor__v писал(а): Интерпретация строки чисел с перехватом ошибок и восстановлением контекста ФС Явно не хватает слова ReadInt. |
Автор: | Victor__v [ Вт фев 18, 2020 16:48 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Hishnik писал(а): Victor__v писал(а): Интерпретация строки чисел с перехватом ошибок и восстановлением контекста ФС Явно не хватает слова ReadInt. STR>NUM \ A U -- num err|0 Конечно, можно заморочиться и написать такое слово, только код сложнее будет у меня) |
Автор: | Hishnik [ Вт фев 18, 2020 23:06 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Вводить и складывать два числа через перехват исключений - это сильно. Для этого и нужны тесты вроде RosettaCode. Тут вообще можно ограничиться + . - это если оговорить, что числа вводятся с клавиатуры в консоль, а дальше как принято в Форте. У меня больше строк, да... но это GUI. |
Автор: | Hishnik [ Вс май 24, 2020 01:20 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Rosetta Code оказался эффективным мотиватором для изменения нового Кварка Вариант кода с чуть улучшенным взаимодействием виджетов. Код: 0 LABEL.SHOW 20 40 100 40 0 LABEL.RECT " A" 0 LABEL.TEXT 1 LABEL.SHOW 180 40 100 40 1 LABEL.RECT " B" 1 LABEL.TEXT 2 LABEL.SHOW 300 40 100 40 2 LABEL.RECT 0 TEXTEDIT.SHOW 0 80 100 40 0 TEXTEDIT.RECT 1 TEXTEDIT.SHOW 120 80 100 40 1 TEXTEDIT.RECT 0 BUTTON.SHOW 320 80 100 50 0 BUTTON.RECT " A+B" 0 BUTTON.TEXT VARIABLE FLAG FLAG OFF : WAITGUI BEGIN FLAG @ UNTIL FLAG OFF ; : EDIT.GETLINE FLAG SETFLAG TEXTEDIT.GETLINE WAITGUI ; CREATE $BUF 256 ALLOT : GETA $BUF 0 0 EDIT.GETLINE $BUF STR> ; : GETB $BUF 0 1 EDIT.GETLINE $BUF STR> ; : SHOWRESULT $BUF >STR $BUF 2 LABEL.TEXT ; " GETA GETB + SHOWRESULT" 0 BUTTON.ACTION Теперь чтение строки "обернуто" в еще одно слово. После некоторых позиционных войн с Qt выяснилось, что взаимодействие потоков не так просто, и заставить Qt "прокачивать" очередь сообщений не особенно удается, если Форт-машина при этом стоит. А она стоит, потому что ждет реакции на запрос (например, содержимого TextEdit). Скомпилировать серию вызовов на C++ в целом не получается, а вот слово EDIT.GETLINE работает. |
Автор: | KPG [ Ср сен 15, 2021 00:29 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Нет решения такой несложной задачи на Форт. Phrase_reversals Самое простое схемное решение видится в создании слова Reverse ( addr n -- addr n ) - например считыванием всех символов строки в стэк, а потом из него их извлечением из стэка переписать строку символов. а, остальные варианты из этой задачи применением слова Reverse и считывания отдельных слов из потока/строки. P.S. Пока на Forth 543 решений задач на rosettacode. |
Автор: | Total Vacuum [ Ср сен 15, 2021 10:44 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Ну да, там 3 подзадачи: - инвертировать строку; - инвертировать слова, не меняя порядок слов; - поменять порядок слов; Для первого случая, например, можно тупо запихать всю всю строку посимвольно в стек, а затем вывести содержимое... Во втором почти то же самое, но выводить и опустошать стек каждый раз, когда попался пробел... А для случая 3 можно запоминать в стеке адреса начала слов... На esoteric forth, например, первая задача решается как-то так: Код: % c или даже так: % s : p "rosetta code phrase reversal" ; : r # , ( # , $ 1 + # , ) _ ; : w # ( c # ) _ ; 0 p r w > lasrever esarhp edoc attesor Код: %c%s0"rosetta code phrase reversal"#(#,$1+#,)(c#)_ На обычном Форте могло бы быть что-то вроде:> lasrever esarhp edoc attesor Код: include "xxx" \ подключаем какие-то нужные библиотеки Если бы не одно НО... У меня ж asciiz, поэтому за такое решение меня адепты секты ans94 на вилы поднимут, а переделывать под расово правильный Форт мне лень... : phrase "rosetta code phrase reversal" ; : reverse begin dup c@ while dup c@ swap 1+ repeat drop ; : write begin dup while emit repeat drop ; 0 phrase reverse write В принципе, для "правильных" строк еще проще может получиться, т.к. длину строки мы знаем, поэтому можем выводить строку посимвольно, начиная с strlen-1, но все равно лень... |
Автор: | KPG [ Ср сен 15, 2021 15:23 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Например один из вариантов решения по реверсу строки , при проверке в gForth Online может быть такой Код: create AXD S" rosetta code phrase reversal" S, : reverse { addr len } addr len bounds do I c@ loop addr len bounds do I c! loop ; AXD count 2dup reverse type Тыц P.S. Конечно gForth немного в "себе" Форт в сравнении с другими реализациями Forth и вроде бы такие простые вещи для него не так просты в реализации (может возможно более немногословное решение) |
Автор: | Total Vacuum [ Ср сен 15, 2021 15:57 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
ну или так: Код: : phrase s" rosetta code phrase reversal" ; или даже так: : reverse { addr len } addr len bounds do i c@ loop len 0 do emit loop ; phrase reverse Код: : phrase s" rosetta code phrase reversal" ; : reverse over + 1- do i c@ emit -1 +loop ; phrase reverse А для реализаций с asciiz, возможно, самым коротким будет вариант с рекурсией (у меня в таком виде работает, хотя в каких-то других системах надо будет использовать recurse): Код: : phrase "rosetta code phrase reversal" ;
: reverse dup 1+ c@ if dup 1+ reverse then c@ emit ; phrase reverse |
Автор: | Victor__v [ Ср сен 15, 2021 20:06 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Total Vacuum писал(а): Ну да, там 3 подзадачи: - инвертировать строку; - инвертировать слова, не меняя порядок слов; - поменять порядок слов; Код: : REV-WORD \ a len -- DUP 2 < IF 2DROP EXIT THEN \ ОТ ДУРАКА OVER + 1- 2>R BEGIN 2R@ = 2R@ > OR IF RDROP RDROP EXIT THEN 1 RPICK C@ R@ C@ 1 RPICK C! R@ C! R> 1- R> 1+ >R >R AGAIN ; S" HELLO WORD!" 2DUP REV-WORD TYPE CR : REV-WORDS-IN-STR \ a u FROM ParseBuff.simb KEEP! FROM ParseBuff KEEP! 0 >IN KEEP! BEGIN PARSE-NAME DUP WHILE REV-STR REPEAT 2DROP ; S" HELLO WORD!" 2DUP REV-WORDS-IN-STR TYPE CR : REV-WORDS-ORDER \ xt a u -- xt: new-a new-u FROM ParseBuff.simb KEEP! FROM ParseBuff KEEP! 0 >IN KEEP! >R 0 >R BEGIN PARSE-NAME DUP WHILE RP@ 1+! REPEAT 2DROP BEGIN R@ WHILE 1 RPICK EXECUTE BL EMIT R> 1- >R REPEAT RDROP RDROP ; ' TYPE S" HELLO WORD!" REV-WORDS-ORDER Последняя подзадача сделана квадратно-гнездовым способом, т. к. не учитывает пробельные символы. Заморачиваться для примера лень |
Автор: | KPG [ Ср сен 15, 2021 21:57 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Victor__v писал(а): Total Vacuum писал(а): Ну да, там 3 подзадачи: - инвертировать строку; - инвертировать слова, не меняя порядок слов; - поменять порядок слов; Последняя подзадача сделана квадратно-гнездовым способом, т. к. не учитывает пробельные символы. Заморачиваться для примера лень Такое решение представлено на rosettacode Код: : not-empty? dup 0 > ;
: (reverse) parse-name not-empty? IF recurse THEN type space ; : reverse (reverse) cr ; reverse ---------- Ice and Fire ------------ reverse reverse fire, in end will world the say Some reverse ice. in say Some reverse desire of tasted I've what From reverse fire. favor who those with hold I reverse reverse ... elided paragraph last ... reverse reverse Frost Robert ----------------------- |
Автор: | Total Vacuum [ Ср сен 15, 2021 23:14 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Симпатичное решение, но можно и проще: Код: : (reverse) parse-name dup IF recurse THEN type space ; Возможно, у автора решения какая-то диковинная версия parse-name...
: reverse (reverse) cr ; reverse ---------- Ice and Fire ------------ reverse reverse fire, in end will world the say Some reverse ice. in say Some reverse desire of tasted I've what From reverse fire. favor who those with hold I reverse reverse ... elided paragraph last ... reverse reverse Frost Robert ----------------------- |
Автор: | KPG [ Ср сен 15, 2021 23:48 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Total Vacuum писал(а): Возможно, у автора решения какая-то диковинная версия parse-name... Решение 2-й подзадачи Код: : reverse { addr len } addr len bounds do I c@ loop addr len bounds do I c! loop ; : (reverse) parse-name dup IF 2dup reverse type space recurse THEN ; : reverse (reverse) cr ; reverse rosetta code phrase reversal s" reverse rosetta code phrase reversal" evaluate Output: Цитата: attesor edoc esarhp lasrever
attesor edoc esarhp lasrever |
Автор: | KPG [ Ср июл 12, 2023 10:08 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Задача разделения строк(и) текста на токены по разделителю "," (запятая) Вход: ( addr len ) \ s" Hello,How,Are,You,Today" Вывод тестовой печати: Hello.How.Are.You.Today Решение: https://rosettacode.org/wiki/Tokenize_a_string#Forth Код: : split ( str len separator len -- tokens count ) here >r 2swap begin 2dup 2, \ save this token ( addr len ) 2over search \ find next separator while dup negate here 2 cells - +! \ adjust last token length 2over nip /string \ start next search past separator repeat 2drop 2drop r> here over - ( tokens length ) dup negate allot \ reclaim dictionary 2 cells / ; \ turn byte length into token count : .tokens ( tokens count -- ) 1 ?do dup 2@ type ." ." cell+ cell+ loop 2@ type ; s" Hello,How,Are,You,Today" s" ," split .tokens \ Hello.How.Are.You.Today В строке словом Search находятся токены по разделителю и адрес и длина найденных токенов в реализации слова split записывается по адресу Here (для временного сохранения в области памяти), а по завершению сканирования строки слово Split оставляет после себя адрес Here и количество найденных токенов. (токен представлен 2-я числами - addr len) а сам адрес Here востанавливается на момент вызова слова Split. P.S. В gForth Online код выполняется. Если просто вывести строку с заменой символа "," на "." без деления на токены при этом то решение может быть таким. Код: : split> ( addr len -- ) here >r dup c, here swap cmove> r@ dup c@ 1+ bounds do i c@ dup [char] , = if drop [char] . emit else emit then loop here r> - negate allot ; s" Hello,How,Are,You,Today" split> Исходная строка, при этом сохранена по Here адресу до момента изменения этой области памяти. Код: here dup c@ type
|
Автор: | Hishnik [ Ср июл 12, 2023 16:07 ] |
Заголовок сообщения: | Re: Список актуальных задач из Rosetta code |
Такую операцию можно вставить и в словарь. |
Страница 4 из 5 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |