FreeBASIC syntax challenge games

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

FreeBASIC syntax challenge games

Post by fxm »

Enigma #1, force 1 (for the beginning)

Without modifying the code already existing, only insert your own code (one line is sufficient here) under the matching comment so that the program works as requested:

Code: Select all

Type UDT Extends Object
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = Cast(Byte Ptr, @This.dummy) - Offsetof(UDT, dummy) Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p
' Other lines of code and allocations may follow here

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------



'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep
[edit]
- Code of member function checkAddr() improved from a dodicat's proposal.
Last edited by fxm on Dec 20, 2016 11:41, edited 8 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: FreeBASIC syntax challenge game

Post by MrSwiss »

You should perhaps, change the Title to "FreeBASIC OO syntax challenge game" ...
(to be more closely to the point at issue)
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

I rather put a "s" to "game"!
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

Since @ cannot be used, and there is no equivalent, then We cheat!

Code: Select all

Type UDT Extends Object
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = @This.dummy - 1 Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------

dim as any ptr q 'next memory slot
p=@q              'get the address
p=p+2*sizeof(integer) 'relocate 2 pointers (size of ptr = sizeof integer)


'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep 
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

No, there is a very simple and safe solution in a pure FreeBASIC (a short line of code) without cheating neither presuming where the memory for 'u' is allocated.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

After almost 100 views, I am surprised because I thought the solution was very simple to find, a simple and short code line (or this does not interest many people).
I thought that this first challenge was only a warm up.
I'm afraid for the in-continuation challenge (higher level) I have already prepared.

To help those who still want to play, I could point out the fact that UDT extends OBJECT.
(If necessary, a second largest indication will follow)
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

If you get @(object) then you can get @u.
But it is the same principle as my last solution, an offset from a known address.

Code: Select all

Type UDT Extends Object
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = @This.dummy - 1 Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------

p=@object-iif(sizeof(object)=8,4,3)



'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep 
But this solution is messy and crappy.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Yes, a proposal similar to your previous one:
@object
is a shortcut for
@object()
which constructs a temporary instance of OBJECT.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Last indication:
Look at the description of keyword CAST in documentation, paragraph: "Upcasting" (only two lines).
greenink
Posts: 200
Joined: Jan 28, 2016 15:45

Re: FreeBASIC syntax challenge games

Post by greenink »

The problem is most people who use Basic are interested in "plain facts" programming, not tricks.
sancho2
Posts: 547
Joined: May 17, 2015 6:41

Re: FreeBASIC syntax challenge games

Post by sancho2 »

p = @Cast(object, u)

Not possible for me without the last hint. And this is the easy one.
I think that this kind of challenge could be a great learning tool.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

sancho2 wrote:p = @Cast(object, u)
You have won!
sancho2 wrote:I think that this kind of challenge could be a great learning tool.
That's how I also see it.

What is important to remember from this challenge is that 'Cast()' returns generally by value.
In only some cases, it returns by reference:
- When upcasting an instance (thanks to inheritance).
- When casting a variable of integer datatype while remaining in a similar datatype (for example: 'byte' <-> 'ubyte', or 'integer <-> uinteger', ...).

As 'Cast(Object, u)' is a (temporary) reference of type 'Object', referring to 'u' of type 'UDT', both verify:
@Cast(Object, u) = @u
and this equality is verified only because of referencing.

The '@' operator is private only for an 'UDT' instance (and not for an 'Object' instance), we can so get the address of 'u' by using a reference to 'u', but of an other type (as 'Object').

Full solution:

Code: Select all

Type UDT Extends Object
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = Cast(Byte Ptr, @This.dummy) - Offsetof(UDT, dummy) Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p
' Other lines of code and allocations may follow here

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------

p = @Cast(Object, u)

'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep
For those which do not like use the operator Cast(), another solution but in 2 lines:
Dim Byref As Object o = u
p = @o


[edit]
- Added another solution (2 lines)
Last edited by fxm on Jan 03, 2017 19:33, edited 2 times in total.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Enigma #2, force 3 (for continuing)

The same problem except that now the UDT no longer extends another Type.
One must find a more generic solution which works for any datatype, pre-defined type or user type (therefore also works for the previous case).

Without modifying the code already existing, only insert your own code (a few lines, 4 for my solution, must be sufficient here) under the matching comment so that the program works as requested:

Code: Select all

Type UDT
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = Cast(Byte Ptr, @This.dummy) - Offsetof(UDT, dummy) Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p
' Other lines of code and allocations may follow here

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------







'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep
As before, the solution is a safe code in pure FreeBASIC.
I still wait a bit before giving an indication.


[edit]
- Code of member function checkAddr() improved from a dodicat's proposal.
Last edited by fxm on Dec 20, 2016 11:42, edited 8 times in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

I am not very good at this stuff.
Although interested.

I can only suggest creating a clone of the first udt (twin udt's), then taking two steps through the stack, back to where the first udt was born.
In this respect, if the first udt (twin) is either extremely lean (as your example) or stuffed full of fields, then the second twin will be also, so two steps back should be correct in either case.

Code: Select all

Type UDT
  Public:
    Declare Function checkAddr (Byval pu As Any Ptr) As String
  Private:
    Declare Operator @ () As Any Ptr
    Dim As Any Ptr dummy
End Type
Function UDT.checkAddr (Byval pu As Any Ptr) As String
    If pu = @This.dummy Then
      Return "Good address"
    Else
      Return "Bad address"
    End If
End Function

Dim As UDT u
Dim As Any Ptr p

'p = @u  ' error 201: Illegal member access, UDT.operator.@
'
' Insert below the right code to assign the address of u to p
' so that calling u.checkAddr(p) returns "Good address"
'--------------------- Begin insertion ----------------------

type identical extends udt
end type
dim as identical twin
p= cast(any ptr,@twin)+2*sizeof(twin)

'---------------------- End insertion -----------------------

Print u.checkAddr(p)

Sleep 
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Your proposal principle is similar to that proposed by dodicat, not safe and presuming the maping in memory between the various allocations.

You must consider that other lines of code and allocations (unknown) may follow the line:
Dim As Any Ptr p
just before your own inserted code.

I added a comment about that in my code template.

A very safe solution exists (4 lines for me), regardless of any memory mapping considerations.
Last edited by fxm on Dec 19, 2016 23:51, edited 2 times in total.
Post Reply