Posts: 60
Threads: 8
Joined: Apr 2022
Reputation:
5
How difficult would it be to implement something similar to this in QB64PE?
OPTION _EXPLICIT
DIM AS LONG LNUMS(5) = {1, 2, 5, 8, 4000}
This is syntax similar to C, and it is also supported to an extent by FreeBASIC. I have used this construct in FreeBASIC, and I have found it useful when initializing short arrays of 'fixed' data in a program.
(I always use OPTION _EXPLICIT, it has saved me more than a few times from fat-fingered typing.)
Posts: 2,180
Threads: 222
Joined: Apr 2022
Reputation:
104
I suppose there are a couple of ways it could be coded into a function...
Code: (Select All) DIM AS LONG LNUMS(5)
RESTORE mytmp
DIM a AS LONG
FOR i = 1 TO UBOUND(LNUMS)
READ a
LNUMS(i) = a
NEXT
mytmp:
DATA 1,2,5,8,4000
' Proof.
FOR i = 1 TO UBOUND(LNUMS)
PRINT LNUMS(i)
NEXT
'--------------------- Next method...
ERASE LNUMS
'--------------------- Begin...
a$ = "{1, 2, 5, 8, 4000}"
a$ = MID$(a$, 2, LEN(a$) - 2)
FOR i = 1 TO UBOUND(LNUMS)
j = INSTR(seed, a$ + ",", ",")
LNUMS(i) = VAL(MID$(a$, seed + 1, j - seed - 1))
seed = j + 1
NEXT
' Proof
FOR i = 1 TO UBOUND(LNUMS)
PRINT LNUMS(i)
NEXT
I suppose it all depends on finding a dev who could use it frequently enough to include it in a future release.
Pete
Shoot first and shoot people who ask questions, later.
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
12-21-2022, 03:59 PM
(This post was last modified: 12-21-2022, 04:28 PM by mnrvovrfc.
Edit Reason: I'm going to edit this post one more time I guess
)
Could code a subprogram that takes two arguments: a string which is the list of values to initialize, and a dynamic array (which will be changed) to take the individual values from the list. Decide what will be the delimeter of the list. For mine I chose semicolon. Must also decide which type, even if it's integer. Sadly, for general purpose must choose "_INTEGER64".
The advantage of this is that the programmer doesn't have to worry about the array's size. The trade-off is that it's difficult this way to work with static arrays. It's clunky sometimes working with strings and having to parse them, but there's no other way to support an user's subprogram which accepts a number of parameters unknown to the compiler, something like the fabled "printf()" function in C runtime library.
Wait a moment -- @bobalooie why do you want to initialize an array with subscript zero as the first element? :O
I was hoping SMcNeill would come over to show off one of his functions... but here is my attempt.
Code: (Select All) redim l(1 to 1) as integer
dim i as integer
fillinteger "1;2;5;8;4000", l()
for i = 1 to ubound(l)
print i, l(i)
next
end
sub fillinteger (slist as string, li() as integer)
static as long u, v, k
if slist = "" then exit sub
u = 1
v = instr(slist, ";")
k = 0
do while v > 0
k = k + 1
redim _preserve li(1 to k) as integer
li(k) = val(mid$(slist, u, v - u))
u = v + 1
v = instr(u + 1, slist, ";")
loop
k = k + 1
redim _preserve li(1 to k) as integer
li(k) = val(mid$(slist, u))
end sub
Posts: 734
Threads: 30
Joined: Apr 2022
Reputation:
43
@bobalooie I, too, am an advocate for OPTION _EXPLICIT usage. If only it had been used in the QB64 source code.
Tread on those who tread on you
Posts: 60
Threads: 8
Joined: Apr 2022
Reputation:
5
12-21-2022, 05:46 PM
(This post was last modified: 12-21-2022, 06:08 PM by bobalooie.)
(12-21-2022, 03:59 PM)mnrvovrfc Wrote: Wait a moment -- @bobalooie why do you want to initialize an array with subscript zero as the first element? :O
Well, in this case I am interested in just iterating through the array as a lookup table of sorts, so it doesn't really matter if the first element is at 0 or 1. If I was working in C, I could use the syntax I showed or perhaps make a doubly-linked list so I could iterate either direction.
Your example works well, but I perceive that I would need a new fill function for every data type I want to store. Not really a challenge of course, except for a list of CONST values.
Soldiering on.
Posts: 60
Threads: 8
Joined: Apr 2022
Reputation:
5
(12-21-2022, 05:23 AM)Pete Wrote: I suppose there are a couple of ways it could be coded into a function...
Code: (Select All) DIM AS LONG LNUMS(5)
RESTORE mytmp
DIM a AS LONG
FOR i = 1 TO UBOUND(LNUMS)
READ a
LNUMS(i) = a
NEXT
mytmp:
DATA 1,2,5,8,4000
' Proof.
FOR i = 1 TO UBOUND(LNUMS)
PRINT LNUMS(i)
NEXT
'--------------------- Next method...
ERASE LNUMS
'--------------------- Begin...
a$ = "{1, 2, 5, 8, 4000}"
a$ = MID$(a$, 2, LEN(a$) - 2)
FOR i = 1 TO UBOUND(LNUMS)
j = INSTR(seed, a$ + ",", ",")
LNUMS(i) = VAL(MID$(a$, seed + 1, j - seed - 1))
seed = j + 1
NEXT
' Proof
FOR i = 1 TO UBOUND(LNUMS)
PRINT LNUMS(i)
NEXT
I suppose it all depends on finding a dev who could use it frequently enough to include it in a future release.
Pete
Yup, both good approaches. I'm just trying to be lazy and not have to type all that extra code.
Posts: 733
Threads: 103
Joined: Apr 2022
Reputation:
14
(12-21-2022, 03:36 AM)bobalooie Wrote: How difficult would it be to implement something similar to this in QB64PE?
OPTION _EXPLICIT
DIM AS LONG LNUMS(5) = {1, 2, 5, 8, 4000}
This is syntax similar to C, and it is also supported to an extent by FreeBASIC. I have used this construct in FreeBASIC, and I have found it useful when initializing short arrays of 'fixed' data in a program.
(I always use OPTION _EXPLICIT, it has saved me more than a few times from fat-fingered typing.)
This would definitely be a nice feature - a function like what @mnrvovrfc (how do you pronounce that anyway?!) should work. When I am at my PC, I'll give it a try. Thanks mnrvovrfc!
Posts: 2,698
Threads: 327
Joined: Apr 2022
Reputation:
217
(12-21-2022, 03:59 PM)mnrvovrfc Wrote: I was hoping SMcNeill would come over to show off one of his functions... but here is my attempt.
My way of doing this type of thing is really, really simple:
Code: (Select All) DIM foo(10) AS INTEGER
foodata: DATA 1,2,4,6,8000,12,56,23,45,89,12
Restore foodata
FOR i = 1 to 10: Read foo(i): Next
The label and restore aren't required in the code above, but it's just one of them things that I've gotten into the habit of always using. I *NEVER* do a READ with my DATA, without doing a RESTORE first. I do too much work with library files and other such things, so I never go under the assumption that the data I want to read is necessarily the first data in the program (or the next data in the program). Restore always puts you at the data you want, and I'm just in the habit of always using it. Skip it, if you don't think you need it for your own uses.
A lot simpler than a function and parsing a string and all that complicated stuff.
Posts: 2,180
Threads: 222
Joined: Apr 2022
Reputation:
104
12-21-2022, 07:01 PM
(This post was last modified: 12-21-2022, 07:27 PM by Pete.)
I liked mn's example.
Well, I don't see a function, because we are returning a set of array values, not just a single value; so a sub seems a more likely choice...
Code: (Select All) REDIM LNUMS(0): myray LNUMS(), "1, 2, 5, 8, 4000"
FOR i = 1 TO 5
PRINT lNUMS(i)
NEXT
SUB myray (myarray(), myarray_elements AS STRING)
DO
i = i + 1
j = INSTR(seed, myarray_elements + ",", ",")
IF j = 0 THEN EXIT DO
REDIM _PRESERVE myarray(i)
myarray(i) = VAL(MID$(myarray_elements, seed + 1, j - seed - 1))
seed = j + 1
LOOP
END SUB
Now I think we need to restrict it to dynamic arrays, to avoid a duplicate definition. Maybe this could be expanded on to handle string arrays, too. As far as how to define them by type, single, long, etc. That's more complicated.
Edit: Steve was posting while I was writing. I se the same method.In fact, just recently in my replies to the password thread.
Pete
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
12-21-2022, 07:40 PM
(This post was last modified: 12-21-2022, 07:42 PM by mnrvovrfc.
Edit Reason: Wanted to be correct about what I typed here earlier
)
(12-21-2022, 07:01 PM)Pete Wrote: Well, I don't see a function, because we are returning a set of array values, not just a single value; so a sub seems a more likely choice...
You should do your loop from 0 to 4, not 1 to 5 because you started an array at subscript zero...
Also the subprogram that you wrote doesn't initialize the array at subscript zero, it just increases local "i" by one. Then its value is one at first pass.
Even better (in main program) do:
Code: (Select All) FOR i = LBOUND(LNUMS) to UBOUND(LNUMS)
|