Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Victor__v писал(а): Осталось придумать где такое прототипирование будет наиболее актуальным. Очень удобная штука, просто чтобы не заниматься отслеживанием стековых перестановок. Полная аналогия локальных объявлений (не только переменных), с единственным ограничением - рекурсия не будет создавать новый набор локальных переменных, поэтому не поддерживается. Но это как-то ни разу не мешало. Victor__v писал(а): в x86 под 64 бита стек 64-битный и ничего с этим не поделать. Стек данных я у себя тоже сделал 64-битным.
Эмулированный стек - это массив в памяти. Он может быть char, int, int64_t, и какой угодно еще. Сейчас для эмуляции нет смысла рассматривать программы больше 4 Гб размером, поэтому 32 разряда для адреса вполне достаточно. Соответственно, стек возвратов может хранить 32 разряда. Как с этим работает процессор на уровне машинного кода - второй вопрос. Особенно интересно это для переносимого Qt, под который можно собрать ВМ и для 32-разрядного ARM, и тут таскать лишние разряды совершенно не к месту. В целом манипуляции со стеком возвратов видятся методически неправильными. Да, про это было в ранних волнах публикаций по Форту, особенно чтобы подчеркнуть, что стек возвратов и стек данных - не одно и то же, и в Форте "все можно сделать". Но с тем же успехом данные можно складывать в HERE, рассчитывая, что их пока там никто не испортит, а потом заберем. Это тоже хак, основанный на знании нюансов поведения транслятора. Оно не стоит того, чтобы вокруг этого выстраивать примеры кода, шаблоны и продолжать это все развивать и поддерживать.
[quote="Victor__v"]Осталось придумать где такое прототипирование будет наиболее актуальным.[/quote] Очень удобная штука, просто чтобы не заниматься отслеживанием стековых перестановок. Полная аналогия локальных объявлений (не только переменных), с единственным ограничением - рекурсия не будет создавать новый набор локальных переменных, поэтому не поддерживается. Но это как-то ни разу не мешало.
[quote="Victor__v"]в x86 под 64 бита стек 64-битный и ничего с этим не поделать. Стек данных я у себя тоже сделал 64-битным. [/quote] Эмулированный стек - это массив в памяти. Он может быть char, int, int64_t, и какой угодно еще. Сейчас для эмуляции нет смысла рассматривать программы больше 4 Гб размером, поэтому 32 разряда для адреса вполне достаточно. Соответственно, стек возвратов может хранить 32 разряда. Как с этим работает процессор на уровне машинного кода - второй вопрос. Особенно интересно это для переносимого Qt, под который можно собрать ВМ и для 32-разрядного ARM, и тут таскать лишние разряды совершенно не к месту.
В целом манипуляции со стеком возвратов видятся методически неправильными. Да, про это было в ранних волнах публикаций по Форту, особенно чтобы подчеркнуть, что стек возвратов и стек данных - не одно и то же, и в Форте "все можно сделать". Но с тем же успехом данные можно складывать в HERE, рассчитывая, что их пока там никто не испортит, а потом заберем. Это тоже хак, основанный на знании нюансов поведения транслятора. Оно не стоит того, чтобы вокруг этого выстраивать примеры кода, шаблоны и продолжать это все развивать и поддерживать.
|
|
|
|
Добавлено: Пт июл 14, 2023 18:02 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Hishnik писал(а): Нет, они там и остаются, но не видны в поиске после завершения компиляции слова. Код: : newword local[ // включается режим интерпретации, сюда компилируется переход вперед variable x // любые определения, поскольку это обычный режим интерпретации int y : sqr dup * ;
]local // разрешается переход вперед для обхода скомпилированных слов x @ // x виден в поиске, поскольку он уже в словаре y sqr
; // определение завершается, и восстанавливается вход в словарь как он был на момент создания newword
// теперь последним словом будет newword, а созданные внутри него остались в коде, но не могут быть найдены Ну, я тоже подобное могу у себя сделать при этом с удалением словарных структур (слава временным словарям!). Осталось придумать где такое прототипирование будет наиболее актуальным. Hishnik писал(а): Да и в x86 нет, если стеки эмулировать. Разве? в x86 под 64 бита стек 64-битный и ничего с этим не поделать. Стек данных я у себя тоже сделал 64-битным.
[quote="Hishnik"] Нет, они там и остаются, но не видны в поиске после завершения компиляции слова.
[code] : newword local[ // включается режим интерпретации, сюда компилируется переход вперед variable x // любые определения, поскольку это обычный режим интерпретации int y : sqr dup * ;
]local // разрешается переход вперед для обхода скомпилированных слов x @ // x виден в поиске, поскольку он уже в словаре y sqr
; // определение завершается, и восстанавливается вход в словарь как он был на момент создания newword
// теперь последним словом будет newword, а созданные внутри него остались в коде, но не могут быть найдены[/code]
[/quote]
Ну, я тоже подобное могу у себя сделать при этом с удалением словарных структур (слава временным словарям!). Осталось придумать где такое прототипирование будет наиболее актуальным.
[quote="Hishnik"]Да и в x86 нет, если стеки эмулировать.[/quote] Разве? в x86 под 64 бита стек 64-битный и ничего с этим не поделать. Стек данных я у себя тоже сделал 64-битным.
|
|
|
|
Добавлено: Пт июл 14, 2023 17:51 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Victor__v писал(а): Т. е. при определении слова в словаре создаются переменные. А когда слово завершается, словарные структуры переменных удаляются из словаря. Нет, они там и остаются, но не видны в поиске после завершения компиляции слова. Код: : newword local[ // включается режим интерпретации, сюда компилируется переход вперед variable x // любые определения, поскольку это обычный режим интерпретации int y : sqr dup * ;
]local // разрешается переход вперед для обхода скомпилированных слов x @ // x виден в поиске, поскольку он уже в словаре y sqr
; // определение завершается, и восстанавливается вход в словарь как он был на момент создания newword
// теперь последним словом будет newword, а созданные внутри него остались в коде, но не могут быть найдены Victor__v писал(а): Если да, то как это работает с рекурсией?
Hishnik писал(а): Они не реентерабельны, потому что привязаны к глобальным адресам, Victor__v писал(а): Смотря где. В x86 гарантия вот есть) Да и в x86 нет, если стеки эмулировать.
[quote="Victor__v"]Т. е. при определении слова в словаре создаются переменные. А когда слово завершается, словарные структуры переменных удаляются из словаря.[/quote] Нет, они там и остаются, но не видны в поиске после завершения компиляции слова.
[code] : newword local[ // включается режим интерпретации, сюда компилируется переход вперед variable x // любые определения, поскольку это обычный режим интерпретации int y : sqr dup * ;
]local // разрешается переход вперед для обхода скомпилированных слов x @ // x виден в поиске, поскольку он уже в словаре y sqr
; // определение завершается, и восстанавливается вход в словарь как он был на момент создания newword
// теперь последним словом будет newword, а созданные внутри него остались в коде, но не могут быть найдены[/code]
[quote="Victor__v"]Если да, то как это работает с рекурсией? [/quote] [quote="Hishnik"]Они не реентерабельны, потому что привязаны к глобальным адресам,[/quote]
[quote="Victor__v"]Смотря где. В x86 гарантия вот есть) [/quote]
Да и в x86 нет, если стеки эмулировать.
|
|
|
|
Добавлено: Пт июл 14, 2023 16:35 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Цитата: Это они пускай сохраняют. У меня локальные переменные, как и любые слова Форта, могут появляться в виде "тупиковых ответвлений" в словаре внутри определяемого слова. Они не реентерабельны, потому что привязаны к глобальным адресам, просто после завершения определения слова этот созданный "отросток" пропадет из списка поиска. Т. е. при определении слова в словаре создаются переменные. А когда слово завершается, словарные структуры переменных удаляются из словаря. Правильно понял? Если да, то как это работает с рекурсией? Цитата: Но это не гарантия того, что после >R R> не отрежутся старшие разряды. В ПЛИС есть вполне разумный прием экономии на стеке возвратов, если он аппаратный (а это полезно). Так что не все, существовавшее 30-40 лет назад, стоит безоговорочно воспроизводить в современных условиях Смотря где. В x86 гарантия вот есть) Впрочем, кмк, обсуждение данной подтемы бессмысленно. Мы говорим о разных архитектурах и разных форт-системах, а не разрабатываем единый форт-стандарт, который будет работать и на калькуляторе и на квантовом компухтере.
[quote]Это они пускай сохраняют. У меня локальные переменные, как и любые слова Форта, могут появляться в виде "тупиковых ответвлений" в словаре внутри определяемого слова. Они не реентерабельны, потому что привязаны к глобальным адресам, просто после завершения определения слова этот созданный "отросток" пропадет из списка поиска.[/quote]
Т. е. при определении слова в словаре создаются переменные. А когда слово завершается, словарные структуры переменных удаляются из словаря. Правильно понял? Если да, то как это работает с рекурсией?
[quote]Но это не гарантия того, что после >R R> не отрежутся старшие разряды. В ПЛИС есть вполне разумный прием экономии на стеке возвратов, если он аппаратный (а это полезно). Так что не все, существовавшее 30-40 лет назад, стоит безоговорочно воспроизводить в современных условиях[/quote] Смотря где. В x86 гарантия вот есть) Впрочем, кмк, обсуждение данной подтемы бессмысленно. Мы говорим о разных архитектурах и разных форт-системах, а не разрабатываем единый форт-стандарт, который будет работать и на калькуляторе и на квантовом компухтере.
|
|
|
|
Добавлено: Пт июл 14, 2023 12:28 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Victor__v писал(а): Ну а я про что? А дополнительный стек вполне можно. На уровне >L somefunction L> Victor__v писал(а): Которые те же компиляторы мейстримных языков сохраняют на стеке, да.
Это они пускай сохраняют. У меня локальные переменные, как и любые слова Форта, могут появляться в виде "тупиковых ответвлений" в словаре внутри определяемого слова. Они не реентерабельны, потому что привязаны к глобальным адресам, просто после завершения определения слова этот созданный "отросток" пропадет из списка поиска. Victor__v писал(а): Но и не запрещает) Но это не гарантия того, что после >R R> не отрежутся старшие разряды. В ПЛИС есть вполне разумный прием экономии на стеке возвратов, если он аппаратный (а это полезно). Так что не все, существовавшее 30-40 лет назад, стоит безоговорочно воспроизводить в современных условиях.
[quote="Victor__v"]Ну а я про что?[/quote] А дополнительный стек вполне можно. На уровне >L somefunction L>
[quote="Victor__v"]Которые те же компиляторы мейстримных языков сохраняют на стеке, да. [/quote] Это они пускай сохраняют. У меня локальные переменные, как и любые слова Форта, могут появляться в виде "тупиковых ответвлений" в словаре внутри определяемого слова. Они не реентерабельны, потому что привязаны к глобальным адресам, просто после завершения определения слова этот созданный "отросток" пропадет из списка поиска.
[quote="Victor__v"]Но и не запрещает)[/quote] Но это не гарантия того, что после >R R> не отрежутся старшие разряды. В ПЛИС есть вполне разумный прием экономии на стеке возвратов, если он аппаратный (а это полезно). Так что не все, существовавшее 30-40 лет назад, стоит безоговорочно воспроизводить в современных условиях.
|
|
|
|
Добавлено: Чт июл 13, 2023 23:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Hishnik писал(а): Ну уж стек возвратов точно не может использовать куча функций. Ну а я про что? Hishnik писал(а): Кроме того, есть локальные переменные. Которые те же компиляторы мейстримных языков сохраняют на стеке, да. Hishnik писал(а): Там никто не требует делать стеки одинаковой разрядности, потому что они технически разные. Но и не запрещает)
[quote="Hishnik"]Ну уж стек возвратов точно не может использовать куча функций. [/quote] Ну а я про что? [quote="Hishnik"]Кроме того, есть локальные переменные. [/quote] Которые те же компиляторы мейстримных языков сохраняют на стеке, да.
[quote="Hishnik"]Там никто не требует делать стеки одинаковой разрядности, потому что они технически разные.[/quote] Но и не запрещает)
|
|
|
|
Добавлено: Чт июл 13, 2023 21:45 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Victor__v писал(а): А потом может начаться, что куча функций использует этот стек и в самый ответственный момент там лежат левые данные. Это если стек относительно глобальный. Конечно, можно выделить небольшую область в хипе и сохранить указатель на нее в стеке. Но это выглядит переусложнением и не всегда оправдано, ИМХО. Ну уж стек возвратов точно не может использовать куча функций. Поэтому если уж очень хочется завести стек для переноса туда чисел, создающих хаос на основном стеке данных, можно именно такой стек и сделать. Кроме того, есть локальные переменные. Victor__v писал(а): У x86 под 64 бита стек 64-битный. А выше я упомянул форт-процессоры и виртуальные машины. Там никто не требует делать стеки одинаковой разрядности, потому что они технически разные.
[quote="Victor__v"]А потом может начаться, что куча функций использует этот стек и в самый ответственный момент там лежат левые данные. Это если стек относительно глобальный. Конечно, можно выделить небольшую область в хипе и сохранить указатель на нее в стеке. Но это выглядит переусложнением и не всегда оправдано, ИМХО.[/quote] Ну уж стек возвратов точно не может использовать куча функций. Поэтому если уж очень хочется завести стек для переноса туда чисел, создающих хаос на основном стеке данных, можно именно такой стек и сделать.
Кроме того, есть локальные переменные.
[quote="Victor__v"]У x86 под 64 бита стек 64-битный.[/quote] А выше я упомянул форт-процессоры и виртуальные машины. Там никто не требует делать стеки одинаковой разрядности, потому что они технически разные.
|
|
|
|
Добавлено: Чт июл 13, 2023 19:01 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Hishnik писал(а): Если уж так нужен дополнительный стек для временного перебрасывания туда данных, можно отдельно его и ввести. А потом может начаться, что куча функций использует этот стек и в самый ответственный момент там лежат левые данные. Это если стек относительно глобальный. Конечно, можно выделить небольшую область в хипе и сохранить указатель на нее в стеке. Но это выглядит переусложнением и не всегда оправдано, ИМХО. Hishnik писал(а): А я давно отвык так делать, потому что в форт-процессоре с аппаратным стеком возвратом нет смысла делать его под 32 бита основных данных (достаточно 16, это заметная экономия ресурсов), а в 64-битном трансляторе отводить под адрес 64 бита тоже странно. Пусть даже памяти не жалко, читать 64 бита, из которых старшие заведомо нули - это же еще и падение скорости. Вообще не нужны вот эти хаки на уровне "ну все же знают, как оно устроено". После набора критической массы таких "ну все же знают" образуется каша с перекрестными побочными эффектами. У x86 под 64 бита стек 64-битный. И как бы, если хранить на стеке кучу значений, то логично использовать слово для автоочистки стека. Как там было... POP RBX CALL RBX POP RSP RET
[quote="Hishnik"]Если уж так нужен дополнительный стек для временного перебрасывания туда данных, можно отдельно его и ввести. [/quote]
А потом может начаться, что куча функций использует этот стек и в самый ответственный момент там лежат левые данные. Это если стек относительно глобальный. Конечно, можно выделить небольшую область в хипе и сохранить указатель на нее в стеке. Но это выглядит переусложнением и не всегда оправдано, ИМХО.
[quote="Hishnik"]А я давно отвык так делать, потому что в форт-процессоре с аппаратным стеком возвратом нет смысла делать его под 32 бита основных данных (достаточно 16, это заметная экономия ресурсов), а в 64-битном трансляторе отводить под адрес 64 бита тоже странно. Пусть даже памяти не жалко, читать 64 бита, из которых старшие заведомо нули - это же еще и падение скорости. Вообще не нужны вот эти хаки на уровне "ну все же знают, как оно устроено". После набора критической массы таких "ну все же знают" образуется каша с перекрестными побочными эффектами.[/quote]
У x86 под 64 бита стек 64-битный. И как бы, если хранить на стеке кучу значений, то логично использовать слово для автоочистки стека. Как там было... POP RBX CALL RBX POP RSP RET
|
|
|
|
Добавлено: Чт июл 13, 2023 18:00 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Если уж так нужен дополнительный стек для временного перебрасывания туда данных, можно отдельно его и ввести. А я давно отвык так делать, потому что в форт-процессоре с аппаратным стеком возвратом нет смысла делать его под 32 бита основных данных (достаточно 16, это заметная экономия ресурсов), а в 64-битном трансляторе отводить под адрес 64 бита тоже странно. Пусть даже памяти не жалко, читать 64 бита, из которых старшие заведомо нули - это же еще и падение скорости. Вообще не нужны вот эти хаки на уровне "ну все же знают, как оно устроено". После набора критической массы таких "ну все же знают" образуется каша с перекрестными побочными эффектами.
Если уж так нужен дополнительный стек для временного перебрасывания туда данных, можно отдельно его и ввести. А я давно отвык так делать, потому что в форт-процессоре с аппаратным стеком возвратом нет смысла делать его под 32 бита основных данных (достаточно 16, это заметная экономия ресурсов), а в 64-битном трансляторе отводить под адрес 64 бита тоже странно. Пусть даже памяти не жалко, читать 64 бита, из которых старшие заведомо нули - это же еще и падение скорости. Вообще не нужны вот эти хаки на уровне "ну все же знают, как оно устроено". После набора критической массы таких "ну все же знают" образуется каша с перекрестными побочными эффектами.
|
|
|
|
Добавлено: Чт июл 13, 2023 17:33 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Hishnik писал(а): Стек возвратов выглядит как "недокументированная возможность". Это по архитектурным соображениям неправильно - есть управление выполнением, а есть работа с данными. С самого начала в Форте стеки разделены, и вдруг начинается >R R>. А если у этих стеков разные разрядности, то это источник труднообнаружимых ошибок. Как бы сказать... Кучи других языков хранят данные стеке. Можно ввести еще несколько стеков, не вопрос. Но как мне кажется преимущество стека возвратов в форте в том, что в него без нужды (или понимания как оно работает) никто не лезет.
[quote="Hishnik"]Стек возвратов выглядит как "недокументированная возможность". Это по архитектурным соображениям неправильно - есть управление выполнением, а есть работа с данными. С самого начала в Форте стеки разделены, и вдруг начинается >R R>. А если у этих стеков разные разрядности, то это источник труднообнаружимых ошибок.[/quote] Как бы сказать... Кучи других языков хранят данные стеке.
Можно ввести еще несколько стеков, не вопрос. Но как мне кажется преимущество стека возвратов в форте в том, что в него без нужды (или понимания как оно работает) никто не лезет. :D
|
|
|
|
Добавлено: Чт июл 13, 2023 17:23 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Стек возвратов выглядит как "недокументированная возможность". Это по архитектурным соображениям неправильно - есть управление выполнением, а есть работа с данными. С самого начала в Форте стеки разделены, и вдруг начинается >R R>. А если у этих стеков разные разрядности, то это источник труднообнаружимых ошибок.
Стек возвратов выглядит как "недокументированная возможность". Это по архитектурным соображениям неправильно - есть управление выполнением, а есть работа с данными. С самого начала в Форте стеки разделены, и вдруг начинается >R R>. А если у этих стеков разные разрядности, то это источник труднообнаружимых ошибок.
|
|
|
|
Добавлено: Ср июл 12, 2023 17:52 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Hishnik писал(а): Такую операцию можно вставить и в словарь. Ну да, SPLIT у меня с самого начала весьма полезное слово) У меня есть даже слово для конкатенации 2 строк на стеке возвратов 2MOVE->R Как говорится дешево и сердито.
[quote="Hishnik"]Такую операцию можно вставить и в словарь.[/quote] Ну да, SPLIT у меня с самого начала весьма полезное слово) У меня есть даже слово для конкатенации 2 строк на стеке возвратов 2MOVE->R Как говорится дешево и сердито.
|
|
|
|
Добавлено: Ср июл 12, 2023 16:19 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
KPG писал(а): Задача разделения строк(и) текста на токены по разделителю "," (запятая) Вход: ( addr len ) \ s" Hello,How,Are,You,Today" Вывод тестовой печати: Hello.How.Are.You.Today Решение: https://rosettacode.org/wiki/Tokenize_a_string#ForthЛегкотня. Код для Nova-forth Код: : SPLIT-ITER: \ a1 l1 a2 l2 \ xt: a3 l3 2>R BEGIN 2R@ SPLIT 0= IF 3 RPICK EXECUTE RDROP RDROP RDROP EXIT THEN
2>R 5 RPICK EXECUTE 2R> AGAIN ;
: SPLIT-TYPE S" ," SPLIT-ITER: TYPE ;
S" Hello,How,Are,You,Today" SPLIT-TYPE
[quote="KPG"]Задача разделения строк(и) текста на токены по разделителю "," (запятая) Вход: ( addr len ) \ s" Hello,How,Are,You,Today" Вывод тестовой печати: Hello.How.Are.You.Today Решение: https://rosettacode.org/wiki/Tokenize_a_string#Forth [/quote]
Легкотня. Код для Nova-forth
[code] : SPLIT-ITER: \ a1 l1 a2 l2 \ xt: a3 l3 2>R BEGIN 2R@ SPLIT 0= IF 3 RPICK EXECUTE RDROP RDROP RDROP EXIT THEN
2>R 5 RPICK EXECUTE 2R> AGAIN ;
: SPLIT-TYPE S" ," SPLIT-ITER: TYPE ;
S" Hello,How,Are,You,Today" SPLIT-TYPE
[/code]
|
|
|
|
Добавлено: Ср июл 12, 2023 16:09 |
|
|
|
|
|
Заголовок сообщения: |
Re: Список актуальных задач из Rosetta code |
|
|
Такую операцию можно вставить и в словарь.
Такую операцию можно вставить и в словарь.
|
|
|
|
Добавлено: Ср июл 12, 2023 16:07 |
|
|
|
|
|
Заголовок сообщения: |
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
Задача разделения строк(и) текста на токены по разделителю "," (запятая) Вход: ( addr len ) \ s" Hello,How,Are,You,Today" Вывод тестовой печати: Hello.How.Are.You.Today Решение: https://rosettacode.org/wiki/Tokenize_a_string#Forth
[code]: 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[/code]
В строке словом [b]Search [/b] находятся токены по разделителю и адрес и длина найденных токенов в реализации слова [b]split [/b] записывается по адресу Here (для временного сохранения в области памяти), а по завершению сканирования строки слово [b]Split [/b]оставляет после себя адрес Here и количество найденных токенов. (токен представлен 2-я числами - addr len) а сам адрес Here востанавливается на момент вызова слова Split.
P.S. В gForth Online код выполняется.
Если просто вывести строку с заменой символа "," на "." без деления на токены при этом то решение может быть таким. [code]: 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>[/code] Исходная строка, при этом сохранена по Here адресу до момента изменения этой области памяти. [code] here dup c@ type [/code]
|
|
|
|
Добавлено: Ср июл 12, 2023 10:08 |
|
|
|
|