void ASTFuncExpr::Prepare(Executor& exe)const { // | res | // | res | <-top exe.AddUnit( new ExePush() ); // save result // | res | // | param | 1 // | param | 2 // ... .. // | param | n // | param | n <-top for( std::size_t i=0; i<paths.Size(); ++i ){ paths[i]->Prepare(exe); exe.AddUnit( new ExePush() ); // save params } // | res | // | param | 1 // | param | 2 // ... .. // | param | n <-top exe.AddUnit( new ExePop() ); // pop the last dup param // save result to old res exe.AddUnit( new ExeFunc() ); // | res | <-top exe.AddUnit( new ExePop( paths.Size() ) ); // pop n params }
void ASTRecurPathExpr::Prepare(Executor& exe)const { // | res | // | res | <-top exe.AddUnit( new ExePush() ); // save result // | res | // | path | <-top path->Prepare(exe); //FIXME: How to loop? exe.AddUnit( new ExePop() ); }
void ASTValLit::Prepare(Executor& exe)const { // | ??? | <-top ExeVal *e = new ExeVal(); e->val = this->val; exe.AddUnit(e); // save value to stack top }
void ASTNodeLabelExpr::Prepare(Executor& exe)const { // | res | <-top ExeModelLabel *e = new ExeModelLabel();// operates on stack top e->ident = this->ident; exe.AddUnit(e); }
void ASTypeCastExpr::Prepare(Executor& exe)const { // | res | <-top ExeModelType *e = new ExeModelType();// operates on stack top e->ident = this->ident; exe.AddUnit(e); }
void ASTModelElemExpr::Prepare(Executor& exe)const { // | res | <-top if( ident ){ ExeModelIdent *e = new ExeModelIdent(); // operates on stack top e->ident = this->ident; exe.AddUnit(e); } // // FIXME: new ExeXXX() change to no new? Memory optimization. // if( type ){ type->Prepare(exe); } if( label ){ label->Prepare(exe); } if( node ){ node->Prepare(exe); } }
void ASTMetaVarExpr::Prepare(Executor& exe)const { // | ??? | <-top ExeMetaVar *e = new ExeMetaVar(); e->ident = this->ident; exe.AddUnit( e ); // save meta var to stack top }
void ASTolerLit::Prepare(Executor& exe)const { // | ??? | <-top ExeToler *e = new ExeToler(); e->l = this->l->val; e->r = this->r->val; exe.AddUnit( e ); // save toler to stack top }
void ASTPathDecl::Prepare(Executor& exe)const { // | res | // | res | <-top exe.AddUnit( new ExePush() ); // save stack top // | res | // | path | <-top path->Prepare(exe); // generate new result to stack top ExePathDecl *decl = new ExePathDecl();// operates on stack top decl->ident = this->ident; exe.AddUnit( decl ); // assign new result to ident // | res | // | res | <-top exe.AddUnit( new ExePop() ); // restore stack top }
void ASTIndexOp::Prepare(Executor& exe)const { // | res | <-top ExeIndex *e = new ExeIndex(); e->intv = this->intv; // | res | <-top exe.AddUnit( e ); // overwrite res with selectd index. }
void ASTListLit::Prepare(Executor& exe)const { // | ??? | <-top ExeList *e = new ExeList(); for(std::size_t i=0; i<vals.Size(); ++i){ e->vals.Push( this->vals[i]->val ); } exe.AddUnit( e ); // save list to stack top }
void ASTAndExpr::Prepare(Executor& exe)const { // After preparing BaseTerm: // // | res | // | lop | // | rop | <- top // // ExeAnd needs two operands assert( terms.Size() % 2 == 1 ); terms.Front()->Prepare(exe); for(std::size_t i=1; i<terms.Size(); ++i){ terms[i]->Prepare(exe); exe.AddUnit( new ExeAnd() ); } }
void ASTOrExpr::Prepare(Executor& exe)const { // After preparing BaseTerm: // // | res | // | lop | // | rop | <- top // // ExeOr needs two operands assert( ands.Size() % 2 == 1 ); ands.Front()->Prepare(exe); for(std::size_t i=1; i<ands.Size(); ++i){ ands[i]->Prepare(exe); exe.AddUnit( new ExeOr() );// operates on stack top } }
void ASTBaseTerm::Prepare(Executor& exe)const { // | res | // | res | <- top exe.AddUnit( new ExePush() ); // save stack top // | res | // | lpath | // | lpath | <- top lpath->Prepare(exe); exe.AddUnit( new ExePush() ); // save lpath result // | res | // | lpath | // | rpath | <- top rpath->Prepare(exe); // prepare to stack top // | res | // | lpath | // | rpath | <- top // op operates on above 3 operands and save to old result. assert(op); assert(op->op); switch( op->op->Rep() ){ case TOK_lt: exe.AddUnit( new ExeLT() ); break; case TOK_gt: exe.AddUnit( new ExeGT() ); break; case TOK_le: exe.AddUnit( new ExeLE() ); break; case TOK_ge: exe.AddUnit( new ExeGE() ); break; case TOK_eq: exe.AddUnit( new ExeEQ() ); break; case TOK_ne: exe.AddUnit( new ExeNE() ); break; case TOK_like: exe.AddUnit( new ExeLike() ); break; default: assert(0); break; } // | res | <-top exe.AddUnit( new ExePop() ); exe.AddUnit( new ExePop() ); }