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

Re: FreeBASIC syntax challenge games

Post by fxm »

Enigma #22, force 1 (to rest a bit)

Through the following program, this challenge shows how a same member procedure ('Child.test()') can produce a different execution only depending on its calling way on a same object, either on Child-typed instance 'cc' (by static binding at compile-time), or on Parent-typed instance 'pc' (then dynamic binding at run-time).
Compile with fbc rev >= 1.04.0:

Code: Select all

Dim Shared As String s0
s0 = "Typename"

Type Parent Extends Object                            '' beginning of Parent type declaration
  Declare Abstract Sub test (Byref s As String = s0)
End Type                                              '' ending of Parent type declaration

Type Child Extends Parent                             '' beginning of Child type declaration
  Declare Sub test (Byref s As String = s0)
End Type                                              '' ending of Child type declaration

Sub Child.test (Byref s As String = s0)
  Print "Calling Child.test() on a " & s & "-typed instance"
End Sub


Dim As Child c
Dim Byref As Child cc = c
Dim Byref As Parent pc = c

cc.test()
pc.test()

Sleep
By inserting only one field in each of two type declarations ('Parent' and 'Child'), make that the above program prints the exact type of each of two instances ('cc' and 'pc') that refer to same object:
Calling Child.test() on a Child-typed instance
Calling Child.test() on a Parent-typed instance
Instead of:
Calling Child.test() on a Typename-typed instance
Calling Child.test() on a Typename-typed instance
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

This one seems very easy.

Do you need all the byref stuff to access the sub?
Or is it a deliberate complication!

Code: Select all

Dim Shared As String s0
s0 = "Typename"

Type Parent Extends Object                            '' beginning of Parent type declaration
     const s0="Parent"
  Declare Abstract Sub test (Byref s As String = s0)
End Type                                              '' ending of Parent type declaration

Type Child Extends Parent                             '' beginning of Child type declaration
    const s0="Child"
  Declare Sub test (Byref s As String = s0)
End Type                                              '' ending of Child type declaration

Sub Child.test (Byref s As String = s0)
  Print "Calling Child.test() on a " & s & "-typed instance"
End Sub


Dim As Child c
Dim Byref As Child cc = c
Dim Byref As Parent pc = c

cc.test()
pc.test()

print


type<Child>.test
*cast(parent ptr,@child).test




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

Re: FreeBASIC syntax challenge games

Post by fxm »

