亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? expressions.cpp.svn-base

?? 這是一段游戲修改工具的源代碼.ring3功能由dephi開發,驅動是C開發.希望對大家有幫助
?? SVN-BASE
?? 第 1 頁 / 共 3 頁
字號:
/* Expressions.cpp
 * Code to manipulate expressions - the type PExpr
 * UnderC C++ interpreter
 * Steve Donovan, 2001
 * This is GPL'd software, and the usual disclaimers apply.
 * See LICENCE
 *
 * Expr is a fairly basic type, consisting of an operation type (e.g. FUNCTION)
 * and up to two operands. C++ expressions are represented by binary trees built out of
 * Expr pointers.
 */

#include "expressions.h"
#include "common.h"
#include "function_match.h"
#include "tparser.h"
#include "operators.h"
#include "directcall.h"
#include <assert.h>
#include <map>
typedef std::map<int,int> IntMap;

extern Table* gScopeContext; // from common.cpp (yes, a hack)

// found in type.cpp (of all places!)
 Signature *unique_signature(Signature *sig);
// found in common.cpp
string as_str(Type t);

namespace {
  IntMap assign_equiv_op, float_op;
};

bool
Expr::is_function()
{
 return m_op == FUNCTION || m_op == METHOD_CALL || m_op == DCALL;
}

string 
Expr::name()
{
 if (is_entry()) {
    if (!entry()->is_constant()) return entry()->name;
    if (!entry()->type.is_int()) return "?";
    return itos(Parser::const_int_expr(entry()));
 } else
 if (is_function()) return function()->name(); else
 if (is_expr()) return "(...)"; 
 else { // we assume it's a specific operator!
   return Operators::name_from_id(op());
 }
}

bool
Expr::is_variable()
{
 return is_entry() && type().is_reference() && ! entry()->type.is_reference();
}

bool   Expr::is_expr_list()
{ 
 return is_function() && function()==NULL;
}

bool  Expr::is_brace_list()
{ 
  return is_expr_list() && m_type == t_int;
}

