12# define DBG_SET_CALLBACK_INFO \
13 prg.act().DbgInfo.Callback= cInfo.DbgCallbackName; \
14 prg.act().DbgInfo.Plugin = ppp.plugin;
16# define DBG_SET_CALLBACK_INFO
45 : assembly ( pAssembly )
46 , resultStack( pResultStack) {}
55 VM::Command& at( VM::PC pc ) {
return *assembly[size_t(pc)]; }
59 VM::Command& act() {
return *assembly.back(); }
63 VM::Command& prev() {
return **( assembly.end() - 2 ); }
67 VM::PC actPC() {
return static_cast<VM::PC
>( assembly.size() - 1); }
70 void eraseLast() { assembly.pop_back(); }
74 void erase( VM::PC pc ) { assembly.erase( assembly.begin() + pc ); }
79 void erase( VM::PC begin, VM::PC end )
81 assembly.erase( assembly.begin() + begin,
82 assembly.begin() + end );
91 template<
typename... TArgs>
92 VM::Command& insertAt( VM::PC pc, TArgs && ... args ) {
93 auto* cmd= assembly.get_allocator().AIF().New<VM::Command>(std::forward<TArgs>( args )... );
94 assembly.emplace( assembly.begin() + pc, cmd );
102 template<
typename... TArgs>
103 VM::Command& add( TArgs && ... args ) {
104 assembly.emplace_back(
105 assembly.get_allocator().AIF().New<VM::Command>( std::forward<TArgs>( args )... ) );
106 return *assembly.back();
111 void pushResultPC() { resultStack.push_back( actPC() ); }
114 void popResultPC() { resultStack.pop_back(); }
117 VM::PC & resultPC() {
return resultStack.back(); }
120 VM::PC & lhsResultPC() {
return resultStack[resultStack.size() - 2]; }
124 VM::PC lhsResultStartPC() {
125 auto qtyResults = resultStack.size();
126 return qtyResults == 2 ? 0
127 : resultStack[qtyResults - 3] + 1;
137#define ASSERT_ASSEMBLE \
138 ALIB_ASSERT_ERROR( prg.resultStack.empty() \
139 || prg.resultPC() == prg.actPC() \
140 || prg.act().IsJump() , \
141 "EXPR", "Internal error: Last in result stack is not last command." )
146 "EXPR",
"Internal error. This should never happen." )
150 stack->reserve(
size_t( qty ));
152 bool allAreConst=
true;
153 for(
integer i= qty; i > 0 ; --i ) {
155 bool isConstant= cmd.IsConstant();
156 stack->emplace_back( cmd.ResultType );
157 allAreConst&= isConstant;
173 false, idxInOriginal, idxInNormalized ) );
186 if(
compiler.CfgNestedExpressionFunction.GetDefinitionName().IsNotEmpty()
187 &&
compiler.CfgNestedExpressionFunction.Match(functionName ) )
193 || !prg.at( *(prg.resultStack.end() - ( qtyArgs == 3 ? 2 : qtyArgs) ) )
194 .ResultType.IsType<
String>() )
197 compiler.CfgNestedExpressionFunction );
206 expression.GetOriginalString(), idxInOriginal );
211 String nestedExpressionName= prg.at(prg.resultStack.back()).ResultType.Unbox<
String>();
214 nested=
compiler.GetNamed( nestedExpressionName );
220 nestedExpressionName );
230 nested->ResultType(),
231 compiler.CfgNestedExpressionFunction.GetDefinitionName(),
232 idxInOriginal, idxInNormalized );
238 prg.add(
static_cast<Program*
>(
nullptr ),
Box(
nullptr ),
239 compiler.CfgNestedExpressionFunction.GetDefinitionName(),
240 idxInOriginal, idxInNormalized );
241 prg.act().ResultType= prg.prev().ResultType;
247 prg.add(
dynamic_cast<Program*
>(
this ),
248 prg.act().ResultType,
249 compiler.CfgNestedExpressionFunction.GetDefinitionName(),
250 idxInOriginal, idxInNormalized );
253 prg.resultPC()= prg.actPC();
264 functionName, isIdentifier,
271 if( !ppp.plugin->TryCompilation( cInfo ) )
288 prg.resultPC()= prg.actPC();
292 DBG_SET_CALLBACK_INFO
300 idxInOriginal, idxInNormalized );
308 prg.resultPC()= prg.actPC();
311 DBG_SET_CALLBACK_INFO
323 catch( std::exception& stdException )
328 expression.GetOriginalString(), idxInOriginal );
364 auto globalAliasIt=
compiler.AlphabeticUnaryOperatorAliases.Find(op);
365 if( globalAliasIt !=
compiler.AlphabeticUnaryOperatorAliases.end() ) {
367 opReference= globalAliasIt.Mapped();
374 && opReference ==
compiler.CfgNestedExpressionOperator
380 expression.GetOriginalString(), idxInOriginal );
388 nested=
compiler.GetNamed( expressionName );
405 op= globalAliasIt->first;
411 idxInOriginal, idxInNormalized );
418 for(
int pass= 0; pass < 2 ; ++pass ) {
422 opReference, isConstant );
426 if( !ppp.plugin->TryCompilation( cInfo ) )
433 op= globalAliasIt->first;
442 DBG_SET_CALLBACK_INFO
448 prg.add( cInfo.
Callback,
false, 1, cInfo.
TypeOrValue, op,
true, idxInOriginal, idxInNormalized );
451 DBG_SET_CALLBACK_INFO
463 prg.at( prg.resultPC() ).IsConstant(),
false );
465 if( !pppAutoCast.plugin->TryCompilation( ciAutoCast ) )
471 if( ciAutoCast.
Callback ==
nullptr ) {
482 prg.insertAt( prg.resultPC() + 1, ciAutoCast.
Callback,
false, 1,
485 idxInOriginal, idxInNormalized );
489 newCmd.DbgInfo.Plugin = pppAutoCast.plugin; )
506 catch( std::exception& stdException )
535 auto globalAliasIt=
compiler.AlphabeticBinaryOperatorAliases.Find(op);
536 if( globalAliasIt !=
compiler.AlphabeticBinaryOperatorAliases.end() ) {
538 opReference= globalAliasIt.Mapped();
541 bool foundOperator=
false;
542 bool triedToAutoCast=
false;
544 Box lhsOrigType= prg.at(prg.lhsResultPC()).ResultType;
545 Box rhsOrigType= prg.at(prg. resultPC()).ResultType;
555 opReference, lhsIsConstant, rhsIsConstant );
560 if( !ppp.plugin->TryCompilation( cInfo ) )
567 op= globalAliasIt->first;
576 prg.erase( prg.lhsResultStartPC() );
581 prg.resultPC()= prg.actPC();
592 prg.erase( prg.lhsResultStartPC(), prg.resultPC() );
595 prg.resultPC()= prg.actPC();
606 prg.add( cInfo.
Callback,
false, 2, cInfo.
TypeOrValue, op,
true, idxInOriginal, idxInNormalized );
607 prg.resultPC()= prg.actPC();
609 DBG_SET_CALLBACK_INFO
620 if( !foundOperator && triedToAutoCast ) {
630 triedToAutoCast=
true;
634 prg.at( prg.lhsResultPC() ).IsConstant(),
635 prg.at( prg. resultPC() ).IsConstant() );
638 if( !pppAutoCast.plugin->TryCompilation( ciAutoCast ) )
644 if( ciAutoCast.
Callback ==
nullptr ) {
646 VM::Command& cmdToPatch= prg.at( prg.lhsResultPC() );
655 prg.insertAt( prg.lhsResultPC() + 1, ciAutoCast.
Callback,
false, 1,
658 idxInOriginal, idxInNormalized );
663 newCmd.DbgInfo.Plugin= pppAutoCast.plugin; )
672 ALIB_DBG( prg.act().DbgInfo.Plugin= pppAutoCast.plugin; )
679 prg.insertAt( prg.resultPC() + 1, ciAutoCast.
CallbackRhs,
false, 1,
682 idxInOriginal, idxInNormalized );
686 newCmd.DbgInfo.Plugin= pppAutoCast.plugin; )
700 catch( std::exception& stdException )
733 Box& condition= prg.act().ResultType;
739 prg.add( idxInOriginal, idxInNormalized, Command::JumpType::Conditional );
740 compileStorage->ConditionalStack.emplace_back( prg.actPC(), 0, constQ );
752 prg.add( idxInOriginal, idxInNormalized, Command::JumpType::Unconditional );
759 prg.at(actCond.QJumpPos).Parameter.Distance= prg.length() - actCond.QJumpPos;
762 actCond.TJumpPos= prg.actPC();
778 prg.at( actCond.TJumpPos ).Parameter.Distance= prg.length() - actCond.TJumpPos;
782 if( !prg.at( prg.lhsResultPC() ).ResultType.IsSameType( prg.at( prg.resultPC() ).ResultType ) ) {
788 prg.at( prg.lhsResultPC() ).IsConstant(),
789 prg.at( prg. resultPC() ).IsConstant() );
794 if( ppp.plugin->TryCompilation( ciAutoCast ) ) {
797 if( ciAutoCast.
Callback ==
nullptr ) {
799 prg.at(prg.lhsResultPC()).ResultType = ciAutoCast.
TypeOrValue;
801 ALIB_DBG( prg.at(prg.lhsResultPC()).DbgInfo.Plugin= ppp.plugin; )
807 ++prg.at(actCond.QJumpPos).Parameter.Distance;
808 ++prg.at(actCond.TJumpPos).Parameter.Distance;
812 prg.insertAt( actCond.TJumpPos++, ciAutoCast.
Callback,
false, 1,
816 idxInOriginal, idxInNormalized );
818 newCmd.DbgInfo.Plugin= ppp.plugin; )
824 if( ciAutoCast.
Callback ==
nullptr ) {
829 prg.act().DbgInfo.Plugin= ppp.plugin; )
838 idxInOriginal, idxInNormalized );
840 ++prg.at(actCond.TJumpPos).Parameter.Distance;
843 prg.act().DbgInfo.Plugin= ppp.plugin; )
857 catch( std::exception& stdException )
879 if( actCond.ConstFlags ) {
881 if( (actCond.ConstFlags & 1) == 0 ) {
882 prg.erase( actCond.QJumpPos, actCond.TJumpPos + 1 );
887 prg.erase( actCond.TJumpPos, prg.actPC() + 1 );
888 prg.erase( actCond.QJumpPos );
892 prg.act().SetEndOfConditionalFlag();
901 prg.resultPC()= prg.actPC();
913 "Finalizing program, while conditional stack is of size {}.",
916 "Finalizing program, while result stack is of size {}.",
931#undef ASSERT_ASSEMBLE
932#undef DBG_SET_CALLBACK_INFO
#define ALIB_CALLER_NULLED
#define ALIB_ERROR(domain,...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
Exception & Add(const lang::CallerInfo &ci, TEnum type, TArgs &&... args)
const Enum & Type() const
Scope * getExpressionCTScope(ExpressionVal &ev)
MonoAllocator & getExpressionAllocator(ExpressionVal &ev)
Compiler::PluginList & getCompilerPlugins(Compiler &cmp)
ExpressionVal & expression
The expression that this program evaluates.
const Box & ResultType() const
void AssembleUnaryOp(String &op, integer idxInOriginal, integer idxInNormalized)
int qtyOptimizations
Counter of the number of optimization made during program assembly.
void AssembleFunction(AString &functionName, bool isIdentifier, int qtyArgs, integer idxInOriginal, integer idxInNormalized)
void AssembleBinaryOp(String &op, integer idxInOriginal, integer idxInNormalized)
void AssembleCondFinalize_Q(integer idxInOriginal, integer idxInNormalized)
Program(Compiler &pCompiler, ExpressionVal &pExpression, MonoAllocator *ctAlloc)
void AssembleConstant(Box &value, integer idxInOriginal, integer idxInNormalized)
Compiler & compiler
The compiler that created this object.
StdVectorMA< Expression > ctNestedExpressions
void AssembleCondFinalize_F(integer idxInOriginal, integer idxInNormalized)
CompileStorage * compileStorage
bool collectArgs(integer qty)
integer commandsCount
The number of commands.
VM::Command * commands
The array of commands.
void AssembleCondFinalize_T(integer idxInOriginal, integer idxInNormalized)
DbgInformation DbgInfo
Operation code of this command. Available only with debug-builds.
void DbgDisableBufferReplacementWarning()
@ ReplaceVerbalOperatorsToDefinedLetterCase
See sibling flag #"Normalization::ReplaceVerbalOperatorsToSymbolic".
@ ReplaceVerbalOperatorsToSymbolic
@ PluginExceptionFallThrough
@ AllowCompileTimeNestedExpressions
@ NestedExpressionCallArgumentMismatch
@ UnknownIdentifier
Compile-time exception thrown when an expression uses an unknown identifier name.
@ UnaryOperatorNotDefined
@ UnknownFunction
Compile-time exception thrown when an expression uses an unknown function name.
@ NamedExpressionNotFound
Compile-time exception thrown when an expression refers to an unknown named nested expression.
@ IncompatibleTypesInConditional
@ NamedExpressionNotConstant
@ NestedExpressionNotFoundCT
@ BinaryOperatorNotDefined
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
lang::integer integer
Type alias in namespace #"%alib".
boxing::Box Box
Type alias in namespace #"%alib".
strings::TString< character > String
Type alias in namespace #"%alib".
exceptions::Exception Exception
Type alias in namespace #"%alib".
LocalString< 128 > String128
Type alias name for #"TLocalString;TLocalString<character,128>".
boxing::FIsTrue FIsTrue
Type alias in namespace #"%alib".
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace #"%alib".
TIntegral Integral() const
String ReverseCastFunctionNameRhs
String ReverseCastFunctionName
const nchar * DbgCallbackNameRhs
bool NonConstArgIsResult
Output: Used with optimization, see this struct's documentation for more information.
ListMA< String > & FunctionsWithNonMatchingArguments
const nchar * DbgCallbackName
CallbackDecl Callback
Output: The native C++ callback function to be set by one of the plug-ins.
StdVectorMA< Box > * Stack