I am continue to learn Red/System. And now I am trying to understand how to pass word with context to function.
Here is my code:
Red [Note: "compile in release mode (-r flag)"]
mycontext: context [
list: []
]
foo: routine [
blk
/local
int [integer!]
str [c-string!]
][
blk: as red-block! _context/get-any <CONTEXTHERE> symbol/make "list" ; ?? <CONTEXTHERE>
int: 123
str: "Hello"
block/rs-append blk as red-value! integer/box int
string/load-in str length? str blk UTF-8
]
foo mycontext ; passing context to foo
probe mycontext
This code do not work because list is placed in mycontext
. The example of passing list
without context can be found here
I tried different approaches, but every time I got error.
https://github.com/red/red/blob/master/runtime/datatypes/structures.reds#L188
Firstly, the type specification of your routine is incorrect (that's what the error message tells you):
Compiling to native code...
*** Compilation Error: invalid definition for function exec/foo: [
blk [red-red-block!]
/local
int [integer!]
str [c-string!]
]
Compiler automatically puts red-*
prefix for routine's arguments, so the correct specification should be:
foo: routine [
blk [block!]
/local
int [integer!]
str [c-string!]
][
...
]
Secondly, this isn't correct either; you are passing an object!
, not a block!
:
*** Compilation Error: datatype not allowed
Which means that one should write:
foo: routine [
obj [object!]
/local
int [integer!]
str [c-string!]
][
...
]
Now, as I understand, you want to get a hold of that empty block referenced by list
and append values to it. This requires having a context node
obj/ctx
and symbol ID
symbol/make "list"
Having two in place we can make a call to _context/get-any
:
foo: routine [
obj [object!]
/local
blk [red-block!]
int [integer!]
str [c-string!]
][
blk: as red-block! _context/get-any symbol/make "list" obj/ctx
int: 123
str: "Hello"
block/rs-append blk as red-value! integer/box int
string/load-in str length? str blk UTF-8
]
Alternative solution would be to construct a word!
value using word/load
and call object/rs-select
:
foo: routine [
obj [object!]
/local
blk [red-block!]
int [integer!]
str [c-string!]
][
blk: as red-block! object/rs-select obj as red-value! word/load "list"
int: 123
str: "Hello"
block/rs-append blk as red-value! integer/box int
string/load-in str length? str blk UTF-8
]
Both approaches yield the expected result:
make object! [
list: [123 "Hello"]
]
Personally, I wouldn't complicate things that much and simply pass the block to your routine:
mycontext: context [
list: []
]
foo: routine [
blk [block!]
/local
int [red-integer!]
str [c-string!]
][
str: "Hello"
int: as red-integer! stack/push*
int/header: TYPE_INTEGER
int/value: 123
block/rs-append blk as red-value! int
string/load-in str length? str blk UTF-8
]
foo mycontext/list
probe mycontext