namespace Expressions {

// *add 1.2.3 A mechanism for defering function errors when looking at operators
FunctionEntry* mErrPfe;
string mErrMatch; 

PExpr expr_error(string msg); // forward

void set_function_error(FunctionEntry* pfe, string str)
{
    mErrPfe = pfe;
    mErrMatch = str;
}

PExpr function_error()
{
    if (mErrPfe) {
       cerr << "Candidates were\n";
       mErrPfe->dump(cerr);
    }
    PExpr e = expr_error(mErrMatch);
    mErrPfe = NULL;
    mErrMatch = "";
    return e;
}

PExpr function_call(const char *name, PExprList pel)
{
 Function *fn = Function::lookup(name);
 return new Expr(FUNCTION,fn->return_type(),fn,pel);
}

PExpr bcast_op(Type t, PExpr e)
{
 if (t == e->type()) return e;
 else {
  if (e->type().is_plain_reference()) t.make_reference();   // *fix 0.9.7 made var casts to be references!
  return new Expr(BCAST,t,e);
 }  
}

bool is_lvalue(Type t)
{
 return t.is_reference() && !t.is_const();  
}

Type type_of(PExpr e)
{
// this peculiar logic is the inverse of that in entry_op() below!
 if (e->is_entry()) return e->entry()->type;
 else return e->type();
}

// *add 0.9.3 The (non-standard) typeof operator is still experimental. 
// So far, I have to strip reference types to make __typeof(*p)
// work properly.
Type typeof_op(PExpr e)
{
 Type t = type_of(e);
 t.strip_reference();
 return t;
}

bool is_true_reference(PExpr e)
{
 return type_of(e).is_reference();
}

PExpr nil() 
{
 return new Expr(NIL,t_void);
}

PExpr expr_error(string msg)
{
 error(msg);
 return nil();
}

string quoted_op_name(int op) { return Parser::quotes(Operators::name_from_id(op)); }

PExpr not_for_float(int op)
{
 return expr_error(quoted_op_name(op)+" does not take floating point arguments");
}

PExprList expr_list(PExpr e1, PExpr e2)
{
  PExprList pel = new ExprList;
  if (e1) pel->push_back(e1);
  if (e2) pel->push_back(e2);
  return pel;
}

const int NTYPES = 9;

PExpr pointer_addition_op(int op, PExpr e1, PExpr e2)
{
 if (op == MINUS) e2 = make_op(UMINUS,e2->type(),e2);
 return make_op(ARRAY,e1->type(),e1,e2);
}

// here are the functions which the parser uses to generate expressions
PExpr arith_op(int op, PExpr e1, PExpr e2)
{
  static Type types[NTYPES]
   = {t_double,t_ulong,t_long, t_uint,t_int,t_ushort,t_short,t_uchar,t_char};   
  Type t1 = e1->type(), t2 = e2->type();
  t1.strip_qualifiers();
  t2.strip_qualifiers();
  if (t1.is_number() && t2.is_number()) { 
   if (t1 == t_float) { e1 = bcast_op(t_double,e1); t1 = t_double; }
   if (t2 == t_float) { e2 = bcast_op(t_double,e2); t2 = t_double; }
   for(int i = 0; i < NTYPES; i++) { 
    Type tt = types[i];
    if (t1 == tt || t2 == tt) {
      if (tt == t_double && float_op[op] == 0) return not_for_float(op);
      if (t1 != tt) e1 = bcast_op(tt,e1);
      if (t2 != tt) e2 = bcast_op(tt,e2);
      return make_op(op,tt,e1,e2);
    }
   }
 } else
  if (op == PLUS || op == MINUS) {
     // *add 0.9.3 Subtracting two pointers should give the number of elements...
     // *fix 1.2.1 Wrong! p1-p2 should be equiv. to (int)p1 - (int)p2; also, it was wrong for int types!
     // *fix 1.2.4 Sorry, wrong again!  I was right for 0.9.3.
      if (t1.is_pointer() && t2.is_pointer()) {
          if (op == MINUS) {
              t1.decr_pointer();
              PExpr ae = make_op(MINUS,t_int,e1,e2);
              return make_op(DIVIDE,t_int,ae,sizeof_op(t1.size()));
          } 
          else return expr_error("Cannot add pointers");
      }

     if (t1.is_pointer() && t2.is_int()) return pointer_addition_op(op,e1,e2); else
     if (t2.is_pointer() && t1.is_int()) return pointer_addition_op(op,e2,e1); 
  }

  // otherwise, try for user-defined operator!  
  return bin_op(op,e1,e2);
}

PExpr dot_function_op(void *pfn, PExpr obj)
{
  return make_op(DOT,obj->type(),obj,entry_op((PEntry)pfn));
}

PExpr method_op(PEntry pef, PExpr obj, PExprList pel)
{
// *NOTE* are we having returning-object problems w/ this one?
// used for bin_op() methods, also operator().
 return function_op(dot_function_op(pef,obj),pel);
}   

PExpr construct_context_op(PExpr e1, PExpr e2=NULL, int ctype=0); // forward
PEntry add_temporary(Type t, PExpr e, bool always_construct, bool dont_do_dtor = false);  // forward
void set_first_object(PExpr e1);  // forward;
PExpr init_op(PExpr el, int arr_sz, PExpr er, PExprList pel, int ctype); // forward;

void fn_return_object(Type rt, PExprList args)
{
 // Functions returning objects are passed a temporary reference; 
 // if it's an object requiring destruction, we also push the ODS!
   PExpr et = entry_op(add_temporary(rt,NULL,false));
   if (rt.as_class()->destructor()) et = make_op(FCONTEXT,rt,et,0);
   args->push_front(et);	
}

// *add 1.2.6 true return-by-value requires a different coding;
PExpr fn_return_object_as_value(Type rt, PExpr er)
{
   PExpr et = entry_op(add_temporary(rt,NULL,false));
   PExpr ret_obj = Parser::get_object_return_expr();
   Type init_rt = rt;
//   init_rt.make_reference();
//   init_rt.make_const();
   ret_obj->entry()->type = init_rt;
   ret_obj->set_type(init_rt);
   return append_op(er,                              // the function expresssion
           append_op(init_op(et,1,ret_obj,NULL,1),   // initializing the temporary
		   et,true)                                      // pushing the temporary
	   );
}

PExpr method_call(PFunction fn, PExpr obj, PExprList pel)
// note: will mess w/ pel!!
{
  Type rt = fn->return_type();
  if (!pel) pel = new ExprList;  /// empty arg list
  if (rt.is_object()) fn_return_object(rt,pel);
  pel->push_back(obj);
  return make_op(METHOD_CALL,rt,(PExpr)fn,(PExpr)pel);
}

typedef bool (TypeCheck)(Type t);

bool to_number(Type t)  { return t.is_number() ; }
bool to_pointer(Type t) { return t.is_pointer(); }

static Type mType;

bool to_specified_type(Type t)
{
  return match(mType,t) != NO_MATCH;
}   

PExpr try_convert(PExpr e, TypeCheck type_check)
{
  if (!e) return NULL;
  Type t = e->type();  
  if (type_check(t)) return e;
  if (t.is_class()) { 
    TypeList tl;
    PClass pc = t.as_class();
    if (pc->get_to_type_list(tl)) {
       TypeList::iterator tli;
       for (tli = tl.begin(); tli != tl.end(); ++tli)
         if (type_check(*tli)) { 
           PFunction pf = pc->get_conversion_to(*tli);
           return method_call(pf,e,NULL);
         }
     }
   }
   return NULL;
}

PExpr try_convert_to(PExpr e, Type t)
{
   mType = t;
   return try_convert(e,to_specified_type);
}

bool is_assign_op(int op)  // note: dependent on these values being continguous.
{
 return op >= ASSIGN && op <= XOR_A;
}

bool is_object(PExpr e)
// note: Type::is_object() fails for class _references_.
// Not sure if that is sensible, but here goes...
{ 
 if (e==NULL) return false;
 Type t = e->type();
 return t.is_class() && !t.is_pointer();
}

string type_as_str(PExpr e)
{
  return as_str(e->type());
}

PExpr cannot_convert_error(PExpr e1, PExpr e2)
{
 return expr_error("cannot convert " + type_as_str(e2) + " to " + type_as_str(e1));
}

PExpr bin_op(int op, PExpr e1, PExpr e2)
{
 string name = Operators::name_from_id(op);
 PEntry pe = NULL;
 bool class_args = is_object(e1) || is_object(e2);
 if (class_args) { 
   // first see if it's a method of an object
   if (is_object(e1)) pe = e1->type().as_class()->lookup(name);
   // then if it's global (or at least injected into global)
   if(!pe) pe = Parser::global().lookup(name);
   if (pe && Parser::is_class(pe->context)) { // was a method operator
     PExpr er = method_op(pe,e1,expr_list(e2));
     return er;
   }
 }
 if (pe) { // plain old operator - treat as function!  
 // *fix 1.1.0 If we can't match the bin op, pass thru and try conversions...
    PExpr efn = function_op(entry_op(pe),expr_list(e1,e2),true);
	if (efn) return efn;
 }
  
 // no entry was found, or no match possible; 
 if (is_assign_op(op)) { // *fix 0.9.6 try for assignment conversions 
   Type t = e1->type();
   PExpr ce = try_convert_to(e2,t);
   if (ce) {
     if (op == ASSIGN) return make_op(ASSIGN,t,e1,ce);
                 else  return compound_assign_op(op,e1,ce);
   } else return cannot_convert_error(e1,e2); 
 } else
 if (op != COMMA) { // try for numerical/pointer conversions
   PExpr ce1,ce2;
   ce1 = try_convert(e1,to_number);
   ce2 = try_convert(e2,to_number);
   if (!e2 && ce1) return make_op(op,ce1->type(),ce1,NULL);  // unary case!
   else if (ce1 && ce2) return arith_op(op,ce1,ce2);

   if (op == PLUS || op == MINUS) { // pointer arithmetric
     if (ce2) ce1 = try_convert(e1,to_pointer);
     if (ce1) ce2 = try_convert(e2,to_pointer);
     if (ce1 && ce2) return arith_op(op,ce1,ce2);
   }
 }
 if (class_args) {
  // *hack 0.9.7 list<> needs op== at the mo, whether or not it's used.
  // This seems arbitrary but is nicer than shoving a spurious op== into every class!
  // *add 1.2.3  Now give a more informative error message
     if (op == EQUAL) return constant_op(t_int,0);
     else return function_error(); 
 }
 else return make_op(op,e1->type(),e1,e2);
}

PExpr append_op(PExpr e1, PExpr e2, bool drop_values)
{ 
  return make_op(drop_values ? COMMA : APPEND, e1->type(),e1,e2); 
}

void set_first_object(PExpr e1)
{
   if (e1->is_entry() && e1->entry()->is_stack_relative()) {
	  // *fix 1.0.0 The first object on an auto var frame is the first one put on the ODS... 
      e1->entry()->context->first_obj(e1->entry()); 
   }
}

PExpr construct_context_op(PExpr e1, PExpr e2, int ctype)
{
 Type t;
 // default is a normal auto var, ctype==1 means a temporary
 if (ctype == 0) t = t_void; else t = t_int;

 return make_op(CCONTEXT,t,e2,e1); //*NOTE* order has switched for DOT compat!
}

PExpr dynamic_context_op(PExpr efn)
{
  return make_op(DCONTEXT,t_void,efn,NULL);
}

PExpr vector_context_op(PExpr efn, PExpr e = NULL)
{
  if (e) set_first_object(e);
  return make_op(VCONTEXT,t_void,e,efn);
}

PExpr add_const_op(Type t, int val, PExpr e)
{
 PExpr ec = constant_op(t_int,val);
 return make_op(PLUS,t,e,ec); 
}

PExpr delete_op(PExpr e1, bool is_arr)
{
// destructing the object, if necessary, and freeing the memory
// the pointer includes the VMT entry, if any, which means subtracting
// a word to get the actual alloc pointer.
// *change 1.1.0 This is handled by the builtin delete_ex, unless delete is overloaded.
 Type t = e1->type();
 t.decr_pointer();          
 PClass pc = t.is_class() ? t.as_class() : NULL;
 bool overalloc = Parser::debug.do_overalloc || (pc != NULL ? pc->has_true_VMT() : false);
 bool overloaded = Function::lookup("delete") != NULL;
 const char *delete_fn = overloaded ? "delete" : (overalloc ? "_delete_ex" : "_delete"); 
 PExpr er,ed=NULL,ez = constant_op(t_int,t.size());  
 if (pc != NULL) {
	if (pc->destructor()) {
      PEntry pe = pc->lookup(pc->destructor_name());
      ed = function_op(entry_op(pe),expr_list());

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品资源网站| 91在线观看免费视频| av在线播放一区二区三区| 欧美一个色资源| 中文字幕精品综合| 天堂一区二区在线| 91视视频在线直接观看在线看网页在线看 | 久久精品亚洲一区二区三区浴池 | 美女免费视频一区| 91亚洲永久精品| 国产色产综合色产在线视频| 视频一区二区欧美| 欧美专区在线观看一区| 中文字幕亚洲电影| 风间由美性色一区二区三区| 精品99999| 日本不卡免费在线视频| 在线观看日韩电影| 一区二区三区在线免费播放| 成人av网站在线观看免费| 精品av久久707| 奇米一区二区三区av| 欧美日韩你懂得| 香港成人在线视频| 欧美亚洲综合另类| 亚洲精品欧美激情| 91蜜桃婷婷狠狠久久综合9色| 久久久久久久综合狠狠综合| 国产在线精品视频| 欧美精品一区二区久久婷婷| 九九久久精品视频| 精品久久久久一区二区国产| 美女一区二区视频| 欧美成人a视频| 国内成+人亚洲+欧美+综合在线| 日韩三级精品电影久久久| 日本特黄久久久高潮| 欧美一级免费观看| 久久99久久精品| 久久综合久久99| 国产成人精品亚洲777人妖| 久久精品人人做人人爽97| 国产成人综合在线| 亚洲天堂久久久久久久| 色综合天天综合色综合av| 99精品一区二区三区| 亚洲人成7777| 欧美日韩一级二级| 麻豆国产欧美日韩综合精品二区 | 国产日韩三级在线| 国产成人午夜精品影院观看视频 | 亚洲午夜国产一区99re久久| 欧美日韩国产高清一区| 男男成人高潮片免费网站| 久久综合九色综合欧美亚洲| 成人福利视频网站| 亚洲精品久久久蜜桃| 色一情一乱一乱一91av| 免费观看91视频大全| 久久午夜免费电影| 在线视频欧美区| 免费一级片91| 亚洲欧洲日产国产综合网| 欧美久久久一区| 国产美女在线精品| 亚洲美女免费视频| 日韩一级大片在线观看| 成人免费视频视频| 天天色天天操综合| 亚洲国产精品黑人久久久| 色综合中文字幕| 日韩国产精品久久| 中文字幕欧美国产| 欧美伦理电影网| 成人涩涩免费视频| 久久99久久久久久久久久久| 国产精品美日韩| 欧美一区二区三区四区视频| 成人免费看视频| 亚洲成人午夜电影| 国产精品三级电影| 日韩视频免费直播| 91猫先生在线| 国产高清亚洲一区| 天堂一区二区在线| 亚洲欧美色图小说| 久久久噜噜噜久久中文字幕色伊伊| aaa国产一区| 国产一区二区调教| 亚洲国产va精品久久久不卡综合| 26uuu欧美| 欧美老女人在线| 色综合视频在线观看| 国产成人夜色高潮福利影视| 午夜亚洲国产au精品一区二区| 日韩一区日韩二区| 久久精品亚洲国产奇米99| 在线不卡一区二区| 色综合久久中文字幕综合网 | 在线观看日韩国产| www.在线成人| 国产高清在线观看免费不卡| 久久66热偷产精品| 日本成人在线视频网站| 亚洲成人动漫精品| 亚洲国产cao| 五月激情综合网| 亚洲已满18点击进入久久| 亚洲美女视频一区| 亚洲男人都懂的| 亚洲摸摸操操av| 亚洲色图欧洲色图婷婷| 中文字幕一区二区三区av| 国产精品少妇自拍| 亚洲欧美一区二区不卡| 国产精品短视频| 亚洲欧洲日韩综合一区二区| 国产精品家庭影院| 中文字幕在线一区免费| 亚洲国产激情av| 国产精品视频九色porn| 国产精品乱码久久久久久 | 日韩女优制服丝袜电影| 3atv在线一区二区三区| 欧美一区日本一区韩国一区| 欧美高清视频一二三区| 91精品国产一区二区三区蜜臀| 欧美丰满嫩嫩电影| 日韩欧美国产1| 欧美高清在线一区二区| 亚洲特级片在线| 亚洲妇女屁股眼交7| 午夜精品久久久久久| 秋霞电影一区二区| 久久99精品国产麻豆不卡| 国产久卡久卡久卡久卡视频精品| 国产精品夜夜嗨| 色综合久久综合网97色综合 | 91在线精品一区二区| 在线观看一区日韩| 欧美一区二区精品久久911| 久久综合成人精品亚洲另类欧美| 国产网红主播福利一区二区| 成人免费在线视频观看| 五月天一区二区三区| 国产在线播放一区三区四| 成人va在线观看| 欧美日韩高清影院| 国产亚洲女人久久久久毛片| 亚洲综合一区二区| 奇米影视一区二区三区| 99这里都是精品| 欧美日韩精品高清| 2020国产成人综合网| 亚洲伦理在线免费看| 美女视频第一区二区三区免费观看网站| 国产成人av福利| 欧美午夜宅男影院| 国产欧美精品一区二区色综合| 亚洲美女屁股眼交3| 国产综合久久久久影院| 在线看不卡av| 中文字幕免费观看一区| 婷婷开心激情综合| 成人免费毛片片v| 欧美成人vps| 亚洲国产wwwccc36天堂| 成人av电影在线| 精品处破学生在线二十三| 亚洲午夜精品久久久久久久久| 大胆亚洲人体视频| 欧美精品一区二区三区久久久 | 欧美熟乱第一页| 国产欧美一区二区精品仙草咪| 午夜精品福利在线| 成人激情av网| 久久色.com| 日韩国产欧美视频| 在线中文字幕不卡| 国产精品久久久久久久久晋中| 麻豆视频观看网址久久| 在线观看视频一区二区欧美日韩| 欧美国产精品久久| 国产中文字幕精品| 日韩欧美电影一区| 免费人成黄页网站在线一区二区| 欧美亚洲另类激情小说| 综合久久国产九一剧情麻豆| 国产成人免费视| 日韩午夜小视频| 日本网站在线观看一区二区三区 | 91社区在线播放| 中文字幕成人av| 国产传媒日韩欧美成人| 精品免费一区二区三区| 轻轻草成人在线| 日韩欧美国产电影| 精品一区二区日韩| 日韩三级在线观看| 日本成人中文字幕|