FreeBASIC syntax challenge games

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

Inspired by vdecampo's great big cheat:

Code: Select all

Type UDT
  Dim As String S = "You lost!"
End Type
Const As String S0 = "You won!"

Dim Shared As UDT u0
u0.S = S0
#define initializer u0

'--- Zone beginning of code insertion ---
#undef shared
#define shared
'--- Zone ending of code insertion ------

Dim Shared As UDT u = initializer

Print u.S

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

Re: FreeBASIC syntax challenge games

Post by fxm »

Little cheater !
('u' must remain a shared variable)
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

But the code to insert obviously redefines 'initializer':

Code: Select all

'--- Zone beginning of code insertion ---
#undef initializer
.....
.....
#define initializer .....
'--- Zone ending of code insertion ------
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

The challenge #12 could have been more difficult because I already have solved half the problem by defining the UDT so that:

Code: Select all

Dim Shared As UDT u0
Dim Shared As UDT u = u0
is allowed.


For a simple numeric type:

Code: Select all

Dim Shared As Integer I
Dim Shared As Integer J = I  '' error 11: Expected constant in 'Dim Shared As Integer J = I'
is not allowed!
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

fxm wrote:redefines 'initializer'
I'm pretty sure that's not what's expected but this works :)

Code: Select all

'--- Zone beginning of code insertion ---
#undef initializer
    type UDT2
        declare constructor(byref as string)
        declare operator cast() as UDT
            as string   _s
    end type
    constructor UDT2(byref S as string)
        THIS._s = S
    end constructor
    operator UDT2.cast() as UDT
        dim as UDT u
        u.S = THIS._s
        return u
    end operator
#define initializer     UDT2(S0)
'--- Zone ending of code insertion ------
This way I obtain a draw, neither win nor lost:

Code: Select all

   
 #undef initializer
    type UDT2
        declare constructor(byref as string)
        declare operator cast() as UDT
            as string   _s
    end type
    constructor UDT2(byref S as string)
        THIS._s = S
    end constructor
    operator UDT2.cast() as UDT
        dim as UDT u
        u.S = THIS._s
        return u
    end operator
#define initializer     UDT2(u.S)
There is something anyway I don't understand. The UDT2 constructor is called first at the very begining, maybe before all the instructions, as shown by printing something from inside UDT2 constructor...

Code: Select all

Type UDT
  Dim As String S = "You lost!"
End Type
Const As String S0 = "You won!"

Dim Shared As UDT u0
u0.S = S0
? "why am I second?", u0.S

#define initializer u0

'--- Zone beginning of code insertion ---
    #undef initializer
    type UDT2
        declare constructor(byref as string)
        declare operator cast() as UDT
            as string   _s
    end type
    constructor UDT2(byref S as string)
        ? "why am I first?", S
        THIS._s = S
    end constructor
    operator UDT2.cast() as UDT
        dim as UDT u
        u.S = THIS._s
        return u
    end operator
    
    #define initializer     UDT2(u.S)
'--- Zone ending of code insertion ------

Dim Shared As UDT u =  initializer

? "third here is neither win or lost"
Print "::"; u.S

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

Re: FreeBASIC syntax challenge games

Post by fxm »

Yes, it is a correct solution but much more complex than mine:
- You use an additional UDT with constructor and cast operator (13 lines in all).
- I use only simple function (5 lines in all):

Code: Select all

'--- Zone beginning of code insertion ---
#undef initializer
Function createInitUDT () As UDT
  Dim As UDT u
  u.S = S0
  Return u
