@@ -85,24 +85,39 @@ array: func [
85
85
size [integer! block! ] "Size or block of sizes for each dimension"
86
86
/initial "Specify an initial value for all elements"
87
87
value "Initial value (will be called each time if a function)"
88
- /local block rest
88
+ /local block rest word
89
+ /with tag indexes ; Token to ensure internal use, and block of index expressions
89
90
] [
91
+ unless same? :tag 'tag [with: tag: indexes: none] ; Enforced internal option
90
92
if block? size [
93
+ if all [not with any-function? :value ] [ ; Make indexes to pass to function
94
+ indexes: append /dup make block! 2 * length? size [index? block] length? size
95
+ ]
91
96
if tail? rest: next size [rest: none]
92
97
unless integer? set /any 'size first size [
93
98
cause-error 'script 'expect-arg reduce ['array 'size type? :size ]
94
99
]
95
100
]
96
101
block: make block! size
97
102
case [
98
- block? rest [
99
- loop size [block: insert /only block array/initial rest :value ]
103
+ block? :rest [
104
+ either any-function? :value [ ; Must construct params to pass to function
105
+ word: in make object! copy [x: block] 'x ; Make a persistent word for this level
106
+ indexes: change next indexes word ; Put that word in the params block
107
+ loop size [ ; Pass indexes block to recursive call, at that level's position
108
+ set word insert /only get word array/initial/with rest :value 'tag indexes
109
+ ]
110
+ block: get word
111
+ ] [ ; Regular value, no parameter handling needed
112
+ loop size [block: insert /only block array/initial rest :value ]
113
+ ]
100
114
]
101
115
series? :value [
102
116
loop size [block: insert /only block copy/deep value]
103
117
]
104
- any-function? :value [ ; So value can be a thunk :)
105
- loop size [block: insert /only block value] ; Called every time
118
+ any-function? :value [
119
+ unless indexes [indexes: [index? block]] ; Single dimension, single index
120
+ loop size [block: insert /only block apply :value head indexes]
106
121
]
107
122
insert /dup block value size
108
123
]
@@ -423,8 +438,8 @@ printf: func [
423
438
split : func [
424
439
"Split a series into pieces; fixed or variable size, fixed number, or at delimiters"
425
440
series [series! ] "The series to split"
426
- dlm [block! integer! char! bitset! any-string! ] "Split size, delimiter(s), or rule(s)."
427
- /pieces "If dlm is an integer, split into n pieces, rather than pieces of length n."
441
+ dlm [block! integer! char! bitset! any-string! ] "Split size, delimiter(s), or rule(s)."
442
+ /into "If dlm is an integer, split into n pieces, rather than pieces of length n."
428
443
/local size piece-size count mk1 mk2 res fill-val add-fill-val
429
444
] [
430
445
either all [block? dlm parse dlm [some integer! ]] [
@@ -441,7 +456,7 @@ split: func [
441
456
size: dlm ; alias for readability
442
457
res: collect [
443
458
parse/all series case [
444
- all [integer? size pieces ] [
459
+ all [integer? size into ] [
445
460
if size < 1 [cause-error 'Script 'invalid-arg size]
446
461
count: size - 1
447
462
piece-size: to integer! round/down divide length? series size
@@ -460,14 +475,14 @@ split: func [
460
475
]
461
476
]
462
477
]
463
- ; Special processing, to handle cases where the spec'd more items in
464
- ; /pieces than the series contains (so we want to append empty items),
465
- ; or where the dlm was a char/string/charset and it was the last char
466
- ; (so we want to append an empty field that the above rule misses).
478
+ ;-- Special processing, to handle cases where the spec'd more items in
479
+ ; /into than the series contains (so we want to append empty items),
480
+ ; or where the dlm was a char/string/charset and it was the last char
481
+ ; (so we want to append an empty field that the above rule misses).
467
482
fill-val : does [copy either any-block? series [[]] ["" ]]
468
483
add-fill-val : does [append /only res fill-val]
469
484
case [
470
- all [integer? size pieces ] [
485
+ all [integer? size into ] [
471
486
; If the result is too short, i.e., less items than 'size, add
472
487
; empty items to fill it to 'size.
473
488
; We loop here, because insert/dup doesn't copy the value inserted.
@@ -482,7 +497,7 @@ split: func [
482
497
; implied empty field after it, which we add here.
483
498
case [
484
499
bitset? dlm [
485
- ; ATTEMPT is here because LAST will return NONE for an
500
+ ; ATTEMPT is here because LAST will return NONE for an
486
501
; empty series, and finding none in a bitest is not allowed.
487
502
if attempt [find dlm last series] [add-fill-val]
488
503
]
@@ -498,7 +513,7 @@ split: func [
498
513
]
499
514
]
500
515
]
501
-
516
+
502
517
res
503
518
]
504
519
]
0 commit comments