Mixed datatype
Re: Mixed datatype
Yep, but more likely a ZString Ptr ... (since, String handles that 'behind the scenes').
Re: Mixed datatype
perhaps it's a good Idea to post the corrected version here for others
corrections are thanks to fxm
mixed.bi
Mixed_test.bas
corrections are thanks to fxm
mixed.bi
Code: Select all
''
'' Mixed datatype definition
''
'' by Aleksandar Ruzicic
''
#Ifndef __MIXED_TYPE__
#Define __MIXED_TYPE__
#Macro MixedDeclareOperators(_TYPE_)
Declare Operator Cast As _TYPE_
Declare Operator Let(value As _TYPE_)
Declare Operator +=(value As _TYPE_)
Declare Operator -=(value As _TYPE_)
Declare Operator *=(value As _TYPE_)
Declare Operator /=(value As _TYPE_)
Declare Operator \=(value As _TYPE_)
Declare Operator ^=(value As _TYPE_)
Declare Operator Mod=(value As _TYPE_)
Declare Operator Shl=(value As _TYPE_)
Declare Operator Shr=(value As _TYPE_)
Declare Operator And=(value As _TYPE_)
Declare Operator Or=(value As _TYPE_)
Declare Operator Xor=(value As _TYPE_)
Declare Operator Imp=(value As _TYPE_)
Declare Operator Eqv=(value As _TYPE_)
#EndMacro
#Macro MixedImplementAssignmentOperators(_TYPE_)
Operator Mixed.+=(value As _TYPE_)
This = Cast(_TYPE_, This) + value
End Operator
Operator Mixed.-=(value As _TYPE_)
This = Cast(_TYPE_, This) - value
End Operator
Operator Mixed.*=(value As _TYPE_)
This = Cast(_TYPE_, This) * value
End Operator
Operator Mixed./=(value As _TYPE_)
This = Cast(_TYPE_, This) / value
End Operator
Operator Mixed.\=(value As _TYPE_)
This = Cast(_TYPE_, This) \ value
End Operator
Operator Mixed.^=(value As _TYPE_)
This = Cast(_TYPE_, This) ^ value
End Operator
Operator Mixed.Mod=(value As _TYPE_)
This = Cast(_TYPE_, This) Mod value
End Operator
Operator Mixed.Shl=(value As _TYPE_)
This = Cast(_TYPE_, This) Shl value
End Operator
Operator Mixed.Shr=(value As _TYPE_)
This = Cast(_TYPE_, This) Shr value
End Operator
Operator Mixed.And=(value As _TYPE_)
This = Cast(_TYPE_, This) And value
End Operator
Operator Mixed.Or=(value As _TYPE_)
This = Cast(_TYPE_, This) Or value
End Operator
Operator Mixed.Xor=(value As _TYPE_)
This = Cast(_TYPE_, This) Xor value
End Operator
Operator Mixed.Imp=(value As _TYPE_)
This = Cast(_TYPE_, This) Imp value
End Operator
Operator Mixed.Eqv=(value As _TYPE_)
This = Cast(_TYPE_, This) Eqv value
End Operator
#EndMacro
#Macro MixedImplementBinaryOperator(_OP_)
Operator _OP_(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
If lhs.TypeId < fbInteger Or rhs.TypeId < fbInteger Then
Return CDbl(lhs) _OP_ CDbl(rhs)
Else
Return CInt(lhs) _OP_ CInt(rhs)
EndIf
End Operator
#EndMacro
Enum MixedType
fbEmpty
fbString
fbDouble
fbSingle
fbLongInt
fbLong
fbInteger
fbShort
fbByte
fbAnyPointer
End Enum
Type Mixed
Public:
Declare Destructor
Declare Property TypeId As MixedType
Declare Operator Cast As String
Declare Operator Let(value As String)
Declare Operator +=(value As String)
Declare Operator &=(value As String)
MixedDeclareOperators(Double)
MixedDeclareOperators(Single)
MixedDeclareOperators(LongInt)
MixedDeclareOperators(Long)
MixedDeclareOperators(Integer)
MixedDeclareOperators(Short)
MixedDeclareOperators(Byte)
Declare Operator Cast As Any Pointer
Declare Operator Let(value As Any Pointer)
Private:
StoredType As MixedType = fbEmpty
StoredData As Any Pointer = 0
End Type
Destructor Mixed
If This.StoredType <> fbEmpty And this.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
End Destructor
Property Mixed.TypeId As MixedType
Return This.StoredType
End Property
Operator Mixed.Cast As String
Select Case This.StoredType
Case fbEmpty: Return ""
Case fbString: Return *Cast(String Pointer, This.StoredData)
Case fbDouble: Return Str(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return Str(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return Str(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return Str(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return Str(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return Str(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return Str(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(String Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As String)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
This.StoredType = fbString
This.StoredData = Callocate(SizeOf(String))
*Cast(String Pointer, This.StoredData) = value
End Operator
Operator Mixed.+=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.&=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.Cast As Double
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CDbl(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return *Cast(Double Pointer, This.StoredData)
Case fbSingle: Return CDbl(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CDbl(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CDbl(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CDbl(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CDbl(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CDbl(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Double Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Double)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbDouble
This.StoredData = Allocate(SizeOf(Double))
*Cast(Double Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Double)
Operator Mixed.Cast As Single
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CSng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CSng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return *Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return CSng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CSng(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CSng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CSng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CSng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Single Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Single)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbSingle
This.StoredData = Allocate(SizeOf(Single))
*Cast(Single Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Single)
Operator Mixed.Cast As LongInt
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLngInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLngInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLngInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return *Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return CLngInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CLngInt(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLngInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLngInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(LongInt Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As LongInt)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLongInt
This.StoredData = Allocate(SizeOf(LongInt))
*Cast(LongInt Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(LongInt)
Operator Mixed.Cast As Long
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLng(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CLng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return *Cast(Long Pointer, This.StoredData)
Case fbInteger: Return CLng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Long Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Long)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLong
This.StoredData = Allocate(SizeOf(Long))
*Cast(Long Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Long)
Operator Mixed.Cast As Integer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CInt(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return *Cast(Integer Pointer, This.StoredData)
Case fbShort: Return CInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Integer Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbInteger
This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Integer)
Operator Mixed.Cast As Short
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CShort(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CShort(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CShort(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CShort(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CShort(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CShort(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return *Cast(Short Pointer, This.StoredData)
Case fbByte: Return CShort(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Short Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Short)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbShort
This.StoredData = Allocate(SizeOf(Short))
*Cast(Short Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Short)
Operator Mixed.Cast As Byte
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CByte(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CByte(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CByte(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CByte(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CByte(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CByte(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CByte(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return *Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return *Cast(Byte Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Byte)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbByte
This.StoredData = Allocate(SizeOf(Byte))
*Cast(Byte Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Byte)
Operator Mixed.Cast As Any Pointer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return Cast(String Pointer, This.StoredData)
Case fbDouble: Return Cast(Double Pointer, This.StoredData)
Case fbSingle: Return Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return Cast(Long Pointer, This.StoredData)
Case fbInteger: Return Cast(Integer Pointer, This.StoredData)
Case fbShort: Return Cast(Short Pointer, This.StoredData)
Case fbByte: Return Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return This.StoredData
End Select
End Operator
Operator Mixed.Let(Value As Any Pointer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbAnyPointer
This.StoredData = Allocate(SizeOf(Any Pointer))
This.StoredData = value
End Operator
Operator -(ByRef rhs As Mixed) As Mixed
Select Case rhs.TypeId
Case fbEmpty: Return 0
Case Else: Return -Cast(Double, rhs)
End Select
End Operator
Operator &(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
Return Str(lhs) & Str(rhs)
End Operator
MixedImplementBinaryOperator(+)
MixedImplementBinaryOperator(-)
MixedImplementBinaryOperator(*)
MixedImplementBinaryOperator(/)
MixedImplementBinaryOperator(\)
MixedImplementBinaryOperator(Mod)
MixedImplementBinaryOperator(Shl)
MixedImplementBinaryOperator(Shr)
MixedImplementBinaryOperator(And)
MixedImplementBinaryOperator(Or)
MixedImplementBinaryOperator(Xor)
MixedImplementBinaryOperator(Imp)
MixedImplementBinaryOperator(Eqv)
MixedImplementBinaryOperator(^)
MixedImplementBinaryOperator(=)
MixedImplementBinaryOperator(<>)
MixedImplementBinaryOperator(<)
MixedImplementBinaryOperator(>)
MixedImplementBinaryOperator(<=)
MixedImplementBinaryOperator(>=)
#EndIf
Code: Select all
#include "mixed.bi"
Dim m As Mixed
Dim As string Mixed_types(9) = {"fbEmpty", "fbString", "fbDouble",_
"fbSingle", "fbLongInt", "fbLong", _
"fbInteger", "fbShort", "fbByte", _
"fbAnyPointer"}
m = 123 ' Integer
Print "m = "; m, Mixed_types(m.TypeId)
m /= 5! ' Single
Print "m = "; m, Mixed_types(m.TypeId)
m = 3.141592653589793
Print "m = "; m, Mixed_types(m.TypeId)
m = "bla bla" ' String
Print "m = "; m, Mixed_types(m.TypeId)
m = m + 5 ' Integer
Print "m = "; m, Mixed_types(m.TypeId)
Print
Print "Press RETURN to quit"
Sleep
Re: Mixed datatype
unfortunately the mixed type is problematic, the following code will probably crash or give bad result
Code: Select all
#include "mixed.bi"
Dim As string Mixed_types(9) = {"fbEmpty", "fbString", "fbDouble",_
"fbSingle", "fbLongInt", "fbLong", _
"fbInteger", "fbShort", "fbByte", _
"fbAnyPointer"}
redim shared stack(10) as Mixed
dim shared as integer stack_pointer=0, stack_ubound=10
sub push(byval n as Mixed)
stack(stack_pointer)=n
if stack_pointer=stack_ubound then
stack_ubound+=10
redim preserve stack(stack_ubound)
end if
stack_pointer+=1
end sub
function pop() as Mixed
if stack_pointer=0 then
print "stack is empty"
return 9
end if
stack_pointer-=1
return stack(stack_pointer)
end function
dim as double i
dim n as Mixed
for i=0 to 15
n=i
push(n)
next
for i=0 to 15
n=pop()
print i,n, Mixed_types(n.TypeId)
next
n=pop()
Print "Press RETURN to quit"
Sleep
Re: Mixed datatype
You can not pass and return a Mixed instance by value (in push and pop procedures) because the copy-constructor(byref as Mixed) is not defined in the Mixed Type.
A simpler workaround (without defining this member procedure) would be to pass and return a Mixed instance by reference only:The program runs but the result is wrong (because stack(stack_pointer)=n and n=pop() call the Let-operator).
Otherwise (as difficult exercise), define these two member procedures in mixed.bi !
A simpler workaround (without defining this member procedure) would be to pass and return a Mixed instance by reference only:
Code: Select all
sub push(byref n as Mixed)
stack(stack_pointer)=n
if stack_pointer=stack_ubound then
stack_ubound+=10
redim preserve stack(stack_ubound)
end if
stack_pointer+=1
end sub
function pop() byref as Mixed
if stack_pointer=0 then
print "stack is empty"
static as Mixed m
m = 9
return m
end if
stack_pointer-=1
return stack(stack_pointer)
end function
Code: Select all
0 15 fbDouble
1 15 fbDouble
2 15 fbDouble
3 15 fbDouble
4 15 fbDouble
5 15 fbDouble
6 15 fbDouble
7 15 fbDouble
8 15 fbDouble
9 15 fbDouble
10 15 fbDouble
11 15 fbDouble
12 15 fbDouble
13 15 fbDouble
14 15 fbDouble
15 15 fbDouble
stack is empty
Press RETURN to quit
Otherwise (as difficult exercise), define these two member procedures in mixed.bi !
Last edited by fxm on Jun 17, 2020 9:40, edited 4 times in total.
Re: Mixed datatype
I see, I will study the Mixed code a bit, thanks.
Re: Mixed datatype
My way of solving the problems caused new/delete allocate/deallocate (as I have posted several times) is to use a static memory stack(array), in each
mixed.let in this code.
This way allocated memory is contiguous in memory, and destroyed normally at the program end, as any array is annihilated.
Instead of deallocating throughout the code where it is written,I just set to zero, but this move isn't even necessary.
I have set an upper bound of 500 mixed elements, at the top, which can be changed of course.
Tested win 32/64 and gas64
mixed.let in this code.
This way allocated memory is contiguous in memory, and destroyed normally at the program end, as any array is annihilated.
Instead of deallocating throughout the code where it is written,I just set to zero, but this move isn't even necessary.
I have set an upper bound of 500 mixed elements, at the top, which can be changed of course.
Code: Select all
''
'' Mixed datatype definition
''
'' by Aleksandar Ruzicic
''
#define lim 500
#Ifndef __MIXED_TYPE__
#Define __MIXED_TYPE__
#Macro MixedDeclareOperators(_TYPE_)
Declare Operator Cast As _TYPE_
Declare Operator Let(value As _TYPE_)
Declare Operator +=(value As _TYPE_)
Declare Operator -=(value As _TYPE_)
Declare Operator *=(value As _TYPE_)
Declare Operator /=(value As _TYPE_)
Declare Operator \=(value As _TYPE_)
Declare Operator ^=(value As _TYPE_)
Declare Operator Mod=(value As _TYPE_)
Declare Operator Shl=(value As _TYPE_)
Declare Operator Shr=(value As _TYPE_)
Declare Operator And=(value As _TYPE_)
Declare Operator Or=(value As _TYPE_)
Declare Operator Xor=(value As _TYPE_)
Declare Operator Imp=(value As _TYPE_)
Declare Operator Eqv=(value As _TYPE_)
#EndMacro
#Macro MixedImplementAssignmentOperators(_TYPE_)
Operator Mixed.+=(value As _TYPE_)
This = Cast(_TYPE_, This) + value
End Operator
Operator Mixed.-=(value As _TYPE_)
This = Cast(_TYPE_, This) - value
End Operator
Operator Mixed.*=(value As _TYPE_)
This = Cast(_TYPE_, This) * value
End Operator
Operator Mixed./=(value As _TYPE_)
This = Cast(_TYPE_, This) / value
End Operator
Operator Mixed.\=(value As _TYPE_)
This = Cast(_TYPE_, This) \ value
End Operator
Operator Mixed.^=(value As _TYPE_)
This = Cast(_TYPE_, This) ^ value
End Operator
Operator Mixed.Mod=(value As _TYPE_)
This = Cast(_TYPE_, This) Mod value
End Operator
Operator Mixed.Shl=(value As _TYPE_)
This = Cast(_TYPE_, This) Shl value
End Operator
Operator Mixed.Shr=(value As _TYPE_)
This = Cast(_TYPE_, This) Shr value
End Operator
Operator Mixed.And=(value As _TYPE_)
This = Cast(_TYPE_, This) And value
End Operator
Operator Mixed.Or=(value As _TYPE_)
This = Cast(_TYPE_, This) Or value
End Operator
Operator Mixed.Xor=(value As _TYPE_)
This = Cast(_TYPE_, This) Xor value
End Operator
Operator Mixed.Imp=(value As _TYPE_)
This = Cast(_TYPE_, This) Imp value
End Operator
Operator Mixed.Eqv=(value As _TYPE_)
This = Cast(_TYPE_, This) Eqv value
End Operator
#EndMacro
#Macro MixedImplementBinaryOperator(_OP_)
Operator _OP_(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
If lhs.TypeId < fbInteger Or rhs.TypeId < fbInteger Then
Return CDbl(lhs) _OP_ CDbl(rhs)
Else
Return CInt(lhs) _OP_ CInt(rhs)
EndIf
End Operator
#EndMacro
Enum MixedType
fbEmpty
fbString
fbDouble
fbSingle
fbLongInt
fbLong
fbInteger
fbShort
fbByte
fbAnyPointer
End Enum
Type Mixed
Public:
Declare Destructor
Declare Property TypeId As MixedType
Declare Operator Cast As String
Declare Operator Let(value As String)
Declare Operator +=(value As String)
Declare Operator &=(value As String)
MixedDeclareOperators(Double)
MixedDeclareOperators(Single)
MixedDeclareOperators(LongInt)
MixedDeclareOperators(Long)
MixedDeclareOperators(Integer)
MixedDeclareOperators(Short)
MixedDeclareOperators(Byte)
Declare Operator Cast As Any Pointer
Declare Operator Let(value As Any Pointer)
Private:
StoredType As MixedType = fbEmpty
StoredData As Any Pointer = 0
End Type
Destructor Mixed
If This.StoredType <> fbEmpty And this.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
End Destructor
Property Mixed.TypeId As MixedType
Return This.StoredType
End Property
Operator Mixed.Cast As String
Select Case This.StoredType
Case fbEmpty: Return ""
Case fbString: Return *Cast(String Pointer, This.StoredData)
Case fbDouble: Return Str(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return Str(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return Str(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return Str(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return Str(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return Str(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return Str(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(String Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As String)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
'DeAllocate This.StoredData
EndIf
static as string mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredType = fbString
This.StoredData = @mem(counter)
*Cast(String Pointer, This.StoredData) = value
End Operator
Operator Mixed.+=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.&=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.Cast As Double
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CDbl(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return *Cast(Double Pointer, This.StoredData)
Case fbSingle: Return CDbl(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CDbl(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CDbl(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CDbl(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CDbl(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CDbl(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Double Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Double)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as double mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbDouble
*Cast(Double Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Double)
Operator Mixed.Cast As Single
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CSng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CSng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return *Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return CSng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CSng(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CSng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CSng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CSng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Single Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Single)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as single mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbSingle
*Cast(Single Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Single)
Operator Mixed.Cast As LongInt
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLngInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLngInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLngInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return *Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return CLngInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CLngInt(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLngInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLngInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(LongInt Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As LongInt)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as ulongint mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbLongInt
' This.StoredData = Allocate(SizeOf(LongInt))
*Cast(LongInt Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(LongInt)
Operator Mixed.Cast As Long
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLng(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CLng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return *Cast(Long Pointer, This.StoredData)
Case fbInteger: Return CLng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Long Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Long)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as long mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbLong
'This.StoredData = Allocate(SizeOf(Long))
*Cast(Long Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Long)
Operator Mixed.Cast As Integer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CInt(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return *Cast(Integer Pointer, This.StoredData)
Case fbShort: Return CInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Integer Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as integer mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbInteger
'This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Integer)
Operator Mixed.Cast As Short
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CShort(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CShort(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CShort(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CShort(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CShort(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CShort(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return *Cast(Short Pointer, This.StoredData)
Case fbByte: Return CShort(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Short Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Short)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as short mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbShort
'This.StoredData = Allocate(SizeOf(Short))
*Cast(Short Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Short)
Operator Mixed.Cast As Byte
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CByte(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CByte(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CByte(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CByte(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CByte(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CByte(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CByte(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return *Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return *Cast(Byte Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Byte)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as byte mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbByte
'This.StoredData = Allocate(SizeOf(Byte))
*Cast(Byte Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Byte)
Operator Mixed.Cast As Any Pointer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return Cast(String Pointer, This.StoredData)
Case fbDouble: Return Cast(Double Pointer, This.StoredData)
Case fbSingle: Return Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return Cast(Long Pointer, This.StoredData)
Case fbInteger: Return Cast(Integer Pointer, This.StoredData)
Case fbShort: Return Cast(Short Pointer, This.StoredData)
Case fbByte: Return Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return This.StoredData
End Select
End Operator
Operator Mixed.Let(Value As Any Pointer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
This.StoredData=0
EndIf
static as any ptr mem(lim)
static as long counter
counter+=1
if counter>lim then counter=1
This.StoredData = @mem(counter)
This.StoredType = fbAnyPointer
'This.StoredData = Allocate(SizeOf(Any Pointer))
This.StoredData = value
End Operator
Operator -(ByRef rhs As Mixed) As Mixed
Select Case rhs.TypeId
Case fbEmpty: Return 0
Case Else: Return -Cast(Double, rhs)
End Select
End Operator
Operator &(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
Return Str(lhs) & Str(rhs)
End Operator
MixedImplementBinaryOperator(+)
MixedImplementBinaryOperator(-)
MixedImplementBinaryOperator(*)
MixedImplementBinaryOperator(/)
MixedImplementBinaryOperator(\)
MixedImplementBinaryOperator(Mod)
MixedImplementBinaryOperator(Shl)
MixedImplementBinaryOperator(Shr)
MixedImplementBinaryOperator(And)
MixedImplementBinaryOperator(Or)
MixedImplementBinaryOperator(Xor)
MixedImplementBinaryOperator(Imp)
MixedImplementBinaryOperator(Eqv)
MixedImplementBinaryOperator(^)
MixedImplementBinaryOperator(=)
MixedImplementBinaryOperator(<>)
MixedImplementBinaryOperator(<)
MixedImplementBinaryOperator(>)
MixedImplementBinaryOperator(<=)
MixedImplementBinaryOperator(>=)
#EndIf
Dim m As Mixed
m = 123 ' Integer
Print "m = "; m
m /= 5 ' Single
Print "m = "; m
m = "bla bla" ' String
Print "m = "; m
m = m + 5 ' Integer
Print "m = "; m
Dim As string Mixed_types(9) = {"fbEmpty", "fbString", "fbDouble",_
"fbSingle", "fbLongInt", "fbLong", _
"fbInteger", "fbShort", "fbByte", _
"fbAnyPointer"}
redim shared stack(10) as Mixed
dim shared as integer stack_pointer=0, stack_ubound=10
sub push(byval n as Mixed)
stack(stack_pointer)=n
if stack_pointer=stack_ubound then
stack_ubound+=10
redim preserve stack(stack_ubound)
end if
stack_pointer+=1
end sub
function pop() as Mixed
if stack_pointer=0 then
print "stack is empty"
return 9
end if
stack_pointer-=1
return stack(stack_pointer)
end function
dim as double i
dim n as Mixed
for i=0 to 15
select case i
case 1,2:n=cint(i)
case 3,4:n=clng(i)
case 5,6:n=clngint(i)
case 7,8:n=cdbl(i)
case 9,10:n=csng(i)
case 11,12:n=cshort(i)
case 13,14:n=cbyte(i)
case 0,15:n=str(i)
end select
push(n)
next
for i=0 to 15
n=pop()
print i,n, Mixed_types(n.TypeId)
next
n=pop()
Print "Press RETURN to quit"
Sleep
Re: Mixed datatype
nicely done dodicat, thanks
I like the concept of Mixed type, but it's implementation is too complex for my limited intellect.
I like the concept of Mixed type, but it's implementation is too complex for my limited intellect.
Re: Mixed datatype
New version of mixed.bi working with your last code:
Code: Select all
''
'' Mixed datatype definition
''
'' by Aleksandar Ruzicic
''
#Ifndef __MIXED_TYPE__
#Define __MIXED_TYPE__
#Macro MixedDeclareOperators(_TYPE_)
Declare Operator Cast As _TYPE_
Declare Operator Let(value As _TYPE_)
Declare Operator +=(value As _TYPE_)
Declare Operator -=(value As _TYPE_)
Declare Operator *=(value As _TYPE_)
Declare Operator /=(value As _TYPE_)
Declare Operator \=(value As _TYPE_)
Declare Operator ^=(value As _TYPE_)
Declare Operator Mod=(value As _TYPE_)
Declare Operator Shl=(value As _TYPE_)
Declare Operator Shr=(value As _TYPE_)
Declare Operator And=(value As _TYPE_)
Declare Operator Or=(value As _TYPE_)
Declare Operator Xor=(value As _TYPE_)
Declare Operator Imp=(value As _TYPE_)
Declare Operator Eqv=(value As _TYPE_)
#EndMacro
#Macro MixedImplementAssignmentOperators(_TYPE_)
Operator Mixed.+=(value As _TYPE_)
This = Cast(_TYPE_, This) + value
End Operator
Operator Mixed.-=(value As _TYPE_)
This = Cast(_TYPE_, This) - value
End Operator
Operator Mixed.*=(value As _TYPE_)
This = Cast(_TYPE_, This) * value
End Operator
Operator Mixed./=(value As _TYPE_)
This = Cast(_TYPE_, This) / value
End Operator
Operator Mixed.\=(value As _TYPE_)
This = Cast(_TYPE_, This) \ value
End Operator
Operator Mixed.^=(value As _TYPE_)
This = Cast(_TYPE_, This) ^ value
End Operator
Operator Mixed.Mod=(value As _TYPE_)
This = Cast(_TYPE_, This) Mod value
End Operator
Operator Mixed.Shl=(value As _TYPE_)
This = Cast(_TYPE_, This) Shl value
End Operator
Operator Mixed.Shr=(value As _TYPE_)
This = Cast(_TYPE_, This) Shr value
End Operator
Operator Mixed.And=(value As _TYPE_)
This = Cast(_TYPE_, This) And value
End Operator
Operator Mixed.Or=(value As _TYPE_)
This = Cast(_TYPE_, This) Or value
End Operator
Operator Mixed.Xor=(value As _TYPE_)
This = Cast(_TYPE_, This) Xor value
End Operator
Operator Mixed.Imp=(value As _TYPE_)
This = Cast(_TYPE_, This) Imp value
End Operator
Operator Mixed.Eqv=(value As _TYPE_)
This = Cast(_TYPE_, This) Eqv value
End Operator
#EndMacro
#Macro MixedImplementBinaryOperator(_OP_)
Operator _OP_(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
If lhs.TypeId < fbInteger Or rhs.TypeId < fbInteger Then
Return CDbl(lhs) _OP_ CDbl(rhs)
Else
Return CInt(lhs) _OP_ CInt(rhs)
EndIf
End Operator
#EndMacro
Enum MixedType
fbEmpty
fbString
fbDouble
fbSingle
fbLongInt
fbLong
fbInteger
fbShort
fbByte
fbAnyPointer
End Enum
Type Mixed
Public:
Declare Constructor
Declare Constructor(ByRef m As Mixed)
Declare Operator Let(ByRef m As Mixed)
Declare Destructor
Declare Property TypeId As MixedType
Declare Operator Cast As String
Declare Operator Let(value As String)
Declare Operator +=(value As String)
Declare Operator &=(value As String)
MixedDeclareOperators(Double)
MixedDeclareOperators(Single)
MixedDeclareOperators(LongInt)
MixedDeclareOperators(Long)
MixedDeclareOperators(Integer)
MixedDeclareOperators(Short)
MixedDeclareOperators(Byte)
Declare Operator Cast As Any Pointer
Declare Operator Let(value As Any Pointer)
Private:
StoredType As MixedType = fbEmpty
StoredData As Any Pointer = 0
End Type
Constructor Mixed
End Constructor
Constructor Mixed(ByRef m As Mixed)
This = m
End Constructor
Operator Mixed.Let(ByRef m As Mixed)
Select Case m.StoredType
Case fbEmpty:
Case fbString: This = *Cast(String Pointer, m.StoredData)
Case fbDouble: This = *Cast(Double Pointer, m.StoredData)
Case fbSingle: This = *Cast(Single Pointer, m.StoredData)
Case fbLongInt: This = *Cast(LongInt Pointer, m.StoredData)
Case fbLong: This = *Cast(Long Pointer, m.StoredData)
Case fbInteger: This = *Cast(Integer Pointer, m.StoredData)
Case fbShort: This = *Cast(Short Pointer, m.StoredData)
Case fbByte: This = *Cast(Byte Pointer, m.StoredData)
Case fbAnyPointer: This = *Cast(Single Pointer, m.StoredData)
End Select
End Operator
Destructor Mixed
If This.StoredType <> fbEmpty And this.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
End Destructor
Property Mixed.TypeId As MixedType
Return This.StoredType
End Property
Operator Mixed.Cast As String
Select Case This.StoredType
Case fbEmpty: Return ""
Case fbString: Return *Cast(String Pointer, This.StoredData)
Case fbDouble: Return Str(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return Str(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return Str(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return Str(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return Str(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return Str(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return Str(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(String Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As String)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
This.StoredType = fbString
This.StoredData = CAllocate(SizeOf(String))
*Cast(String Pointer, This.StoredData) = value
End Operator
Operator Mixed.+=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.&=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.Cast As Double
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CDbl(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return *Cast(Double Pointer, This.StoredData)
Case fbSingle: Return CDbl(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CDbl(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CDbl(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CDbl(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CDbl(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CDbl(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Double Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Double)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbDouble
This.StoredData = Allocate(SizeOf(Double))
*Cast(Double Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Double)
Operator Mixed.Cast As Single
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CSng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CSng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return *Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return CSng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CSng(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CSng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CSng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CSng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Single Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Single)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbSingle
This.StoredData = Allocate(SizeOf(Single))
*Cast(Single Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Single)
Operator Mixed.Cast As LongInt
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLngInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLngInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLngInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return *Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return CLngInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CLngInt(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLngInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLngInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(LongInt Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As LongInt)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLongInt
This.StoredData = Allocate(SizeOf(LongInt))
*Cast(LongInt Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(LongInt)
Operator Mixed.Cast As Long
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLng(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CLng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return *Cast(Long Pointer, This.StoredData)
Case fbInteger: Return CLng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Long Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Long)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLong
This.StoredData = Allocate(SizeOf(Long))
*Cast(Long Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Long)
Operator Mixed.Cast As Integer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CInt(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return *Cast(Integer Pointer, This.StoredData)
Case fbShort: Return CInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Integer Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbInteger
This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Integer)
Operator Mixed.Cast As Short
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CShort(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CShort(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CShort(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CShort(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CShort(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CShort(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return *Cast(Short Pointer, This.StoredData)
Case fbByte: Return CShort(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Short Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Short)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbShort
This.StoredData = Allocate(SizeOf(Short))
*Cast(Short Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Short)
Operator Mixed.Cast As Byte
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CByte(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CByte(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CByte(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CByte(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CByte(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CByte(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CByte(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return *Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return *Cast(Byte Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Byte)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbByte
This.StoredData = Allocate(SizeOf(Byte))
*Cast(Byte Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Byte)
Operator Mixed.Cast As Any Pointer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return Cast(String Pointer, This.StoredData)
Case fbDouble: Return Cast(Double Pointer, This.StoredData)
Case fbSingle: Return Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return Cast(Long Pointer, This.StoredData)
Case fbInteger: Return Cast(Integer Pointer, This.StoredData)
Case fbShort: Return Cast(Short Pointer, This.StoredData)
Case fbByte: Return Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return This.StoredData
End Select
End Operator
Operator Mixed.Let(Value As Any Pointer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbAnyPointer
This.StoredData = Allocate(SizeOf(Any Pointer))
This.StoredData = value
End Operator
Operator -(ByRef rhs As Mixed) As Mixed
Select Case rhs.TypeId
Case fbEmpty: Return 0
Case Else: Return -Cast(Double, rhs)
End Select
End Operator
Operator &(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
Return Str(lhs) & Str(rhs)
End Operator
MixedImplementBinaryOperator(+)
MixedImplementBinaryOperator(-)
MixedImplementBinaryOperator(*)
MixedImplementBinaryOperator(/)
MixedImplementBinaryOperator(\)
MixedImplementBinaryOperator(Mod)
MixedImplementBinaryOperator(Shl)
MixedImplementBinaryOperator(Shr)
MixedImplementBinaryOperator(And)
MixedImplementBinaryOperator(Or)
MixedImplementBinaryOperator(Xor)
MixedImplementBinaryOperator(Imp)
MixedImplementBinaryOperator(Eqv)
MixedImplementBinaryOperator(^)
MixedImplementBinaryOperator(=)
MixedImplementBinaryOperator(<>)
MixedImplementBinaryOperator(<)
MixedImplementBinaryOperator(>)
MixedImplementBinaryOperator(<=)
MixedImplementBinaryOperator(>=)
#EndIf
Code: Select all
#include "mixed.bi"
Dim As string Mixed_types(9) = {"fbEmpty", "fbString", "fbDouble",_
"fbSingle", "fbLongInt", "fbLong", _
"fbInteger", "fbShort", "fbByte", _
"fbAnyPointer"}
redim shared stack(10) as Mixed
dim shared as integer stack_pointer=0, stack_ubound=10
sub push(byval n as Mixed)
stack(stack_pointer)=n
if stack_pointer=stack_ubound then
stack_ubound+=10
redim preserve stack(stack_ubound)
end if
stack_pointer+=1
end sub
function pop() as Mixed
if stack_pointer=0 then
print "stack is empty"
return 9
end if
stack_pointer-=1
return stack(stack_pointer)
end function
dim as double i
dim n as Mixed
for i=0 to 15
n=i
push(n)
next
for i=0 to 15
n=pop()
print i,n, Mixed_types(n.TypeId)
next
n=pop()
Print "Press RETURN to quit"
Sleep
Code: Select all
0 15 fbDouble
1 14 fbDouble
2 13 fbDouble
3 12 fbDouble
4 11 fbDouble
5 10 fbDouble
6 9 fbDouble
7 8 fbDouble
8 7 fbDouble
9 6 fbDouble
10 5 fbDouble
11 4 fbDouble
12 3 fbDouble
13 2 fbDouble
14 1 fbDouble
15 0 fbDouble
stack is empty
Press RETURN to quit
Re: Mixed datatype
thank you fxm, this is definitely a must study :-)
Re: Mixed datatype
@fxm
this code is more complex than I have dealt with before, from what I have seen, a constructor basically has the body of a let but it may also need memory allocation/initialization
I am groping in the dark here, would a mixed integer constructor have the same body as that of the let operator or does it need extra memory management?
so I made a copy of the Operator Mixed.Let(Value As Integer) and made a constructor out of it, what do think?
it seems to work, I can do: Print Mixed(i) where i is an integer
this code is more complex than I have dealt with before, from what I have seen, a constructor basically has the body of a let but it may also need memory allocation/initialization
I am groping in the dark here, would a mixed integer constructor have the same body as that of the let operator or does it need extra memory management?
so I made a copy of the Operator Mixed.Let(Value As Integer) and made a constructor out of it, what do think?
Code: Select all
Constructor Mixed(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbInteger
This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Constructor
Re: Mixed datatype
it was the integer constructor that I had added that was causing the problem
Code: Select all
dim n as mixed
dim x as double
n=16
x=1.23
n=n*x
n*=x will have the desired result, however n=n*x should also promote n to fbDouble with the correct result
so I un-privated the members StoredType and StoredData
now I can add operators
Code: Select all
Operator * (byref lhs as Mixed, byval rhs As Double) as Mixed
dim as Mixed res
res = lhs
If res.StoredType <> fbEmpty And res.StoredType <> fbAnyPointer Then
DeAllocate res.StoredData
EndIf
res.StoredType = fbDouble
res.StoredData = Allocate(SizeOf(Double))
*Cast(Double Pointer, res.StoredData) = cdbl(lhs) * rhs
return res
End Operator
@fxm
what do you think?
complete code follows
Code: Select all
''
'' Mixed datatype definition
''
'' by Aleksandar Ruzicic
''
#Ifndef __MIXED_TYPE__
#Define __MIXED_TYPE__
#Macro MixedDeclareOperators(_TYPE_)
Declare Operator Cast As _TYPE_
Declare Operator Let(value As _TYPE_)
Declare Operator +=(value As _TYPE_)
Declare Operator -=(value As _TYPE_)
Declare Operator *=(value As _TYPE_)
Declare Operator /=(value As _TYPE_)
Declare Operator \=(value As _TYPE_)
Declare Operator ^=(value As _TYPE_)
Declare Operator Mod=(value As _TYPE_)
Declare Operator Shl=(value As _TYPE_)
Declare Operator Shr=(value As _TYPE_)
Declare Operator And=(value As _TYPE_)
Declare Operator Or=(value As _TYPE_)
Declare Operator Xor=(value As _TYPE_)
Declare Operator Imp=(value As _TYPE_)
Declare Operator Eqv=(value As _TYPE_)
#EndMacro
#Macro MixedImplementAssignmentOperators(_TYPE_)
Operator Mixed.+=(value As _TYPE_)
This = Cast(_TYPE_, This) + value
End Operator
Operator Mixed.-=(value As _TYPE_)
This = Cast(_TYPE_, This) - value
End Operator
Operator Mixed.*=(value As _TYPE_)
This = Cast(_TYPE_, This) * value
End Operator
Operator Mixed./=(value As _TYPE_)
This = Cast(_TYPE_, This) / value
End Operator
Operator Mixed.\=(value As _TYPE_)
This = Cast(_TYPE_, This) \ value
End Operator
Operator Mixed.^=(value As _TYPE_)
This = Cast(_TYPE_, This) ^ value
End Operator
Operator Mixed.Mod=(value As _TYPE_)
This = Cast(_TYPE_, This) Mod value
End Operator
Operator Mixed.Shl=(value As _TYPE_)
This = Cast(_TYPE_, This) Shl value
End Operator
Operator Mixed.Shr=(value As _TYPE_)
This = Cast(_TYPE_, This) Shr value
End Operator
Operator Mixed.And=(value As _TYPE_)
This = Cast(_TYPE_, This) And value
End Operator
Operator Mixed.Or=(value As _TYPE_)
This = Cast(_TYPE_, This) Or value
End Operator
Operator Mixed.Xor=(value As _TYPE_)
This = Cast(_TYPE_, This) Xor value
End Operator
Operator Mixed.Imp=(value As _TYPE_)
This = Cast(_TYPE_, This) Imp value
End Operator
Operator Mixed.Eqv=(value As _TYPE_)
This = Cast(_TYPE_, This) Eqv value
End Operator
#EndMacro
#Macro MixedImplementBinaryOperator(_OP_)
Operator _OP_(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
If lhs.TypeId < fbInteger Or rhs.TypeId < fbInteger Then
Return CDbl(lhs) _OP_ CDbl(rhs)
Else
Return CInt(lhs) _OP_ CInt(rhs)
EndIf
End Operator
#EndMacro
Enum MixedType
fbEmpty
fbString
fbDouble
fbSingle
fbLongInt
fbLong
fbInteger
fbShort
fbByte
fbAnyPointer
End Enum
Type Mixed
Public:
Declare Constructor
Declare Constructor(ByRef m As Mixed)
'v
declare Constructor (Value As Integer)
'^
Declare Operator Let(ByRef m As Mixed)
Declare Destructor
Declare Property TypeId As MixedType
Declare Operator Cast As String
Declare Operator Let(value As String)
Declare Operator +=(value As String)
Declare Operator &=(value As String)
MixedDeclareOperators(Double)
MixedDeclareOperators(Single)
MixedDeclareOperators(LongInt)
MixedDeclareOperators(Long)
MixedDeclareOperators(Integer)
MixedDeclareOperators(Short)
MixedDeclareOperators(Byte)
Declare Operator Cast As Any Pointer
Declare Operator Let(value As Any Pointer)
'Private:
StoredType As MixedType = fbEmpty
StoredData As Any Pointer = 0
End Type
Constructor Mixed
End Constructor
Constructor Mixed(ByRef m As Mixed)
This = m
End Constructor
'v
Constructor Mixed(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbInteger
This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Constructor
'MixedImplementAssignmentOperators(Integer)
'^
Operator Mixed.Let(ByRef m As Mixed)
Select Case m.StoredType
Case fbEmpty:
Case fbString: This = *Cast(String Pointer, m.StoredData)
Case fbDouble: This = *Cast(Double Pointer, m.StoredData)
Case fbSingle: This = *Cast(Single Pointer, m.StoredData)
Case fbLongInt: This = *Cast(LongInt Pointer, m.StoredData)
Case fbLong: This = *Cast(Long Pointer, m.StoredData)
Case fbInteger: This = *Cast(Integer Pointer, m.StoredData)
Case fbShort: This = *Cast(Short Pointer, m.StoredData)
Case fbByte: This = *Cast(Byte Pointer, m.StoredData)
Case fbAnyPointer: This = *Cast(Single Pointer, m.StoredData)
End Select
End Operator
Destructor Mixed
If This.StoredType <> fbEmpty And this.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
End Destructor
Property Mixed.TypeId As MixedType
Return This.StoredType
End Property
Operator Mixed.Cast As String
Select Case This.StoredType
Case fbEmpty: Return ""
Case fbString: Return *Cast(String Pointer, This.StoredData)
Case fbDouble: Return Str(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return Str(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return Str(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return Str(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return Str(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return Str(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return Str(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(String Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As String)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
If This.StoredType = fbString Then
*Cast(String Pointer, This.StoredData) = ""
EndIf
DeAllocate This.StoredData
EndIf
This.StoredType = fbString
This.StoredData = CAllocate(SizeOf(String))
*Cast(String Pointer, This.StoredData) = value
End Operator
Operator Mixed.+=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.&=(value As String)
This = Cast(String, This) & value
End Operator
Operator Mixed.Cast As Double
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CDbl(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return *Cast(Double Pointer, This.StoredData)
Case fbSingle: Return CDbl(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CDbl(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CDbl(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CDbl(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CDbl(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CDbl(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Double Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Double)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbDouble
This.StoredData = Allocate(SizeOf(Double))
*Cast(Double Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Double)
Operator Mixed.Cast As Single
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CSng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CSng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return *Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return CSng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CSng(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CSng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CSng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CSng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Single Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Single)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbSingle
This.StoredData = Allocate(SizeOf(Single))
*Cast(Single Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Single)
Operator Mixed.Cast As LongInt
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLngInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLngInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLngInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return *Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return CLngInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CLngInt(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLngInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLngInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(LongInt Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As LongInt)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLongInt
This.StoredData = Allocate(SizeOf(LongInt))
*Cast(LongInt Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(LongInt)
Operator Mixed.Cast As Long
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CLng(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CLng(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CLng(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CLng(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return *Cast(Long Pointer, This.StoredData)
Case fbInteger: Return CLng(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CLng(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CLng(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Long Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Long)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbLong
This.StoredData = Allocate(SizeOf(Long))
*Cast(Long Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Long)
Operator Mixed.Cast As Integer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CInt(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CInt(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CInt(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CInt(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CInt(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return *Cast(Integer Pointer, This.StoredData)
Case fbShort: Return CInt(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return CInt(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Integer Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Integer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbInteger
This.StoredData = Allocate(SizeOf(Integer))
*Cast(Integer Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Integer)
Operator Mixed.Cast As Short
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CShort(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CShort(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CShort(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CShort(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CShort(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CShort(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return *Cast(Short Pointer, This.StoredData)
Case fbByte: Return CShort(*Cast(Byte Pointer, This.StoredData))
Case fbAnyPointer: Return *Cast(Short Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Short)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbShort
This.StoredData = Allocate(SizeOf(Short))
*Cast(Short Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Short)
Operator Mixed.Cast As Byte
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return CByte(*Cast(String Pointer, This.StoredData))
Case fbDouble: Return CByte(*Cast(Double Pointer, This.StoredData))
Case fbSingle: Return CByte(*Cast(Single Pointer, This.StoredData))
Case fbLongInt: Return CByte(*Cast(LongInt Pointer, This.StoredData))
Case fbLong: Return CByte(*Cast(Long Pointer, This.StoredData))
Case fbInteger: Return CByte(*Cast(Integer Pointer, This.StoredData))
Case fbShort: Return CByte(*Cast(Short Pointer, This.StoredData))
Case fbByte: Return *Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return *Cast(Byte Pointer, This.StoredData)
End Select
End Operator
Operator Mixed.Let(Value As Byte)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbByte
This.StoredData = Allocate(SizeOf(Byte))
*Cast(Byte Pointer, This.StoredData) = value
End Operator
MixedImplementAssignmentOperators(Byte)
Operator Mixed.Cast As Any Pointer
Select Case This.StoredType
Case fbEmpty: Return 0
Case fbString: Return Cast(String Pointer, This.StoredData)
Case fbDouble: Return Cast(Double Pointer, This.StoredData)
Case fbSingle: Return Cast(Single Pointer, This.StoredData)
Case fbLongInt: Return Cast(LongInt Pointer, This.StoredData)
Case fbLong: Return Cast(Long Pointer, This.StoredData)
Case fbInteger: Return Cast(Integer Pointer, This.StoredData)
Case fbShort: Return Cast(Short Pointer, This.StoredData)
Case fbByte: Return Cast(Byte Pointer, This.StoredData)
Case fbAnyPointer: Return This.StoredData
End Select
End Operator
Operator Mixed.Let(Value As Any Pointer)
If This.StoredType <> fbEmpty And This.StoredType <> fbAnyPointer Then
DeAllocate This.StoredData
EndIf
This.StoredType = fbAnyPointer
This.StoredData = Allocate(SizeOf(Any Pointer))
This.StoredData = value
End Operator
Operator -(ByRef rhs As Mixed) As Mixed
Select Case rhs.TypeId
Case fbEmpty: Return 0
Case Else: Return -Cast(Double, rhs)
End Select
End Operator
Operator &(ByRef lhs As Mixed, ByRef rhs As Mixed) As Mixed
Return Str(lhs) & Str(rhs)
End Operator
MixedImplementBinaryOperator(+)
MixedImplementBinaryOperator(-)
MixedImplementBinaryOperator(*)
MixedImplementBinaryOperator(/)
MixedImplementBinaryOperator(\)
MixedImplementBinaryOperator(Mod)
MixedImplementBinaryOperator(Shl)
MixedImplementBinaryOperator(Shr)
MixedImplementBinaryOperator(And)
MixedImplementBinaryOperator(Or)
MixedImplementBinaryOperator(Xor)
MixedImplementBinaryOperator(Imp)
MixedImplementBinaryOperator(Eqv)
MixedImplementBinaryOperator(^)
MixedImplementBinaryOperator(=)
MixedImplementBinaryOperator(<>)
MixedImplementBinaryOperator(<)
MixedImplementBinaryOperator(>)
MixedImplementBinaryOperator(<=)
MixedImplementBinaryOperator(>=)
Operator *(byref lhs as Mixed, byval rhs As Double) as Mixed
dim as Mixed res
res = lhs
If res.StoredType <> fbEmpty And res.StoredType <> fbAnyPointer Then
DeAllocate res.StoredData
EndIf
res.StoredType = fbDouble
res.StoredData = Allocate(SizeOf(Double))
*Cast(Double Pointer, res.StoredData) = cdbl(lhs) * rhs
return res
End Operator
#EndIf
Dim As string Mixed_types(9) = {"fbEmpty", "fbString", "fbDouble",_
"fbSingle", "fbLongInt", "fbLong", _
"fbInteger", "fbShort", "fbByte", _
"fbAnyPointer"}
dim as Mixed n
dim as double x
n=16
print n, Mixed_types(n.TypeId)
x=1.23
n=n*x
print n, Mixed_types(n.TypeId)
Print "Press RETURN to quit"
Sleep
Last edited by srvaldez on Jun 17, 2020 10:12, edited 1 time in total.
Re: Mixed datatype
A 'Let-operator(as udt2)' may be necessary in a complex udt1 Type if one want to use for example a udt1 instance assignment from a udt2 instance such as:
dim as udt2 u2
dim as udt1 u1
u1 = u2 '' <==
or else:
function test () as udt1
dim as udt2 u2
function = u2 '' <==
end function
A 'Constructor(as udt2)' may be necessary in a complex udt1 Type if one want to use for example a udt1 instance construction with a udt2 instance initializer such as:
dim as udt2 u2
dim as udt1 u1 = u2 '' <==
or else:
function test () as udt1
dim as udt2 u2
return u2 '' <==
end function
or else:
sub test (byval u1 as udt1)
end sub
dim as udt2 u2
test(u2) '' <==
In your specific example above, I don't see why a 'Constructor (Value As Integer)' would be needed.
dim as udt2 u2
dim as udt1 u1
u1 = u2 '' <==
or else:
function test () as udt1
dim as udt2 u2
function = u2 '' <==
end function
A 'Constructor(as udt2)' may be necessary in a complex udt1 Type if one want to use for example a udt1 instance construction with a udt2 instance initializer such as:
dim as udt2 u2
dim as udt1 u1 = u2 '' <==
or else:
function test () as udt1
dim as udt2 u2
return u2 '' <==
end function
or else:
sub test (byval u1 as udt1)
end sub
dim as udt2 u2
test(u2) '' <==
In your specific example above, I don't see why a 'Constructor (Value As Integer)' would be needed.
Last edited by fxm on Jun 17, 2020 9:35, edited 6 times in total.
Re: Mixed datatype
If you are interested, you can read the following topics in the Programmer's Guide:
- Constructors and Destructors (basics)
- Constructors, '=' Assignment-Operators, and Destructors (advanced, part #1)
- Constructors, '=' Assignment-Operators, and Destructors (advanced, part #2)
- Constructors and Destructors (basics)
- Constructors, '=' Assignment-Operators, and Destructors (advanced, part #1)
- Constructors, '=' Assignment-Operators, and Destructors (advanced, part #2)
Re: Mixed datatype
If you create a constructor for each datatype
VIZ
constructor mixed
end constructor
constructor mixed(i as integer)
this=i 'use let
end constructor
constructor mixed(i as double)
this=i 'use let
end constructor
. . .
it allows you to do things like
Result:
But the author's code is now 569 lines long.
I had to adjust srvaldez pop to return a byref value otherwise I got an ambiguous call error.
and sub push( n as Mixed) instead of byval n as Mixed.
The author probably wanted to concentrate on other aspects of the code, which I think is pretty comprehensive.
And from 2008 to now and running with little alteration is a testament to the freebasic language.
VIZ
constructor mixed
end constructor
constructor mixed(i as integer)
this=i 'use let
end constructor
constructor mixed(i as double)
this=i 'use let
end constructor
. . .
it allows you to do things like
Code: Select all
dim as mixed k(. . .)={csng(sqr(2)),sqr(2),"Hello",5,__function__,13ll,cubyte(asc("a"))}
for n as long=lbound(k) to ubound(k)
print k(n);tab(30);Mixed_types(k(n).TypeId)
next n
Code: Select all
1.414214 fbSingle
1.414213562373095 fbDouble
Hello fbString
5 fbInteger
__FB_MAINPROC__ fbString
13 fbLongInt
97 fbByte
Press RETURN to quit
I had to adjust srvaldez pop to return a byref value otherwise I got an ambiguous call error.
and sub push( n as Mixed) instead of byval n as Mixed.
The author probably wanted to concentrate on other aspects of the code, which I think is pretty comprehensive.
And from 2008 to now and running with little alteration is a testament to the freebasic language.
Re: Mixed datatype
or define a 'Constructor Mixed (Byref As Mixed)'.dodicat wrote:I had to adjust srvaldez pop to return a byref value otherwise I got an ambiguous call error.
and sub push( n as Mixed) instead of byval n as Mixed.
And an 'Operator Mixed.Let (Byref As Mixed)' because 'stack(stack_pointer)=n' and 'n=pop()' also call the Let-operator.