TypeOf()

Just starting out? Need help? Post your questions and find answers here.
Little John
Addict
Addict
Posts: 4823
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

TypeOf()

Post 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()?
User avatar
idle
Always Here
Always Here
Posts: 6130
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: TypeOf()

Post 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
Little John
Addict
Addict
Posts: 4823
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: TypeOf()

Post 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!
Little John
Addict
Addict
Posts: 4823
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: TypeOf()

Post 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())
#NULL
Addict
Addict
Posts: 1500
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: TypeOf()

Post 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.
Little John
Addict
Addict
Posts: 4823
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: TypeOf()

Post 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())
Post Reply