gsmoper.cc
来自「Gambit 是一个游戏库理论软件」· CC 代码 · 共 2,227 行 · 第 1/5 页
CC
2,227 行
//-------static Portion *GSM_Null(GSM &, Portion** param){ return new NullPortion(param[0]->Spec().Type);}//-----// Or//-----static Portion *GSM_Or(GSM &, Portion** param){ gTriState x = ((BoolPortion *) param[0])->Value(); gTriState y = ((BoolPortion *) param[1])->Value(); if (x == triTRUE || y == triTRUE) return new BoolPortion(triTRUE); else if (x == triUNKNOWN || y == triUNKNOWN) return new BoolPortion(triUNKNOWN); else return new BoolPortion(triFALSE);}//----------// Output//----------static Portion *GSM_Output(GSM &, Portion** param){ gText filename = ((TextPortion*) param[0])->Value(); bool append = ((BoolPortion*) param[1])->Value(); bool close = ((BoolPortion*) param[2])->Value(); try { return new OutputPortion(*new gFileOutput(filename, append, close)); } catch (gFileOutput::OpenFailed &) { throw gclRuntimeError((gText) "Error opening file \"" + ((TextPortion*) param[0])->Value() + "\""); }}//--------------// Parentheses//--------------static Portion *GSM_Parentheses(GSM &, Portion **param){ return param[0]->ValCopy();}//-------// Plus//-------static Portion *GSM_Plus_Number(GSM &, Portion** param){ return new NumberPortion(((NumberPortion*) param[0])->Value() + ((NumberPortion*) param[1])->Value());}static Portion *GSM_Plus_Text(GSM &, Portion** param){ return new TextPortion(((TextPortion*) param[0])->Value() + ((TextPortion*) param[1])->Value());}static Portion *GSM_Plus_Mixed(GSM &, Portion** param){ MixedPortion *result = new MixedPortion(new MixedSolution(*((MixedPortion *) param[0])->Value())); *result->Value() += *((MixedPortion*) param[1])->Value(); return result;}static Portion *GSM_Plus_Behav(GSM &, Portion** param){ if(((BehavPortion*) param[0])->Value()->Support() != ((BehavPortion*) param[1])->Value()->Support()) throw gclRuntimeError("Support mismatch"); BehavPortion *result = new BehavPortion(new BehavSolution(*((BehavPortion *) param[0])->Value())); *result->Value() += *((BehavPortion*) param[1])->Value(); return result;}//----------// Power//----------static Portion *GSM_Power(GSM &, Portion** param){ gNumber base = ((NumberPortion*) param[0])->Value(); gNumber exponent = ((NumberPortion*) param[1])->Value(); if (base.Precision() == precDOUBLE || exponent.Precision() == precDOUBLE) return new NumberPortion(pow((double) base, (double) exponent)); else if (base.Precision() == precRATIONAL && exponent.IsInteger()) return new NumberPortion(pow(base.operator gRational(), exponent.operator gRational().numerator())); else throw gclRuntimeError("Not implemented for rational base with non-integer exponent");}//-------------// Precision//-------------static Portion *GSM_Precision(GSM &, Portion** param){ return new PrecisionPortion(((NumberPortion *) param[0])->Value().Precision());}//--------// Print//--------static Portion *GSM_Print(GSM &gsm, Portion **param){ param[0]->Output(gsm.OutputStream()); gsm.OutputStream() << '\n'; return param[0]->ValCopy();}//-------// Quit//-------static Portion *GSM_Quit(GSM &, Portion **param){ throw gclQuitOccurred(((NumberPortion *) param[0])->Value());}//------------// Randomize//------------long _idum = -1;static Portion *GSM_Randomize(GSM &, Portion** param){ long _RandomSeed = ((NumberPortion*) param[1])->Value(); if(_RandomSeed > 0) _RandomSeed = -_RandomSeed; long v; if(_RandomSeed != 0) _idum = _RandomSeed; v = ran1(&_idum); gRational x(v,(long)IM); return new NumberPortion(x);}//-----------// Rational//-----------static Portion *GSM_Rational(GSM &, Portion **param){ return new NumberPortion (((NumberPortion *) param[0])->Value().operator gRational());}//--------// Read//--------static Portion *GSM_Read_Bool(GSM &, Portion** param){ gInput &input = ((InputPortion*) param[0])->Value(); long old_pos = input.getpos(); gTriState value = triUNKNOWN; bool error = false; char c = ' '; if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } while (!input.eof() && isspace(c)) input.get(c); if (c == 'T') { if (!input.eof()) input.get(c); if (c != 'r') error = true; if (!input.eof()) input.get(c); if (c != 'u') error = true; if (!input.eof()) input.get(c); if (c != 'e') error = true; value = triTRUE; } else if (c == 'F') { if (!input.eof()) input.get(c); if (c != 'a') error = true; if (!input.eof()) input.get(c); if (c != 'l') error = true; if (!input.eof()) input.get(c); if (c != 's') error = true; if (!input.eof()) input.get(c); if (c != 'e') error = true; value = triFALSE; } else if (c == 'U') { if (!input.eof()) input.get(c); if (c != 'n') error = true; if (!input.eof()) input.get(c); if (c != 'k') error = true; if (!input.eof()) input.get(c); if (c != 'n') error = true; if (!input.eof()) input.get(c); if (c != 'o') error = true; if (!input.eof()) input.get(c); if (c != 'w') error = true; if (!input.eof()) input.get(c); if (c != 'n') error = true; value = triUNKNOWN; } else error = true; if (error) { input.setpos(old_pos); throw gclRuntimeError("No BOOLEAN data found"); } ((BoolPortion*) param[1])->SetValue(value); // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *p = param[0]; param[0] = p->RefCopy(); return p;}static Portion *GSM_Read_Number(GSM &, Portion** param){ gNumber value; gInput& input = ((InputPortion*) param[0])->Value(); long old_pos = input.getpos(); if(input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } try { input >> value; } catch (gFileInput::ReadFailed &) { input.setpos(old_pos); throw gclRuntimeError("No NUMBER data found"); } ((NumberPortion*) param[1])->SetValue(value); // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *p = param[0]; param[0] = p->RefCopy(); return p;}static Portion *GSM_Read_Text(GSM &, Portion** param){ char c = ' '; gText s, t; gInput& input = ((InputPortion*) param[0])->Value(); long old_pos = input.getpos(); while (!input.eof() && isspace(c)) input.get(c); if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } if (c != '"') { input.setpos(old_pos); throw gclRuntimeError("No TEXT data found"); } if (!input.eof() && c == '\"') input.get(c); else { input.unget(c); input.setpos(old_pos); throw gclRuntimeError("File read error: missing starting \""); } while (!input.eof() && c != '\"') { t += c; input.get(c); } if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } ((TextPortion*) param[1])->SetValue(t); // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *p = param[0]; param[0] = p->RefCopy(); return p;}static Portion *GSM_ReadText_Number(GSM &, Portion** param){ char c = ' '; gText t; gInput& input = ((InputPortion*) param[0])->Value(); unsigned int n = ((NumberPortion *) param[2])->Value(); long old_pos = input.getpos(); while (t.Length()<n) { input.get(c); if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } t += c; } ((TextPortion*) param[1])->SetValue(t); // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *p = param[0]; param[0] = p->RefCopy(); return p;}static Portion *GSM_ReadText_Text(GSM &, Portion** param){ char c = ' '; gText t; gInput& input = ((InputPortion*) param[0])->Value(); gText x = ((TextPortion *) param[2])->Value(); int n = x.Length(); long old_pos = input.getpos(); while (t.Right(n)!=x) { input.get(c); if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } t += c; } ((TextPortion*) param[1])->SetValue(t); // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *p = param[0]; param[0] = p->RefCopy(); return p;}static Portion *GSM_Read_List(GSM &gsm, Portion** param, PortionSpec spec, Portion *(*func) (GSM &, Portion **), bool ListFormat){ Portion *sub_param[2]; ListPortion *list; char c = ' '; gInput& input = ((InputPortion*) param[0])->Value(); list = ((ListPortion*) param[1]); long old_pos = input.getpos(); while (!input.eof() && isspace(c)) input.get(c); if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } if (!ListFormat) { if (c == '{') ListFormat = true; else input.unget(c); } else { if (c != '{') { input.setpos(old_pos); throw gclRuntimeError("\'{\' expected"); } } for (int i = 1; i <= list->Length(); i++) { Portion *p; sub_param[0] = param[0]; sub_param[1] = (*list)[i]; if (i > 1) { c = ' '; while (!input.eof() && isspace(c)) input.get(c); if (c == ',') { if (!ListFormat) input.unget(c); } else input.unget(c); } try { if ((*list)[i]->Spec() == spec) p = (*func)(gsm, sub_param); else p = GSM_Read_List(gsm, sub_param, spec, func, ListFormat); } catch (...) { input.setpos(old_pos); throw; } // okay, complicated things going on here // we want to delete the return value, but // p is actually swapped with sub_param[0] in the // GSM_Read() functions! So, can't just delete p; // need to swap p and sub_param[0] first. // delete and swap delete sub_param[0]; sub_param[0] = p; } if (ListFormat) { c = ' '; while (!input.eof() && isspace(c)) input.get(c); if (c != '}') { input.setpos(old_pos); throw gclRuntimeError("Mismatched braces"); } if (input.eof()) { input.setpos(old_pos); throw gclRuntimeError("End of file reached"); } } // swap the first parameter with the return value, so things like // Input["..."] >> x >> y would work Portion *result = param[0]; param[0] = result->RefCopy(); return result;}static Portion *GSM_Read_List_Bool(GSM &gsm, Portion** param){ Portion *temp = param[1]->ValCopy(); try {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?