TYPEOF() changes, or something new?

Forum for discussion about the documentation project.
Post Reply
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

TYPEOF() changes, or something new?

Post by speedfixer »

At present (mine: Version 1.06.0 (02-17-2019) this code doesn't work:

Code: Select all

dim as integer aa
dim as string bb
dim as integer ptr ppi
dim as string ptr pps

aa = 1
bb = "l"

ppi = @aa
pps = @bb

print typeof(aa)

if ((typeof(aa)) = (typeof(bb))) then print "true"  ' or any variation of (())

if ((typeof(ppi)) = (typeof(pps))) then print "true"
1 - Is this code bad, or can it be made to work?
(I want this to work in the runtime, not the preprocessor. When only pointers are flying around, this could be valuable.)

2 - And, am I seeing that the new array features effort would allow this to work as a true, full keyword in the runtime - for arrays only?
If so, shouldn't any new UDT type be enumerated so each would have its own type id in the runtime? The preprocessor has to do this already. I have to believe that the debug code should have an amount of code that could point the way. A programmer just has to know his code and old libraries and that a UDT id is not fixed if he codes some static linked functions. Or, better, could that new id be derived or assigned (think, FREEFILE) so that he can track them himself. Lots of possible wrinkles around this.

There should be room for 2 bytes (and a new table in debug) or so to allow something like this.

If new, extra code is included just for the array feature work, and TYPEOF modded (or a new keyword introduced) - shouldn't it be complete?
With this, '-exx' or '-nostrip' could keep and table the typenames so more convenient errors checks/msgs could be possible. The error/debug routines are going to have to be addressed, anyway. If the meat of your routines lie in only pushing pointers around, your view gets muddy very quickly.

Is this not practical?

(Just my thoughts.)

david
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Re: TYPEOF() changes, or something new?

Post by Juergen Kuehlwein »

I made TYPEOF() work in regular code too in my array additions. It returns the the name of a variable´s type as an uppercase string for all variables (not only arrays). This may seem not to be the most elegant solution, but it allows to distinguish between different UDTs, because the name as given in TYPE <name> is returned.

Another approach would be to make use of the compiler´s internal "dtype", which would return all standard types (including UDTs), but cannot keep apart different UDTs. I need to keep apart different UDTs, therefore i used TYPEOF()

To my knowledge the preprocessor doesn´t assign IDs to UDTs.


JK
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: TYPEOF() changes, or something new?

Post by dodicat »

Barring
print typeof(aa)
Which would have to be listed as per help file (#if typeof() = bla bla bla)
The other request could be answered by a macro.
(That is your question 1 only)

Code: Select all

Dim As Integer aa
Dim As String bb
Dim As Integer Ptr ppi
Dim As String Ptr pps


aa = 1
bb = "l"

ppi = @aa
pps = @bb

#macro compare(a,b,res)
#if typeof(a)=typeof(b)
res=true
#else
res=false
#endif
#endmacro

Dim As Long counter
Dim As boolean res
Do
    counter+=1  
    
    compare(aa,bb,res)
    Print res;" ";
    
    compare(ppi,pps,res)
    Print res;" ";
    
    Dim As Ubyte Ptr Ptr x,y
    compare(x,y,res)
    
    Print res;" ";
    
    Select Case counter
    Case 2
        Dim As Long x
        Dim As Integer y
        compare(x,y,res)
        Print res;" ";
        
    Case 3
        Dim As Double x,y
        compare(x,y,res)
        Print res;" ";
        
    case 5
    print "skip";" ";
    
    case 10
        counter=0
        print
        print "Start again"
        randomize
        
    Case Is>3
        If Rnd>.5 Then
            Dim As zstring Ptr x,y
            compare(x,y,res)
            Print res;" ";
        Else
            Dim As zstring Ptr x
            Dim As wstring Ptr y
            compare(x,y,res)
            Print res;" "; 
        End If
        
    
    
    End Select
    
    Print
    Sleep
    
Loop Until Inkey=Chr(27)
Sleep




'print typeof(aa)

'if ((typeof(aa)) = (typeof(bb))) then print "true"  ' or any variation of (())

'if ((typeof(ppi)) = (typeof(pps))) then print "true"   
Keep pressing space, when you get fed up press <esc>
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: TYPEOF() changes, or something new?

Post by speedfixer »

Excellent.
You answered most of my questions/concerns.

It will be a bit before I am able to check this new TYPEOF for myself, but it sounds like it is much more as I felt it should be, now.

Thank you.

david
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: TYPEOF() changes, or something new?

Post by fxm »

Presently, the only typenames accessible (not easily) by user at run-time are those of UDTs extending the built-in OBJECT (thanks to RTTI).
See my article "How using RTTI from FB built-in OBJECT to extract Typename and those of all Bases of an instance" for more information.

One workaround (rather heavy) for your concern is to create your own UDT objects (integer object and string object in your case) and to get their types from the RTTI information block.
Example for the fun:

Code: Select all

Function typeNameFromRTTI (Byref o As Object, Byval baseIndex As Integer = 0) As String
  ' Function to get any typename in the inheritance up hierarchy
  ' of the type of an instance ('o') compatible with the built-in 'Object'
  '
  ' ('baseIndex =  0' to get the typename of the instance)
  ' ('baseIndex = -1' to get the base.typename of the instance, or "" if not existing)
  ' ('baseIndex = -2' to get the base.base.typename of the instance, or "" if not existing)
  ' (.....)
  '
    Dim As String s
    Dim As Zstring Ptr pz
    Dim As Any Ptr p = Cptr(Any Ptr Ptr Ptr, @o)[0][-1]     ' Ptr to RTTI info
    For I As Integer = baseIndex To -1
      p = Cptr(Any Ptr Ptr, p)[2]                           ' Ptr to Base RTTI info of previous RTTI info
      If p = 0 Then Return s
    Next I
    pz = Cptr(Any Ptr Ptr, p)[1]                            ' Ptr to mangled-typename
    Do
      Do While (*pz)[0] > Asc("9") Orelse (*pz)[0] < Asc("0")
        If (*pz)[0] = 0 Then Return s
        pz += 1
      Loop
      Dim As Integer N = Val(*pz)
      Do
        pz += 1
      Loop Until (*pz)[0] > Asc("9") Orelse (*pz)[0] < Asc("0")
      If s <> "" Then s &= "."
      s &= Left(*pz, N)
      pz += N
    Loop
End Function


Type integer_UDT Extends Object
  Dim As Integer I
  Declare Constructor (Byval i As Integer = 0)
  Declare Operator Let (Byval i As Integer)
  Declare Operator Cast () Byref As Integer
End Type
Constructor integer_UDT (Byval i As Integer = 0)
  This.I = i
End Constructor
Operator integer_UDT.Let (Byval i As Integer)
  This.I = i
End Operator
Operator integer_UDT.Cast () Byref As Integer
  Return This.I
End Operator

Type string_UDT Extends Object
  Dim As String S
  Declare Constructor (Byref s As String = "")
  Declare Operator Let (Byref s As String)
  Declare Operator Cast () Byref As String
End Type
Constructor string_UDT (Byref s As String = "")
  This.S = s
End Constructor
Operator string_UDT.Let (Byref s As String)
  This.S = s
End Operator
Operator string_UDT.Cast () Byref As String
  Return This.S
End Operator


Dim As Integer_UDT aa
Dim As string_UDT bb
Dim As integer_UDT Ptr ppi
Dim As string_UDT Ptr pps

aa = 1
bb = "1"

ppi = @aa
pps = @bb

Print "Type(aa) : ";
Print typeNameFromRTTI(aa)
Print "Type(bb) : ";
Print typeNameFromRTTI(bb)
Print
Print "(Type(aa) = Type(bb)) ? ";
if typeNameFromRTTI(aa) = typeNameFromRTTI(bb) then print "true" else print "false"
Print "(Type(*ppi) = Type(*pps)) ? ";
if typeNameFromRTTI(*ppi) = typeNameFromRTTI(*pps) then print "true" else print "false"
Print "(Type(aa) = Type(*ppi)) ? ";
if typeNameFromRTTI(aa) = typeNameFromRTTI(*ppi) then print "true" else print "false"
Print "(Type(bb) = Type(*pps)) ? ";
if typeNameFromRTTI(bb) = typeNameFromRTTI(*pps) then print "true" else print "false"

Sleep

Code: Select all

Type(aa) : INTEGER_UDT
Type(bb) : STRING_UDT

(Type(aa) = Type(bb)) ? false
(Type(*ppi) = Type(*pps)) ? false
(Type(aa) = Type(*ppi)) ? true
(Type(bb) = Type(*pps)) ? true
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: TYPEOF() changes, or something new?

Post by speedfixer »

Thank you.
Post Reply