Old Idea from DocKimbel For Rebol2 => Rebol3/Red

This is something I just ran across from a long time ago, which I thought would be interesting to look at with modern eyes.

It's a Gist: https://gist.github.com/dockimbel/5083375 of a proposal of actually making a DO variant that would rewrite the source of a script.

He is quoted as having said: "A JIT-migration tool would be more accurate. It would run just after LOAD and before DO to rewrite part of the R2 sources in a R3 compatible format."

Static analysis of Turing-Complete programs is notoriously on the difficult-if-not-impossible scale, even for simple languages. So JIT-rewriting even something like PARSE rules is only going to be feasible if those rules were not built by code.

His example just looks for one source pattern (negative literal indexing, so like translating between data/0 and data/-1). But determining what is "code" and what is "data" is deliberately more complex in Rebol than other language.

In Ren-C we have code like enbin [BE +/- 32] and that path is never meant to execute, it's just there to convey the notion of wanting to encode a signed number. Going around and randomly turning all paths with 0 in them to be -1 misses the whole point of "relative expressions"; you don't know what they're relative to.

So the ironic point of preserving this is just to say "nothing to see, here". :slight_smile: %redbol.reb is a saner track. But I do think it's going to wind up requiring DO itself being different... a DO2 (like UPARSE2). It won't rewriting the code block given, but hook the evaluator with different rules.

REBOL [
    Author:  "Nenad Rakocevic"
    Date:      04/03/2013
    Purpose: {
        Show how to achieve R2 source rewriting suitable for evaluation
        using R3 interpreter.
    }
        Note: "Use it from %Red/ folder"
]

context [
    do*: s: none
    
    path-rewrite: [
        some [
            s: integer! (if negative? s/1 [s/1: s/1 + 1])
            ;| handle other indexed-access cases here
            | skip
        ]
    ]

    patched-do: func [value /arg /local saved rule mark path file][
        unless file? :value [return do* value]

        saved: system/script/path
        set [path file] split-path :value
        change-dir path
        value: load file

        parse value rule: [
            any [
                mark: [path! | set-path! | lit-path!] :mark into path-rewrite
                ;; | mark: string! :mark into string-rewrite 
                ;; add more rewritting rules here
                | mark: any-block! :mark into rule
                | skip
            ]
        ]
        also 
            do* value
            system/script/path: saved
    ]
    
    set 'do-r2 func [blk [block!]][
        do*: :do
        set 'do :patched-do
        do blk
        set 'do :do*
    ]
]

do-r2 [
    do %red/compiler.r
]
save %red.new red  ;-- inspect the file to see the changes
halt