ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
autocast.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10#if !defined (HPP_ALIB_EXPRESSIONS_PLUGINS_AUTOCAST)
12#endif
13
14// we are using method ToString
15#if !defined (HPP_ALIB_EXPRESSIONS_PLUGINS_STRINGS)
17#endif
18
19// ...and method ToBoolean
20#if !defined (HPP_ALIB_EXPRESSIONS_PLUGINS_ARITHMETICS)
22#endif
23#endif // !defined(ALIB_DOX)
24
25//! @cond NO_DOX
26
27#define ARG0 (*args)
28#define BOL(box) (box).Unbox<bool >()
29#define INT(box) (box).Unbox<integer>()
30//#define FLT(box) (box).Unbox<double >()
31#define FUNC( name,...) Box name( Scope& scope, \
32 ArgIterator args, \
33 ArgIterator end ) \
34 { (void) scope; (void) args; (void) end; __VA_ARGS__ }
35
36
37namespace alib { namespace expressions { namespace plugins {
38
40: CompilerPlugin( "ALib Auto Cast", compiler )
41{}
42
43namespace {
44
45enum class SortedTypes
46{
47 UNKNOWN = 0,
48 Bool = 1,
49 Integer = 2,
50 Float = 4,
51 String = 8,
52};
53
54SortedTypes SortedType( Type type )
55{
56 if( type.IsType<bool >() ) return SortedTypes::Bool;
57 if( type.IsType<integer>() ) return SortedTypes::Integer;
58 if( type.IsType<double >() ) return SortedTypes::Float;
59 if( type.IsType<String >() ) return SortedTypes::String;
60 return SortedTypes::UNKNOWN;
61}
62
63// conversion integer to float.
64FUNC( castI2F , return static_cast<double >( INT(ARG0) ); )
65FUNC( castB2F , return static_cast<double >( BOL(ARG0) ); )
66FUNC( castB2I , return static_cast<integer>( BOL(ARG0)); )
67
68} // anonymous namespace
69
70
71// #################################################################################################
72// ### AutoCast - TryCompilation
73// #################################################################################################
74bool AutoCast::TryCompilation( CIAutoCast& ciAutoCast )
75{
76 // we do not work on unary ops
77 if ( ciAutoCast.ArgsBegin + 1 >= ciAutoCast.ArgsEnd )
78 return false;
79
80 // convert the minor type to the major
81 SortedTypes t1= SortedType( * ciAutoCast.ArgsBegin );
82 SortedTypes t2= SortedType( *(ciAutoCast.ArgsBegin+1) );
83 if( t1 == t2 )
84 return false;
85 SortedTypes major;
86 SortedTypes minor;
87 if( t1 > t2 ) { major= t1; minor= t2; }
88 else { major= t2; minor= t1; }
89
90 // choose upgrade function
91 CallbackDecl upgradeCast;
92 String decompileFunctionCall;
93 ALIB_DBG( const char* upgradeCastDBG; )
94
95 // we can cast every type to string
96 if( major == SortedTypes::String )
97 {
98 upgradeCast = CBToString;
99 decompileFunctionCall = A_CHAR("String");
100ALIB_DBG(upgradeCastDBG = "CBToString"; )
101 }
102
103 // integer to float?
104 else if( major == SortedTypes::Float && minor == SortedTypes::Integer )
105 {
106 upgradeCast = castI2F;
107 decompileFunctionCall = A_CHAR("Float");
108ALIB_DBG(upgradeCastDBG = "castI2F"; )
109
110 }
111
112 // bool to float?
113 else if( major == SortedTypes::Float && minor == SortedTypes::Bool )
114 {
115 upgradeCast = castB2F;
116 decompileFunctionCall = A_CHAR("Float");
117ALIB_DBG(upgradeCastDBG = "castB2F"; )
118
119 }
120
121 // we can cast every type to integer via boolean
122 else if( major == SortedTypes::Integer && minor == SortedTypes::Bool )
123 {
124 upgradeCast = castB2I;
125 decompileFunctionCall = A_CHAR("Integer");
126ALIB_DBG(upgradeCastDBG = "castB2I"; )
127 }
128
129 // we can cast every type to boolean as well
130 else if( major == SortedTypes::Bool )
131 {
132 upgradeCast = ToBoolean;
133 decompileFunctionCall = A_CHAR("Boolean");
134ALIB_DBG(upgradeCastDBG = "ToBoolean"; )
135 }
136
137 else
138 return false;
139
140 // set upgrade function to the right callback
141 if( t1 < t2 )
142 {
143 ciAutoCast.Callback = upgradeCast;
144 ciAutoCast.TypeOrValue = *(ciAutoCast.ArgsBegin + 1);
145 ciAutoCast.ReverseCastFunctionName = decompileFunctionCall;
146ALIB_DBG(ciAutoCast.DbgCallbackName = upgradeCastDBG; )
147 }
148 else
149 {
150 ciAutoCast.CallbackRhs = upgradeCast;
151 ciAutoCast.TypeOrValueRhs = *(ciAutoCast.ArgsBegin );
152 ciAutoCast.ReverseCastFunctionNameRhs = decompileFunctionCall;
153ALIB_DBG(ciAutoCast.DbgCallbackNameRhs = upgradeCastDBG; )
154 }
155
156 // If constant values were given, we can we do it right away (compile-time optimization)
157 if( ciAutoCast.IsConst && ciAutoCast.Callback != nullptr )
158 {
159 ciAutoCast.TypeOrValue = ciAutoCast.Callback( ciAutoCast.CompileTimeScope,
160 ciAutoCast.ArgsBegin ,
161 ciAutoCast.ArgsEnd - 1 );
162 ciAutoCast.Callback = nullptr;
163 }
164 else if( ciAutoCast.RhsIsConst && ciAutoCast.CallbackRhs != nullptr )
165 {
166 ciAutoCast.TypeOrValueRhs= ciAutoCast.CallbackRhs( ciAutoCast.CompileTimeScope,
167 ciAutoCast.ArgsBegin + 1 ,
168 ciAutoCast.ArgsEnd );
169 ciAutoCast.CallbackRhs = nullptr;
170 }
171
172
173 return true;
174}
175
176
177
178}}} // namespace [alib::expressions::detail]
179
180#undef ARG0
181#undef BOL
182#undef INT
183//#undef FLT
184#undef FUNC
185//! @endcond
#define A_CHAR(STR)
#define ALIB_DBG(...)
Definition alib.hpp:457
ALIB_API Box CBToString(Scope &scope, ArgIterator args, ArgIterator)
ALIB_API Box ToBoolean(Scope &scope, ArgIterator args, ArgIterator)
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
platform_specific integer
Definition integers.hpp:50
Definition alib.cpp:57
expressions::CompilerPlugin CompilerPlugin
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
Definition compiler.hpp:596
ALIB_API AutoCast(Compiler &compiler)