How could I imitate VBScript Array() function?

General FreeBASIC programming questions.
Post Reply
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

How could I imitate VBScript Array() function?

Post by Julcar »

In VBScript there is an Array() function: https://www.w3schools.com/asp/func_array.asp

In FB is possible to do this:

Code: Select all

DIM AS STRING MyDogs(2) = {"spike", "bitter", "bobby"} 
Now let's say I have the following procedure

Code: Select all

SUB FindMyDogs(MyDogs() AS STRING)
  FOR i AS ULONG = 0 TO UBOUND(MyDogs)
    PRINT MyDogs(i)
  NEXT
END SUB
Afaik, is not possible to do this

Code: Select all

FindMyDogs({"spike", "bitter", "bobby"})
But in VBScript is possible to do this

Code: Select all

FindMyDogs(Array("spike", "bitter", "bobby"))
I would like to find a way to pass a string array to a procedure right from the calling line, as in the VBScript example.

Regards
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: How could I imitate VBScript Array() function?

Post by Lost Zergling »

I think FB is powerfull enought to make it possible to implement your own 'Array() like' function using a dedicated type to handle an array the custom way you prefer. Of course, this custom type shall be first declared and instanciated using its own rules (you can define) but then you'd get a form of 'syntactic wrapper'. I did use this approach in LZAE with aext (array extension) type.
It is then possible to write MyFunction(aext.set(parameters)) or even MyFunction(aext(parameters)).
It is probably not the only nor the best way doing it, but you could just have a look at it and do your own 'cooking'.
You'd get a feature very close to what you describe, I think.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: How could I imitate VBScript Array() function?

Post by srvaldez »

have a look at https://github.com/glasyalabolas/fb-collections , specifically look at the Dictionary bi and examples
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: How could I imitate VBScript Array() function?

Post by TeeEmCee »

One way to accomplish that is to create a macro wrapper around FindMyDogs:

Code: Select all

#MACRO FindMyDogs(strings...)
    SCOPE
        DIM strarray(...) as string = {strings}
        FindMyDogs_ strarray()
    END SCOPE
#ENDMACRO

SUB FindMyDogs_(MyDogs() AS STRING)
  FOR i AS ULONG = 0 TO UBOUND(MyDogs)
    PRINT MyDogs(i)
  NEXT
END SUB

FindMyDogs("spike", "bitter", "bobby")
srvaldez wrote: Jul 17, 2022 13:49 have a look at https://github.com/glasyalabolas/fb-collections , specifically look at the Dictionary bi and examples
I looked at the dictionary examples and some of the other examples and couldn't find anything like that. Could you point it out?
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: How could I imitate VBScript Array() function?

Post by TeeEmCee »

