r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3]

Robert
4-Jul-2011
[9162x2]
Thanks Peter.
- I / RMA will be the main communication channel. I have access to 
Rebol-3 twitter and there exists a RMA twitter.

- We will continue to work on the R3-GUI and release it as we did 
before (sometimes there might be longer periods of no-release, if 
we are doing massive changes)

- The main focus will be: fixing bugs, defining and writing down 
how datatypes are handled WRT conversion, priority, sorting etc.
shadwolf
6-Jul-2011
[9164x7]
NDA ?
LOL  AFTER 111 version there zill be a NDA ( non disclosure agreement) 
but non disclosure agreement to disclose what the  emptyness  of 
nothingness ?  go ahead  please :)
Robert I'm happy you say you will continue to work on r3-gui but 
will that work produce some result  ?
Carl didn't lost interrest ?? aaaaaaaaahahaha who do you think you 
are fooling Robert serriously ?
wasn't carl some moth ago that was saying the rebol was a commercial 
faillure and that he needed tto get a real work to feed his familly 
?
aaaaaaaaahahaah isn't that called loosing interest  ?
I laughed so much that I'm impatient to comeback in september to 
see the bunch of new jokes you will have in stock
Rebolek
7-Jul-2011
[9171]
Where he said, that it's a commercial failure?
Kaj
7-Jul-2011
[9172]
In Alphe's imagination
Geomol
15-Jul-2011
[9173]
Can R3 load and use shared libraries like R2 with load/library ?


I see a group named "!REBOL3 /library". Is that about such libraries, 
or are extensions for that? (Group "!REBOL3 Extensions".)
Pekr
15-Jul-2011
[9174x2]
There was a bounty, and attempt from Max (not finished IIRC), to 
bring R2 like DLL interface to R3, to simplify it for users not being 
able to utilise full extension interface.
Some ppl found out, that using extension interface is not so hard 
as it seems though ...
Geomol
15-Jul-2011
[9176x2]
Has it been tried to get the source for R2's load/library, make routine! 
and then the calling from Carl? That seems to me to be a lot easier 
to start with that code, as it do work.
I know, it has been tried many times to get sources, but maybe he 
would agree on such a specific case, as it would be needed in R3 
anyway.
Robert
15-Jul-2011
[9178]
Converting a R2 DLL into a R3 one is really simple. I have done our 
DLLs in a way that I can compile them as R2 or R3 version. The only 
change is a .DEF file for the linker. Everything else is the same.
Geomol
15-Jul-2011
[9179]
I think about others DLLs, like OpenGL.
Robert
15-Jul-2011
[9180]
To make them into a R3 extension is pretty simple. The R3 external 
interface is way simpler than in R2. So, yes, via IMPORT and R3 extension.
Geomol
15-Jul-2011
[9181x2]
Ok, I get this error:


>> opengl: import %/System/Library/Frameworks/OpenGL.framework/OpenGL

** syntax error: script is missing a REBOL header: %/System/Library/Frameworks/OpenGL.framework/OpenGL

So such DLLs need to be wrapped in some REBOL code, or?
There is some doc here:

http://www.rebol.com/r3/docs/concepts/extensions-making.html#section-19


As I read it, I would need to write an extension to access external 
APIs like standard OS libraries.
Pekr
15-Jul-2011
[9183]
Geomol - yes, you need to write a wrapper for each DLL you are about 
to utilise ...
Andreas
15-Jul-2011
[9184]
Geomol, yes, the "!REBOL3 /library" group is about R2/Library-style 
access to DSOs. I.e. using pre-existing DSOs from within REBOL.


The "!REBOL3 Extensions" group is for discussion about native R3 
 extensions. I.e. writing special-purpose DSOs which can export native-like 
functions into R3.
Henrik
16-Jul-2011
[9185x2]
http://curecode.org/rebol3/ticket.rsp?id=1888&cursor=1

This doesn't look like a bug to me. Anyone?
http://curecode.org/rebol3/ticket.rsp?id=1886&cursor=3