Yes, too easy (I didn't use 'Const so = "Typename"' in the global scope to avoid giving too many ideas for the solution):
- The default values of passed parameters by the caller are always defined at compile-time.
- I have just updated the documentation on the keyword "Const", because its visibility rules did not seem obvious to everyone (KeyPgConst → fxm [Added visibility rules]).

Under the hood, a string (var-len) is always passed by reference (like an array) because it is the address of its descriptor that is always passed.
If you choose the "Byval" passing mode, then a string copy is make, but this copy is itself passed by reference.
So there is no interest to pass a string by value (to avoid unnecessarily copying the string data characters) unless you want to be able to modify the passed string in the procedure body without impacting the original string.
(it's why the default passing mode of strings is by reference like for the arrays and type instances)
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

In your previous example, having sy and sn both constant, this works.
( *iif(cast(object,(expression)) is typename,@(typename),0))

But I think there is a bug somewhere in this:

Code: Select all

#undef private
#define private


type udt
    private:
    const s="Hello"
   as long dummy
end type



sub dothis constructor 
    print type<udt>.s
    end sub


sleep 
Mini challenge, get it to print "Hello".
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

dodicat wrote:In your previous example, having sy and sn both constant, this works.
( *iif(cast(object,(expression)) is typename,@(typename),0))
We can always call a non virtual member procedure on a null pointer:
- The program only crashes if it attempts to access a non static member data because none object has been constructed (for a virtual procedure, the crash is immediate because the vptr->vtable has not been constructed).
Last edited by fxm on Sep 16, 2017 22:05, 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 »

dodicat wrote:Mini challenge, get it to print "Hello".
My simplest modification to solve the challenge:

Code: Select all

#undef private
#define private

type udt
    private:
    const s="Hello"
    as long dummy = 0  '' added an initializer (or "= any") to impose an udt implicit constructor
end type

sub dothis constructor
    print type<udt>.s
    end sub

sleep 
or else:

Code: Select all

    print type<udt>(0).s
(these two solutions are not compatible together)
Last edited by fxm on Sep 16, 2017 22:16, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

That's right fxm.
Just initialize the dummy.
Or add another string field, no need to initializing it.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Enigma #23, force 3-4 (for those who claim more difficulty)

Code: Select all

#define instruction_1  '' To be completed with one very simple instruction
#define instruction_2  '' To be completed with one very simple instruction

Type Parent Extends Object
  Declare Virtual Sub method ()
  Dim As Integer I = 1
End Type
Sub Parent.method ()
  Print "Calling #" & This.I & " Parent.method()"
  This.I += 1
End Sub

Type Child Extends Parent
  Declare Sub method ()
End Type
Sub Child.method ()
  If This.I <= 7 Then
    instruction_1
    instruction_2
  End If
End Sub

Dim As Child c
Dim As Parent Ptr pc = @c
pc->method()

Sleep
By only defining 'instruction_1' and 'instruction_2' (the first two lines to be completed with one very simple instruction each), make that the above program prints the output as following:

Code: Select all

Calling #1 Parent.method()
Calling #2 Parent.method()
Calling #3 Parent.method()
Calling #4 Parent.method()
Calling #5 Parent.method()
Calling #6 Parent.method()
Calling #7 Parent.method()
[edit]
- The very simple solution only works for fbc revision >= 1.00.0
Last edited by fxm on Sep 23, 2017 8:46, edited 2 times in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

With #define in freebasic you have much scope to do things.
Create temporary variables, have two instructions separated by :, and much more

I have a solution, but will wait.
Perhaps my function could be used. (my own challenge from way back is still unanswered)

Code: Select all

dim as string s = _
"171792080305435183131953721961195267518616010730011635131441103102065819537186271918988328074582794119362878600779369001" + _
"175245860501686498391717920803054351831319537219611952675186160107300119482624500779315560082609239317684531781701654131" + _
"168502283602187625281886999562163264112519533919861954039072193596170117848276800225731429114295604216344932851444963698" + _
"197056573713946338251830838901186911651706904955880538970637054404128412268634251734702190122686320508241963841850018317" + _
"203555645201686500960543323475170199483218317610061869116517069049558805389706371852404304112631000417687133130589326190" + _
"053936950619362878280639650094134428316818521421771701654132168502283602203425681411391498077931556010262364890168636704" + _
"054345274102245563711409944842054351884118188472992017796196168495653216326411391953391986053897063718184533160543519329" + _
"054332347517524586050673211503115828663314114090060224751737165185613817684406081831756908186911651706904955880538970637" + _
"141140948107793155601027350601141139740802253387280538976266053897063718523832641970435187186918205102213395020538976266" + _
"053752963217637130561920234350176923531708451149910538970637053752963202202091841159733258122685963011582866941394631790" + _
"016864933317660667011933647981176844060816630672441766066701193364798119189801280544501349054437179210255327840224608288" + _
"076149146619528041580677670760021876253717015979620538996837"


function unscramble(g as string) as string
    
    
    
    
    
end function

print unscramble(s)
sleep 
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

dodicat wrote:With #define in freebasic you have much scope to do things.
Create temporary variables, have two instructions separated by :, and much more
But the expected solution is one single very simple instruction (so ":" forbidden) for eah of the two lines to complete.
(total of less than 30 characters for both lines)

Obviously, this type of proposal is out of demand:

Code: Select all

#define instruction_1  For I As Integer = 1 to 7:Print "Calling #" & I & " Parent.method()"
#define instruction_2  Next I'
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

dodicat wrote:I have a solution, but will wait.
Your proposal is really on the right way, but you can more simplify it:
- Try not to create a new object at each iteration.
- This will reduce instruction_1 and even instruction_2 (no longer need to increment 'I' also here).
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

fxm wrote:Your proposal is really on the right way, but you can more simplify it:
- Try not to create a new object at each iteration.
- This will reduce instruction_1 and even instruction_2 (no longer need to increment 'I' also here).
Are you still looking for my simplest and shortest solution?
If you wish, I can give you a little help!
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

Maybe let it run for a bit.
I don't have an elegant solution, others might want to give it a try.
Give a little clue in a couple of days if is not solved perhaps.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: FreeBASIC syntax challenge games

Post by dafhi »

quick research and now i know more about virtuals. don't have a solution though
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Small clue:
My enigma solution does not work with a fbc version before 1.00.0, because of a bug fixed in revision 1.00.0.
Post Reply