'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

General FreeBASIC programming questions.
Post Reply
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

'Procptr (member procedure address)' now allows virtual member operator chaining when inheritance/polymorphism

It is only since fbc 1.10.0 that the 'Procptr (member procedure address)' operator allows virtual member operator chaining when inheritance or polymorphism.
Previously, such chaining was impossible to code safely.

- Example with the 'Cast' member operator:

Code: Select all

Type Parent Extends Object
    Dim As String Sp = "   Parent"
    Declare Virtual Operator Cast() As String
End Type

Operator Parent.Cast() As String
    Return This.Sp
End Operator

Type Child Extends Parent
    Dim As String Sc = "   Child"
    Declare Virtual Operator Cast() As String
End Type

Operator Child.Cast() As String
'    Print Cast(Parent, This)         '' NOK : infinite loop
    Print Procptr(Parent.Cast)(This)  '' OK
    Return This.Sc
End Operator

Dim As Parent p
Dim As Child c               '' for inheritance tests
Dim Byref As Parent rpc = c  '' for polymorphism tests

Print "'Print p' :"
Print p
Print

Print "'Print c' :"
Print c
Print

Print "'Print rpc' :"
Print rpc
Print

Sleep
  • Code: Select all

    'Print p' :
       Parent
    
    'Print c' :
       Parent
       Child
    
    'Print rpc' :
       Parent
       Child
    

- Example with the '@' member operator:

Code: Select all

Type Parent Extends Object
    Dim As String Sp = "   Parent"
    Declare Virtual Operator @() As String Ptr
End Type

Operator Parent.@() As String Ptr
    Return @This.Sp
End Operator

Type Child Extends Parent
    Dim As String Sc = "   Child"
    Declare Virtual Operator @() As String Ptr
End Type

Operator Child.@() As String Ptr
'    Print *@Cast(Parent, This)     '' NOK : infinite loop
    Print *Procptr(Parent.@)(This)  '' OK
    Return @This.Sc
End Operator

Dim As Parent p
Dim As Child c               '' for inheritance tests
Dim Byref As Parent rpc = c  '' for polymorphism tests

Print "'Print *@p' :"
Print *@p
Print

Print "'Print *@c' :"
Print *@c
Print

Print "'Print *@rpc' :"
Print *@rpc
Print

Sleep
  • Code: Select all

    'Print *@p' :
       Parent
    
    'Print *@c' :
       Parent
       Child
    
    'Print *@rpc' :
       Parent
       Child
    

- Example with the 'Let' member operator:

Code: Select all

Type Parent Extends Object
    Dim As Integer Ip
    Declare Virtual Operator Let(Byref p As Parent)
End Type

Operator Parent.Let(Byref p As Parent)
    This.Ip = p.Ip
    Print "   (lhs).Ip = (rhs).Ip"
End Operator

Type Child Extends Parent
    Dim As Integer Ic
    Declare Virtual Operator Let(Byref p As Parent)
End Type

Operator Child.Let(Byref p As Parent)
'    Cast(Parent, This) = p       '' NOK : infinite loop
    Procptr(Parent.Let)(This, p)  '' OK
    If p Is Child Then
        This.Ic = Cptr(Child Ptr, @p)->Ic
        Print "   (lhs).Ic = (rhs).Ic"
    End If
End Operator

Dim As Parent p1, p2
Dim As Child c1, c2                       '' for inheritance tests
Dim Byref As Parent rpc1 = c1, rpc2 = c2  '' for polymorphism tests

Print "'p1 = p2' :"
p1 = p2
Print

Print "'c1 = c2' :"
c1 = c2
Print

Print "'rpc1 = rpc2' :"
rpc1 = rpc2
Print

Print "'rpc1 = c2' :"
rpc1 = c2
Print

Print "'c1 = rpc2' :"
c1 = rpc2
Print

