Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use load/next/error when there may be embedded blocks?

Tags:

rebol

rebol3

transcode/next/error returns the first loaded value, and the position after the value, so you can then go to load the next value:

>> transcode/next/error to binary! " a b c "
== [a #{2062206320}]

Or you get an error, and the position after the error value:

>> transcode/next/error to binary! " 1a b c " 
== [make error! [                             
    code: 200                             
    type: 'Syntax                         
    id: 'invalid                          
    arg1: "integer"                       
    arg2: "1a"                            
    arg3: none                            
    near: "(line 1) 1a b c "              
    where: [transcode]                    
] #{2062206320}]                          

But if the value to load is a block, and there's an error inside the block, then

  • you get an error!
  • the position after the error value, and
  • the good values inside the block are discarded:

like here

>> transcode/next/error to binary! "[ a b 1c ]"
== [make error! [
    code: 200
    type: 'Syntax
    id: 'invalid
    arg1: "integer"
    arg2: "1c"
    arg3: none
    near: "(line 1) [ a b 1c ]"
    where: [transcode]
] #{205D}]

My current[*] solution is, to correct the input string, and restart from the last position. This way I am reloading the whole block, to get it in one go.

Is there any better way to handle this?

[*] see here https://github.com/IngoHohmann/rebol3-tools/blob/master/load-all.r3

like image 711
ingo Avatar asked Dec 21 '25 06:12

ingo


1 Answers

Assuming you have a loop that invokes each instance of 'transcode, you could precede transcode with your own mechanism to process block characters [](). You then become responsible for arbitrating valid blocks, but since your goal is to load any data, you will likely need to handle block delimiters that aren't balanced anyhow.

All that you'd need is a mechanism that worked like transcode, but for block delimiters:

block-transcode: func [source [binary!] /local symbol][
    if parse source [
        any space  ; space should be defined
        copy symbol [#"[" | #"]" | #"(" | #")"]
        source: to end
    ][
        reduce [symbol source]
    ]
]

Of course, this wouldn't check for blocks within parens within paths, but it's a start...

like image 175
rgchris Avatar answered Dec 23 '25 05:12

rgchris