From 17be0a6c893eae3d4fcbd859f0fce23d72f35862 Mon Sep 17 00:00:00 2001 From: Koichi Nakamura Date: Sun, 17 Jan 2021 21:09:29 +0900 Subject: [PATCH 1/3] Fixed bug of (free) --- bootstrap.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.fs b/bootstrap.fs index 41d044b..3532fd7 100644 --- a/bootstrap.fs +++ b/bootstrap.fs @@ -2400,7 +2400,7 @@ BLOCK-SIZE remaining-size ! ; \ Bootstrapping version of free do nothing. -: (free) ( addr -- ) ; +: (free) ( addr -- ) drop ; ( === File I/O === ) From d75afc11c1c942783fc6438f514ad238abfc1e3c Mon Sep 17 00:00:00 2001 From: Koichi Nakamura Date: Sun, 17 Jan 2021 23:29:25 +0900 Subject: [PATCH 2/3] Add check-argument --- lib/core.fs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/core.fs b/lib/core.fs index 66821a8..cfa6e6d 100644 --- a/lib/core.fs +++ b/lib/core.fs @@ -19,3 +19,9 @@ defined? roll [unless] s" }T" streq if exit then again ; + +s" Invalid argument" exception constant INVALID-ARGUMENT + +: check-argument ( f -- ) + unless INVALID-ARGUMENT throw then +; From 3a857b0e6a1bc291d6aca0d885d1a7ba31b9435b Mon Sep 17 00:00:00 2001 From: Koichi Nakamura Date: Sun, 17 Jan 2021 23:29:51 +0900 Subject: [PATCH 3/3] Add lib/array.fs --- lib/array.fs | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++ runtests.fs | 1 + 2 files changed, 138 insertions(+) create mode 100644 lib/array.fs diff --git a/lib/array.fs b/lib/array.fs new file mode 100644 index 0000000..0109daf --- /dev/null +++ b/lib/array.fs @@ -0,0 +1,137 @@ +\ planckforth - +\ Copyright (C) 2021 nineties + +( === Variable Length Array === ) + +private{ + +( === Allocation strategy === ) +defined? array-alloc-strategy [unless] + +\ Compute new capacity +: array-alloc-strategy ( u1 -- u2 ) + dup 0= if 4 else 2 * then +; + +[then] + +struct + ptr% field array>buf + int% field array>size + int% field array>capa +end-struct array% + +s" Index out of range" exception constant OUT-OF-RANGE export + +\ Allocate array with capacity +: allocate-array ( n capa -- arr ) + array% %allocate throw + ( n capa addr ) + over cells allocate throw over array>buf ! + swap over array>capa ! + swap over array>size ! +; + +: make-array ( n -- arr ) + dup 0>= check-argument + \ compute capa + dup 0= if 10 else dup then + allocate-array +; export + +: array-size ( arr -- n ) array>size @ ; export + +: check-index ( i arr -- ) + over 0< if OUT-OF-RANGE throw then + array-size >= if OUT-OF-RANGE throw then +; + +: array@ ( i arr -- w ) + 2dup check-index + array>buf @ swap cells + @ +; export + +: array! ( v i arr -- ) + 2dup check-index + array>buf @ swap cells + ! +; export + +: array-reallocate ( capa arr -- ) + over cells allocate throw + \ copy elements to new buffer + over array>buf @ over 3 pick array>size @ cells memcpy + over array>buf @ free + over array>buf ! + over over array>capa ! + 2drop +; + +: array-resize ( n arr -- ) + over 0>= check-argument + 2dup array>capa @ < if + \ If n is smaller than the capacity + \ just change array>size + array>size ! + exit + else + 2dup array-reallocate + array>size ! + then +; export + +: array-push ( w arr -- ) + dup array>size @ over array>capa @ >= if + dup array>capa @ array-alloc-strategy + ( w arr new-capa ) + over array-reallocate + then + swap ( arr w ) + over array>buf @ 2 pick array>size @ cells + ! + array>size 1 swap +! +; export + +: array-pop ( arr -- w ) + dup array-size 0> unless OUT-OF-RANGE throw then + 1 over array>size -! + dup array-size cells swap array>buf @ + @ +; export + + +}private + +T{ -1 ' make-array catch -> -1 INVALID-ARGUMENT }T + +T{ 0 make-array constant A -> }T +T{ A array-size -> 0 }T +T{ 0 A ' array@ catch -> 0 A OUT-OF-RANGE }T +T{ 1 0 A ' array! catch -> 1 0 A OUT-OF-RANGE }T +T{ A ' array-pop catch -> A OUT-OF-RANGE }T + +T{ :noname 100 0 do i A array-push loop ; execute -> }T + +T{ A array-size -> 100 }T +T{ 0 A array@ -> 0 }T +T{ 5 A array@ -> 5 }T +T{ 10 A array@ -> 10 }T +T{ 50 A array@ -> 50 }T +T{ 99 A array@ -> 99 }T + +T{ A array-pop -> 99 }T +T{ A array-size -> 99 }T +T{ A array-pop -> 98 }T +T{ A array-size -> 98 }T + +T{ -1 A ' array-resize catch -> -1 A INVALID-ARGUMENT }T +T{ 5 A array-resize -> }T +T{ A array-size -> 5 }T +T{ 100 A array-resize -> }T +T{ A array-size -> 100 }T + +T{ 1 -1 A ' array! catch -> 1 -1 A OUT-OF-RANGE }T +T{ 1 100 A ' array! catch -> 1 100 A OUT-OF-RANGE }T +T{ -1 A ' array@ catch -> -1 A OUT-OF-RANGE }T +T{ 100 A ' array@ catch -> 100 A OUT-OF-RANGE }T +T{ 1 0 A array! -> }T +T{ 0 A array@ -> 1 }T +T{ 2 99 A array! -> }T +T{ 99 A array@ -> 2 }T diff --git a/runtests.fs b/runtests.fs index 38ab946..932dc87 100644 --- a/runtests.fs +++ b/runtests.fs @@ -14,6 +14,7 @@ include test/errorreport.fs include test/coreexttest.fs include test/export.fs +include lib/array.fs report-errors report-and-exit