Instead of using wrapper macros (which aren't even possible for functions), here's a generic implementation of an Array macro for strings specifically:

Code: Select all

Type StrArrayType
    contents(any) as string
End Type

Function hStrArray(count as integer, ...) as StrArrayType
    dim ret as StrArrayType
    redim ret.contents(0 to count - 1)
    dim args As cva_list
    cva_start(args, count)

    for idx as integer = 0 to count - 1
        'Strings passed as variable arguments are converted to zstring ptrs
        ret.contents(idx) = *cva_arg(args, zstring ptr)
    next

    cva_end(args)
    return ret
End Function

#define Array(strings...) hStrArray(__FB_ARG_COUNT__(strings), strings).contents()
Example:

Code: Select all

SUB FindMyDogs(MyDogs() AS STRING)
  FOR i AS ULONG = 0 TO UBOUND(MyDogs)
    PRINT MyDogs(i)
  NEXT
END SUB

FindMyDogs(Array("spike", "bitter", "bobby"))
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How could I imitate VBScript Array() function?

Post by dodicat »

Up to 26 pooches.

Code: Select all


#define setz(z) z as string =""
#define setstrings setz(a),setz(b),setz(c),setz(d),setz(e),setz(f),setz(g), _
                   setz(h),setz(i),setz(j),setz(k),setz(l),setz(m),setz(n), _
                   setz(o),setz(p),setz(q),setz(r),setz(s),setz(t),setz(u), _
                   setz(v),setz(w),setz(x),setz(y),setz(z)
#define alphabet a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z 


type array
      as string st(1 to 26)
      declare constructor(setstrings)
      declare operator cast() as string
end type

constructor array(setstrings)
dim as string gg(1 to 26)={alphabet}
for n as long=1 to 26
      st(n)=gg(n)
      next
end constructor

operator array.cast() as string
for n as long=1 to 26
      if this.st(n)<>"" then print st(n)
next n
return ""
end operator


var mydogs=array("Tommy","Sheba","Candy","Louis","Gilly","Bob")

print mydogs
print "press any key to end"
sleep

 
This is a true story of my life with dogs, alas only Bob is left.
Julcar
Posts: 141
Joined: Oct 19, 2010 18:52
Contact:

Re: How could I imitate VBScript Array() function?

Post by Julcar »

TeeEmCee wrote: Jul 22, 2022 10:03 Instead of using wrapper macros (which aren't even possible for functions), here's a generic implementation of an Array macro for strings specifically:

Code: Select all

Type StrArrayType
    contents(any) as string
End Type

Function hStrArray(count as integer, ...) as StrArrayType
    dim ret as StrArrayType
    redim ret.contents(0 to count - 1)
    dim args As cva_list
    cva_start(args, count)

    for idx as integer = 0 to count - 1
        'Strings passed as variable arguments are converted to zstring ptrs
        ret.contents(idx) = *cva_arg(args, zstring ptr)
    next

    cva_end(args)
    return ret
End Function

#define Array(strings...) hStrArray(__FB_ARG_COUNT__(strings), strings).contents()
Example:

Code: Select all

SUB FindMyDogs(MyDogs() AS STRING)
  FOR i AS ULONG = 0 TO UBOUND(MyDogs)
    PRINT MyDogs(i)
  NEXT
END SUB

FindMyDogs(Array("spike", "bitter", "bobby"))
Hey! I look this very promising, I didn't know you can use variadic (...) as array parameter
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How could I imitate VBScript Array() function?

Post by fxm »

To work on Windows:
Function hStrArray cdecl(count as integer, ...) as StrArrayType
(cdecl is the default calling convention on Linux only)
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: How could I imitate VBScript Array() function?

Post by TeeEmCee »

Oh, right.

The disadvantage of dodicat's solution is that it's less efficient: the compiler always initialises and passes 26 strings. Plus obviously it's limited in the number of args. Also, the "st(n)=gg(n)" line does an additional string copy, which could be eliminated by writing directly to the st() array.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: How could I imitate VBScript Array() function?

Post by Lost Zergling »

@TeeEmCee. Very nice implementation. Interesting, a taste of virtual function using #define in FB ?
Intuitively, I would have expect
define Array(strings...) hStrArray(__FB_ARG_COUNT__(strings), strings.contents())
instead of
define Array(strings...) hStrArray(__FB_ARG_COUNT__(strings), strings).contents()
:-)
However, I wonder what is actual memory scope (persistency) of Array ?
Is it static ? Or if FindMyDog was a function, does it vanish out of scope ? Would be.perfect.
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: How could I imitate VBScript Array() function?

Post by TeeEmCee »

Lost Zergling wrote: Jul 27, 2022 22:21 However, I wonder what is actual memory scope (persistency) of Array ?
It is a temporary value on the stack which is destructed after the call to FindMyDogs.

However looking at the code generated by fbc I see (remember) that hArray actually constructs the 'ret' array, copies it into the array that's actually returned (the temp value in the parent scope), and deletes 'ret'. Unfortunately I don't think that inefficiency can be avoided in FB except by using global variables instead of returning values from functions. In which case hArray could return a StrArrayType pointer.
Post Reply