Как мне создать массив в Forth? - PullRequest
0 голосов
/ 09 января 2019

Я знаю, вопрос часто задавался в прошлом, и, возможно, информация была дана в предыдущих публикациях переполнения стека. Но изучение Forth - очень сложная задача, и повторение помогает понять преимущества конкатенативного языка программирования по сравнению с альтернативными языками, такими как C.

Из уроков Forth я узнал, что Forth не предоставляет команды для создания 2D-массива, но пользователь должен реализовать все с нуля в программе. Я нашел два варианта в памяти Forth. Сначала создав новое слово:

: namelist s” hello” s” world” ;

или, во-вторых, оператором CREATE:

create temperature 10 allot
temperature 10 cells dump

Пока все хорошо; мы создали массив из 10 ячеек, в котором можно хранить целочисленные переменные. Но что, если мне нужно сохранить числа с плавающей запятой? Должен ли я всегда преобразовывать float в int или они могут быть сохранены в обычные ячейки?

Другая открытая проблема - как хранить строковые значения в массиве. Насколько я знаю, строка содержит указатель плюс размер. Так что теоретически я могу хранить только 5 строк в массиве из 10 ячеек, и дополнительно мне нужна память где-то еще, которая содержит саму строку. Это не имеет особого смысла.

Существует ли какая-либо более высокая абстракция для хранения значений в массивах, которые можно использовать для написания легко читаемых программ? Я имею в виду, что если каждый программист использует свой собственный метод Forth для хранения чего-либо в памяти, другим программистам будет трудно читать код.

Ответы [ 3 ]

0 голосов
/ 13 января 2019

Ты запутался в строках. Строка просто входит в память, и память по этому адресу выделяется для этой строки, и она там навсегда (если вы не измените это).

Так что, если вы хотите сохранить 5 (c-addr u) строк в выделенном блоке памяти (называть это массивом - это немного растянуть), вы можете просто сохранить c-addr в ячейке n и длина u в ячейке n + 1 .

Если вас беспокоит, что 10 ячеек занимают много места (на самом деле беспокоиться не о чем) и вы хотите использовать только 5 ячеек, вы можете хранить свои строки в виде подсчитанных строк, используя такие слова, как C" - подсчитанные строки хранить длину в первом байте, каждый последующий байт является символом.

Кроме того, вы можете хранить вещи в словаре на текущий момент dp, используя слово , (запятая).

0 голосов
/ 23 января 2019

Обобщенный 2-й массив элементов. Принимает размер элемента в качестве параметра

\ size is the per element multiplier
\ n size * is the per_row factor
\ m n size * * is the total space required

: 2darray  \ create>  m n size -- ; does> mix nix -- a
\  size is the number of bytes for one element
\  
  create  2dup * ,      \ multiplier to apply to m index 
          dup ,         \ multiplier to apply to n index
          * * allot     \ calculate total bytes and allot them
  does>  \ mix nix a 
    >r r@ cell+ @ *     \ offset from n index  
       swap r@ @ * +    \ offset with m index
   r> + 2 cells+        \ 2 cells offset for the 'admin' cells
;

Примеры

50 40 /float 2darray 50x40floats
50 40 2 cells 2darray 50x40stringpairs

даже

20 constant /record
10 200 /record 2darray 2000records
0 голосов
/ 09 января 2019

create создает слово, которое возвращает адрес буфера в словаре (пространство данных); изначально это нулевая длина, поэтому вы должны зарезервировать для нее необходимое место сразу.

allot резервирует пространство, которое измеряется в единицах адреса (обычно в байтах), поэтому необходимо рассчитать требуемый размер в байтах.

Например:

create a 10 cells allot
create b 10 floats allot
Это всего лишь буферы, и вам все равно нужно иметь дело с арифметикой указателей, чтобы получить или установить элемент, например:
0.35e  2 floats b +  f! \ store the float number into third item (0-based indexing)

Пример слова, которое создает в словаре массив чисел с плавающей запятой:

: create-floats-array ( length "name" -- ) create floats allot does> swap 1- floats + ;

10 create-floats-array c

0.35e  3 c f! \ store the float number into third item (1-based indexing)
3 c f@ f. \ print float number form third item

Если вам нужно много массивов и много строк, лучше использовать соответствующие библиотеки. Например, см. Модуль массива ячеек и Модуль динамической текстовой строки из Forth Foundation Library .

...