如何在forth中实现矢量或动态数组?



我需要一个动态数组,但我不知道如何实现它。我在网上搜索了一下,也找不到任何结果。我对forth很陌生,刚刚开始学习。我想我可以使用一个变量来存储长度,并分配更多,但我不知道这是否有效,因为我也能够在数组的分配空间之外写入。

这取决于你真正需要什么。下面是创建动态单元格数组的代码。快速测试在VFX Forth和GForth。可能有更整洁更好的优化版本。

0 [IF]
dynamic array is an address stored in the dictionary pointing to 
a structure stored in allocated memory 
0 CELL    data size in bytes  n CELLS 
1 CELL    start of data
...
n CELL    End of data 
[THEN]
 Take dictionary address and return addresses of the array 
: array-size    a -- n ;
@ @ ;
: array-data     a -- a' ;
@ CELL + ;
 **********************************************************
 **********************************************************
 Expand the data structure and copy the 'old' data into it.
 This either expands the data to size or to twice the 
 original size whichever is larger.   
 ALLOCATE THROW and FREE THROW catch & report any memory 
 errors. 
 **********************************************************
: dyn-expand    size a-dict -- ;
DUP >R
array-size 2* MAX              new-size  = largest of the ix offset 
 or 2 * current size.
DUP CELL + ALLOCATE THROW     ( new-size new-addr )
2DUP CELL + SWAP ERASE         zero the newly allocated memory
R@ array-data OVER CELL + R@ array-size    
( size new-addr old-data-a new-data-a old-size )
MOVE     Shift existing data to the new addr.   ( size new-addr )
R@ @ FREE THROW       Free the old data's memory
TUCK !                Store the new size
R> ! ;             Store the new address in the dictionary
: dynamic-array    CREATE: count -- ; DOES> ix -- a
 Creates a dynamic array of count cells in ALLOCATED memory.  
CREATE    count -- ;
CELLS DUP CELL + ALLOCATE THROW   ( count addr )
DUP ,                       Store the data address in the dictionary
2DUP !                      Store the data size in the allocated memory                    
CELL + SWAP ERASE           Zero the new data region. 
DOES>    ix -- addr-of-ix-cell ;
 Returns the address of the ix th cell.  Expanding the array if required.
( ix a )
SWAP CELLS SWAP 2DUP array-size >= IF    ix not in allocated range
2DUP dyn-expand
THEN   
( ix-cells a )  array-data + ;
: dyn-stats.    a -- ; Prints base address and array size 
." Base data address: " DUP .
." Data size in bytes: " CELL - @ . ;

快速测试和使用:

16 dynamic-array ]test   ok
456 0 ]test !    4560  10 ]test !  ok
CR 0 ]test dyn-stats.  ." 0th and 10th Data: " 0 ]test @ . 10 ]test @ .  CR 
Base data address: 9459864 Data size in bytes: 128 0th and 10th Data: 456 4560 
*******                     ***
ok
1600  16 ]test !    This extends the array.  ok
CR 0 ]test dyn-stats.  ." 0th and 10th Data: " 0 ]test @ . 10 ]test @ .  CR 
Base data address: 10502952 Data size in bytes: 256 0th and 10th Data: 456 4560 
ok                ******** Address Changed     *** & size changed    unchanged!!
." 16th data: " 16 ]test @ .  16th data: 1600  ok

相关内容

  • 没有找到相关文章

最新更新