Search code examples
arraysrandomstackforthgforth

Problems with setting array elements in Forth


I am writing code in Forth that should create a 12x12 array of random numbers from 1 to 8.

create big_array 144 allocate drop
: reset_array big_array 144 0 fill ;
reset_array 
variable rnd here rnd !
: random rnd @ 31421 * 6927 + dup rnd ! ;
: choose random um* nip ;
: random_fill 144 1 do 8 choose big_array i + c! loop ;
random_fill
: Array_@ 12 * + big_array swap + c@ ;
: show_small_array cr 12 0 do 12 0 do i j Array_@ 5 u.r loop cr loop ;
show_small_array

However, I notice that elements 128 to 131 of my array are always much larger than expected:

0    4    0    4    2    6    0    5    2    5    7    3
6    3    7    3    7    7    3    1    5    0    6    1
0    3    3    0    3    1    0    7    2    0    4    5
3    7    6    6    2    1    0    2    3    4    2    7
4    7    1    5    3    5    7    2    3    5    3    6
3    0    6    4    1    3    3    2    5    4    4    7
3    2    1    4    3    4    3    7    2    6    5    5
2    4    4    3    4    5    4    4    6    5    6    0
2    5    2    7    3    1    5    0    1    4    6    7
2    0    3    3    0    7    3    6    4    1    3    6
0    1    1    6    0    3    0    2  169  112   41   70
7    2    3    1    2    2    7    6    0    5    1    2

Moreover, when I try to change the value of these elements individually, this causes the other three elements to change value. For example, if I code:

9 choose big_array 128 + c!

then the array will become:

0    4    0    4    2    6    0    5    2    5    7    3
6    3    7    3    7    7    3    1    5    0    6    1
0    3    3    0    3    1    0    7    2    0    4    5
3    7    6    6    2    1    0    2    3    4    2    7
4    7    1    5    3    5    7    2    3    5    3    6
3    0    6    4    1    3    3    2    5    4    4    7
3    2    1    4    3    4    3    7    2    6    5    5
2    4    4    3    4    5    4    4    6    5    6    0
2    5    2    7    3    1    5    0    1    4    6    7
2    0    3    3    0    7    3    6    4    1    3    6
0    1    1    6    0    3    0    2    2   12  194   69
7    2    3    1    2    2    7    6    0    5    1    2

Do you have any idea why these specific elements are always impacted and if there is a way to prevent this?


Solution

  • Better readability and less error prone: 144 allocate144 chars allocate

    A mistake: create big_array 144 allocate dropcreate big_array 144 chars allot

    A mistake: random um* niprandom swap mod

    A mistake: 144 1 do144 0 do

    An excessive operation: big_array swap +big_array +

    And add the stack comments, please. Especially, when you ask for help.

    Do you have any idea why these specific elements are always impacted and if there is a way to prevent this?

    Since you try to use memory in the dictionary space without reserving it. This memory is used by the Forth system.