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