ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
calculus.cpp
2
3namespace alib { namespace expressions { namespace plugins {
4
5//##################################################################################################
6// Operator setup helpers (unary and binary)
7//##################################################################################################
9 Type lhsType,
10 Type rhsType,
11 CallbackDecl callback,
12 #if ALIB_DEBUG
13 const char* dbgCallbackName,
14 #endif
15 Type resultType,
16 CTInvokable cti )
17{
18 #if ALIB_DEBUG
19 auto result=
20 Operators.EmplaceIfNotExistent(
21 OperatorKey { op, lhsType.TypeID(), rhsType.TypeID() },
22 std::make_tuple( callback, resultType, cti ALIB_DBG(, dbgCallbackName) ) );
23
24 ALIB_ASSERT_ERROR( result.second == true, "EXPR", // assert this was an insert!
25 "Binary operator '{}' already defined for types <{}> (aka {})\n"
26 " and <{}> (aka {}).",
27 op, Cmplr.TypeName( lhsType ), &lhsType.TypeID(),
28 Cmplr.TypeName( rhsType ), &rhsType.TypeID() )
29 #else
30 Operators.EmplaceUnique(
31 OperatorKey { op, lhsType.TypeID(), rhsType.TypeID() },
32 std::make_tuple( callback, resultType, cti ALIB_DBG(, dbgCallbackName) ) );
33 #endif
34}
35
36void Calculus::AddOperators( OperatorTableEntry* table, size_t length ) {
38 ALIB_DBG( auto actBucketCount= Operators.BucketCount(); )
39
40 #define OP std::get<0>( *(table + i) )
41 #define LHS_TYPE std::get<1>( *(table + i) ).TypeID()
42 #define RHS_TYPE std::get<2>( *(table + i) ).TypeID()
43 #define CBFUNC std::get<3>( *(table + i) )
44 #define RESULTTYPE std::get<ALIB_REL_DBG(4,5)>( *(table + i) )
45 #define CTINVOKE std::get<ALIB_REL_DBG(5,6)>( *(table + i) )
46
47 for( size_t i= 0 ; i < length ; ++i ) {
48 #if ALIB_DEBUG
49 auto result=
50 Operators.EmplaceIfNotExistent(
51 OperatorKey { OP, LHS_TYPE, RHS_TYPE },
52 std::make_tuple( CBFUNC, RESULTTYPE, CTINVOKE
53 ALIB_DBG(, std::get<4>( *(table + i) )) ) );
54
55 ALIB_ASSERT_ERROR( result.second == true, "EXPR",// assert this was an insert!
56 "Binary operator '{}' already defined for types <{}> (aka {})\n"
57 " and <{}> (aka {}).",
58 OP, Cmplr.TypeName(std::get<1>( *(table+i))), &LHS_TYPE,
59 Cmplr.TypeName(std::get<2>( *(table+i))), &RHS_TYPE )
60 #else
61 Operators.EmplaceUnique(
62 OperatorKey { OP, LHS_TYPE, RHS_TYPE },
63 std::make_tuple( CBFUNC, RESULTTYPE, CTINVOKE
64 ALIB_DBG(, std::get<4>( *(table + i) )) ) );
65 #endif
66 }
67
68 ALIB_ASSERT_ERROR( actBucketCount == Operators.BucketCount(), "EXPR",
69 "This is rather an internal error of HashTable: The number of buckets "
70 "of hash map 'Operators' increased, although it was reserved above." )
71
72 #undef OP
73 #undef LHS_TYPE
74 #undef RHS_TYPE
75 #undef CBFUNC
76 #undef RESULTTYPE
77 #undef CTINVOKE
78}
79
80void Calculus::AddOperatorAlias( const String& alias, Type lhs, Type rhs, const String& op ) {
81 #if ALIB_DEBUG
82 auto result=
83 OperatorAliases.EmplaceIfNotExistent( OperatorKey { alias, lhs.TypeID(), rhs.TypeID() },
84 op );
85
86 ALIB_ASSERT_ERROR( result.second == true, "EXPR",// assert this was an insert!
87 "Binary operator alias '{}' already defined for types <{}> (aka {})\n"
88 "and <{}> (aka {}).",
89 alias, Cmplr.TypeName( lhs ), &lhs.TypeID(),
90 Cmplr.TypeName( rhs ), &rhs.TypeID() )
91 #else
92 OperatorAliases.EmplaceUnique( OperatorKey { alias, lhs.TypeID(), rhs.TypeID() },
93 op );
94 #endif
95}
96
99
100 #define ALIAS std::get<0>( *(table + i) )
101 #define LHS_TYPE std::get<1>( *(table + i) ).TypeID()
102 #define RHS_TYPE std::get<2>( *(table + i) ).TypeID()
103 #define OP std::get<3>( *(table + i) )
104
105 for( size_t i= 0 ; i < length ; ++i ) {
106 #if ALIB_DEBUG
107 auto result=
108 OperatorAliases.EmplaceIfNotExistent( OperatorKey { ALIAS, LHS_TYPE, RHS_TYPE }, OP );
109
110 ALIB_ASSERT_ERROR( result.second == true, "EXPR",// assert this was an insert!
111 "Binary operator alias '{}' already defined for types <{}> (aka {})\n"
112 "and <{}> (aka {}).",
113 ALIAS, Cmplr.TypeName( std::get<1>( *(table + i) ) ), &LHS_TYPE,
114 Cmplr.TypeName( std::get<2>( *(table + i) ) ), &RHS_TYPE )
115 #else
116 OperatorAliases.EmplaceUnique( OperatorKey { ALIAS, LHS_TYPE, RHS_TYPE },
117 OP );
118 #endif
119 }
120
121 #undef ALIAS
122 #undef LHS_TYPE
123 #undef RHS_TYPE
124 #undef OP
125}
126
127//##################################################################################################
128// Unary operators
129//##################################################################################################
131 Box& arg= ciUnaryOp.CompileTimeScope.Stack->at(0);
132 OperatorKey key = { ciUnaryOp.Operator, arg.TypeID(), typeid(void) };
133 auto hashCode= OperatorKey::Hash()( key );
134
135 // search alias first
136 {
137 auto aliasIt= OperatorAliases.Find( key, hashCode );
138 if( aliasIt != OperatorAliases.end() )
139 ciUnaryOp.Operator= aliasIt.Mapped();
140 }
141
142
143 // search callback
144 auto opIt= Operators.Find( key, hashCode );
145 if( opIt == Operators.end() )
146 return false;
147
148 auto& op= opIt.Mapped();
149
150 // for constants, the callback might b invoked right away (optimizing cal out)
151 if( ciUnaryOp.ArgIsConst && std::get<2>(op) ) {
152 // calculate constant value
153 ciUnaryOp.TypeOrValue= std::get<0>(op)( ciUnaryOp.CompileTimeScope,
154 ciUnaryOp.ArgsBegin,
155 ciUnaryOp.ArgsEnd );
156ALIB_DBG(ciUnaryOp.DbgCallbackName= std::get<3>(op);)
157 ALIB_ASSERT_ERROR(ciUnaryOp.TypeOrValue.IsSameType(std::get<1>(op)), "EXPR",
158 "Type mismatch in definition of unary operator \"{}\" ({}) in plugin \"{}\".\n"
159 " Type specified: <{}> (aka {})\n"
160 " Type returned by callback: <{}> (aka {})",
161 ciUnaryOp.Operator, ciUnaryOp.DbgCallbackName, CompilerPlugin::Name,
162 CompilerPlugin::Cmplr.TypeName(std::get<1>(op)),
163 &std::get<1>(op).TypeID(),
164 CompilerPlugin::Cmplr.TypeName(ciUnaryOp.TypeOrValue),
165 &ciUnaryOp.TypeOrValue.TypeID() )
166 return true;
167 }
168 ciUnaryOp.Callback = std::get<0>(op);
169 ciUnaryOp.TypeOrValue = std::get<1>(op);
170ALIB_DBG(ciUnaryOp.DbgCallbackName= std::get<3>(op);)
171
172 return true;
173}
174
175//##################################################################################################
176// Binary operators
177//##################################################################################################
180
181 #define OP std::get<0>( *(table + i) )
182 #define SIDE std::get<1>( *(table + i) )
183 #define CONSTVAL std::get<2>( *(table + i) )
184 #define CONSTTYPE std::get<2>( *(table + i) ).TypeID()
185 #define OTHERBOX std::get<3>( *(table + i) )
186 #define OTHERTYPE std::get<3>( *(table + i) ).TypeID()
187 #define RESULT std::get<4>( *(table + i) )
188
189 for( size_t i= 0 ; i < length ; ++i ) {
190 #if ALIB_DEBUG
191 auto result=
192 BinaryOperatorOptimizations.EmplaceIfNotExistent( BinOpOptKey { OP, SIDE, CONSTVAL, OTHERTYPE }, RESULT );
193
194 ALIB_ASSERT_ERROR( result.second == true, "EXPR", // assert this was an insert!
195 "Optimization already defined for operator \"{}\" with {!Lower}-hand "
196 "constant value \"{}\" of type <{}> (aka {}) and with "
197 "{!L}-hand type <{}> (aka {}).",
198 OP, SIDE, CONSTVAL, Cmplr.TypeName(CONSTVAL), &CONSTTYPE,
200 : lang::Side::Left, Cmplr.TypeName(OTHERBOX), &OTHERTYPE )
201 #else
202 BinaryOperatorOptimizations.EmplaceUnique( BinOpOptKey { OP, SIDE, CONSTVAL, OTHERTYPE },
203 RESULT );
204 #endif
205 }
206
207 #undef OP
208 #undef TYPE
209 #undef CONSTVAL
210 #undef RESULT
211}
212
213
215 Box& lhs= * ciBinaryOp.ArgsBegin;
216 Box& rhs= *(ciBinaryOp.ArgsBegin + 1);
217
218 OperatorKey key = { ciBinaryOp.Operator, lhs.TypeID(), rhs.TypeID() };
219 auto hashCode= OperatorKey::Hash()( key );
220
221 // search alias first
222 if( ciBinaryOp.Operator == A_CHAR("=")
223 && HasBits( Cmplr.CfgCompilation, Compilation::AliasEqualsOperatorWithAssignOperator ) )
224 {
225 ciBinaryOp.Operator= A_CHAR("==");
226 } else {
227 auto aliasIt = OperatorAliases.Find( key, hashCode );
228 if( aliasIt != OperatorAliases.end() )
229 ciBinaryOp.Operator= aliasIt.Mapped();
230 }
231
232 #define CBFUNC std::get<0>(op)
233 #define RESULTTYPE std::get<1>(op)
234 #define CT_INVOKABLE std::get<2>(op)
235 #if ALIB_DEBUG
236 # define DBG_CB_NAME std::get<3>(op)
237 #endif
238
239// search callback
240 auto opIt = Operators.Find( key, hashCode );
241 if( opIt == Operators.end() )
242 return false;
243
244 auto& op= opIt.Mapped();
245
246 // if both are constant, the callback might be invoked right away (optimizing the call out)
247 if( ciBinaryOp.LhsIsConst && ciBinaryOp.RhsIsConst ) {
248 if( CT_INVOKABLE ) {
249 // calculate constant value
250 ciBinaryOp.TypeOrValue= CBFUNC ( ciBinaryOp.CompileTimeScope,
251 ciBinaryOp.ArgsBegin,
252 ciBinaryOp.ArgsEnd );
253ALIB_DBG( ciBinaryOp.DbgCallbackName= DBG_CB_NAME; )
254 ALIB_ASSERT_ERROR(ciBinaryOp.TypeOrValue.IsSameType(RESULTTYPE), "EXPR",
255 "Type mismatch in definition of binary operator \"{}\" ({}) of plugin \"{}\".\n"
256 " Type specified: <{}> (aka {})\n"
257 " Type returned by callback: <{}> (aka {})",
258 ciBinaryOp.Operator, ciBinaryOp.DbgCallbackName, CompilerPlugin::Name,
259 CompilerPlugin::Cmplr.TypeName(RESULTTYPE ),
260 &RESULTTYPE .TypeID(),
261 CompilerPlugin::Cmplr.TypeName(ciBinaryOp.TypeOrValue),
262 &ciBinaryOp.TypeOrValue.TypeID() )
263 return true;
264 } }
265
266
267 // if one is constant, we may find an entry in BinaryOpConsL/RHSOptimizations
268 else if( ciBinaryOp.LhsIsConst || ciBinaryOp.RhsIsConst ) {
269 auto& nonConstType= (ciBinaryOp.LhsIsConst ? *(ciBinaryOp.ArgsBegin + 1 )
270 : *(ciBinaryOp.ArgsBegin ) ).TypeID();
271 auto& constValue= ciBinaryOp.LhsIsConst ? *(ciBinaryOp.ArgsBegin )
272 : *(ciBinaryOp.ArgsBegin + 1 );
273
274 auto entryIt= BinaryOperatorOptimizations.Find( { ciBinaryOp.Operator,
276 constValue,
277 nonConstType
278 } );
279 if( entryIt != BinaryOperatorOptimizations.end() ) {
280 // found! If it is an unset box, this tells us, that the result is the other side
281 // (identity operation). Otherwise it is a constant.
282 if( entryIt.Mapped().IsType<void>() )
283 ciBinaryOp.NonConstArgIsResult= true;
284 else
285 ciBinaryOp.TypeOrValue = entryIt.Mapped();
286 return true;
287 } }
288
289
290 ciBinaryOp.Callback = CBFUNC;
291 ciBinaryOp.TypeOrValue = RESULTTYPE;
293 ciBinaryOp.DbgCallbackName= DBG_CB_NAME; )
294 return true;
295
296
297 #undef CBFUNC
298 #undef RESULTTYPE
299 #undef CT_INVOKABLE
300 #if ALIB_DEBUG
301 #undef DBG_CB_NAME
302 #endif
303}
304
305
306//##################################################################################################
307// Functions
308//##################################################################################################
310 String& name= ciFunction.Name;
311
312 // search in constant identifiers
313 if( ciFunction.QtyArgs() == 0 ) {
314 for( auto& entry : ConstantIdentifiers ) {
315 if ( entry.Descriptor.Match( name ) ) {
316 // check for wrong parentheses
317 if( ciFunction.IsIdentifier
320 entry.Descriptor );
321
322 if( !ciFunction.IsIdentifier
325 entry.Descriptor );
326
327
328 // accept
329 ciFunction.Name.Reset( entry.Descriptor );
330 ciFunction.TypeOrValue= entry.Result;
331 return true;
332 } } }
333
334 // search in functions
335 for( auto& entry : Functions ) {
336 if( entry.Descriptor.Match( name ) ) {
337 // collect information about given and requested parameters
338 size_t qtyGiven = ciFunction.QtyArgs();
339 size_t qtyRequired = entry.SignatureLength;
340 bool isVariadic = false;
341 if( entry.SignatureLength > 0 && ( entry.Signature[entry.SignatureLength - 1] == nullptr
342 || entry.Signature[entry.SignatureLength - 1]->IsType<void>() ) )
343 {
344 isVariadic= true;
345 --qtyRequired;
346 }
347
348 size_t qtyShared = (std::min)( qtyGiven, qtyRequired );
349 bool sharedAreSameType = true;
350 for( size_t i= 0; i != qtyShared ; ++i )
351 sharedAreSameType&= ciFunction.Arg(i).IsSameType( *entry.Signature[i] );
352
353 // check if given parameter doesn't match
354 if( !sharedAreSameType
355 || ( isVariadic ? qtyGiven < qtyRequired
356 : qtyGiven != qtyRequired ) )
357 {
358 String256 buffer( entry.Descriptor );
359 if( qtyRequired )
360 Cmplr.WriteFunctionSignature( entry.Signature,
361 entry.SignatureLength,
362 buffer );
363 ciFunction.AddFunctionsWithNonMatchingArguments( buffer );
364
365 // search next
366 continue;
367 }
368
369 // check for wrong parentheses
370 if( ciFunction.IsIdentifier
371 && entry.Signature != nullptr
374 entry.Descriptor );
375
376 if( !ciFunction.IsIdentifier
377 && entry.Signature == nullptr
380 entry.Descriptor );
381
382 // accept
383 ciFunction.Name.Reset( entry.Descriptor );
384
385 if( !entry.Callback ) {
386 ciFunction.TypeOrValue = *entry.ResultType;
387 ALIB_DBG( ciFunction.DbgCallbackName = entry.DbgCallbackName; )
388 return true;
389 }
390
391 // for constants, the callback might b invoked right away (optimizing cal out)
392 if( ciFunction.AllArgsAreConst && entry.IsCTInvokable ) {
393 // calculate constant value
394 ciFunction.TypeOrValue = entry.Callback( ciFunction.CompileTimeScope,
395 ciFunction.ArgsBegin,
396 ciFunction.ArgsEnd );
397 ALIB_ASSERT_ERROR(ciFunction.TypeOrValue.IsSameType(*entry.ResultType), "EXPR",
398 "Type mismatch in definition of function \"{}\" ({}) in plugin \"{}\".\n"
399 " Type specified: <{}> (aka {})\n"
400 " Type returned by callback: <{}> (aka {})",
401 entry.Descriptor, entry.DbgCallbackName, CompilerPlugin::Name,
402 CompilerPlugin::Cmplr.TypeName(*entry.ResultType),
403 &entry.ResultType->TypeID(),
404 CompilerPlugin::Cmplr.TypeName(ciFunction.TypeOrValue),
405 &ciFunction.TypeOrValue.TypeID() )
406 ALIB_DBG( ciFunction.DbgCallbackName = entry.DbgCallbackName; )
407 return true;
408 }
409
410 ciFunction.Callback = entry.Callback;
411 ciFunction.TypeOrValue = *entry.ResultType;
412 ALIB_DBG( ciFunction.DbgCallbackName = entry.DbgCallbackName; )
413 return true;
414 } }
415
416 return false;
417}
418
419//##################################################################################################
420// Auto-Casts
421//##################################################################################################
422//! @cond NO_DOX
423namespace {
424Calculus::AutoCastEntry* findAutoCastEntry( std::vector<Calculus::AutoCastEntry>& table,
425 Calculus::CIAutoCast& ciAutoCast,
426 int argNo ) {
427 Box& valueToCast= *(ciAutoCast.ArgsBegin + argNo);
428
429 // main loop over all table entries
430 for( auto& entry : table ) {
431 // first check for source type
432 if( !entry.Type.IsSameType( valueToCast ) )
433 continue;
434
435 // operator included in list of accepted (if list given)?
436 bool operatorIsIn= true;
437 if( entry.OperatorsAccepted != nullptr
438 && entry.OperatorsAccepted->size() > 0 )
439 {
440 operatorIsIn= false;
441 for( auto& op : *entry.OperatorsAccepted )
442 if( op.Equals<NC>( ciAutoCast.Operator ) ) {
443 operatorIsIn= true;
444 break;
445 } }
446
447 // operator included in decline list?
448 if( operatorIsIn
449 && entry.OperatorsDeclined != nullptr
450 && entry.OperatorsDeclined->size() > 0 )
451 {
452 for( auto& op : *entry.OperatorsDeclined )
453 if( op.Equals<NC>( ciAutoCast.Operator ) ) {
454 operatorIsIn= false;
455 break;
456 } }
457
458 // found?
459 if( operatorIsIn )
460 return &entry;
461 }
462
463 return nullptr;
464}
465
466Box any2Int ( expressions::Scope&, ArgIterator argsBegin, ArgIterator )
467{ return argsBegin->Data().Integrals.Array[0]; }
468
469} //anonymous namespace
470//! @endcond
471
472
474 bool result= false;
475
476 //----------------------------------------- cast first arg ---------------------------------------
477 AutoCastEntry* entry= findAutoCastEntry( AutoCasts, ciAutoCast, 0 );
478 if( entry != nullptr ) {
479 result= true;
481
482 CallbackDecl callback;
483 if( entry->Callback == nullptr ) {
484 callback = any2Int;
485ALIB_DBG( ciAutoCast.DbgCallbackName= "any2Int"; )
486 ciAutoCast.TypeOrValue = Types::Integer;
487 } else {
488 callback = entry->Callback;
489ALIB_DBG( ciAutoCast.DbgCallbackName= entry->DbgCallbackName; )
490 ciAutoCast.TypeOrValue = entry->ResultType;
491 }
492
493 if( ciAutoCast.IsConst )
494 ciAutoCast.TypeOrValue= callback( ciAutoCast.CompileTimeScope,
495 ciAutoCast.ArgsBegin,
496 ciAutoCast.ArgsEnd );
497 else
498 ciAutoCast.Callback = callback;
499 }
500
501 // no RHS given?
502 if( ciAutoCast.ArgsBegin + 1 >= ciAutoCast.ArgsEnd )
503 return result;
504
505 //------------------------------------- cast second arg (rhs) ------------------------------------
506 entry= findAutoCastEntry( AutoCasts, ciAutoCast, 1 );
507 if( entry != nullptr ) {
508 //
509 result= true;
511
512 CallbackDecl callback;
513 if( entry->Callback == nullptr ) {
514 callback = any2Int;
515ALIB_DBG( ciAutoCast.DbgCallbackNameRhs= "any2Int"; )
516 ciAutoCast.TypeOrValueRhs = Types::Integer;
517 } else {
518 callback = entry->Callback;
519ALIB_DBG( ciAutoCast.DbgCallbackNameRhs= entry->DbgCallbackName; )
520 ciAutoCast.TypeOrValueRhs = entry->ResultType;
521 }
522
523 if( ciAutoCast.RhsIsConst )
524 ciAutoCast.TypeOrValueRhs= callback( ciAutoCast.CompileTimeScope,
525 ciAutoCast.ArgsBegin + 1,
526 ciAutoCast.ArgsEnd );
527 else
528 ciAutoCast.CallbackRhs = callback;
529 }
530
531
532 return result;
533}
534
535}}} // namespace [alib::expressions::plugin]
536
#define ALIB_CALLER_NULLED
#define A_CHAR(STR)
#define ALIB_POP_ALLOWANCE
#define ALIB_DEBUG
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_ALLOW_UNUSED_MACRO
bool IsSameType(const Box &other) const
Definition box.hpp:578
const std::type_info & TypeID() const
Definition box.hpp:759
const Placeholder & Data() const
Definition box.hpp:674
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
const alib::boxing::Box & Type
StdVectorMA< Box >::iterator ArgIterator
@ Right
Denotes the right side of something.
@ Left
Denotes the left side of something.
@ Relative
Referring to a relative value.
Definition alox.cpp:14
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
exceptions::Exception Exception
Type alias in namespace #"%alib".
LocalString< 256 > String256
Type alias name for #"TLocalString;TLocalString<character,256>".
bool RhsIsConst
Input: denotes if rhs argument is constant value.
bool LhsIsConst
Input: Denotes if the lhs-argument is a constant value.
bool NonConstArgIsResult
Output: Used with optimization, see this struct's documentation for more information.
bool RhsIsConst
Input: Denotes if the rhs-argument is a constant value.
String & Operator
Input/Output: The binary operator symbol.
AString & Name
Input: The identifier name to search.
void AddFunctionsWithNonMatchingArguments(const String &signature)
String & Operator
Input/Output: The unary operator.
CallbackDecl Callback
Output: The native C++ callback function to be set by one of the plug-ins.
Compiler & Cmplr
The compiler that this plug-in is attached to.
StdVectorMA< Box > * Stack
Definition scope.hpp:101
static Box Integer
Sample type-box for integer types. (Precisely for type #"lang::integer".).
An entry of the field AutoCasts. Defines auto-casts for custom types.
Definition calculus.hpp:690
Key type for operator hash maps Operators and OperatorAliases.
Definition calculus.hpp:560
Key type for operator hash maps #"Calculus::Operators" and #"Calculus::OperatorAliases".
Definition calculus.hpp:356
void AddOperatorAlias(const String &alias, Type lhsType, Type rhsType, const String &op)
Definition calculus.cpp:80
HashMap< MonoAllocator, OperatorKey, std::tuple< CallbackDecl, Box, CTInvokable ALIB_DBG(, const char *) >, OperatorKey::Hash, OperatorKey::EqualTo > Operators
Definition calculus.hpp:414
const std::tuple< String, Type, Type, CallbackDecl, Type, CTInvokable > OperatorTableEntry
Definition calculus.hpp:445
virtual bool TryCompilation(CIFunction &ciFunction) override
Definition calculus.cpp:309
void AddOperatorAliases(OperatorAliasTableEntry(&table)[TCapacity])
Definition calculus.hpp:539
const std::tuple< String, lang::Side, Type, const Box &, const Box & > BinaryOpOptimizationsTableEntry
Definition calculus.hpp:620
std::vector< ConstantIdentifierEntry > ConstantIdentifiers
List of identifiers that return constant values to be compiled by this plug-in.
Definition calculus.hpp:277
void AddBinaryOpOptimizations(BinaryOpOptimizationsTableEntry(&table)[TCapacity])
Definition calculus.hpp:629
HashMap< MonoAllocator, BinOpOptKey, Box, BinOpOptKey::Hash, BinOpOptKey::EqualTo > BinaryOperatorOptimizations
Definition calculus.hpp:607
std::vector< AutoCastEntry > AutoCasts
List of auto-casts to be compiled by this plug-in.
Definition calculus.hpp:754
void AddOperators(OperatorTableEntry(&table)[TCapacity])
Definition calculus.hpp:506
std::vector< FunctionEntry > Functions
List of functions to be compiled by this plug-in.
Definition calculus.hpp:336
void AddOperator(const String &op, Type lhsType, Type rhsType, CallbackDecl callback, const char *dbgCallbackName, Type resultType, CTInvokable cti)
Definition calculus.cpp:8
HashMap< MonoAllocator, OperatorKey, String, OperatorKey::Hash, OperatorKey::EqualTo > OperatorAliases
Definition calculus.hpp:427
const std::tuple< String, Type, Type, String > OperatorAliasTableEntry
Definition calculus.hpp:458
detail::UnionIntegrals Integrals
Collection of integrals of different sizes, placed next to each other.
integer Array[2]
Array of 64-bit signed integrals of length two on 64-bit platform, one on a 32-bit platform.