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

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

?? expressions.cpp

?? 這是一段游戲修改工具的源代碼.ring3功能由dephi開發,驅動是C開發.希望對大家有幫助
?? CPP
?? 第 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一区二区三区免费野_久草精品视频
9色porny自拍视频一区二区| 亚洲天堂av一区| 日本欧美在线观看| 欧美亚洲一区三区| 午夜伦欧美伦电影理论片| 欧美日韩久久久一区| 肉丝袜脚交视频一区二区| 日韩写真欧美这视频| 精品一区中文字幕| 欧美激情综合在线| 在线亚洲+欧美+日本专区| 日韩一区精品字幕| 欧美精品一区二区三区在线播放| 国产99精品视频| 亚洲精品中文字幕在线观看| 91麻豆精品久久久久蜜臀| 久久99国产精品成人| 欧美韩日一区二区三区四区| 色网综合在线观看| 麻豆精品在线视频| 欧美激情一区二区三区四区 | 理论电影国产精品| 国产日韩欧美不卡在线| 一本色道久久综合狠狠躁的推荐| 日精品一区二区| 国产情人综合久久777777| 91国在线观看| 久久国产精品色| 亚洲欧美日韩电影| 精品久久久久久久久久久久久久久| 国产v综合v亚洲欧| 日韩电影在线观看网站| 中文一区在线播放| 91精品国产色综合久久ai换脸| 国产成人免费9x9x人网站视频| 亚洲色图制服诱惑| 久久久久久久久岛国免费| 欧美探花视频资源| 成人深夜在线观看| 日韩av中文在线观看| 亚洲三级理论片| 亚洲精品在线观看视频| 欧美日韩一卡二卡| jlzzjlzz国产精品久久| 精品在线一区二区| 五月婷婷综合网| 亚洲欧洲精品天堂一级| 久久综合国产精品| 在线中文字幕一区二区| 色婷婷狠狠综合| 亚洲美女屁股眼交3| 蜜桃一区二区三区在线| 欧美日韩一区在线| 国产欧美精品一区aⅴ影院 | 成人精品鲁一区一区二区| 欧美国产一区视频在线观看| 91免费国产在线| 三级一区在线视频先锋| 久久网站热最新地址| 成人免费高清视频在线观看| 最近中文字幕一区二区三区| 欧美在线免费观看视频| 久草精品在线观看| 中文字幕免费不卡在线| 欧美探花视频资源| 国产美女精品一区二区三区| 亚洲欧美区自拍先锋| 欧美一级xxx| 97se亚洲国产综合自在线观| 五月婷婷欧美视频| 国产精品天美传媒| 91精品国产91久久综合桃花| 国产盗摄精品一区二区三区在线| 亚洲九九爱视频| 2024国产精品视频| 在线观看免费成人| 国产91丝袜在线18| 天天综合色天天综合色h| 欧美国产综合色视频| 日韩欧美你懂的| 色吧成人激情小说| 国产a视频精品免费观看| 国产亚洲综合在线| 欧美日韩一区二区欧美激情| 国产裸体歌舞团一区二区| 亚洲一二三专区| 国产丝袜在线精品| 欧美一区二区视频在线观看| 97久久精品人人爽人人爽蜜臀| 日本一不卡视频| 亚洲一级二级在线| 中文字幕视频一区二区三区久| 欧美一区二区三区免费视频| 91网站在线观看视频| 国产寡妇亲子伦一区二区| 日韩成人午夜电影| 亚洲最新在线观看| 亚洲私人黄色宅男| 国产精品天天看| 国产日产精品1区| 日韩精品一区二区三区蜜臀| 欧美日本在线播放| 日本乱人伦一区| 97精品国产露脸对白| 国产iv一区二区三区| 国产激情一区二区三区桃花岛亚洲| 蜜臀久久99精品久久久画质超高清| 亚洲主播在线播放| 亚洲自拍偷拍欧美| 亚洲成人一区在线| 亚洲最快最全在线视频| 一色桃子久久精品亚洲| 国产精品久久久久久妇女6080| 久久精品一区四区| 久久久国产精华| 久久亚洲精品国产精品紫薇| 精品噜噜噜噜久久久久久久久试看| 91麻豆精品国产91久久久使用方法 | 亚洲一区二区三区四区的| 亚洲男人的天堂av| 一区二区三区欧美视频| 亚洲网友自拍偷拍| 婷婷国产v国产偷v亚洲高清| 日韩综合在线视频| 久久99精品久久只有精品| 国产一区二区三区在线观看精品 | 欧美视频中文一区二区三区在线观看| eeuss鲁片一区二区三区在线观看| 岛国一区二区在线观看| av一区二区三区四区| 色婷婷综合久色| 欧美精品欧美精品系列| 欧美一区二区三区在线观看| 欧美成人精品3d动漫h| 国产亚洲一二三区| 亚洲女同ⅹxx女同tv| 亚洲高清免费在线| 蜜臀国产一区二区三区在线播放| 国产精品1区2区| 91网上在线视频| 欧美挠脚心视频网站| 久久青草国产手机看片福利盒子 | 久久久五月婷婷| 最近中文字幕一区二区三区| 天堂久久一区二区三区| 久久99精品一区二区三区三区| 99久久99久久精品免费看蜜桃 | 成人黄色大片在线观看| 91久久香蕉国产日韩欧美9色| 欧美疯狂做受xxxx富婆| 久久精品视频免费观看| 亚洲在线中文字幕| 精品一区二区av| 色婷婷av一区二区三区gif| 日韩久久久久久| 一区精品在线播放| 欧美96一区二区免费视频| 不卡一卡二卡三乱码免费网站| 欧美日韩免费一区二区三区视频| 久久综合九色综合97婷婷女人 | 91精品国产aⅴ一区二区| 久久九九影视网| 香蕉久久一区二区不卡无毒影院 | 欧美日韩亚洲不卡| 国产亚洲欧美日韩俺去了| 亚洲大片一区二区三区| 国产精品综合一区二区| 欧美日韩的一区二区| 欧美高清在线一区| 美女诱惑一区二区| 色噜噜狠狠一区二区三区果冻| 久久这里只有精品6| 视频精品一区二区| 日本高清不卡一区| 中文字幕的久久| 国产一区二区三区香蕉| 91精品在线观看入口| 亚洲在线观看免费视频| 99精品视频一区二区三区| 久久亚洲综合色一区二区三区| 麻豆精品在线视频| 91精品福利在线一区二区三区 | 亚洲精品成人悠悠色影视| 国产综合色产在线精品| 日韩一区二区在线看| 亚洲综合久久久| 欧洲一区二区三区在线| ...xxx性欧美| www.欧美日韩| 久久久久青草大香线综合精品| 久久精品国产精品亚洲综合| 制服丝袜中文字幕亚洲| 午夜久久久久久| 欧美天天综合网| 婷婷中文字幕一区三区| 欧美性色欧美a在线播放| 一区二区三区在线观看动漫| 一本色道久久综合亚洲aⅴ蜜桃| 亚洲摸摸操操av| 日本久久精品电影|