Sleep
  • Code: Select all

    'p1 = p2' :
       (lhs).Ip = (rhs).Ip
    
    'c1 = c2' :
       (lhs).Ip = (rhs).Ip
       (lhs).Ic = (rhs).Ic
    
    'rpc1 = rpc2' :
       (lhs).Ip = (rhs).Ip
       (lhs).Ic = (rhs).Ic
    
    'rpc1 = c2' :
       (lhs).Ip = (rhs).Ip
       (lhs).Ic = (rhs).Ic
    
    'c1 = rpc2' :
       (lhs).Ip = (rhs).Ip
       (lhs).Ic = (rhs).Ic
    
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

'Procptr (vtable index)' now allows to start, as a secondary thread, the most derived virtual subroutine associated to a based-type object

It is only since fbc 1.10.0 that the 'Procptr (vtable index)' operator allows to start, as a secondary thread, the most derived virtual subroutine associated to an object in a polymorphic list.
Previously, such thread launching was impossible to code safely.

Example with an inheritance structure and a based-type list of different derived objects:

Code: Select all

Type animal Extends Object
    Dim As String s = "   animal"
    Declare Virtual destructor()
    Declare Virtual Sub thread()
End Type

Destructor animal()
End Destructor

Sub animal.thread()
    Print This.s
End Sub

Type cat Extends animal
    Dim As String s = "   cat"
    Declare Virtual destructor()
    Declare Virtual Sub thread()
End Type

Destructor cat()
End Destructor

Sub cat.thread()
    Print This.s
End Sub

Type dog Extends animal
    Dim As String s = "   dog"
    Declare Virtual destructor()
    Declare Virtual Sub thread()
End Type

Destructor dog()
End Destructor

Sub dog.thread()
    Print This.s
End Sub

'' polymorphic list of objects
Dim As animal Ptr p(...) = {New animal, New cat, New dog}

'' Normal call for each object in the polymorphic list
Print "Normal calls:"
For I As Integer = Lbound(p) To Ubound(P)
    p(I)->thread()
Next I
Print

'' Thread launch for each object in the polymotphic list
Print "Thread launches:"
For I As Integer = Lbound(p) To Ubound(P)
    Dim As Any Ptr pt = Threadcreate(CPtr(Any Ptr Ptr Ptr, p(I))[0][ProcPtr(animal.thread, Virtual)], p(I))
    Threadwait(pt)
Next I
Print

For I As Integer = Lbound(p) To Ubound(P)
    Delete p(I)
Next I

Sleep
  • Code: Select all

    Normal calls:
       animal
       cat
       dog
    
    Thread launches:
       animal
       cat
       dog
    
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

'Procptr (member procedure address)' currently does not support non-member overload operators

@Jeff,

'Procptr (member procedure address)' could support a non-member overload operators by using as second argument the user operator signature, in order to resolve the operator overload.

Is such a complement expected in the short term ?

Example that does not currently work:

Code: Select all

Type Vector2D
    As Single x, y
End Type

Operator Abs ( ByRef rhs As Vector2D ) As Single
    Return Sqr( rhs.x * rhs.x + rhs.y * rhs.y )
End Operator

Print Procptr( Abs , Function ( ByRef As Vector2D ) As Single )  '' error 24: Invalid data types, before ','

Sleep
  • (a workaround wold be to define a wrapper function on the Abs operator)
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by coderJeff »

fxm wrote: Feb 27, 2024 13:08 'Procptr (member procedure address)' could support a non-member overload operators by using as second argument the user operator signature, in order to resolve the operator overload.

Is such a complement expected in the short term ?
In the short term, probably can be achieved because it looks to be mostly a parsing problem and some management of information within the compiler.

I check my notes and I think I left off working on:
- allowing global namespace specifier for global operators (e.g. '..+', '..ABS', etc)
- some internal support functions for working with operators

