Как построить простой генератор в Форт? - PullRequest
0 голосов
/ 18 декабря 2018

Моей целью было построить генератор простых чисел в Форте.Не сито Эратосфена, а два вложенных цикла, которые брутфорсируют все комбинации чисел А и В. В исходном коде у меня есть слово для цикла, для проверки, является ли условие истинным, а также некоторая попытка выполнить вложенный цикл.Но после выполнения кода с помощью gforth отображается ошибка переполнения стека.Может быть, где-то отсутствует какое-то дублирование, но также возможно, что индексы i и j в циклах неверны.Проблема в том, что если я что-то изменю в коде, стек будет другим.Это означает, что после вывода на экран индексного числа цикла for невозможно получить доступ к этому номеру.Также я нахожу, что трудно получить доступ к переменным, потому что Форт, кажется, вообще не имеет переменных.Поэтому я создал вспомогательную переменную, но неясно, как ее использовать.

Я знаю, код выглядит немного запутанным, кто-нибудь может помочь?

variable temp
: numbers
  10 0 do i . loop
;
: cond
  0 dup
  0 = if ." equal 0" endif
;
: plain
10 2 mod .
10 3 mod .
10 4 mod .
10 5 mod .
10 6 mod .
10 7 mod .
10 8 mod .
10 9 mod .
;
: plain2
10 temp !
\ 10 0 do temp @ i mod . loop
\ 10 0 do temp @ . i . loop
10 2 do temp @ i mod . cond loop
;
: cond2 ( n - n )
  10 2 do i 
  10 2 do i 
  mod .
  loop cr loop
;

: main
  \ numbers
  cond2
  \ plain
  \ plain2
;
main
CR bye

1 Ответ

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

В вашем коде есть несколько ошибок и повторений.Например, в вашем слове cond вы помещаете 0 в стек данных, затем dup его и сравниваете верхнее значение стека (которое составляет 0) с 0.Конечно, вы будете получать true каждый раз.

Кажется, что вы пытаетесь написать много определений слов одновременно и использовать их в своей программе без тщательной отладки каждого слова.При Forth программировании лучше составить (и отладить) несколько коротких слов, а затем составить из них более сложный код.Я бы рекомендовал вам прочитать Starting Forth book , в которой очень хорошо описан этот подход.

Что касается вашего кода - лучше переписать его полностью.Вот оно:

: is-not-divided-by mod 0= INVERT ;

: check-prime-number true SWAP DUP 2 DO DUP I is-not-divided-by ROT AND SWAP loop DROP ;

: is-prime-number DUP 2 > IF check-prime-number ELSE DROP true THEN ; 

: prime-numbers 1 DO I is-prime-number IF I . THEN LOOP ;

и теперь 10 prime-numbers будет печатать простые числа от 1 до 9.

...