📄 gsm.cc
字号:
_RefTableStack->Push(new RefHashTable); _FuncNameStack->Push( funcname ); for (int i = 0; i < func_info.NumParams; i++) { if (param[i] != 0 && param[i]->Spec().Type != porREFERENCE) { VarDefine(func_info.ParamInfo[i].Name, param[i]); param[i] = param[i]->RefCopy(); } } try { result = Execute(&program, true); if (result) { _ResolveRef(result); if (result->Spec().Type == porREFERENCE) { throw gclRuntimeError("Reference to unknown variable " + ((ReferencePortion *) result)->Value() + " returned from function " + UserFuncName()); } if (result->IsReference()) { result_copy = result->ValCopy(); delete result; result = result_copy; } for (int i = 0; i < func_info.NumParams; i++) { if (func_info.ParamInfo[i].PassByReference) { if (VarIsDefined(func_info.ParamInfo[i].Name)) { delete param[i]; param[i] = _VarRemove(func_info.ParamInfo[i].Name); } } } delete _RefTableStack->Pop(); _FuncNameStack->Pop(); } } // The reason for this dual handler is that Borland apparently has // some compiler bug with rethrowing exceptions. When the throw // above was introduced to check for returning undefined variables // crashes ensued. This seems to fix matters. -- magyar, 3/18/99 catch (gclRuntimeError &E) { delete _RefTableStack->Pop(); _FuncNameStack->Pop(); throw E; } catch (...) { delete _RefTableStack->Pop(); _FuncNameStack->Pop(); throw; } return result;}gText GSM::UserFuncName( void ) const{ if( _FuncNameStack->Depth() > 0 ) return _FuncNameStack->Peek(); else return "";}//----------------------------------------------------------------------------// miscellaneous functions//----------------------------------------------------------------------------void GSM::Clear(void){ while (_RefTableStack->Depth() > 0) delete _RefTableStack->Pop(); _RefTableStack->Push(new RefHashTable);}Portion* GSM::Help(gText funcname, bool udf, bool bif, bool getdesc){ int i; int j; unsigned int fk, ck; int cfk; bool match; int found = 0; gText curname; const gList<gclFunction*>* funcs = _FuncTable->Value(); gclFunction *func; gList<gclFunction*> funclist; gSortList<gclFunction*> funcslist; Portion* result; if(_FuncTable->IsDefined(funcname)) { func = (*_FuncTable)(funcname); gList<gText> list = func->FuncList( udf, bif, getdesc ); result = new ListPortion(); for(i=1; i<=list.Length(); i++) ((ListPortion*) result)->Append(new TextPortion(list[i])); } else { funcname = funcname.Dncase(); for(i=0; i<_FuncTable->NumBuckets(); i++) for(j=1; j<=funcs[i].Length(); j++) funclist.Append(funcs[i][j]); for(i=1; i<=funclist.Length(); i++) { match = true; curname = funclist[i]->FuncName().Dncase(); fk = 0; ck = 0; cfk = -1; while(match && (fk <funcname.Length()) && (ck<curname.Length())) { if(funcname[fk]=='*') { if(fk+1==funcname.Length()) break; cfk = fk; fk++; while(ck<curname.Length() && funcname[fk]!=curname[ck]) ck++; if(ck==curname.Length()) { match = false; break; } } if(funcname[fk]==curname[ck]) { fk++; ck++; } else if(funcname[fk]=='?') { fk++; ck++; } else { if(cfk<0) match = false; else { fk = cfk; } } } if((fk>=funcname.Length()) != (ck>=curname.Length())) match = false; if(fk+1==funcname.Length() && funcname[fk]=='*') match = true; if(match) { if( (udf && funclist[i]->UDF()) || (bif && funclist[i]->BIF()) ) { func = funclist[i]; funcslist.Append(func); found++; } } } gFuncListSorter sorter; if(found==1) { gList<gText> list = func->FuncList( udf, bif, getdesc ); result = new ListPortion(); for(i=1; i<=list.Length(); i++) ((ListPortion*) result)->Append(new TextPortion(list[i])); } else { sorter.Sort(funcslist); result = new ListPortion(); for(i=1; i<=funcslist.Length(); i++) ((ListPortion*) result)-> Append(new TextPortion(funcslist[i]->FuncName())); } } if(!result) throw gclRuntimeError("No match found"); return result;}Portion* GSM::HelpVars(gText varname){ int i; int j; unsigned int fk, ck; int cfk; bool match; gText curname; const gList<gText>* vars = _RefTableStack->Peek()->Key(); gText var; gList<gText> varlist; gSortList<gText> varslist; Portion* result; if(_RefTableStack->Peek()->IsDefined(varname)) { result = new ListPortion(); ((ListPortion*) result)->Append(new TextPortion(varname + ":" + PortionSpecToText((*(_RefTableStack->Peek()))(varname)->Spec()))); } else { varname = varname.Dncase(); for(i=0; i<_RefTableStack->Peek()->NumBuckets(); i++) for(j=1; j<=vars[i].Length(); j++) varlist.Append(vars[i][j]); for(i=1; i<=varlist.Length(); i++) { match = true; curname = varlist[i].Dncase(); fk = 0; ck = 0; cfk = -1; while(match && (fk<varname.Length()) && (ck<curname.Length())) { if(varname[fk]=='*') { if(fk+1==varname.Length()) break; cfk = fk; fk++; while(ck<curname.Length() && varname[fk]!=curname[ck]) ck++; if(ck==curname.Length()) { match = false; break; } } if(varname[fk]==curname[ck]) { fk++; ck++; } else if(varname[fk]=='?') { fk++; ck++; } else { if(cfk<0) match = false; else { fk = cfk; } } } if((fk>=varname.Length()) != (ck>=curname.Length())) match = false; if(fk+1==varname.Length() && varname[fk]=='*') match = true; if (match) { var = varlist[i]; varslist.Append(var); } } gTextListSorter sorter; sorter.Sort(varslist); result = new ListPortion(); for(i=1; i<=varslist.Length(); i++) ((ListPortion*) result)->Append(new TextPortion(varslist[i] + ":" + PortionSpecToText((*(_RefTableStack->Peek()))(varslist[i])->Spec()))); } if(!result) throw gclRuntimeError("No match found"); return result;}//-------------------------// InvalidateGameProfile//-------------------------void GSM::InvalidateGameProfile( void* game, bool IsEfg ){ gStack< RefHashTable* > tempRefTableStack; while( _RefTableStack->Depth() > 0 ) { const gList<Portion*>* vars = _RefTableStack->Peek()->Value(); gList<Portion*> varslist; for (int i = 0; i<_RefTableStack->Peek()->NumBuckets(); i++) for (int j = 1; j<=vars[i].Length(); j++) varslist.Append(vars[i][j]); for (int i = 1; i <= varslist.Length(); i++ ) { if( varslist[i]->Game() == game && varslist[i]->GameIsEfg() == IsEfg ) { if (!IsEfg && varslist[i]->Spec() == porMIXED) ((MixedPortion *) varslist[i])->Value()->Invalidate(); else if (IsEfg && varslist[i]->Spec() == porBEHAV) ((BehavPortion *) varslist[i])->Value()->Invalidate(); } } // go through all scopes on the stack; restore later tempRefTableStack.Push( _RefTableStack->Pop() ); } while( tempRefTableStack.Depth() > 0 ) { // restore the original variable stack _RefTableStack->Push( tempRefTableStack.Pop() ); }}//------------------------// UnAssignGameElement//------------------------void GSM::UnAssignGameElement( void* game, bool /*IsEfg*/, PortionSpec spec ){ if (spec.ListDepth > 0) return; gStack< RefHashTable* > tempRefTableStack; while( _RefTableStack->Depth() > 0 ) { const gList<Portion*>* vars = _RefTableStack->Peek()->Value(); gList<Portion*> varslist; for (int i=0; i<_RefTableStack->Peek()->NumBuckets(); i++) for (int j=1; j<=vars[i].Length(); j++) varslist.Append(vars[i][j]); for (int i = 1; i <= varslist.Length(); i++ ) { if( varslist[i]->Spec().ListDepth == 0 ) { if( varslist[i]->Game() == game ) { if( varslist[i]->Spec().Type & spec.Type ) { _RefTableStack->Peek()->Remove( varslist[i] ); } } } else { if( ((ListPortion*) varslist[i])->BelongsToGame( game ) ) { if( varslist[i]->Spec().Type & spec.Type ) { _RefTableStack->Peek()->Remove( varslist[i] ); } } } } // go through all scopes on the stack; restore later tempRefTableStack.Push( _RefTableStack->Pop() ); } while( tempRefTableStack.Depth() > 0 ) { // restore the original variable stack _RefTableStack->Push( tempRefTableStack.Pop() ); }}//---------------------// UnAssignEfgElement//---------------------void GSM::UnAssignEfgElement( efgGame *game, PortionSpec spec, void* data ){ gStack< RefHashTable* > tempRefTableStack; while( _RefTableStack->Depth() > 0 ) { const gList<Portion*>* vars = _RefTableStack->Peek()->Value(); gList<Portion*> varslist; for (int i=0; i<_RefTableStack->Peek()->NumBuckets(); i++) for (int j=1; j<=vars[i].Length(); j++) varslist.Append(vars[i][j]); for (int i = 1; i <= varslist.Length(); i++ ) { if( varslist[i]->Spec().ListDepth == 0 ) { if( varslist[i]->Game() == game ) { if( spec.Type & porEFSUPPORT ) { if( ((EfSupportPortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } if( spec.Type & porEFBASIS ) { if( ((EfBasisPortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } if( spec.Type & porEFPLAYER ) { if( ((EfPlayerPortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } if( spec.Type & porINFOSET ) { if( ((InfosetPortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } if( spec.Type & porNODE ) { if( ((NodePortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } if( spec.Type & porACTION ) { if( ((ActionPortion*) varslist[i])->Value() == data ) _RefTableStack->Peek()->Remove( varslist[i] ); } } } else // varslist[i] is a list { if( spec.Type & varslist[i]->Spec().Type ) { if( ((ListPortion*) varslist[i])->MatchGameData( game, data ) ) { _RefTableStack->Peek()->Remove( varslist[i] ); } } } } // go through all scopes on the stack; restore later tempRefTableStack.Push( _RefTableStack->Pop() ); } while( tempRefTableStack.Depth() > 0 ) { // restore the original variable stack _RefTableStack->Push( tempRefTableStack.Pop() ); }}void GSM::UnAssignEfgOutcome(efgGame *game, const efgOutcome *data){ gStack< RefHashTable* > tempRefTableStack; while (_RefTableStack->Depth() > 0) { const gList<Portion*>* vars = _RefTableStack->Peek()->Value(); gList<Portion*> varslist; for (int i=0; i<_RefTableStack->Peek()->NumBuckets(); i++) for (int j=1; j<=vars[i].Length(); j++) varslist.Append(vars[i][j]); for (int i = 1; i <= varslist.Length(); i++) { if (varslist[i]->Spec().ListDepth == 0) { if (varslist[i]->Game() == game && varslist[i]->Spec() == porEFOUTCOME) { if (((EfOutcomePortion*) varslist[i])->Value() == data) { _RefTableStack->Peek()->Remove(varslist[i]); } } }#ifdef FIXME // FIXME: need to check lists else { // varslist[i] is a list if (spec.Type & varslist[i]->Spec().Type) { if (((ListPortion*) varslist[i])->MatchGameData( game, data )) { _RefTableStack->Peek()->Remove( varslist[i] ); } } }#endif // FIXME } // go through all scopes on the stack; restore later tempRefTableStack.Push( _RefTableStack->Pop() ); } while (tempRefTableStack.Depth() > 0) { // restore the original variable stack _RefTableStack->Push(tempRefTableStack.Pop()); }}void GSM::UnAssignEfgInfoset(efgGame * game, Infoset* infoset ){ for (int i = 1; i <= infoset->NumActions(); i++ ) UnAssignEfgElement( game, porACTION, (Action *)infoset->Actions()[i] ); UnAssignEfgElement( game, porINFOSET, infoset ); }void GSM::UnAssignEfgSubTree( efgGame * game, Node* node ){ for (int i = 1; i <= game->NumChildren(node); i++) { Infoset* infoset = node->GetInfoset(); if (infoset) { const gArray<Action *>& actions = infoset->Actions(); for (int j = actions.First(); j <= actions.Last(); j++ ) UnAssignEfgElement( game, porACTION, (Action *)actions[j] ); UnAssignEfgElement( game, porINFOSET, infoset ); } UnAssignEfgSubTree( game, node->GetChild( i ) ); } UnAssignEfgElement( game, porNODE, node );}void GSM::GlobalVarDefine ( const gText& var_name, Portion* p ){ if (var_name == "") throw gclRuntimeError("Attempted to define empty variable name"); if( GlobalVarIsDefined( var_name ) ) GlobalVarRemove( var_name ); _GlobalRefTable.Define(var_name, p);}bool GSM::GlobalVarIsDefined ( const gText& var_name ) const{ if (var_name == "") throw gclRuntimeError("Attempted to define empty variable name"); return _GlobalRefTable.IsDefined(var_name);}Portion* GSM::GlobalVarValue ( const gText& var_name ) const{ if (var_name == "") throw gclRuntimeError("Attempted to get value of empty variable name"); return _GlobalRefTable(var_name);}void GSM::GlobalVarRemove ( const gText& var_name ){ if (var_name == "") throw gclRuntimeError("Attempted to remove empty variable name"); delete _GlobalRefTable.Remove(var_name);}void GSM::StartAlgorithmMonitor(const gText &){ }void GSM::EndAlgorithmMonitor(void){ GetStatusMonitor().Reset();}gclRuntimeError::gclRuntimeError(const gText &s) : message(s){ }gclRuntimeError::~gclRuntimeError(){ }gText gclRuntimeError::Description(void) const{ return message; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -