FreeBASIC syntax challenge games
Re: FreeBASIC syntax challenge games
@dafhi,
Have you decoded the dodicat's proposal (viewtopic.php?p=236283#p236283)?
Maybe you do not block together on the same problem (he found one of the two expected simple instructions, and not the most obvious in my opinion).
Have you decoded the dodicat's proposal (viewtopic.php?p=236283#p236283)?
Maybe you do not block together on the same problem (he found one of the two expected simple instructions, and not the most obvious in my opinion).
Re: FreeBASIC syntax challenge games
I thought of 2 ways
c++ style
instruction_1 = Print ... This.i++ .. :D
the other would use function pointer which I am unfamiliar with. As far as dodicat's idea, i am clueless
c++ style
instruction_1 = Print ... This.i++ .. :D
the other would use function pointer which I am unfamiliar with. As far as dodicat's idea, i am clueless
Re: FreeBASIC syntax challenge games
Hi dafhi.
Here is mine so far.
instruction_1 is ugly, but I can't get a temporary parent to increment it's i
e.g.
(parent).method
finds the correct sub, but .i stays at 1
Here is mine so far.
Code: Select all
#define instruction_1 var t=cast(parent,this):t.method
#define instruction_2 cast(child ptr,@t)->method
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
e.g.
(parent).method
finds the correct sub, but .i stays at 1
Re: FreeBASIC syntax challenge games
I prefer your previous proposal, although longer (one more instruction), :
because at least one of your instructions is one of the 2 very simple instructions of my solution:
Code: Select all
#define instruction_1 var t=cast(parent,this):t.method
#define instruction_2 this.i+=1:this.method
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).
Last edited by fxm on Sep 24, 2017 9:19, edited 1 time in total.
Re: FreeBASIC syntax challenge games
okay here's mine.
:P
Code: Select all
#define instruction_1 Print "Calling #" & This.I & " Parent.method()"
#define instruction_2 i+=1: method
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: FreeBASIC syntax challenge games
It's quite simple, once you got it:
Code: Select all
#Define instruction_1 base.method
#Define instruction_2 this.method
Re: FreeBASIC syntax challenge games
Perfect!
Explanation from the first proposal of dodicat:
The first Dodicat proposal is equivalent to:
OK for instruction_2 ('This.method()') that allows to re-call the 'Child.method ()' as long as 'This.I <= 7'.
So:is functionally equivalent to (recursion replaced by a loop):
After that, to simplify the remaining code line ('instruction_1'), the question asked is:
How to simply call the 'Parent.method ()' (from the 'Child.method ()' body), knowing that 'Child.method ()' overrides 'Parent.method ()'?
Dodicat chose to create a Parent instance in order to avoid the dynamic binding to 'Child.method ()', but as it is a new instance, its own field 'I' is different of the one tested by the caller.
A syntax as 'Cast(Parent, This).method()' does not work because the real type of 'Cast(Parent, This)' is always Child and consequently the dynamic binding is always activated (because works on the real type and not on the compile-type).
But a special FreeBASIC keyword exists to call (from a member procedure) the base method (on the hidden instance), and never the overriding method, even on a Child instance (the compiler forcing a static binding when calling the virtual method).
Use this keyword, and so you will can simplify 'instruction_1', because then working always with the same initial instance (one single field 'I'), so that the macro 'instruction_1' may contain only this one instruction.
This keyword is "BASE (Member Access)":
Explanation from the first proposal of dodicat:
The first Dodicat proposal is equivalent to:
Code: Select all
#define instruction_1 Var t = Cast(Parent, This) : t.method() : This.i += 1
#define instruction_2 This.method()
So:
Code: Select all
Sub Child.method ()
If This.I <= 7 Then
instruction_1
instruction_2
End If
End Sub
Code: Select all
Sub Child.method ()
While This.I <= 7
instruction_1
Wend
End Sub
How to simply call the 'Parent.method ()' (from the 'Child.method ()' body), knowing that 'Child.method ()' overrides 'Parent.method ()'?
Dodicat chose to create a Parent instance in order to avoid the dynamic binding to 'Child.method ()', but as it is a new instance, its own field 'I' is different of the one tested by the caller.
A syntax as 'Cast(Parent, This).method()' does not work because the real type of 'Cast(Parent, This)' is always Child and consequently the dynamic binding is always activated (because works on the real type and not on the compile-type).
But a special FreeBASIC keyword exists to call (from a member procedure) the base method (on the hidden instance), and never the overriding method, even on a Child instance (the compiler forcing a static binding when calling the virtual method).
Use this keyword, and so you will can simplify 'instruction_1', because then working always with the same initial instance (one single field 'I'), so that the macro 'instruction_1' may contain only this one instruction.
This keyword is "BASE (Member Access)":
.....
For virtual methods, base.method() always calls the base method and never the overriding method.
.....
Last edited by fxm on Sep 24, 2017 22:25, edited 1 time in total.
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: FreeBASIC syntax challenge games
Additional to that, if you have a grandchild class you can access the parent class withand so on.
Code: Select all
Base.Base.method
Re: FreeBASIC syntax challenge games
Enigma #24, force 2
Simulation of the 'Base (Member Access)' functionality on a virtual member procedure, but applying it from outside any member procedure.
- Presently, the 'Base (Member Access)' functionality works only from inside a non static member procedure ('Base.child_instance.procedure()' is not allowed).
- 'Cast(Parent, child_instance).procedure()' allows to access the Parent procedure on a Child instance, but only if this Parent procedure is not overridden by a Child procedure.
Insert one fairly simple code line (one single instruction not hacking vptr/vtable) in the dedicated zone of below program, so that to call the 'Base.dec()' virtual procedure and to update the 'ip' field, so to obtain the following program output (check the last line):
Program where add one instruction in the dedicated zone (the solution into one only instruction is possible because of this particular type of procedure, otherwise the same method should request several instructions):
Simulation of the 'Base (Member Access)' functionality on a virtual member procedure, but applying it from outside any member procedure.
- Presently, the 'Base (Member Access)' functionality works only from inside a non static member procedure ('Base.child_instance.procedure()' is not allowed).
- 'Cast(Parent, child_instance).procedure()' allows to access the Parent procedure on a Child instance, but only if this Parent procedure is not overridden by a Child procedure.
Insert one fairly simple code line (one single instruction not hacking vptr/vtable) in the dedicated zone of below program, so that to call the 'Base.dec()' virtual procedure and to update the 'ip' field, so to obtain the following program output (check the last line):
Code: Select all
0 0
0 4
4 4
4 3
3 3
Code: Select all
Type Parent Extends Object
Public:
Declare Property ip () As Integer
Declare Function inc () Byref As Parent
Declare Virtual Function dec () Byref As Parent
Private:
Dim As Integer _ip
End Type
Property Parent.ip () As Integer
Return This._ip
End Property
Function Parent.inc () Byref As Parent
This._ip += 4
Return This
End Function
Function Parent.dec () Byref As Parent
This._ip -= 1
Return This
End Function
Type Child Extends Parent
Public:
Declare Property ic () As Integer
Declare Function inc () Byref As Child
Declare Virtual Function dec () Byref As Child
Private:
Dim As Integer _ic
End Type
Property Child.ic () As Integer
Return This._ic
End Property
Function Child.inc () Byref As Child
This._ic += 4
Return This
End Function
Function Child.dec () Byref As Child
This._ic -= 1
Return This
End Function
Dim As Child c
Print c.ip, c.ic
Print
c.inc()
Print c.ip, c.ic
Cast(Parent, c).inc()
Print c.ip, c.ic
Print
c.dec()
Print c.ip, c.ic
'------------------------------------ zone beginning for insertion of one line -------------------------------------
'Cast(Parent, c).dec() '' does not allow to access 'Parent.dec()' but still 'Child.dec()'
'Cast(Function(Byref As Parent) Byref As Parent, Cptr(Any Ptr Ptr Ptr, @Parent())[0][0])(c) '' hacking vptr/vtable
'-------------------------------------- zone ending for insertion of one line --------------------------------------
Print c.ip, c.ic
Sleep
Re: FreeBASIC syntax challenge games
Overwrite the private section of type parent?
cast(any ptr ptr,@parent)[3]=3
but obviously a poor solution.
cast(any ptr ptr,@parent)[3]=3
but obviously a poor solution.
Re: FreeBASIC syntax challenge games
Not only you hack the allocated memory, but you use the fact that the 'Parent()' temporary instance is contiguous to the 'c' instance!
This true when using 'gas' but not when using 'gcc'.
A less bad solution should be:
cast(any ptr ptr,@c)[1]=3
or:
cast(integer ptr,cast(any ptr,@c))[1]=3
to get no warning.
My solution does not hack the memory, but uses the 'dec()' member function, the 'c' instance, and .....?
This true when using 'gas' but not when using 'gcc'.
A less bad solution should be:
cast(any ptr ptr,@c)[1]=3
or:
cast(integer ptr,cast(any ptr,@c))[1]=3
to get no warning.
My solution does not hack the memory, but uses the 'dec()' member function, the 'c' instance, and .....?
Re: FreeBASIC syntax challenge games
The general solution, to simulate on a derived-instance a call to an overridden base-procedure (without calling the overriding child-procedure), consists on 3 instructions:fxm wrote:Enigma #24, force 2
..... the solution into one only instruction is possible because of this particular type of procedure, otherwise the same method should request several instructions.....
- copy-constuction of a base-instance from the derived-instance to be processed,
- call of the overridden base-procedure on the base-instance created previously,
- assignment of the resulting base-instance fields to the base-fields of the derived-instance to be processed.
If the overridden base-procedure is in particular a function returning a reference to the instance on which it was called, these 3 instructions can be compacted to 1 instruction only.
Re: FreeBASIC syntax challenge games
Pseudo-code for the general solution:fxm wrote:The general solution, to simulate on a derived-instance a call to an overridden base-procedure (without calling the overriding child-procedure), consists on 3 instructions:fxm wrote:Enigma #24, force 2
..... the solution into one only instruction is possible because of this particular type of procedure, otherwise the same method should request several instructions.....
- copy-constuction of a base-instance from the derived-instance to be processed,
- call of the overridden base-procedure on the base-instance created previously,
- assignment of the resulting base-instance fields to the base-fields of the derived-instance to be processed.
If the overridden base-procedure is in particular a function returning a reference to the instance on which it was called, these 3 instructions can be compacted to 1 instruction only.
- Dim As Base_Type base_instance = derived_instance
base_instance.overridden_procedure()
Cast(Base_Type, derived_instance) = base_instance
Re: FreeBASIC syntax challenge games
Pseudo-code for the particular solution (function returning a reference to the instance on which it was called):fxm wrote:Pseudo-code for the general solution:fxm wrote:The general solution, to simulate on a derived-instance a call to an overridden base-procedure (without calling the overriding child-procedure), consists on 3 instructions:fxm wrote:Enigma #24, force 2
..... the solution into one only instruction is possible because of this particular type of procedure, otherwise the same method should request several instructions.....
- copy-constuction of a base-instance from the derived-instance to be processed,
- call of the overridden base-procedure on the base-instance created previously,
- assignment of the resulting base-instance fields to the base-fields of the derived-instance to be processed.
If the overridden base-procedure is in particular a function returning a reference to the instance on which it was called, these 3 instructions can be compacted to 1 instruction only.
- Dim As Base_Type base_instance = derived_instance
base_instance.overridden_procedure()
Cast(Base_Type, derived_instance) = base_instance
- Cast(Base_Type, derived_instance) = Base_Type(derived.instance).overridden_function()
Re: FreeBASIC syntax challenge games
I can do it in two lines:
dim as parent p=c
Cast(Parent,c)=p.dec
dim as parent p=c
Cast(Parent,c)=p.dec