Page 1 of 1

TypeOf()

Posted: Tue Dec 30, 2025 7:13 pm
by Little John
In the following code, both lines at the end raise an error if uncommented. Why?

Code: Select all

; PB 6.30 beta 5 (x64) on Windows

Macro ShowType (_x_)
   Select TypeOf(_x_)
      Case #PB_Array
         Debug "Array"
      Case #PB_Integer
         Debug "Integer"
      Default
         Debug "Other"
   EndSelect
EndMacro


Dim a.i(5)

; ShowType(a())   ; -> error (should display "Array")
; ShowType(a(0))  ; -> error (should display "Integer")
In the help for TypeOf(), it reads:
Return value

The type of the object.

The type can be one of the following values:
#PB_Byte
#PB_Word
#PB_Long
#PB_String
#PB_Structure
#PB_Float
#PB_Character
#PB_Double
#PB_Quad
#PB_List
#PB_Array
#PB_Integer
#PB_Map
#PB_Ascii
#PB_Unicode
#PB_Interface
How can the return value be #PB_Array, if an array is not accepted as argument for TypeOf()?

Re: TypeOf()

Posted: Tue Dec 30, 2025 10:09 pm
by idle
not sure if the behavior changed or not, though it doesn't exactly match the documentation.
It only work through structures and you still can't drill down into it to get the type of the array, it's not runtime.

Code: Select all

; PB 6.30 beta 5 (x64) on Windows

Macro ShowType (_x_)
   Select TypeOf(_x_)
      Case #PB_Array
         Debug "Array"
      Case #PB_Integer
         Debug "Integer"
      Default
         Debug "Other"
   EndSelect
EndMacro

Structure foo 
  a.i 
  Array b.i(0) 
EndStructure  

Global a.foo 

ShowType(a\a)   ;(should display "Integer")
ShowType(a\b)  ;(should display "Array")
A bit more info

the typeof functionality is used by the compiler to make a structure layout table which is only inserted into a binary when you need to dynamically create and copy structures. The information is the bare minimum to initialize, copy and free nested structures but it doesn't provide reflection capabilities to the user.

Type reflection has technically been added by the JSON lib which makes a 2nd structure layout table for specific json structures which includes the field names and types but that not directly accessible to users at runtime, it's abstracted away and used by copyjsonstructure

I hacked a fix so you can use the json info but it's baked into my DB engine though the x64 asm version here shows how it works.
viewtopic.php?p=624129#p624129

Re: TypeOf()

Posted: Wed Dec 31, 2025 8:03 pm
by Little John
Oops, I didn't think about TypeOf() working at compile time for the moment. However, if I replace Select with CompilerSelect, Case with CompilerCase etc., then my above code doesn't work either.

Thanks for the explanation, idle!

Re: TypeOf()

Posted: Thu Jan 01, 2026 2:24 pm
by Little John
My actual goal is to write procedures for arrays, lists, and maps that can process all simple data types. I thought that TypeOf() could help with this. I thought that instead of writing 11 individual procedures, something like the following could work:

Code: Select all

Macro WriteProcedureHeader (_x_)
   CompilerSelect TypeOf(_x_(0))
      CompilerCase #PB_Ascii
         Procedure MyProcedure(_x_.a(1))
      CompilerCase #PB_Byte
         Procedure MyProcedure(_x_.b(1))
      CompilerCase #PB_Character
         Procedure MyProcedure(_x_.c(1))
      CompilerCase #PB_Double
         Procedure MyProcedure(_x_.d(1))
      CompilerCase #PB_Float
         Procedure MyProcedure(_x_.f(1))
      CompilerCase #PB_Integer
         Procedure MyProcedure(_x_.i(1))
      CompilerCase #PB_Long
         Procedure MyProcedure(_x_.l(1))
      CompilerCase #PB_Quad
         Procedure MyProcedure(_x_.q(1))
      CompilerCase #PB_String
         Procedure MyProcedure(_x_.s(1))
      CompilerCase #PB_Unicode
         Procedure MyProcedure(_x_.u(1))
      CompilerCase #PB_Word
         Procedure MyProcedure(_x_.w(1))
   CompilerEndSelect
EndMacro


Dim a.i(5)

WriteProcedureHeader(a)
   Debug a(2)
EndProcedure

MyProcedure(a())

Re: TypeOf()

Posted: Thu Jan 01, 2026 5:57 pm
by #NULL
I would say it's a bug. Also doesn't work with Lists and Maps.

Code: Select all

Define i.i
NewMap m.i()
NewList l.i()
AddElement(l())
l() = 123
Debug l()
Debug TypeOf(i)
;Debug TypeOf(l)
;Debug TypeOf(l())

Also, I would think at least for lists, you would have to omit the braces to get type 'list' and not the element type 'integer' or such. So for consistency you probably would have to omit the braces for arrays and maps as well to get the collection type. But I don't remember how or if it ever worked.

Re: TypeOf()

Posted: Sun Jan 04, 2026 3:37 pm
by Little John
Hi #NULL,

thanks for your reply.
I agree with you. I wrote a corresponding bug report.

At least I've now managed to get some executable code that does what I want by using a dummy variable.
Whether such code will prove useful in practice is another question. ;-)

Code: Select all

; PB 6.30 beta 5

EnableExplicit

Macro ProcedureHeader (_x_)
   CompilerSelect TypeOf(_x_)
      CompilerCase #PB_Ascii
         Procedure MyProcedure_a(Array _x_.a(1))
      CompilerCase #PB_Byte
         Procedure MyProcedure_b(Array _x_.b(1))
      CompilerCase #PB_Character
         Procedure MyProcedure_c(Array _x_.c(1))
      CompilerCase #PB_Double
         Procedure MyProcedure_d(Array _x_.d(1))
      CompilerCase #PB_Float
         Procedure MyProcedure_f(Array _x_.f(1))
      CompilerCase #PB_Integer
         Procedure MyProcedure_i(Array _x_.i(1))
      CompilerCase #PB_Long
         Procedure MyProcedure_l(Array _x_.l(1))
      CompilerCase #PB_Quad
         Procedure MyProcedure_q(Array _x_.q(1))
      CompilerCase #PB_String
         Procedure MyProcedure_s(Array _x_.s(1))
      CompilerCase #PB_Unicode
         Procedure MyProcedure_u(Array _x_.u(1))
      CompilerCase #PB_Word
         Procedure MyProcedure_w(Array _x_.w(1))
   CompilerEndSelect
EndMacro


Define s.i          ; Dummy variable with the same type ...

ProcedureHeader(s)
   Debug ArraySize(s())
EndProcedure

Dim a.i(5)          ; ... as the array that we want to use
MyProcedure_i(a())

; --------------------

Define t.f          ; Dummy variable with the same type ...

ProcedureHeader(t)
   Debug ArraySize(t())
EndProcedure

Dim b.f(8)          ; ... as the array that we want to use
MyProcedure_f(b())