This one looks fixable, as it's a mezzanine.
Steeve
16-Jul-2011
[9187]
About parse: Always been like that, nothing new.
BrianH
16-Jul-2011
[9188]
#1888 is definitely not a bug. #1886 should be looked at by the person 
who knows what SPLIT is supposed to do. It wasn't one of mine, and 
there was never really any consensus about its behavior. SPLIT isn't 
finished yet.
Gregg
17-Jul-2011
[9189x16]
I don't know where the test suite for SPLIT is, but the rule in effect 
for that changed from the old source that Gabriele and I originally 
created. The final rule, for string/char/bitset delimiters was originally 
this:


    [any [mk1: some [mk2: dlm break | skip] (emit copy/part mk1 mk2)]]

but is now this:


    [any [mk1: [to dlm mk2: dlm | to end mk2:] (keep copy/part mk1 mk2)]]


It looks like that changed due to http://issue.cc/r3/573, but obviously 
wasn't run through a test suite. I don't know what caused the issue 
with the above bug, as that parse rule returns a correct result.
Found a small test suite.
test: func [block] [
	print [mold/only :block newline tab mold do block]
]	

test [split "1234567812345678" 4]
;== ["1234" "5678" "1234" "5678"]

test [split "1234567812345678" 3]
;== ["123" "456" "781" "234" "567" "8"]
test [split "1234567812345678" 5]
;== ["12345" "67812" "34567" "8"]

test [split/into [1 2 3 4 5 6] 2]
;== [[1 2 3] [4 5 6]]
test [split/into "1234567812345678" 2]
;== ["12345678" "12345678"]

test [split/into "1234567812345678" 3]
;== ["12345" "67812" "345678"]
test [split/into "1234567812345678" 5]
;== ["123" "456" "781" "234" "5678"]

