Search code examples
rebol3expression-evaluation

Evaluating code blocks in Rebol3


I'm trying to improve the Sliding Tile Puzzle example by making the starting positions random.

There's a better way to do this--"It is considered bad practice to convert values to strings and join them together to pass to do for evaluation."--but the approach I took was to try to generate Rebol3 source, and then evaluate it. I have it generating correctly, I think:

random/seed now
arr: random collect [ repeat tilenum 9 [ keep tilenum ] ]
hgroup-data: copy {}
repeat pos 9 [
    curtile: (pick arr pos)
    append hgroup-data either curtile = 9
        [ reduce "x: box tilesize gameback " ]
        [ rejoin [ { p "} curtile {" } ] ]
    if all [(pos // 3) = 0 pos != 9] [ append hgroup-data " return^/" ]
]
print hgroup-data

...outputs something like:

 p "4" x: box tilesize gameback  p "5"  return
 p "3"  p "7"  p "1"  return
 p "2"  p "8"  p "6" 

...which if I then copy and paste into this part, works correctly:

view/options [
    hgroup [ 
PASTE-HERE
    ]
] [bg-color: gameback]

However, if I try to do it dynamically:

view/options [
    hgroup [ 
        hgroup-data
    ]
] [bg-color: gameback]

...(also print hgroup-data, do hgroup-data, and load hgroup-data), I get this error:

** GUI ERROR: Cannot parse the GUI dialect at: hgroup-data

...(or at: print hgroup-data, etc., depending on which variation I tried.)

If I try load [ hgroup-data ] I get:

** Script error: extend-face does not allow none! for its face argument
** Where: either if forever -apply- apply init-layout make-layout actor all foreach do-actor unless -apply- apply all build-face -apply- apply init-layout make-layout actor all foreach do-actor if build-face -apply- apply init-layout make-layout actor all foreach do-actor unless make-face -apply- apply case view do either either either -apply-
** Near: either all [
    word? act: dial/1
    block? body: get dial...

However, if I use the syntax hgroup do [ hgroup-data ], the program runs, but there are no buttons: it appears to be somehow over-evaluated, so that the return values of the functions p and box and so on are put straight into the hgroup as code.

Surely I'm missing an easy syntax error here. What is it?


Solution

  • First, I would say it's better to construct a block directly, instead of constructing a string and converting it to a block. But if you really want to do that, this should do the trick:

    view/options compose/only [
        hgroup (load hgroup-data)
    ] [bg-color: gameback]