10#if !defined (HPP_ALIB_EXPRESSIONS_PLUGINS_ARITHMETICS)
19#define ARG1 (*(args+1))
20#define BOL(box) (box).Unbox<bool >()
21#define INT(box) (box).Unbox<integer>()
22#define ITF(box) static_cast<double>((box).Unbox<integer>() )
23#define BTF(box) static_cast<double>((box).Unbox<bool >() )
24#define FLT(box) (box).Unbox<double >()
25#define FUNC( name,...) Box name( Scope& scope, \
28 { (void) scope; (void) args; (void) end; __VA_ARGS__ }
30#if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS
31# define TOINT(arg) arg
33# define TOINT(arg) static_cast<integer>(arg)
37namespace alib {
namespace expressions {
namespace plugins {
50Box constFalse =
false;
51Box identity =
nullptr;
52Box bool_false =
false;
63FUNC( toInt_B ,
return static_cast<integer>(BOL(ARG0)); )
64FUNC( toInt_I ,
return ARG0; )
65FUNC( toInt_F ,
return static_cast<integer>(FLT(ARG0)); )
66FUNC( toFloat_B,
return static_cast<double >(BOL(ARG0)); )
67FUNC( toFloat_I,
return static_cast<double >(INT(ARG0)); )
68FUNC( toFloat_F,
return ARG0; )
70FUNC( arrLen,
return ARG0.UnboxLength(); )
77FUNC( pos ,
return ARG0; )
78FUNC( pos_B ,
return static_cast<integer>(BOL(ARG0)); )
79FUNC( neg_B ,
return -
static_cast<integer>(BOL(ARG0)); )
80FUNC( neg_I ,
return -INT(ARG0); )
81FUNC( neg_F ,
return -FLT(ARG0); )
82FUNC( bitNot ,
return ~INT(ARG0); )
83FUNC( boolNot_B,
return !BOL(ARG0); )
84FUNC( boolNot_I,
return INT(ARG0) ==
static_cast<integer>(0); )
85FUNC( boolNot_F,
return FLT(ARG0) == 0.0; )
93 #pragma warning( push )
94 #pragma warning( disable : 4804 )
95 #pragma warning( disable : 4805 )
98FUNC( mul_BB,
return BOL(ARG0) * BOL(ARG1) ; )
99FUNC( mul_BI,
return BOL(ARG0) * INT(ARG1) ; )
100FUNC( mul_BF,
return BOL(ARG0) * FLT(ARG1) ; )
101FUNC( mul_IB,
return INT(ARG0) * BOL(ARG1) ; )
102FUNC( mul_II,
return INT(ARG0) * INT(ARG1) ; )
103FUNC( mul_IF,
return ITF(ARG0) * FLT(ARG1) ; )
104FUNC( mul_FB,
return FLT(ARG0) * BTF(ARG1) ; )
105FUNC( mul_FI,
return FLT(ARG0) * ITF(ARG1) ; )
106FUNC( mul_FF,
return FLT(ARG0) * FLT(ARG1) ; )
107FUNC( div_BI,
return BOL(ARG0) / INT(ARG1) ; )
108FUNC( div_BF,
return BOL(ARG0) / FLT(ARG1) ; )
109FUNC( div_II,
return INT(ARG0) / INT(ARG1) ; )
110FUNC( div_IF,
return ITF(ARG0) / FLT(ARG1) ; )
111FUNC( div_FI,
return FLT(ARG0) / ITF(ARG1) ; )
112FUNC( div_FF,
return FLT(ARG0) / FLT(ARG1) ; )
113FUNC( mod_BI,
return BOL(ARG0) % INT(ARG1) ; )
114FUNC( mod_II,
return INT(ARG0) % INT(ARG1) ; )
115FUNC( mod_BF,
return fmod(BOL(ARG0), FLT(ARG1)); )
116FUNC( mod_FI,
return fmod(FLT(ARG0), INT(ARG1)); )
117FUNC( mod_IF,
return fmod(INT(ARG0), FLT(ARG1)); )
118FUNC( mod_FF,
return fmod(FLT(ARG0), FLT(ARG1)); )
120FUNC( add_BB,
return BOL(ARG0) + BOL(ARG1) ; )
121FUNC( add_BI,
return BOL(ARG0) + INT(ARG1) ; )
122FUNC( add_BF,
return BOL(ARG0) + FLT(ARG1) ; )
123FUNC( add_IB,
return INT(ARG0) + BOL(ARG1) ; )
124FUNC( add_II,
return INT(ARG0) + INT(ARG1) ; )
125FUNC( add_IF,
return ITF(ARG0) + FLT(ARG1) ; )
126FUNC( add_FB,
return FLT(ARG0) + BOL(ARG1) ; )
127FUNC( add_FI,
return FLT(ARG0) + ITF(ARG1) ; )
128FUNC( add_FF,
return FLT(ARG0) + FLT(ARG1) ; )
129FUNC( sub_BB,
return BOL(ARG0) - BOL(ARG1) ; )
130FUNC( sub_BI,
return BOL(ARG0) - INT(ARG1) ; )
131FUNC( sub_BF,
return BOL(ARG0) - FLT(ARG1) ; )
132FUNC( sub_IB,
return INT(ARG0) - BOL(ARG1) ; )
133FUNC( sub_II,
return INT(ARG0) - INT(ARG1) ; )
134FUNC( sub_IF,
return ITF(ARG0) - FLT(ARG1) ; )
135FUNC( sub_FB,
return FLT(ARG0) - BOL(ARG1) ; )
136FUNC( sub_FI,
return FLT(ARG0) - ITF(ARG1) ; )
137FUNC( sub_FF,
return FLT(ARG0) - FLT(ARG1) ; )
139FUNC( shfL_BI,
return TOINT( BOL(ARG0) << INT(ARG1) ); )
140FUNC( shfL_IB,
return INT(ARG0) << BOL(ARG1) ; )
141FUNC( shfL_II,
return INT(ARG0) << INT(ARG1) ; )
142FUNC( shfR_BI,
return TOINT( BOL(ARG0) << INT(ARG1) ); )
143FUNC( shfR_IB,
return INT(ARG0) << BOL(ARG1) ; )
144FUNC( shfR_II,
return INT(ARG0) >> INT(ARG1) ; )
146FUNC( sm_BB,
return BOL(ARG0) < BOL(ARG1) ; )
147FUNC( sm_BI,
return BOL(ARG0) < INT(ARG1) ; )
148FUNC( sm_BF,
return isless(
static_cast<double>(BOL(ARG0)), FLT(ARG1) ); )
149FUNC( sm_IB,
return INT(ARG0) < BOL(ARG1) ; )
150FUNC( sm_II,
return INT(ARG0) < INT(ARG1) ; )
151FUNC( sm_IF,
return isless(
static_cast<double>(INT(ARG0)), FLT(ARG1) ); )
152FUNC( sm_FB,
return isless( FLT(ARG0) ,
static_cast<double>(BOL(ARG1))); )
153FUNC( sm_FI,
return isless( FLT(ARG0) ,
static_cast<double>(INT(ARG1))); )
154FUNC( sm_FF,
return isless( FLT(ARG0) , FLT(ARG1) ); )
155FUNC( smeq_BB,
return BOL(ARG0) <= BOL(ARG1) ; )
156FUNC( smeq_BI,
return BOL(ARG0) <= INT(ARG1) ; )
157FUNC( smeq_BF,
return islessequal(
static_cast<double>(BOL(ARG0)), FLT(ARG1) ); )
158FUNC( smeq_IB,
return INT(ARG0) <= BOL(ARG1) ; )
159FUNC( smeq_II,
return INT(ARG0) <= INT(ARG1) ; )
160FUNC( smeq_IF,
return islessequal(
static_cast<double>(INT(ARG0)), FLT(ARG1) ); )
161FUNC( smeq_FB,
return islessequal( FLT(ARG0) ,
static_cast<double>(BOL(ARG1))); )
162FUNC( smeq_FI,
return islessequal( FLT(ARG0) ,
static_cast<double>(INT(ARG1))); )
163FUNC( smeq_FF,
return islessequal( FLT(ARG0) , FLT(ARG1) ); )
164FUNC( gt_BB,
return BOL(ARG0) > BOL(ARG1) ; )
165FUNC( gt_BI,
return BOL(ARG0) > INT(ARG1) ; )
166FUNC( gt_BF,
return isgreater(
static_cast<double>(BOL(ARG0)), FLT(ARG1) ); )
167FUNC( gt_IB,
return INT(ARG0) > BOL(ARG1) ; )
168FUNC( gt_II,
return INT(ARG0) > INT(ARG1) ; )
169FUNC( gt_IF,
return isgreater(
static_cast<double>(INT(ARG0)), FLT(ARG1) ); )
170FUNC( gt_FB,
return isgreater( FLT(ARG0) ,
static_cast<double>(BOL(ARG1))); )
171FUNC( gt_FI,
return isgreater( FLT(ARG0) ,
static_cast<double>(INT(ARG1))); )
172FUNC( gt_FF,
return isgreater( FLT(ARG0) , FLT(ARG1) ); )
173FUNC( gteq_BB,
return BOL(ARG0) >= BOL(ARG1) ; )
174FUNC( gteq_BI,
return BOL(ARG0) >= INT(ARG1) ; )
175FUNC( gteq_BF,
return isgreaterequal(
static_cast<double>(BOL(ARG0)), FLT(ARG1) ); )
176FUNC( gteq_IB,
return INT(ARG0) >= BOL(ARG1) ; )
177FUNC( gteq_II,
return INT(ARG0) >= INT(ARG1) ; )
178FUNC( gteq_IF,
return isgreaterequal(
static_cast<double>(INT(ARG0)), FLT(ARG1) ); )
179FUNC( gteq_FB,
return isgreaterequal( FLT(ARG0) ,
static_cast<double>(BOL(ARG1))); )
180FUNC( gteq_FI,
return isgreaterequal( FLT(ARG0) ,
static_cast<double>(INT(ARG1))); )
181FUNC( gteq_FF,
return isgreaterequal( FLT(ARG0) , FLT(ARG1) ); )
183FUNC( eq_BB,
return BOL(ARG0) == BOL(ARG1) ; )
184FUNC( eq_BI,
return BOL(ARG0) == INT(ARG1) ; )
185FUNC( eq_BF,
return std::fabs( BOL(ARG0) - FLT(ARG1) ) <= std::numeric_limits<double>::epsilon(); )
186FUNC( eq_IB,
return INT(ARG0) == BOL(ARG1) ; )
187FUNC( eq_II,
return INT(ARG0) == INT(ARG1) ; )
188FUNC( eq_IF,
return std::fabs( ITF(ARG0) - FLT(ARG1) ) <= std::numeric_limits<double>::epsilon(); )
189FUNC( eq_FB,
return std::fabs( FLT(ARG0) - BOL(ARG1) ) <= std::numeric_limits<double>::epsilon(); )
190FUNC( eq_FI,
return std::fabs( FLT(ARG0) - ITF(ARG1) ) <= std::numeric_limits<double>::epsilon(); )
191FUNC( eq_FF,
return std::fabs( FLT(ARG0) - FLT(ARG1) ) <= std::numeric_limits<double>::epsilon(); )
195FUNC( neq_BB,
return BOL(ARG0) != BOL(ARG1) ; )
196FUNC( neq_BI,
return BOL(ARG0) != INT(ARG1) ; )
197FUNC( neq_BF,
return std::fabs( BOL(ARG0) - FLT(ARG1) ) > std::numeric_limits<double>::epsilon(); )
198FUNC( neq_IB,
return INT(ARG0) != BOL(ARG1) ; )
199FUNC( neq_II,
return INT(ARG0) != INT(ARG1) ; )
200FUNC( neq_IF,
return std::fabs( INT(ARG0) - INT(ARG1) ) > std::numeric_limits<double>::epsilon(); )
201FUNC( neq_FB,
return std::fabs( FLT(ARG0) - BOL(ARG1) ) > std::numeric_limits<double>::epsilon(); )
202FUNC( neq_FI,
return std::fabs( FLT(ARG0) - ITF(ARG1) ) > std::numeric_limits<double>::epsilon(); )
203FUNC( neq_FF,
return std::fabs( FLT(ARG0) - FLT(ARG1) ) > std::numeric_limits<double>::epsilon(); )
206FUNC( bitAnd,
return INT(ARG0) & INT(ARG1) ; )
207FUNC( bitXOr,
return INT(ARG0) ^ INT(ARG1) ; )
208FUNC( bitOr ,
return INT(ARG0) | INT(ARG1) ; )
209FUNC( boolAnd_BB,
return BOL(ARG0) && BOL(ARG1) ; )
210FUNC( boolAnd_BI,
return BOL(ARG0) && INT(ARG1) != 0 ; )
211FUNC( boolAnd_BF,
return BOL(ARG0) && FLT(ARG1) != 0.0 ; )
212FUNC( boolAnd_IB,
return INT(ARG0) != 0 && BOL(ARG1) ; )
213FUNC( boolAnd_II,
return INT(ARG0) != 0 && INT(ARG1) != 0 ; )
214FUNC( boolAnd_IF,
return INT(ARG0) != 0 && FLT(ARG1) != 0.0 ; )
215FUNC( boolAnd_FB,
return FLT(ARG0) != 0.0 && BOL(ARG1) ; )
216FUNC( boolAnd_FI,
return FLT(ARG0) != 0.0 && INT(ARG1) != 0 ; )
217FUNC( boolAnd_FF,
return FLT(ARG0) != 0.0 && FLT(ARG1) != 0.0 ; )
218FUNC( boolOr_BB,
return BOL(ARG0) || BOL(ARG1) ; )
219FUNC( boolOr_BI,
return BOL(ARG0) || INT(ARG1) != 0 ; )
220FUNC( boolOr_BF,
return BOL(ARG0) || FLT(ARG1) != 0.0 ; )
221FUNC( boolOr_IB,
return INT(ARG0) != 0 || BOL(ARG1) ; )
222FUNC( boolOr_II,
return INT(ARG0) != 0 || INT(ARG1) != 0 ; )
223FUNC( boolOr_IF,
return INT(ARG0) != 0 || FLT(ARG1) != 0.0 ; )
224FUNC( boolOr_FB,
return FLT(ARG0) != 0.0 || BOL(ARG1) ; )
225FUNC( boolOr_FI,
return FLT(ARG0) != 0.0 || INT(ARG1) != 0 ; )
226FUNC( boolOr_FF,
return FLT(ARG0) != 0.0 || FLT(ARG1) != 0.0 ; )
229 #pragma warning( pop )
436:
Calculus(
"ALib Arithmetics", compiler )
438 constexpr int tableSize= 9;
439 Token functionNames[tableSize];
440 Token::LoadResourcedTokens( EXPRESSIONS,
"CPA", functionNames
443 Token* descriptor= functionNames;
446 { *descriptor++, constTrue },
447 { *descriptor++, constFalse },
448 { *descriptor++, constTrue },
449 { *descriptor++, constFalse },
450 { *descriptor++, constTrue },
451 { *descriptor++, constFalse },
465 AddOperators( OperatorTable );
467 if(
HasBits(compiler.CfgCompilation, Compilation::AllowBitwiseBooleanOperators ) )
469 AddOperatorAliases( bitwiseOpsAliasBooleanOps );
470 AddOperatorAlias (
A_CHAR(
"~"), Types::Boolean, Types::Void,
A_CHAR(
"!") );
473 AddBinaryOpOptimizations( binaryOperatorOptimizations);
476 "Descriptor table size mismatch: Consumed {} descriptors, {} available.",
477 descriptor - functionNames, tableSize)
481bool Arithmetics::TryCompilation( CIFunction& ciFunction )
483 if( Calculus::TryCompilation( ciFunction ) )
486 if( ciFunction.QtyArgs() == 1 && ciFunction.ArgsBegin->IsArray() )
488 constexpr int tableSize= 1;
489 Token functionNames[tableSize];
491 Token::LoadResourcedTokens( EXPRESSIONS,
"CPALen", functionNames
494 if( functionNames[0].Match( ciFunction.Name ) )
496 ciFunction.Name.Reset( functionNames[0] );
497ALIB_DBG( ciFunction.DbgCallbackName =
"arrLen"; )
500 if( ciFunction.AllArgsAreConst )
502 ciFunction.TypeOrValue = ciFunction.ArgsBegin->UnboxLength();
506 ciFunction.Callback = arrLen;
507 ciFunction.TypeOrValue = Types::Integer;
525#undef BIN_ALIAS_ENTRY
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
#define ALIB_WARNINGS_RESTORE
#define CALCULUS_CALLBACK(func)
#define CALCULUS_SIGNATURE(BoxPointerArray)
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
constexpr bool HasBits(TEnum element, TEnum selection) noexcept
ALIB_API Box ToBoolean(Scope &scope, ArgIterator args, ArgIterator)
@ Right
Denotes the right side of something.
@ Left
Denotes the left side of something.
expressions::plugins::Calculus Calculus
Type alias in namespace alib.
boxing::FIsTrue FIsTrue
Type alias in namespace alib.
strings::util::Token Token
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
static ALIB_API Box Integer
static ALIB_API Box Boolean
static ALIB_API Box Float
ALIB_API Arithmetics(Compiler &compiler)
const std::tuple< String, Type, Type, CallbackDecl, Type, CTInvokable > OperatorTableEntry
static constexpr CTInvokable CTI
const std::tuple< String, lang::Side, Type, const Box &, const Box & > BinaryOpOptimizationsTableEntry
const std::tuple< String, Type, Type, String > OperatorAliasTableEntry