本文整理汇总了C++中CBotCStack类的典型用法代码示例。如果您正苦于以下问题:C++ CBotCStack类的具体用法?C++ CBotCStack怎么用?C++ CBotCStack使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CBotCStack类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CBotFor
CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotFor* inst = new CBotFor(); // creates the object
CBotToken* pp = p; // preserves at the ^ token (starting position)
if ( IsOfType( p, TokenTypVar ) &&
IsOfType( p, ID_DOTS ) )
{
inst->m_label = pp->GetString(); // register the name of label
}
inst->SetToken(p);
if (!IsOfType(p, ID_FOR)) return nullptr; // should never happen
if ( !IsOfType(p, ID_OPENPAR)) // missing parenthesis ?
{
pStack->SetError(TX_OPENPAR, p->GetStart());
return nullptr;
}
CBotCStack* pStk = pStack->TokenStack(pp, true); // un petit bout de pile svp
// compiles instructions for initialization
inst->m_Init = CBotListExpression::Compile( p, pStk );
if ( pStk->IsOk() )
{
if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
{
pStack->SetError(TX_OPENPAR, p->GetStart());
delete inst;
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
inst->m_Test = CBotBoolExpr::Compile( p, pStk );
if ( pStk->IsOk() )
{
if ( !IsOfType(p, ID_SEP)) // lack the semicolon?
{
pStack->SetError(TX_OPENPAR, p->GetStart());
delete inst;
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
inst->m_Incr = CBotListExpression::Compile( p, pStk );
if ( pStk->IsOk() )
{
if ( IsOfType(p, ID_CLOSEPAR)) // missing parenthesis ?
{
IncLvl(inst->m_label);
inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
DecLvl();
if ( pStk->IsOk() )
return pStack->Return(inst, pStk);;
}
pStack->SetError(TX_CLOSEPAR, p->GetStart());
}
}
}
delete inst; // error, frees up
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
示例2: Compile
CBotInstr* CBotListInstr::Compile(CBotToken* &p, CBotCStack* pStack, bool bLocal)
{
CBotCStack* pStk = pStack->TokenStack(p, bLocal); // variables are local
CBotListInstr* inst = new CBotListInstr();
while (true)
{
if (p == nullptr) break;
if (IsOfType(p, ID_SEP)) continue; // empty statement ignored
if (p->GetType() == ID_CLBLK) break;
if (p->GetType() == TokenTypNone)
{
pStack->SetError(CBotErrCloseBlock, p->GetStart());
delete inst;
return pStack->Return(nullptr, pStk);
}
CBotInstr* i = CBotBlock::CompileBlkOrInst(p, pStk); // compiles next
if (!pStk->IsOk())
{
delete inst;
return pStack->Return(nullptr, pStk);
}
if (inst->m_instr == nullptr) inst->m_instr = i;
else inst->m_instr->AddNext(i); // added a result
}
return pStack->Return(inst, pStk);
}
示例3: CBotTry
CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotTry* inst = new CBotTry(); // creates the object
CBotToken* pp = p; // preserves at the ^ token (starting position)
inst->SetToken(p);
if (!IsOfType(p, ID_TRY)) return nullptr; // should never happen
CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk );
CBotCatch** pn = &inst->m_ListCatch;
while (pStk->IsOk() && p->GetType() == ID_CATCH)
{
CBotCatch* i = CBotCatch::Compile(p, pStk);
*pn = i;
pn = &i->m_next;
}
if (pStk->IsOk() && IsOfType( p, ID_FINALLY) )
{
inst->m_FinalInst = CBotBlock::CompileBlkOrInst( p, pStk );
}
if (pStk->IsOk())
{
return pStack->Return(inst, pStk); // return an object to the application
}
delete inst; // error, frees up
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
示例4: CompileParams
CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars)
{
bool first = true;
CBotInstr* ret = nullptr; // to return to the list
CBotCStack* pile = pStack;
int i = 0;
if (IsOfType(p, ID_OPENPAR))
{
int start, end;
if (!IsOfType(p, ID_CLOSEPAR)) while (true)
{
start = p->GetStart();
pile = pile->TokenStack(); // keeps the result on the stack
if (first) pStack->SetStartError(start);
first = false;
CBotInstr* param = CBotExpression::Compile(p, pile);
end = p->GetStart();
if (!pile->IsOk())
{
return pStack->Return(nullptr, pile);
}
if (ret == nullptr) ret = param;
else ret->AddNext(param); // construct the list
if (param != nullptr)
{
if (pile->GetTypResult().Eq(99))
{
delete pStack->TokenStack();
pStack->SetError(CBotErrVoid, p->GetStart());
return nullptr;
}
ppVars[i] = pile->GetVar();
ppVars[i]->GetToken()->SetPos(start, end);
i++;
if (IsOfType(p, ID_COMMA)) continue; // skips the comma
if (IsOfType(p, ID_CLOSEPAR)) break;
}
pStack->SetError(CBotErrClosePar, p->GetStart());
delete pStack->TokenStack();
return nullptr;
}
}
ppVars[i] = nullptr;
return ret;
}
示例5: CBotCStack
// used only at compile
CBotCStack* CBotCStack::TokenStack(CBotToken* pToken, bool bBlock)
{
if (m_next != NULL) return m_next; // include on an existing stack
CBotCStack* p = new CBotCStack(this);
m_next = p; // channel element
p->m_bBlock = bBlock;
if (pToken != NULL) p->SetStartError(pToken->GetStart());
return p;
}
示例6: token
CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotToken* pp = p; // conserve le ^au token (début instruction)
if (!IsOfType(p, ID_IF)) return NULL; // ne doit jamais arriver
CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
CBotIf* inst = new CBotIf(); // crée l'object
inst->SetToken( pp );
if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
{
// la condition existe bel et bien
inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, TRUE );
if ( pStk->IsOk() )
{
// le bloc d'instruction est ok (peut être vide)
// regarde si l'instruction suivante est le token "else"
if (IsOfType(p, ID_ELSE))
{
// si oui, compile le bloc d'instruction qui suit
inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, TRUE );
if (!pStk->IsOk())
{
// il n'y a pas de bloc correct après le else
// libère l'objet, et transmet l'erreur qui est sur la pile
delete inst;
return pStack->Return(NULL, pStk);
}
}
// rend l'object correct à qui le demande.
return pStack->Return(inst, pStk);
}
}
// erreur, libère l'objet
delete inst;
// et transmet l'erreur qui se trouve sur la pile.
return pStack->Return(NULL, pStk);
}
示例7: token
CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotToken* pp = p; // preserves at the ^ token (starting instruction)
if (!IsOfType(p, ID_IF)) return nullptr; // should never happen
CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
CBotIf* inst = new CBotIf(); // create the object
inst->SetToken( pp );
if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) )
{
// the condition does exist
inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
if ( pStk->IsOk() )
{
// the statement block is ok (can be empty)
// see if the next instruction is the token "else"
if (IsOfType(p, ID_ELSE))
{
// if so, compiles the following statement block
inst->m_blockElse = CBotBlock::CompileBlkOrInst(p, pStk, true );
if (!pStk->IsOk())
{
// there is no correct block after the else
// frees the object, and transmits the error that is on the stack
delete inst;
return pStack->Return(nullptr, pStk);
}
}
// return the corrent object to the application
return pStack->Return(inst, pStk);
}
}
// error, frees the object
delete inst;
// and transmits the error that is on the stack.
return pStack->Return(nullptr, pStk);
}
示例8: CBotDo
CBotInstr* CBotDo::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotDo* inst = new CBotDo(); // creates the object
CBotToken* pp = p; // preserves at the ^ token (starting position)
if ( IsOfType( p, TokenTypVar ) &&
IsOfType( p, ID_DOTS ) )
{
inst->m_label = pp->GetString(); // register the name of label
}
inst->SetToken(p);
if (!IsOfType(p, ID_DO)) return nullptr; // should never happen
CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
// looking for a statement block after the do
IncLvl(inst->m_label);
inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true );
DecLvl();
if ( pStk->IsOk() )
{
if (IsOfType(p, ID_WHILE))
{
if ( nullptr != (inst->m_Condition = CBotCondition::Compile( p, pStk )) )
{
// the condition exists
if (IsOfType(p, ID_SEP))
{
return pStack->Return(inst, pStk); // return an object to the application
}
pStk->SetError(TX_ENDOF, p->GetStart());
}
}
pStk->SetError(TX_WHILE, p->GetStart());
}
delete inst; // error, frees up
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
示例9: Compile
CBotInstr* CBotCompExpr::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotCStack* pStk = pStack->AddStack();
CBotInstr* left = CBotAddExpr::Compile( p, pStk ); // expression A + B left
if (left == NULL) return pStack->Return(NULL, pStk); // error
if ( p->GetType() == ID_HI ||
p->GetType() == ID_LO ||
p->GetType() == ID_HS ||
p->GetType() == ID_LS ||
p->GetType() == ID_EQ ||
p->GetType() == ID_NE) // the various comparisons
{
CBotCompExpr* inst = new CBotCompExpr(); // element for operation
inst->SetToken(p); // stores the operation
int type1, type2;
type1 = pStack->GetType();
p = p->Next();
if ( NULL != (inst->m_rightop = CBotAddExpr::Compile( p, pStk )) ) // expression A + B right
{
type2 = pStack->GetType();
// are the results compatible
if ( type1 == type2 )
{
inst->m_leftop = left;
pStk->SetVar(new CBotVar(NULL, CBotTypBoolean));
// the result is a boolean
return pStack->Return(inst, pStk);
}
}
delete left;
delete inst;
return pStack->Return(NULL, pStk);
}
return pStack->Return(left, pStk);
}
示例10: Compile
CBotInstr* CBotExprLitNum::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotCStack* pStk = pStack->TokenStack();
CBotExprLitNum* inst = new CBotExprLitNum();
inst->SetToken(p);
std::string s = p->GetString();
inst->m_numtype = CBotTypInt;
if (p->GetType() == TokenTypDef)
{
inst->m_valint = p->GetKeywordId();
}
else
{
if (s.find('.') != std::string::npos || ( s.find('x') == std::string::npos && ( s.find_first_of("eE") != std::string::npos ) ))
{
inst->m_numtype = CBotTypFloat;
inst->m_valfloat = GetNumFloat(s);
}
else
{
inst->m_valint = GetNumInt(s);
}
}
if (pStk->NextToken(p))
{
CBotVar* var = CBotVar::Create("", inst->m_numtype);
pStk->SetVar(var);
return pStack->Return(inst, pStk);
}
delete inst;
return pStack->Return(nullptr, pStk);
}
示例11: CBotWhile
CBotInstr* CBotWhile::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotWhile* inst = new CBotWhile(); // creates the object
CBotToken* pp = p; // preserves at the ^ token (starting position)
if ( IsOfType( p, TokenTypVar ) &&
IsOfType( p, ID_DOTS ) )
{
inst->m_label = pp->GetString(); // records the name of the label
}
inst->SetToken(p);
if (!IsOfType(p, ID_WHILE)) return nullptr; // should never happen
CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp
// a bit of battery please (??)
if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) )
{
// the condition exists
IncLvl(inst->m_label);
inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk, true );
DecLvl();
if ( pStk->IsOk() )
{
// the statement block is ok (it may be empty!
return pStack->Return(inst, pStk); // return an object to the application
// makes the object to which the application
}
}
delete inst; // error, frees the place
return pStack->Return(nullptr, pStk); // no object, the error is on the stack
}
示例12: CBotNew
CBotInstr* CBotNew::Compile(CBotToken* &p, CBotCStack* pStack)
{
CBotToken* pp = p;
if (!IsOfType(p, ID_NEW)) return nullptr;
// verifies that the token is a class name
if (p->GetType() != TokenTypVar)
{
pStack->SetError(CBotErrBadNew, p);
return nullptr;
}
CBotClass* pClass = CBotClass::Find(p);
if (pClass == nullptr)
{
pStack->SetError(CBotErrBadNew, p);
return nullptr;
}
CBotNew* inst = new CBotNew();
inst->SetToken(pp);
inst->m_vartoken = *p;
p = p->GetNext();
// creates the object on the stack
// with a pointer to the object
CBotVar* pVar = CBotVar::Create("", pClass);
// do the call of the creator
CBotCStack* pStk = pStack->TokenStack();
{
// check if there are parameters
CBotVar* ppVars[1000];
inst->m_parameters = CompileParams(p, pStk, ppVars);
if (!pStk->IsOk()) goto error;
// constructor exist?
CBotTypResult r = pClass->CompileMethode(pClass->GetName(), pVar, ppVars, pStk, inst->m_nMethodeIdent);
delete pStk->TokenStack(); // release extra stack
int typ = r.GetType();
// if there is no constructor, and no parameters either, it's ok
if (typ == CBotErrUndefCall && inst->m_parameters == nullptr) typ = 0;
pVar->SetInit(CBotVar::InitType::DEF); // mark the instance as init
if (typ>20)
{
pStk->SetError(static_cast<CBotError>(typ), inst->m_vartoken.GetEnd());
goto error;
}
// if the constructor does not exist, but there are parameters
if (typ<0 && inst->m_parameters != nullptr)
{
pStk->SetError(CBotErrNoConstruct, &inst->m_vartoken);
goto error;
}
// makes pointer to the object on the stack
pStk->SetVar(pVar);
pp = p;
// chained method ?
if (nullptr != (inst->m_exprRetVar = CBotExprRetVar::Compile(p, pStk, true)))
{
inst->m_exprRetVar->SetToken(pp);
delete pStk->TokenStack();
}
if (pStack->IsOk())
return pStack->Return(inst, pStk);
}
error:
delete inst;
return pStack->Return(nullptr, pStk);
}
示例13: CBotFunction
// pre-compile a new function
CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClass* pClass)
{
CBotFunction* func = new CBotFunction();
func->m_nFuncIdent = CBotVar::NextUniqNum();
CBotCStack* pStk = pStack->TokenStack(p, true);
while (true)
{
if ( IsOfType(p, ID_PUBLIC) )
{
// func->m_bPublic = true; // will be done in two passes
continue;
}
if ( IsOfType(p, ID_EXTERN) )
{
func->m_bExtern = true;
continue;
}
break;
}
func->m_retToken = *p;
func->m_retTyp = TypeParam(p, pStack); // type of the result
if (func->m_retTyp.GetType() >= 0)
{
CBotToken* pp = p;
func->m_token = *p;
// un nom de fonction est-il là ?
if (IsOfType(p, TokenTypVar))
{
if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class
{
func->m_MasterClass = pp->GetString();
CBotClass* pClass = CBotClass::Find(pp);
if ( pClass == NULL )
{
pStk->SetError(TX_NOCLASS, pp);
goto bad;
}
pp = p;
func->m_token = *p;
if (!IsOfType(p, TokenTypVar)) goto bad;
}
func->m_Param = CBotDefParam::Compile( p, pStk );
if (pStk->IsOk())
{
// looks if the function exists elsewhere
if (( pClass != NULL || !pStack->CheckCall(pp, func->m_Param)) &&
( pClass == NULL || !pClass->CheckCall(pp, func->m_Param)) )
{
if (IsOfType(p, ID_OPBLK))
{
int level = 1;
// and skips the following instruction block
do
{
int type = p->GetType();
p = p->GetNext();
if (type == ID_OPBLK) level++;
if (type == ID_CLBLK) level--;
}
while (level > 0 && p != NULL);
return pStack->ReturnFunc(func, pStk);
}
pStk->SetError(TX_OPENBLK, p);
}
}
pStk->SetError(TX_REDEF, pp);
}
bad:
pStk->SetError(TX_NOFONC, p);
}
pStk->SetError(TX_NOTYP, p);
delete func;
return pStack->ReturnFunc(NULL, pStk);
}
示例14: Compile
CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type)
{
CBotCStack* pStk = pStack->TokenStack(p);
CBotToken* pp = p;
if (IsOfType( p, ID_NULL ) || (IsOfType(p, ID_OPBLK) && IsOfType(p, ID_CLBLK)))
{
CBotInstr* inst = new CBotExprLitNull();
inst->SetToken(pp);
return pStack->Return(inst, pStk); // ok with empty element
}
p = pp;
CBotListArray* inst = new CBotListArray();
if (IsOfType( p, ID_OPBLK ))
{
// each element takes the one after the other
if (type.Eq( CBotTypArrayPointer ))
{
pStk->SetStartError(p->GetStart());
if (nullptr == ( inst->m_expr = CBotListArray::Compile( p, pStk, type.GetTypElem() ) ))
{
if (pStk->IsOk())
{
inst->m_expr = CBotTwoOpExpr::Compile(p, pStk);
if (inst->m_expr == nullptr || !pStk->GetTypResult().Compare(type)) // compatible type ?
{
pStk->SetError(CBotErrBadType1, p->GetStart());
goto error;
}
}
}
while (IsOfType( p, ID_COMMA )) // other elements?
{
pStk->SetStartError(p->GetStart());
CBotInstr* i = nullptr;
if (nullptr == ( i = CBotListArray::Compile(p, pStk, type.GetTypElem() ) ))
{
if (pStk->IsOk())
{
i = CBotTwoOpExpr::Compile(p, pStk);
if (i == nullptr || !pStk->GetTypResult().Compare(type)) // compatible type ?
{
pStk->SetError(CBotErrBadType1, p->GetStart());
goto error;
}
}
}
inst->m_expr->AddNext3b(i);
if ( p->GetType() == ID_COMMA ) continue;
if ( p->GetType() == ID_CLBLK ) break;
pStk->SetError(CBotErrClosePar, p);
goto error;
}
}
else
{
pStk->SetStartError(p->GetStart());
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
{
goto error;
}
CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
if (!TypeCompatible(valType, type, ID_ASS) )
{
pStk->SetError(CBotErrBadType1, p->GetStart());
goto error;
}
while (IsOfType( p, ID_COMMA )) // other elements?
{
pStk->SetStartError(p->GetStart());
CBotInstr* i = CBotTwoOpExpr::Compile(p, pStk) ;
if (nullptr == i)
{
goto error;
}
CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
if (!TypeCompatible(valType, type, ID_ASS) )
{
pStk->SetError(CBotErrBadType1, p->GetStart());
goto error;
}
inst->m_expr->AddNext3b(i);
if (p->GetType() == ID_COMMA) continue;
if (p->GetType() == ID_CLBLK) break;
//.........这里部分代码省略.........
示例15: while
CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations)
{
int typeMask;
if ( pOperations == nullptr ) pOperations = ListOp;
int* pOp = pOperations;
while ( *pOp++ != 0 ); // follows the table
CBotCStack* pStk = pStack->TokenStack(); // one end of stack please
// search the intructions that may be suitable to the left of the operation
CBotInstr* left = (*pOp == 0) ?
CBotParExpr::Compile( p, pStk ) : // expression (...) left
CBotTwoOpExpr::Compile( p, pStk, pOp ); // expression A * B left
if (left == nullptr) return pStack->Return(nullptr, pStk); // if error, transmit
// did we expected the operand?
int typeOp = p->GetType();
if ( IsInList(typeOp, pOperations, typeMask) )
{
CBotTypResult type1, type2;
type1 = pStk->GetTypResult(); // what kind of the first operand?
if (typeOp == ID_LOGIC) // special case provided for: ? op1: op2;
{
if ( !type1.Eq(CBotTypBoolean) )
{
pStk->SetError( CBotErrBadType1, p);
return pStack->Return(nullptr, pStk);
}
CBotLogicExpr* inst = new CBotLogicExpr();
inst->m_condition = left;
p = p->GetNext(); // skip the token of the operation
inst->m_op1 = CBotExpression::Compile(p, pStk);
CBotToken* pp = p;
if ( inst->m_op1 == nullptr || !IsOfType( p, ID_DOTS ) )
{
pStk->SetError( CBotErrNoDoubleDots, p->GetStart());
delete inst;
return pStack->Return(nullptr, pStk);
}
type1 = pStk->GetTypResult();
inst->m_op2 = CBotExpression::Compile(p, pStk);
if ( inst->m_op2 == nullptr )
{
pStk->SetError( CBotErrNoTerminator, p->GetStart() );
delete inst;
return pStack->Return(nullptr, pStk);
}
type2 = pStk->GetTypResult();
if (!TypeCompatible(type1, type2))
{
pStk->SetError( CBotErrBadType2, pp );
delete inst;
return pStack->Return(nullptr, pStk);
}
pStk->SetType(type1); // the greatest of 2 types
return pStack->Return(inst, pStk);
}
CBotTwoOpExpr* inst = new CBotTwoOpExpr(); // element for operation
inst->SetToken(p); // stores the operation
p = p->GetNext(); // skip the token of the operation
// looking statements that may be suitable for right
if ( nullptr != (inst->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp )) )
// expression (...) right
{
// there is an second operand acceptable
type2 = pStk->GetTypResult(); // what kind of results?
if ( type1.Eq(99) || type2.Eq(99) ) // operand is void
{
pStack->SetError(CBotErrBadType2, &inst->m_token);
delete inst;
return nullptr;
}
// what kind of result?
int TypeRes = std::max( type1.GetType(CBotTypResult::GetTypeMode::NULL_AS_POINTER), type2.GetType(CBotTypResult::GetTypeMode::NULL_AS_POINTER) );
if (typeOp == ID_ADD && type1.Eq(CBotTypString))
{
TypeRes = CBotTypString;
type2 = type1; // any type convertible chain
}
else if (typeOp == ID_ADD && type2.Eq(CBotTypString))
{
TypeRes = CBotTypString;
type1 = type2; // any type convertible chain
}
else if (!TypeOk(TypeRes, typeMask)) type1.SetType(99);// error of type
//.........这里部分代码省略.........