test [split [1 2 3 4 5 6] [2 1 3]]
;== [[1 2] [3] [4 5 6]]
test [split "1234567812345678" [4 4 2 2 1 1 1 1]]
;== ["1234" "5678" "12" "34" "5" "6" "7" "8"]
test [split first [(1 2 3 4 5 6 7 8 9)] 3]
;== [(1 2 3) (4 5 6) (7 8 9)]
test [split #{0102030405060708090A} [4 3 1 2]]
;== [#{01020304} #{050607} #{08} #{090A}]

test [split [1 2 3 4 5 6] [2 1]]
;== [[1 2] [3]]

test [split [1 2 3 4 5 6] [2 1 3 5]]
;== [[1 2] [3] [4 5 6] []]

test [split [1 2 3 4 5 6] [2 1 6]]
;== [[1 2] [3] [4 5 6]]

test [split [1 2 3 4 5 6] [3 2 2 -1 -4 3 -2]]
;== [[1 2 3] [4 5] [6] [6] [2 3 4 5] [2 3 4] [3 4]]	

test [split "abc,de,fghi,jk" #","]
;== ["abc" "de" "fghi" "jk"]
test [split "abc<br>de<br>fghi<br>jk" <br>]
;== ["abc" "de" "fghi" "jk"]

test [split "abc|de/fghi:jk" charset "|/:"]
;== ["abc" "de" "fghi" "jk"]

test [split "abc^M^Jde^Mfghi^Jjk" [crlf | #"^M" | newline]]
;== ["abc" "de" "fghi" "jk"]
test [split "abc     de fghi  jk" [some #" "]]
;== ["abc" "de" "fghi" "jk"]
The original was written before MAP-EACH and the new COLLECT. Here 
is the source I have, updated to use those as the current version 
does, but with the last rule reverted to the original.

Related cc reports: 
    http://issue.cc/r3/1096
    http://issue.cc/r3/690

split: func [

    "Split a series into pieces; fixed or variable size, fixed number, 
    or at delimiters"
    series	[series!] "The series to split"

    dlm		[block! integer! char! bitset! any-string!] "Split size, delimiter(s), 
    or rule(s)." 

    /into	"If dlm is an integer, split into n pieces, rather than pieces 
    of length n."
    /local size count mk1 mk2
][
    either all [block? dlm  parse dlm [some integer!]] [
            map-each len dlm [
                either positive? len [
                    copy/part series series: skip series len
                ] [
                    series: skip series negate len

                    ; return unset so that nothing is added to output
                    ()
                ]
            ]
    ][
        size: dlm   ; alias for readability
        collect [
            parse/all series case [
                all [integer? size into] [

                    if size < 1 [cause-error 'Script 'invalid-arg size]
                    count: size - 1
                    size: round/down divide length? series size
                    [

                        count [copy series size skip (keep/only series)]
                        copy series to end (keep/only series)
                    ]
                ]
                integer? dlm [

                    if size < 1 [cause-error 'Script 'invalid-arg size]

                    [any [copy series 1 size skip (keep/only series)]]
                ]

                'else [ ; = any [bitset? dlm  any-string? dlm  char? dlm]

                    [any [mk1: some [mk2: dlm break | skip] (keep copy/part mk1 mk2)]]
                ]
            ]
        ] 
    ]
]
>> split "a.b.c" "."
== ["a" "b" "c"]

>> split "c c" " "
== ["c" "c"]

>> split "1," " "
== ["1,"]

>> split "1,2" " "
== ["1,2"]

>> split "c,c" ","
== ["c" "c"]

>> split/into "" 1
== [""]

>> split/into "" 2
== ["" ""]

>>  split "This! is a. test? to see " charset "!?."
== ["This" " is a" " test" " to see "]
The test case that fails with this is where the delimiter is the 
last char. You don't get an empty field at the end. 

>> split "1,2,3," ","
== ["1" "2" "3"]
I found some notes that at one point to/thru broke for block and 
bitset targets.
ROUND not returning an integer broke some things too. i.e. currently 
broken.
Another bug has crept in somewhere along the way:

    series: skip series negate len


The NEGATE messes up the skip of the already negative value, which 
breaks cases like this:

    >> split [1 2 3 4 5 6] [3 2 2 -2 2 -4 3]
    == [[1 2 3] [4 5] [6] [5 6] [3 4 5]]
Updated SPLIT. Please test, add tests cases, comment, and critique. 
If you look at the special processing section, and are offended by 
it, feel free to impove it. Well, feel free to improve any of it.


I haven't checked the doc page to see if all the examples work as 
they are doc'd, which also needs to be done.
split: func [

    "Split a series into pieces; fixed or variable size, fixed number, 
    or at delimiters"
    series	[series!] "The series to split"

    dlm		[block! integer! char! bitset! any-string!] "Split size, delimiter(s), 
    or rule(s)." 

    /into	"If dlm is an integer, split into n pieces, rather than pieces 
    of length n."

    /local size piece-size count mk1 mk2 res fill-val add-fill-val
][
    either all [block? dlm  parse dlm [some integer!]] [
        map-each len dlm [
            either positive? len [
                copy/part series series: skip series len
            ] [
                series: skip series len
                ; return unset so that nothing is added to output
                ()
            ]
        ]
    ][
        size: dlm   ; alias for readability
        res: collect [
            parse/all series case [
                all [integer? size  into] [

                    if size < 1 [cause-error 'Script 'invalid-arg size]
                    count: size - 1

                    piece-size: to integer! round/down divide length? series size
                    if zero? piece-size [piece-size: 1]
                    [

                        count [copy series piece-size skip (keep/only series)]
                        copy series to end (keep/only series)
                    ]
                ]
                integer? dlm [

                    if size < 1 [cause-error 'Script 'invalid-arg size]

                    [any [copy series 1 size skip (keep/only series)]]
                ]

                'else [ ; = any [bitset? dlm  any-string? dlm  char? dlm]

                    [any [mk1: some [mk2: dlm break | skip] (keep/only copy/part mk1 
                    mk2)]]
                ]
            ]
        ]

        ;-- Special processing, to handle cases where the spec'd more items 
        in

        ;   /into than the series contains (so we want to append empty items),

        ;   or where the dlm was a char/string/charset and it was the last 
        char

        ;   (so we want to append an empty field that the above rule misses).
        fill-val: does [copy either any-block? series [[]] [""]]
        add-fill-val: does [append/only res fill-val]
        case [
            all [integer? size  into] [

                ; If the result is too short, i.e., less items than 'size, add
                ; empty items to fill it to 'size.

                ; We loop here, because insert/dup doesn't copy the value inserted.
                if size > length? res [
                    loop (size - length? res) [add-fill-val]
                ]
            ]
            ; integer? dlm [
            ; ]

            'else [ ; = any [bitset? dlm  any-string? dlm  char? dlm]

                ; If the last thing in the series is a delimiter, there is an

                ; implied empty field after it, which we add here.
                case [
                    bitset? dlm [

                        ; ATTEMPT is here because LAST will return NONE for an 

                        ; empty series, and finding none in a bitest is not allowed.

                        if attempt [find dlm last series] [add-fill-val]
                    ]
                    char? dlm [
                        if dlm = last series [add-fill-val]
                    ]
                    string? dlm [
                        if all [
                            find series dlm
                            empty? find/last/tail series dlm
                        ] [add-fill-val]
                    ]
                ]
            ]
        ]
                
        res
    ]
]
test: func [block expected-result /local res] [
    if error? try [
        print [mold/only :block newline tab mold res: do block]

        if res <> expected-result [print [tab 'FAILED! tab 'expected mold 
        expected-result]]
    ][
        print [mold/only :block newline tab "ERROR!"]
    ]
]
test [split "1234567812345678" 4]  ["1234" "5678" "1234" "5678"]


test [split "1234567812345678" 3]  ["123" "456" "781" "234" "567" 
"8"]
test [split "1234567812345678" 5]  ["12345" "67812" "34567" "8"]

test [split/into [1 2 3 4 5 6] 2]       [[1 2 3] [4 5 6]]
test [split/into "1234567812345678" 2]  ["12345678" "12345678"]

test [split/into "1234567812345678" 3]  ["12345" "67812" "345678"]

test [split/into "1234567812345678" 5]  ["123" "456" "781" "234" 
"5678"]

test [split/into "123" 6]       ["1" "2" "3" "" "" ""]
test [split/into [1 2 3] 6]     [[1] [2] [3] [] [] []] 



test [split [1 2 3 4 5 6] [2 1 3]]                  [[1 2] [3] [4 
5 6]]

test [split "1234567812345678" [4 4 2 2 1 1 1 1]]   ["1234" "5678" 
"12" "34" "5" "6" "7" "8"]

test [split first [(1 2 3 4 5 6 7 8 9)] 3]          [(1 2 3) (4 5 
6) (7 8 9)]

test [split #{0102030405060708090A} [4 3 1 2]]      [#{01020304} 
#{050607} #{08} #{090A}]

test [split [1 2 3 4 5 6] [2 1]]                [[1 2] [3]]


test [split [1 2 3 4 5 6] [2 1 3 5]]            [[1 2] [3] [4 5 6] 
[]]


test [split [1 2 3 4 5 6] [2 1 6]]              [[1 2] [3] [4 5 6]]


test [split [1 2 3 4 5 6] [3 2 2 -2 2 -4 3]]    [[1 2 3] [4 5] [6] 
[5 6] [3 4 5]]


test [split "abc,de,fghi,jk" #","]              ["abc" "de" "fghi" 
"jk"]

test [split "abc<br>de<br>fghi<br>jk" <br>]     ["abc" "de" "fghi" 
"jk"]

test [split "a.b.c" "."]     ["a" "b" "c"]
test [split "c c" " "]       ["c" "c"]
test [split "1,2,3" " "]     ["1,2,3"]
test [split "1,2,3" ","]     ["1" "2" "3"]
test [split "1,2,3," ","]    ["1" "2" "3" ""]
test [split "1,2,3," charset ",."]    ["1" "2" "3" ""]
test [split "1.2,3." charset ",."]    ["1" "2" "3" ""]


test [split "abc|de/fghi:jk" charset "|/:"]                     ["abc" 
"de" "fghi" "jk"]


test [split "abc^M^Jde^Mfghi^Jjk" [crlf | #"^M" | newline]]     ["abc" 
"de" "fghi" "jk"]

test [split "abc     de fghi  jk" [some #" "]]                  ["abc" 
"de" "fghi" "jk"]
A quick scan of the docs showed that negative skip val usage changed 
from the original design. I will revert the negate on those to match 
the doc'd behavior.
split: func [

    "Split a series into pieces; fixed or variable size, fixed number, 
    or at delimiters"
    series	[series!] "The series to split"

    dlm		[block! integer! char! bitset! any-string!] "Split size, delimiter(s), 
    or rule(s)." 

    /into	"If dlm is an integer, split into n pieces, rather than pieces 
    of length n."

    /local size piece-size count mk1 mk2 res fill-val add-fill-val
][
    either all [block? dlm  parse dlm [some integer!]] [
        map-each len dlm [
            either positive? len [
                copy/part series series: skip series len
            ] [
                series: skip series negate len
                ; return unset so that nothing is added to output
                ()
            ]
        ]
    ][
        size: dlm   ; alias for readability
        res: collect [
            parse/all series case [
                all [integer? size  into] [

                    if size < 1 [cause-error 'Script 'invalid-arg size]
                    count: size - 1

                    piece-size: to integer! round/down divide length? series size
                    if zero? piece-size [piece-size: 1]
                    [

                        count [copy series piece-size skip (keep/only series)]
                        copy series to end (keep/only series)
                    ]
                ]
                integer? dlm [

                    if size < 1 [cause-error 'Script 'invalid-arg size]

                    [any [copy series 1 size skip (keep/only series)]]
                ]

                'else [ ; = any [bitset? dlm  any-string? dlm  char? dlm]

                    [any [mk1: some [mk2: dlm break | skip] (keep/only copy/part mk1 
                    mk2)]]
                ]
            ]
        ]

        ;-- Special processing, to handle cases where the spec'd more items 
        in

        ;   /into than the series contains (so we want to append empty items),

        ;   or where the dlm was a char/string/charset and it was the last 
        char

        ;   (so we want to append an empty field that the above rule misses).
        fill-val: does [copy either any-block? series [[]] [""]]
        add-fill-val: does [append/only res fill-val]
        case [
            all [integer? size  into] [

                ; If the result is too short, i.e., less items than 'size, add
                ; empty items to fill it to 'size.

                ; We loop here, because insert/dup doesn't copy the value inserted.
                if size > length? res [
                    loop (size - length? res) [add-fill-val]
                ]
            ]
            ; integer? dlm [
            ; ]

            'else [ ; = any [bitset? dlm  any-string? dlm  char? dlm]

                ; If the last thing in the series is a delimiter, there is an

                ; implied empty field after it, which we add here.
                case [
                    bitset? dlm [

                        ; ATTEMPT is here because LAST will return NONE for an 

                        ; empty series, and finding none in a bitest is not allowed.

                        if attempt [find dlm last series] [add-fill-val]
                    ]
                    char? dlm [
                        if dlm = last series [add-fill-val]
                    ]
                    string? dlm [
                        if all [
                            find series dlm
                            empty? find/last/tail series dlm
                        ] [add-fill-val]
                    ]
                ]
            ]
        ]
                
        res
    ]
]
; Old design for negative skip vals

;test [split [1 2 3 4 5 6] [3 2 2 -2 2 -4 3]]    [[1 2 3] [4 5] [6] 
[5 6] [3 4 5]]
; New design for negative skip vals
test [split [1 2 3 4 5 6] [2 -2 2]]             [[1 2] [5 6]]
Steeve
18-Jul-2011
[9205x4]
Seems you wrecked the behavior when a parse rule is fulfilled.

[split] should keep the matched parts, you do the contrary (exclusion), 
why this change ?.
Ok, I see now you turned it back to the primary behavior. But it 
should be discussed at first.
I vote for the include behavior.
It makes sense because whatever new junk sequences are added in the 
source, the macthing process will continue to collect the expected 
tokens.
It makes sense because whatever new junk sequences are added in the 
source, the macthing process will continue to collect the expected 
tokens.
Gregg
18-Jul-2011
[9209]
Could you provide examples of what you mean? The original design 
was flexible, but perhaps not as useful. I understand why it was 
changed, and think it's better for general use.
Steeve
18-Jul-2011
[9210x2]
Well, I just read the code.

You replaced this:

    [any [mk1: some [mk2: dlm break | skip] (emit copy/part mk1 mk2)]]
by this:

    [any [mk1: [to dlm mk2: dlm | to end mk2:] (keep copy/part mk1 mk2)]]


In the first case: the rule is used to extract the matching sequences

In the second case, the rule is used to exclude the matching sequences.
Sorry, In fact it's the contrary (swap the 2 cases)