End Function
#define initializer createInitUDT()
'--- Zone ending of code insertion ------
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Extract of documentation about Shared:
NOTES (for Shared variables excluding Common variables):
  • Generally a Shared variable may only be initialized with a constant value (its starting value is set at the start of the program in the .data section before any code is run, and so it cannot depend on any variables or functions in it).
  • A first exception is a Shared variable of var-len string type, that never can be initialized, even with a constant string (because of its structure with a descriptor in the .data section, but to point to a dynamic memory block).
  • A second exception is a Shared variable of user-defined type having a constructor even implicit, that can be initialized with a non-constant value (because it's the constructor code, called when the program starts, which writes the "initial" values into the .data section).
FreeBASIC supports non-constant initializers in case the Shared variable is a user-defined type with constructor:
- In addition to hard-coding the value into the .data section, the global variable's constructor must be called anyways when the program starts, so it may aswell allow non-constant initializers which will end up being arguments in the constructor call.

The above UDT has an implicit constructor because it contains a complex pseudo-object (a var-len string) as member.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

fxm wrote:Yes, it is a correct solution but much more complex than mine
Your solution is a kind of external copy-constructor, that's a nice tip.

But it's still a little weird that u0.S has lost its value in the meantime. For instance neither me or you reuse it: I can't do UDT2(u0.S) for instance, which was what I wanted first rather than UDT2(S0)...

And the execution order is absolutly weird (see paragraph 3 about UDT2 constructor).

This challenge points out very mysterious affairs.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Whatever the positions of the lines 'Dim Shared .....' in the program body, there are all executed at the top of program, before execution of the other lines.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

fxm wrote:Whatever the positions of the lines 'Dim Shared .....' in the program body, there are all executed at the top of program, before execution of the other lines.
About the printing, I miss totally the trick, line 1 is not executed first?

OK, I see now, you mean that not only dim shared is executed first, but it's initialization too! This is something that looked to me totally separated.

Code: Select all

? "why am I second to print? (line 1)"

Type UDT
  Dim As String S = "You lost!"
End Type
Const As String S0 = "You won!"

Dim Shared As UDT u0
u0.S = S0

#define initializer u0

'--- Zone beginning of code insertion ---
    #undef initializer
    type UDT2
        declare constructor(byref as string)
        declare operator cast() as UDT
            as string   _s
    end type
    constructor UDT2(byref S as string)
        ? "why am I first to print? (constructor)"
        THIS._s = S
    end constructor
    operator UDT2.cast() as UDT
        dim as UDT u
        u.S = THIS._s
        return u
    end operator
    
    #define initializer     UDT2(S0)
'--- Zone ending of code insertion ------

print !"\n(line 32)
Dim Shared As UDT u =  initializer

Print u.S

Sleep
Last edited by Tourist Trap on Jan 17, 2017 15:36, edited 1 time in total.
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

See documentation at : Storage classes , paragraph 'Static'.

The lines 'Dim Shared As UDTx .....' call their constructors (with initializers if exist).
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

fxm wrote:See documentation at : Storage classes , paragraph 'Static'.
I thought that "dim shared" or static and so on were just reserving free space at the begining of the program, but that initialization as further assignations would be executed at any time (following the execution order). Ok, now that's clearer. But then I think that initializing a shared variable with a UDT is not the best practice ever ;)

This below is less prone to surprises I think:

Code: Select all

'executes at top
Dim Shared As UDT u

'executes anywhere
u = initializer
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

Well done Tourist Trap.
I knew that if fxm actually defines something, it begs for a re definition.
Here's a trivial one along the lines of first come, first served.

Code: Select all




Declare Sub A 
Declare Sub B
Declare Sub C
Declare Sub D
Declare Sub E
Declare Sub F

F:E:D:C:B:A:Sleep:End

'============= 3 lines to produce ABCDEF on the console (colons) without cls ==============



'==============================================================================

Sub A 
    Print __function__;
End Sub

Sub B 
    Print __function__;
End Sub

Sub C 
    Print __function__;
End Sub

Sub D
    Print __function__;
End Sub

Sub E 
    Print __function__;
End Sub

Sub F 
    Print __function__;
End Sub


Sleep



 
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

dodicat wrote: Here's a trivial one along the lines of first come, first served.
Ahahah, I knew that when you said trivial, it would be what someone might have called tricky , at least for the suggestion below this is so:

Code: Select all

 '============= 3 lines to produce ABCDEF on the console (colons) without cls ==============
#undef __function__

dim shared as integer   cursor = 0

#define __function__     iif(cursor=0, cursor += 1 : "A",  iif(cursor=1, cursor += 1 : "B", iif(cursor=2, cursor += 1 : "C", iif(cursor=3, cursor += 1 : "D", iif(cursor=4, cursor += 1 : "E", "F"))))
'==============================================================================
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Almost !

2 lines:

Code: Select all

 '============= 3 lines to produce ABCDEF on the console (colons) without cls ==============
#undef __function__
Function __function__ () As String : Static As Integer cursor : Function = iif(cursor=0, "A",  iif(cursor=1, "B", iif(cursor=2, "C", iif(cursor=3, "D", iif(cursor=4, "E", "F"))))) : cursor += 1 : End Function
'==============================================================================
Post Reply