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