⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsminstr.cc

📁 Gambit 是一个游戏库理论软件
💻 CC
字号:
//// $Source: /home/gambit/CVS/gambit/sources/gcl/gsminstr.cc,v $// $Date: 2002/08/27 18:57:18 $// $Revision: 1.3 $//// DESCRIPTION:// Implementation of GCL expression classes//// This file is part of Gambit// Copyright (c) 2002, The Gambit Project//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//#include "base/gstatus.h"#include "base/gstream.h"#include "gsminstr.h"#include "gcmdline.h"#include "gsm.h"#include "gsmfunc.h"#include "gsmhash.h"//-------------// Base class//-------------gclExpression::gclExpression(void)  : m_line(0), m_file("Unknown"){ }gclExpression::gclExpression(int p_line, const gText &p_file)  : m_line(p_line), m_file(p_file){ }//---------// Quit//---------PortionSpec gclQuitExpression::Type(void) const{  return porBOOLEAN;}Portion *gclQuitExpression::Evaluate(GSM &){  throw gclQuitOccurred(0);}//--------// Semi//--------gclSemiExpr::gclSemiExpr(gclExpression *e1, gclExpression *e2)  : lhs(e1), rhs(e2){ }gclSemiExpr::~gclSemiExpr(){  delete lhs;  delete rhs;}PortionSpec gclSemiExpr::Type(void) const{  return rhs->Type();}Portion *gclSemiExpr::Evaluate(GSM &p_environment) {  delete lhs->Evaluate(p_environment);  return rhs->Evaluate(p_environment);}//--------------------// ReqParameterList//--------------------gclReqParameterList::gclReqParameterList(void){ }gclReqParameterList::gclReqParameterList(gclExpression *p){  exprs.Append(p);}gclReqParameterList::~gclReqParameterList(){  for (int i = 1; i <= exprs.Length(); delete exprs[i++]);}void gclReqParameterList::Append(gclExpression *p){  exprs.Append(p);}int gclReqParameterList::NumParams(void) const{  return exprs.Length();}gclExpression *gclReqParameterList::operator[](int index) const{  return exprs[index];}//-------------------// OptParameterList//-------------------gclOptParameterList::gclOptParameterList(void){ }gclOptParameterList::gclOptParameterList(const gText &s, gclExpression *p){  names.Append(s);  exprs.Append(p);}gclOptParameterList::~gclOptParameterList(){  for (int i = 1; i <= exprs.Length(); delete exprs[i++]);}void gclOptParameterList::Append(const gText &s, gclExpression *p){  names.Append(s);  exprs.Append(p);}int gclOptParameterList::NumParams(void) const{  return exprs.Length();}gclExpression *gclOptParameterList::operator[](int index) const{  return exprs[index];}gText gclOptParameterList::FormalName(int index) const{  return names[index];}//-----------------// ParameterList//-----------------gclParameterList::gclParameterList(void)  : req(new gclReqParameterList), opt(new gclOptParameterList){ }gclParameterList::gclParameterList(gclReqParameterList *r)  : req(r), opt(new gclOptParameterList){ }gclParameterList::gclParameterList(gclOptParameterList *o)  : req(new gclReqParameterList), opt(o){ }gclParameterList::gclParameterList(gclReqParameterList *r,				   gclOptParameterList *o)  : req(r), opt(o){ }gclParameterList::~gclParameterList(){  delete req;  delete opt;}//----------------// FunctionCall//----------------gclFunctionCall::gclFunctionCall(const gText &p_name,				 int p_line, const gText &p_file)  : gclExpression(p_line, p_file),    name(p_name), params(new gclParameterList), funcptr(0), type(porANYTYPE){ }gclFunctionCall::gclFunctionCall(const gText &p_name, gclExpression *p_op,				 int p_line, const gText &p_file)  : gclExpression(p_line, p_file),    name(p_name), params(new gclParameterList), funcptr(0), type(porANYTYPE){  params->req->Append(p_op);}gclFunctionCall::gclFunctionCall(const gText &p_name,				 gclExpression *p_op1, gclExpression *p_op2,				 int p_line, const gText &p_file)  : gclExpression(p_line, p_file),    name(p_name), params(new gclParameterList), funcptr(0), type(porANYTYPE){  params->req->Append(p_op1);  params->req->Append(p_op2);}gclFunctionCall::gclFunctionCall(const gText &p_name,				 gclParameterList *p_params,				 int p_line, const gText &p_file)  : gclExpression(p_line, p_file),    name(p_name), params(p_params), funcptr(0), type(porANYTYPE){ }gclFunctionCall::~gclFunctionCall(){  delete params;}PortionSpec gclFunctionCall::Type(void) const{  return type;}Portion *gclFunctionCall::Evaluate(GSM &p_environment){  if (!p_environment._FuncTable->IsDefined(name)) {    throw gclRuntimeError("Undefined function " + name);  }  p_environment.GetStatusMonitor().Get();  CallFuncObj call((*p_environment._FuncTable)(name), m_line, m_file);    for (int i = 1; i <= params->req->NumParams(); i++)   {    Portion *val = (*params->req)[i]->Evaluate(p_environment);    if (val->Spec().Type == porREFERENCE)   {      if (p_environment.VarIsDefined(((ReferencePortion *) val)->Value())) {	call.SetCurrParam(p_environment.VarValue(((ReferencePortion *) val)->Value())->RefCopy(), AUTO_VAL_OR_REF);	delete val;      }      else  {	call.SetCurrParam(val, AUTO_VAL_OR_REF);      }    }    else        call.SetCurrParam(val, AUTO_VAL_OR_REF);  }    for (int i = 1; i <= params->opt->NumParams(); i++)  {    call.SetCurrParamIndex(params->opt->FormalName(i));    Portion *val = (*params->opt)[i]->Evaluate(p_environment);    if (val->Spec().Type == porREFERENCE)   {      if (p_environment.VarIsDefined(((ReferencePortion *) val)->Value()))	call.SetCurrParam(p_environment.VarValue(((ReferencePortion *) val)->Value())->RefCopy(), true);      else  {	call.SetCurrParam(val);      }    }    else        call.SetCurrParam(val, AUTO_VAL_OR_REF);  }      Portion **param = 0;  Portion *ret = 0;  try {    param = new Portion *[call.NumParams()];    ret = call.CallFunction(&p_environment, param);          for (int index = 0; index < call.NumParams(); index++)   {      ReferencePortion *refp = call.GetParamRef(index);      if (refp != 0)  {	p_environment.VarDefine(refp->Value(), param[index]->ValCopy());      }    }    delete [] param;  }  catch (...) {    if (param)  delete [] param;    throw;  }  return ret;}//--------------// Assignment//--------------gclAssignment::gclAssignment(gclExpression *lhs, gclExpression *rhs)  : variable(lhs), value(rhs){ }gclAssignment::~gclAssignment(){  delete variable;  delete value;}Portion *gclAssignment::Evaluate(GSM &p_environment){  Portion *lhs = variable->Evaluate(p_environment);  Portion *rhs;  try  {    rhs = value->Evaluate(p_environment);  }  catch (gclRuntimeError &)  {    delete lhs;    throw;  }  // Assign() will delete lhs and rhs  return p_environment.Assign(lhs, rhs);}//----------------// UnAssignment//----------------gclUnAssignment::gclUnAssignment(gclExpression *lhs)  : variable(lhs){ }gclUnAssignment::~gclUnAssignment(){  delete variable;}Portion *gclUnAssignment::Evaluate(GSM &p_environment){  Portion *lhs = variable->Evaluate(p_environment);  p_environment.UnAssign(lhs);  return new BoolPortion(true);}  //-------------// ConstExpr//-------------gclConstExpr::gclConstExpr(Portion *v)  : value(v){ }gclConstExpr::~gclConstExpr(){  delete value;}PortionSpec gclConstExpr::Type(void) const{  return value->Spec();}Portion *gclConstExpr::Evaluate(GSM &){  return value->ValCopy();}//---------------// ListConstant//---------------gclListConstant::gclListConstant(void){ }gclListConstant::gclListConstant(gclExpression *expr){  values.Append(expr);}gclListConstant::~gclListConstant(){  for (int i = 1; i <= values.Length(); delete values[i++]);}void gclListConstant::Append(gclExpression *expr){  values.Append(expr);}Portion *gclListConstant::Evaluate(GSM &p_environment){  ListPortion *ret = new ListPortion;  try  {    for (int i = 1; i <= values.Length(); i++)  {      Portion *v = values[i]->Evaluate(p_environment);      p_environment._ResolveRef(v);      // v is deleted by ListPortion::Append if this call fails      ret->Append(v);    }    return ret;  }  catch (...)   {    delete ret;    throw;  }}//-----------// VarName//-----------gclVarName::gclVarName(const gText &name)  : value(new ReferencePortion(name)){ }gclVarName::~gclVarName(){  delete value;}Portion *gclVarName::Evaluate(GSM &){  if (((ReferencePortion *) value)->Value() == "Quit")    throw gclQuitOccurred(0);  return value->ValCopy();}//---------------// Conditional//---------------gclConditional::gclConditional(gclExpression *g, gclExpression *t,                               gclExpression *f)  : guard(g), truebr(t), falsebr(f){ }gclConditional::~gclConditional(){  delete guard;  delete truebr;  delete falsebr;}Portion *gclConditional::Evaluate(GSM &p_environment){  Portion *guardval = guard->Evaluate(p_environment);  p_environment._ResolveRef(guardval);  if (guardval->Spec().Type != porBOOLEAN ||      guardval->Spec().ListDepth > 0)    throw gclRuntimeError("Guard must evaluate to BOOLEAN");  try  {    Portion *ret;    if (((BoolPortion *) guardval)->Value() == triTRUE) {      ret = truebr->Evaluate(p_environment);    }    else {      ret = falsebr->Evaluate(p_environment);    }    delete guardval;    Portion *retcopy = ret->ValCopy();    delete ret;    return retcopy;  }  catch (...)   {    delete guardval;    throw;  }}//------------// WhileExpr//------------gclWhileExpr::gclWhileExpr(gclExpression *g, gclExpression *b)  : guard(g), body(b){ }gclWhileExpr::~gclWhileExpr(){  delete guard;  delete body;}Portion *gclWhileExpr::Evaluate(GSM &p_environment){  Portion *ret = new NullPortion(porNUMBER);  while (1)   {    Portion *guardval;    try  {      guardval = guard->Evaluate(p_environment);    }    catch (...)  {      delete ret;      throw;    }    try  {      p_environment._ResolveRef(guardval);    }    catch (...)   {      delete guardval;      delete ret;      throw;    }        if (guardval->Spec().Type != porBOOLEAN ||        guardval->Spec().ListDepth > 0)      throw gclRuntimeError("Guard must evaluate to BOOLEAN");    if (((BoolPortion *) guardval)->Value() != triTRUE)  {      delete guardval;      return ret;    }    delete guardval;    delete ret;    p_environment.GetStatusMonitor().Get();    ret = body->Evaluate(p_environment);  }}//-----------// ForExpr//-----------gclForExpr::gclForExpr(gclExpression *i, gclExpression *g,		       gclExpression *s, gclExpression *b)  : init(i), guard(g), step(s), body(b){ }gclForExpr::~gclForExpr(){  delete init;  delete guard;  delete step;  delete body;}Portion *gclForExpr::Evaluate(GSM &p_environment){  Portion *ret = new NullPortion(porNUMBER);  try  {    delete init->Evaluate(p_environment);  }  catch (...)   {    delete ret;    throw;  }  while (1)   {    Portion *guardval;    try  {      guardval = guard->Evaluate(p_environment);    }    catch (...)  {      delete ret;      throw;    }    try  {      p_environment._ResolveRef(guardval);    }    catch (...)  {      delete ret;      delete guardval;      throw;    }    if (guardval->Spec().Type != porBOOLEAN ||	guardval->Spec().ListDepth > 0) {      delete guardval;      throw gclRuntimeError("Guard must evaluate to BOOLEAN");     }    if (((BoolPortion *) guardval)->Value() != triTRUE)  {      delete guardval;      return ret;    }    delete guardval;    delete ret;    p_environment.GetStatusMonitor().Get();    ret = body->Evaluate(p_environment);    try   {      delete step->Evaluate(p_environment);    }    catch (...)  {      delete ret;      throw;    }  }}    //---------------// FunctionDef//---------------gclFunctionDef::gclFunctionDef(gclFunction *f, gclExpression *b)  : func(f), body(b){ }gclFunctionDef::~gclFunctionDef(){ }Portion *gclFunctionDef::Evaluate(GSM &p_environment){  p_environment.AddFunction(func);  return new BoolPortion(true);}//-----------------// DeleteFunction//-----------------gclDeleteFunction::gclDeleteFunction(gclFunction *p_function)  : func(p_function){ }gclDeleteFunction::~gclDeleteFunction(){ }Portion *gclDeleteFunction::Evaluate(GSM &p_environment){  p_environment.DeleteFunction(func);  return new BoolPortion(true);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -