ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
autocast.cpp
1//! @cond NO_DOX
2
3#define ARG0 (*args)
4#define BOL(box) (box).Unbox<bool >()
5#define INT(box) (box).Unbox<integer>()
6//#define FLT(box) (box).Unbox<double >()
7#define FUNC( name,...) Box name( Scope& scope, \
8 ArgIterator args, \
9 ArgIterator end ) \
10 { (void) scope; (void) args; (void) end; __VA_ARGS__ }
11
12
13namespace alib { namespace expressions { namespace plugins {
14
16: CompilerPlugin( "ALib Auto Cast", compiler, CompilePriorities::AutoCast ) {}
17
18namespace {
19
20enum class SortedTypes {
21 UNKNOWN = 0,
22 Bool = 1,
23 Integer = 2,
24 Float = 4,
25 String = 8,
26};
27
28SortedTypes SortedType( Type type ) {
29 if( type.IsType<bool >() ) return SortedTypes::Bool;
30 if( type.IsType<integer>() ) return SortedTypes::Integer;
31 if( type.IsType<double >() ) return SortedTypes::Float;
32 if( type.IsType<String >() ) return SortedTypes::String;
33 return SortedTypes::UNKNOWN;
34}
35
36// conversion integer to float.
37FUNC( castI2F , return double ( INT(ARG0) ); )
38FUNC( castB2F , return double ( BOL(ARG0) ); )
39FUNC( castB2I , return integer( BOL(ARG0)); )
40
41} // anonymous namespace
42
43
44//##################################################################################################
45// ### AutoCast - TryCompilation
46//##################################################################################################
47bool AutoCast::TryCompilation( CIAutoCast& ciAutoCast ) {
48 // we do not work on unary ops
49 if ( ciAutoCast.ArgsBegin + 1 >= ciAutoCast.ArgsEnd )
50 return false;
51
52 // convert the minor type to the major
53 SortedTypes t1= SortedType( * ciAutoCast.ArgsBegin );
54 SortedTypes t2= SortedType( *(ciAutoCast.ArgsBegin+1) );
55 if( t1 == t2 )
56 return false;
57 SortedTypes major;
58 SortedTypes minor;
59 if( t1 > t2 ) { major= t1; minor= t2; }
60 else { major= t2; minor= t1; }
61
62 // choose upgrade function
63 CallbackDecl upgradeCast;
64 String decompileFunctionCall;
65 ALIB_DBG( const char* upgradeCastDBG; )
66
67 // we can cast every type to string
68 if( major == SortedTypes::String ) {
69 upgradeCast = CBToString;
70 decompileFunctionCall = A_CHAR("String");
71ALIB_DBG(upgradeCastDBG = "CBToString"; )
72 }
73
74 // integer to float?
75 else if( major == SortedTypes::Float && minor == SortedTypes::Integer ) {
76 upgradeCast = castI2F;
77 decompileFunctionCall = A_CHAR("Float");
78ALIB_DBG(upgradeCastDBG = "castI2F"; )
79
80 }
81
82 // bool to float?
83 else if( major == SortedTypes::Float && minor == SortedTypes::Bool ) {
84 upgradeCast = castB2F;
85 decompileFunctionCall = A_CHAR("Float");
86ALIB_DBG(upgradeCastDBG = "castB2F"; )
87
88 }
89
90 // we can cast every type to integer via boolean
91 else if( major == SortedTypes::Integer && minor == SortedTypes::Bool ) {
92 upgradeCast = castB2I;
93 decompileFunctionCall = A_CHAR("Integer");
94ALIB_DBG(upgradeCastDBG = "castB2I"; )
95 }
96
97 // we can cast every type to boolean as well
98 else if( major == SortedTypes::Bool ) {
99 upgradeCast = ToBoolean;
100 decompileFunctionCall = A_CHAR("Boolean");
101ALIB_DBG(upgradeCastDBG = "ToBoolean"; )
102 }
103
104 else
105 return false;
106
107 // set upgrade function to the right callback
108 if( t1 < t2 ) {
109 ciAutoCast.Callback = upgradeCast;
110 ciAutoCast.TypeOrValue = *(ciAutoCast.ArgsBegin + 1);
111 ciAutoCast.ReverseCastFunctionName = decompileFunctionCall;
112ALIB_DBG(ciAutoCast.DbgCallbackName = upgradeCastDBG; )
113 } else {
114 ciAutoCast.CallbackRhs = upgradeCast;
115 ciAutoCast.TypeOrValueRhs = *(ciAutoCast.ArgsBegin );
116 ciAutoCast.ReverseCastFunctionNameRhs = decompileFunctionCall;
117ALIB_DBG(ciAutoCast.DbgCallbackNameRhs = upgradeCastDBG; )
118 }
119
120 // If constant values were given, we can we do it right away (compile-time optimization)
121 if( ciAutoCast.IsConst && ciAutoCast.Callback != nullptr ) {
122 ciAutoCast.TypeOrValue = ciAutoCast.Callback( ciAutoCast.CompileTimeScope,
123 ciAutoCast.ArgsBegin ,
124 ciAutoCast.ArgsEnd - 1 );
125 ciAutoCast.Callback = nullptr;
126 }
127 else if( ciAutoCast.RhsIsConst && ciAutoCast.CallbackRhs != nullptr ) {
128 ciAutoCast.TypeOrValueRhs= ciAutoCast.CallbackRhs( ciAutoCast.CompileTimeScope,
129 ciAutoCast.ArgsBegin + 1 ,
130 ciAutoCast.ArgsEnd );
131 ciAutoCast.CallbackRhs = nullptr;
132 }
133
134
135 return true;
136}
137
138
139
140}}} // namespace [alib::expressions::detail]
141
142#undef ARG0
143#undef BOL
144#undef INT
145#undef FLT
146#undef FUNC
147//! @endcond
#define A_CHAR(STR)
#define ALIB_DBG(...)
Box ToBoolean(Scope &scope, ArgIterator args, ArgIterator)
Box CBToString(Scope &scope, ArgIterator args, ArgIterator)
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
platform_specific integer
Definition integers.hpp:32
Definition alox.cpp:14
expressions::Compiler Compiler
Type alias in namespace #"%alib".
Definition compiler.hpp:535
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
expressions::CompilerPlugin CompilerPlugin
Type alias in namespace #"%alib".