Oxygen Basic
Programming => Problems & Solutions => Topic started by: Brian Alvarez on November 19, 2018, 11:47:28 AM
-
IM trying to create the REPLACE feature in oxygen, i have this function:
// replaces parts of a string with specified replacements.
SUB REPLACE(boolean a, string ocu, string rep, string trg)
if len(rep) = 0 then
exit function
end if
int r, i
if a then ' ANY
if len(ocu) <> len(rep) then
trg = ""
exit sub
end if
byte bocu at strptr(ocu)
byte brep at strptr(rep)
byte btrg at strptr(trg)
for r = 1 to len(ocu)
if len(rep) < r then exit for
for i = 1 to len(trg)
if bocu[r] = btrg[i] then
btrg[i] = brep[r]
end if
next i
next r
else ' by word (Code by Charles)
do
i = instr(i+1, trg, ocu)
if i then
trg = left(trg, i-1) + rep + mid(trg, i + len(rep))
else
exit do
end if
i = len(rep) + i - 1
loop
end if
END SUB
The function compiles (it doesnt work yet) but crashes on 64 bit mode, but in 32 bit mode it doesnt compile, it says:
ERROR: Must not assign to a direct string param
Its the exact same code for invocation in both modes:
FUNCTION PBMAIN() AS LONG
STRING st
st = "Hello Mom"
Replace(0, "Mom", "World", st)
print st
END FUNCTION
Thanks!
-
Adding the byref switch to the target string parameter fixed it:
I thought that since byval is not yet supported, BYREF was instrinsic.
// replaces parts of a string with specified replacements.
SUB REPLACE(boolean a, string ocu, string rep, byref string trg)
if len(rep) = 0 then
exit function
end if
int r, i
if a then ' ANY
if len(ocu) <> len(rep) then
trg = ""
exit sub
end if
byte bocu at strptr(ocu)
byte brep at strptr(rep)
byte btrg at strptr(trg)
for r = 1 to len(ocu)
if len(rep) < r then exit for
for i = 1 to len(trg)
if bocu[r] = btrg[i] then
btrg[i] = brep[r]
end if
next i
next r
else ' by word (Code by Charles)
do
i = instr(i+1, trg, ocu)
if i then
trg = left(trg, i-1) + rep + mid(trg, i + len(rep))
else
exit do
end if
i = len(rep) + i - 1
loop
end if
END SUB
-
Hi Brian,
It could also be:
SUB REPLACE(bool a, string ocu, string rep, string ptr trg)
ptr / byref / * are alternatives
Or the compacted form:
SUB REPLACE(bool a, string ocu, rep, *trg)
-
Since this is also a problem between 32 bit and 64 bit, im going to post it here instead of opening a new thread...
feel free to move it to it's own thread if it is worthy of such promotion.
The following is code that PluriBASIC generates. When using rtl32, it works fine,
but when using rtl64, the app crashes when sending the string pointer as a parameter for
"BYREFPAR". Somehow the engine does not like the pointer. Maybe i am sending a pointer not big enough to
hold the 64bit string address.
Please ignore the fact that the class is not freeing strings properly. I simplified the generated code by hand
to make it easier to follow.
What can i be doing wrong?
'Generated with PluriBASIC 6.0.74371.0
$ filename "array_system.exe"
uses rtl64
Declare Function PluriBASICMessageBox Lib "user32.dll" Alias "MessageBoxA"
FUNCTION MSGBOX(string sText, sys mOptions = 0, string sCaption = "PluriBASIC") AS LONG
FUNCTION = PluriBASICMessageBox(null, sText, sCaption, mOptions)
END FUNCTION
#def __dim1 (d1-bnd[1])
#def __dim2 (d2-bnd[3])
#def __dim3 (d3-bnd[5])
#def __class_nam_def class _arr_%1
macro __declare_array_type(dtype)
__class_nam_def(dtype)
int dims ' Number of dimensions
int elems ' Number of elements.
int slength ' length of strings.
int ispointer ' is pointer flag.
sys hBuffer ' Address of the buffer
sys hCustAddr ' Address provided by the inline code.
int BuffLen ' length of the buffer in bytes
int bnd[10] ' bounds.
function redim(int p, int * d, n)
int i
elems = 0
for i = 1 to n step 2
bnd[i+0] = d[i+0]
bnd[i+1] = d[i+1]
elems += (d[i+1]-d[i+0])
next
int nBufLen = (elems * sizeof(sys)) + 32
sys nBuffer = getmemory(nBufLen)
int eBfCopy = BuffLen
if BuffLen
if BuffLen>nBufLen then
eBfCopy = nBufLen
end if
copy nBufLen, BuffLen, eBfCopy
freememory hBuffer
endif
hBuffer = nBuffer
BuffLen = nBufLen
end function
method constructor(int * d, n, isptr, slen, sys hAddr)
ispointer = isptr
slength = slen
hCustAddr = hAddr
dims = n / 2
this.redim(0, d, n)
end method
function destructor()
freememory(hBuffer)
hBuffer = 0
BuffLen = 0
end function
'======================================================================
function c(int d1, d2, d3, dtype v)
dtype dt at (hBuffer + 32)
dt(__dim1 * __dim2 + __dim3) = v
end function
function c(int d1, d2, d3) as dtype
dtype dt at (hBuffer + 32)
return dt(__dim1 * __dim2 + __dim3)
end function
'======================================================================
function p(int d1, d2, d3) as dtype*
dtype dt at (hBuffer + 32)
return @dt(__dim1 * __dim2 + __dim3)
end function
end class
end macro
__declare_array_type(bstring)
SUB BYREFPAR(BYREF ss AS STRING, BYVAL _ByValue_s2 AS STRING)
STRING s2 = _ByValue_s2
ss = "Changed in the SUB"
s2 = "Changed in the SUB"
END SUB
FUNCTION PBMAIN() AS INT
new _arr_bstring sss(int{-10, 100, 0, 100, 0, 100}, countof, 0, 0, 0)
sss.c(5,5,5) = "Original contents 1"
sss.c(5,5,6) = "Original contents 2"
BYREFPAR(sss.p(5,5,5), sss.c(5,5,6))
MSGBOX(sss.c(5,5,5), 0, sss.c(5,5,6)) ' should display one modified and one unmodified.
END FUNCTION
PBMAIN() ' invoke entry point
-
By casting the address to a sys it doesnt crash:
BYREFPAR(cast(sys) sss.p(5,5,5), sss.c(5,5,6))
But the "variable" remains "byval".
Maybe it is somewhere converting it to an int or something,
it should be an easy internal fix, right? :)
-
The 64bit address being passed differs from the address that @ss is displaying.
For the 32bit mode, the address is correct.
-
Brian.
I see one problem:
copy nBufLen, BuffLen, eBfCopy
copy is a low-level procedure and its prototype is
copy(DestAddress, SourceAddress, ByteCount)
-
Hello charles :)
That is a direct copy of the source code you kindly provided me, only the variable names have changed.
https://www.oxygenbasic.org/forum/index.php?topic=1811.msg19715#msg19715
Did you see the other problem i was talking about?
-
Well, tell the author to check his code more diligently. :)
I'm surprised it worked at all.
I think this is the only mod required:
copy nBuffer, hBuffer, eBfCopy
-
Thanks Charles, i made the change. The 64 bit Pointer problem still remains. :)