For interest:
- "ABS" is first seen as a global keyword.
- The parser then writes it in to the AST as an operator.
- lookup for global operator is different than the methods used so far for procedure lookups
- Only when the AST is flushed will the implementation of a global operator be realized. It may be emitted as a procedure call, a builtin in backend expression, or some inline code.
paul doe
Moderator
Posts: 1736
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by paul doe »

What would be a valid use case for this? Either I'm missing something, or I don't see the point of it...
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

paul doe wrote: Mar 01, 2024 11:15 What would be a valid use case for this?
The same way as its use with an overload static subroutine or function.
paul doe
Moderator
Posts: 1736
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by paul doe »

I know that. I guess I'll have to sit down and think a useful use case for the feature...
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

For example to pass an operator to a procedure, in the same way we can pass a sub/function to a procedure.
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by fxm »

For example:

Code: Select all

Type operatorType As Function(Byval As Integer, Byval As Integer) As Integer

Function evaluate(Byval p As operatorType, Byval a As Integer, ByVal b As Integer) As Integer
    Return p(a, b)
End Function

Print evaluate(Procptr(+, operatorType), 3, 5)
Print evaluate(Procptr(-, operatorType), 13, 4)
Print evaluate(Procptr(*, operatorType), 2, 3)
Print evaluate(Procptr(\, operatorType), 14, 3)
Print evaluate(Procptr(mod, operatorType), 12, 5)

Sleep
instead of (with wrapper functions):

Code: Select all

Type operatorType As Function(Byval As Integer, Byval As Integer) As Integer

Function plus Overload(Byval a As Integer, Byval b As Integer) As Integer
    Return a + b
End Function

Function minus Overload(Byval a As Integer, Byval b As Integer) As Integer
    Return a - b
End Function

Function mul Overload(Byval a As Integer, Byval b As Integer) As Integer
    Return a * b
End Function

Function intdiv Overload(Byval a As Integer, Byval b As Integer) As Integer
    Return a \ b
End Function

Function modulus Overload(Byval a As Integer, Byval b As Integer) As Integer
    Return a Mod b
End Function

'Function .....

'Function .....

Function evaluate(Byval p As operatorType, Byval a As Integer, ByVal b As Integer) As Integer
    Return p(a, b)
End Function

Print evaluate(Procptr(plus, operatorType), 3, 5)
Print evaluate(Procptr(minus, operatorType), 13, 4)
Print evaluate(Procptr(mul, operatorType), 2, 3)
Print evaluate(Procptr(intdiv, operatorType), 14, 3)
Print evaluate(Procptr(modulus, operatorType), 12, 5)

Sleep
or instead of (with systematic test):

Code: Select all

Function evaluate(Byref op As String, Byval a As Integer, ByVal b As Integer) As Integer
    Select Case Ucase(op)
    Case "+"
        Return a + b
    Case "-"
        Return a - b
    Case "*"
        Return a * b
    Case "\"
        Return a \ b
    Case "MOD"
        Return a Mod b
'    Case .....
'    Case .....
    Case Else
        Return 0
    End Select
End Function

Print evaluate("+", 3, 5)
Print evaluate("-", 13, 4)
Print evaluate("*", 2, 3)
Print evaluate("\", 14, 3)
Print evaluate("Mod", 12, 5)

Sleep
paul doe
Moderator
Posts: 1736
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by paul doe »

For the last time, I know all this. But I have a hard time figuring out a useful use case for this. Operators be operators; we use them in expressions, we don't pass them as arguments to functions. The only language I can think of that has this feature is Forth, and that only because of its architecture. Even in Forth, I can't think of a useful case for this. But alas, if it's not much fuss to add this, then why not I guess...
dafhi
Posts: 1645
Joined: Jun 04, 2005 9:51

Re: 'Procptr' now supports member procedures/operators as well as their indexing in vtable for virtuals

Post by dafhi »

i can think of a few. run-time eval, procedural functions. i'll keep it on my back-burner
Post Reply