Headbanging: r/w values between Main and Object in another cog
Erlend
Posts: 612
I thought I hade sorted out using @pointers by now, but obviously not. Here's a sample code I wrote for you.
-and the Main to test it
Testing with debug to display the return-write gives garbage. What am I doing wrong?
{Receive DAT value from Main, and write data data to VAR value in Main}
CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
VAR
long LocalInputDataPointer
long LocalOutputDataPointer
long cog, stack[32]
PUB start(InputDataPointer, OutputDataPointer)
cog:= cognew(r_w(LocalInputDataPointer, LocalOutputDataPointer), @stack[0])
LocalInputDataPointer := InputDataPointer
LocalOutputDataPointer := OutputDataPointer
PUB r_w(indataPointer, outdataPointer)
IF long[LocalInputDataPointer] [4] == 6
long[LocalOutputDataPointer] [4] := 3
ELSE
long[LocalOutputDataPointer] [4] := 1
-and the Main to test it
CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
VAR
long OutputData[9]
OBJ
rw : "TESTr_w"
PUB Main | i
rw.start(@InputData, @OutputData)
DAT
InputData long 3, 1, 4, 2, 9, 7, 5, 8, 0, 6
Testing with debug to display the return-write gives garbage. What am I doing wrong?

Comments
PUB start(InputDataPointer, OutputDataPointer) cog:= cognew(r_w(LocalInputDataPointer, LocalOutputDataPointer), @stack[0]) LocalInputDataPointer := InputDataPointer LocalOutputDataPointer := OutputDataPointerTop level object
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ pst : "Parallax Serial Terminal" VAR long OutputData[10] OBJ rw : "TESTr_w" PUB Main | i pst.Start(115_200) rw.start(@InputData, @OutputData) repeat i from 0 to 9 pst.str(string("InputData[")) pst.dec(i) pst.str(string("] = ")) pst.dec(InputData[i]) pst.char(13) pst.char(13) repeat i from 0 to 9 pst.str(string("OutputData[")) pst.dec(i) pst.str(string("] = ")) pst.dec(OutputData[i]) pst.char(13) repeat DAT InputData long 3, 1, 4, 2, 9, 7, 5, 8, 0, 6Child object
{Receive DAT value from Main, and write data data to VAR value in Main} VAR long LocalInputDataPointer long LocalOutputDataPointer long cog, stack[32] PUB start(InputDataPointer, OutputDataPointer) LocalInputDataPointer := InputDataPointer LocalOutputDataPointer := OutputDataPointer cog:= cognew(r_w(LocalInputDataPointer, LocalOutputDataPointer), @stack[0]) PUB r_w(indataPointer, outdataPointer) repeat IF long[LocalInputDataPointer] [4] == 6 long[LocalOutputDataPointer] [4] := 3 ELSE long[LocalOutputDataPointer] [4] := 1This example works and it does demo passing values by reference. It's ok for learning but not a good design pattern.
You find the "bug" without harming by yourself? First you call r_w with parameters but then you don't use them ;o)
In general I don't understand what the LocalXXXXDataPointer variables are good for at all! ... well ... at least when the program keeps being as simple as that. Because having the pointers in the r_w-stack is local enough. If your program get's more complex and you need access from more than one function it might make sense to store the values in a VAR, but then you don't have to pass those LocalXXXX addresses to the functions, because all functions in an object have access to the VARs defined in the object.
One way
{Receive DAT value from Main, and write data data to VAR value in Main} VAR long LocalInputDataPointer long LocalOutputDataPointer long cog, stack[32] PUB start(InputDataPointer, OutputDataPointer) LocalInputDataPointer := InputDataPointer LocalOutputDataPointer := OutputDataPointer cog:= cognew(r_w, @stack[0]) PUB r_w repeat IF long[LocalInputDataPointer] [4] == 6 long[LocalOutputDataPointer] [4] := 3 ELSE long[LocalOutputDataPointer] [4] := 1Another way
{Receive DAT value from Main, and write data data to VAR value in Main} VAR long cog, stack[32] PUB start(InputDataPointer, OutputDataPointer) cog:= cognew(r_w(InputDataPointer, OutputDataPointer), @stack[0]) PUB r_w(indataPointer, outdataPointer) repeat IF long[indataPointer] [4] == 6 long[outdataPointer] [4] := 3 ELSE long[outdataPointer] [4] := 1This is an example of encapsulation...
Top Level
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long OutputData[10] OBJ pst : "Parallax Serial Terminal" rw : "TESTr_w" PUB Main | ptr pst.Start(115_200) ptr := rw.Init PrintArray(ptr) rw.CopyArray(@inputData) PrintArray(ptr) ifnot(rw.SetArray(0, 200)) pst.str(string("Error: Index out of bounds", pst#NL)) else PrintArray(ptr) ifnot(rw.SetArray(1000, 200)) pst.str(string("Error: Index out of bounds", pst#NL)) else PrintArray(ptr) if(rw.IsNull(rw.GetArray(100))) pst.str(string("Error: Index out of bounds", pst#NL)) else pst.str(string("Array[")) pst.dec(100) pst.str(string("] = ")) pst.dec(long[ptr][100]) pst.char(pst#NL) pst.char(pst#NL) if(rw.IsNull(rw.GetArray(1))) pst.str(string("Error: Index out of bounds", pst#NL)) else pst.str(string("Array[")) pst.dec(1) pst.str(string("] = ")) pst.dec(long[ptr][1]) pst.char(pst#NL) pst.char(pst#NL) PUB PrintArray(ptrArray) | i repeat i from 0 to rw#BUFFER_SIZE-1 pst.str(string("Array[")) pst.dec(i) pst.str(string("] = ")) pst.dec(long[ptrArray][i]) pst.char(13) pst.char(13) DAT inputData long 3, 1, 4, 2, 9, 7, 5, 8, 0, 6Child Object
{Receive DAT value from Main, and write data data to VAR value in Main} CON BUFFER_SIZE = 10 DAT array long $[BUFFER_SIZE] null long $0 PUB Init | i 'Initialize the array repeat i from 0 to BUFFER_SIZE-1 array[i] := i return GetArrayPointer PUB CopyArray(ArrayToCopy) | i repeat i from 0 to BUFFER_SIZE-1 array[i] := long[ArrayToCopy][i] PUB GetArray(index) 'Get an array element value if(index > BUFFER_SIZE OR index < 0) return @null else return array[index] PUB SetArray(index, value) 'Set an array element value if(index > BUFFER_SIZE OR index < 0) return false else array[index] := value return true PUB GetArrayPointer return @array PUB IsNull(value) return @null == value