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

📄 astnodes.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
      type = TypeReqUInt;
      operand = OP_BITAND;
      break;
   case '^':
      type = TypeReqUInt;
      operand = OP_XOR;
      break;
   case '|':
      type = TypeReqUInt;
      operand = OP_BITOR;
      break;
   case opSHL:
      type = TypeReqUInt;
      operand = OP_SHL;
      break;
   case opSHR:
      type = TypeReqUInt;
      operand = OP_SHR;
      break;
   }   
}

U32 AssignOpExprNode::precompile(TypeReq type)
{
   // goes like this...
   // eval expr as float or int
   // if there's an arrayIndex

   // OP_LOADIMMED_IDENT
   // varName
   // OP_ADVANCE_STR
   // eval arrayIndex stringwise
   // OP_REWIND_STR
   // OP_SETCURVAR_ARRAY_CREATE

   // else
   // OP_SETCURVAR_CREATE
   // varName

   // OP_LOADVAR_FLT or UINT
   // operand
   // OP_SAVEVAR_FLT or UINT

   // conversion OP if necessary.
   getAssignOpTypeOp(op, subType, operand);
   precompileIdent(varName);
   U32 size = expr->precompile(subType);
   if(type != subType)
      size++;
   if(!arrayIndex)
      return size + 5;
   else
   {
      size += arrayIndex->precompile(TypeReqString);
      return size + 8;
   }
}

U32 AssignOpExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   ip = expr->compile(codeStream, ip, subType);
   if(!arrayIndex)
   {
      codeStream[ip++] = OP_SETCURVAR_CREATE;
      codeStream[ip] = STEtoU32(varName, ip);
      ip++;
   }
   else
   {
      codeStream[ip++] = OP_LOADIMMED_IDENT;
      codeStream[ip] = STEtoU32(varName, ip);
      ip++;
      codeStream[ip++] = OP_ADVANCE_STR;
      ip = arrayIndex->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_REWIND_STR;
      codeStream[ip++] = OP_SETCURVAR_ARRAY_CREATE;
   }
   codeStream[ip++] = (subType == TypeReqFloat) ? OP_LOADVAR_FLT : OP_LOADVAR_UINT;
   codeStream[ip++] = operand;
   codeStream[ip++] = (subType == TypeReqFloat) ? OP_SAVEVAR_FLT : OP_SAVEVAR_UINT;
   if(subType != type)
      codeStream[ip++] = conversionOp(subType, type);
   return ip;
}

TypeReq AssignOpExprNode::getPreferredType()
{
   getAssignOpTypeOp(op, subType, operand);
   return subType;
}

//------------------------------------------------------------

U32 TTagSetStmtNode::precompileStmt(U32 loopCount)
{
   loopCount;
   return 0;
}

U32 TTagSetStmtNode::compileStmt(U32*, U32 ip, U32, U32)
{
   return ip;
}

//------------------------------------------------------------

U32 TTagDerefNode::precompile(TypeReq)
{
   return 0;
}

U32 TTagDerefNode::compile(U32*, U32 ip, TypeReq)
{
   return ip;
}

TypeReq TTagDerefNode::getPreferredType()
{
   return TypeReqNone;
}

//------------------------------------------------------------

U32 TTagExprNode::precompile(TypeReq)
{
   return 0;
}

U32 TTagExprNode::compile(U32*, U32 ip, TypeReq)
{
   return ip;
}

TypeReq TTagExprNode::getPreferredType()
{
   return TypeReqNone;
}

//------------------------------------------------------------

U32 FuncCallExprNode::precompile(TypeReq type)
{
   // OP_PUSH_FRAME
   // arg OP_PUSH arg OP_PUSH arg OP_PUSH
   // eval all the args, then call the function.

   // OP_CALLFUNC
   // function
   // namespace
   // isDot

   U32 size = 0;
   if(type != TypeReqString)
      size++;
   precompileIdent(funcName);
   precompileIdent(nameSpace);
   for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext())
      size += walk->precompile(TypeReqString) + 1;
   return size + 5;
}

U32 FuncCallExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   codeStream[ip++] = OP_PUSH_FRAME;
   for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext())
   {
      ip = walk->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_PUSH;
   }
   if(callType == MethodCall || callType == ParentCall)
      codeStream[ip++] = OP_CALLFUNC;
   else
      codeStream[ip++] = OP_CALLFUNC_RESOLVE;

   codeStream[ip] = STEtoU32(funcName, ip);
   ip++;
   codeStream[ip] = STEtoU32(nameSpace, ip);
   ip++;
   codeStream[ip++] = callType;
   if(type != TypeReqString)
      codeStream[ip++] = conversionOp(TypeReqString, type);
   return ip;
}

TypeReq FuncCallExprNode::getPreferredType()
{
   return TypeReqString;
}

//------------------------------------------------------------

U32 SlotAccessNode::precompile(TypeReq type)
{
   if(type == TypeReqNone)
      return 0;
   U32 size = 0;
   precompileIdent(slotName);
   if(arrayExpr)
   {
      // eval array
      // OP_ADVANCE_STR
      // evaluate object expression sub (OP_SETCURFIELD)
      // OP_TERMINATE_REWIND_STR
      // OP_SETCURFIELDARRAY
      // total add of 4 + array precomp
      size += 3 + arrayExpr->precompile(TypeReqString);
   }
   // eval object expression sub + 3 (op_setCurField + OP_SETCUROBJECT)
   size += objectExpr->precompile(TypeReqString) + 3;

   // get field in desired type:
   return size + 1;
}

U32 SlotAccessNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   if(type == TypeReqNone)
      return ip;

   if(arrayExpr)
   {
      ip = arrayExpr->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_ADVANCE_STR;
   }
   ip = objectExpr->compile(codeStream, ip, TypeReqString);
   codeStream[ip++] = OP_SETCUROBJECT;
   codeStream[ip++] = OP_SETCURFIELD;
   codeStream[ip] = STEtoU32(slotName, ip);
   ip++;
   if(arrayExpr)
   {
      codeStream[ip++] = OP_TERMINATE_REWIND_STR;
      codeStream[ip++] = OP_SETCURFIELD_ARRAY;
   }
   switch(type)
   {
   case TypeReqUInt:
      codeStream[ip++] = OP_LOADFIELD_UINT;
      break;
   case TypeReqFloat:
      codeStream[ip++] = OP_LOADFIELD_FLT;
      break;
   case TypeReqString:
      codeStream[ip++] = OP_LOADFIELD_STR;
      break;
   }
   return ip;
}

TypeReq SlotAccessNode::getPreferredType()
{
   return TypeReqNone;
}

//------------------------------------------------------------

U32 SlotAssignNode::precompile(TypeReq type)
{
   // first eval the expression TypeReqString

   // if it's an array:

   // if OP_ADVANCE_STR 1
   // eval array

   // OP_ADVANCE_STR 1
   // evaluate object expr
   // OP_SETCUROBJECT 1
   // OP_SETCURFIELD 1
   // fieldName 1
   // OP_TERMINATE_REWIND_STR 1

   // OP_SETCURFIELDARRAY 1
   // OP_TERMINATE_REWIND_STR 1

   // else
   // OP_ADVANCE_STR
   // evaluate object expr
   // OP_SETCUROBJECT
   // OP_SETCURFIELD
   // fieldName
   // OP_TERMINATE_REWIND_STR

   // OP_SAVEFIELD
   // convert to return type if necessary.

   U32 size = 0;
   if(type != TypeReqString)
      size++;

   precompileIdent(slotName);

   size += valueExpr->precompile(TypeReqString);

   if(objectExpr)
      size += objectExpr->precompile(TypeReqString) + 5;
   else
      size += 5;

   if(arrayExpr)
      size += arrayExpr->precompile(TypeReqString) + 3;
   return size + 1;
}

U32 SlotAssignNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   ip = valueExpr->compile(codeStream, ip, TypeReqString);
   codeStream[ip++] = OP_ADVANCE_STR;
   if(arrayExpr)
   {
      ip = arrayExpr->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_ADVANCE_STR;
   }
   if(objectExpr)
   {
      ip = objectExpr->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_SETCUROBJECT;
   }
   else
      codeStream[ip++] = OP_SETCUROBJECT_NEW;
   codeStream[ip++] = OP_SETCURFIELD;
   codeStream[ip] = STEtoU32(slotName, ip);
   ip++;
   if(arrayExpr)
   {
      codeStream[ip++] = OP_TERMINATE_REWIND_STR;
      codeStream[ip++] = OP_SETCURFIELD_ARRAY;
   }
   codeStream[ip++] = OP_TERMINATE_REWIND_STR;
   codeStream[ip++] = OP_SAVEFIELD_STR;
   if(type != TypeReqString)
      codeStream[ip++] = conversionOp(TypeReqString, type);
   return ip;
}

TypeReq SlotAssignNode::getPreferredType()
{
   return TypeReqString;
}

//------------------------------------------------------------

U32 SlotAssignOpNode::precompile(TypeReq type)
{
   // first eval the expression as its type

   // if it's an array:
   // eval array
   // OP_ADVANCE_STR
   // evaluate object expr
   // OP_SETCUROBJECT
   // OP_SETCURFIELD
   // fieldName
   // OP_TERMINATE_REWIND_STR
   // OP_SETCURFIELDARRAY

   // else
   // evaluate object expr
   // OP_SETCUROBJECT
   // OP_SETCURFIELD
   // fieldName

   // OP_LOADFIELD of appropriate type
   // operand
   // OP_SAVEFIELD of appropriate type
   // convert to return type if necessary.

   getAssignOpTypeOp(op, subType, operand);
   precompileIdent(slotName);
   U32 size = valueExpr->precompile(subType);
   if(type != subType)
      size++;
   if(arrayExpr)
      return size + 9 + arrayExpr->precompile(TypeReqString) + objectExpr->precompile(TypeReqString);
   else
      return size + 6 + objectExpr->precompile(TypeReqString);
}

U32 SlotAssignOpNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   ip = valueExpr->compile(codeStream, ip, subType);
   if(arrayExpr)
   {
      ip = arrayExpr->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_ADVANCE_STR;
   }
   ip = objectExpr->compile(codeStream, ip, TypeReqString);
   codeStream[ip++] = OP_SETCUROBJECT;
   codeStream[ip++] = OP_SETCURFIELD;
   codeStream[ip] = STEtoU32(slotName, ip);
   ip++;
   if(arrayExpr)
   {
      codeStream[ip++] = OP_TERMINATE_REWIND_STR;
      codeStream[ip++] = OP_SETCURFIELD_ARRAY;
   }
   codeStream[ip++] = (subType == TypeReqFloat) ? OP_LOADFIELD_FLT : OP_LOADFIELD_UINT;
   codeStream[ip++] = operand;
   codeStream[ip++] = (subType == TypeReqFloat) ? OP_SAVEFIELD_FLT : OP_SAVEFIELD_UINT;
   if(subType != type)
      codeStream[ip++] = conversionOp(subType, type);
   return ip;
}

TypeReq SlotAssignOpNode::getPreferredType()
{
   getAssignOpTypeOp(op, subType, operand);
   return subType;
}

//------------------------------------------------------------

U32 ObjectDeclNode::precompileSubObject(bool)
{
   // goes

   // OP_PUSHFRAME 1
   // name expr
   // OP_PUSH 1
   // args... PUSH
   // OP_CREATE_OBJECT 1
   // className 1
   // datablock? 1
   // fail point 1

   // for each field, eval
   // OP_ADD_OBJECT (to UINT[0]) 1
   // root? 1

   // add all the sub objects.
   // OP_END_OBJECT 1
   // root? 1

   U32 argSize = 0;
   precompileIdent(parentObject);
   for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext())
      argSize += exprWalk->precompile(TypeReqString) + 1;
   argSize += classNameExpr->precompile(TypeReqString) + 1;

   U32 nameSize = objectNameExpr->precompile(TypeReqString);

   U32 slotSize = 0;
   for(SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *) slotWalk->getNext())
      slotSize += slotWalk->precompile(TypeReqNone);

   // OP_ADD_OBJECT
   U32 subObjSize = 0;
   for(ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *) objectWalk->getNext())
      subObjSize += objectWalk->precompileSubObject(false);

   failOffset = 10 + nameSize + argSize + slotSize + subObjSize;
   return failOffset;
}

U32 ObjectDeclNode::precompile(TypeReq type)
{
   // root object decl does:

   // push 0 onto the UINT stack OP_LOADIMMED_UINT
   // precompiles the subObject(true)
   // UINT stack now has object id
   // type conv to type

   U32 ret = 2 + precompileSubObject(true);
   if(type != TypeReqUInt)
      return ret + 1;
   return ret;
}

U32 ObjectDeclNode::compileSubObject(U32 *codeStream, U32 ip, bool root)
{
   U32 start = ip;
   codeStream[ip++] = OP_PUSH_FRAME;
   ip = classNameExpr->compile(codeStream, ip, TypeReqString);
   codeStream[ip++] = OP_PUSH;

   ip = objectNameExpr->compile(codeStream, ip, TypeReqString);
   codeStream[ip++] = OP_PUSH;
   for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext())
   {
      ip = exprWalk->compile(codeStream, ip, TypeReqString);
      codeStream[ip++] = OP_PUSH;
   }
   codeStream[ip++] = OP_CREATE_OBJECT;
   codeStream[ip] = STEtoU32(parentObject, ip);
   ip++;
   codeStream[ip++] = structDecl;
   codeStream[ip++] = start + failOffset;
   for(SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *) slotWalk->getNext())
      ip = slotWalk->compile(codeStream, ip, TypeReqNone);
   codeStream[ip++] = OP_ADD_OBJECT;
   codeStream[ip++] = root;
   for(ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *) objectWalk->getNext())
      ip = objectWalk->compileSubObject(codeStream, ip, false);
   codeStream[ip++] = OP_END_OBJECT;
   codeStream[ip++] = root || structDecl;
   return ip;
}

U32 ObjectDeclNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
   codeStream[ip++] = OP_LOADIMMED_UINT;
   codeStream[ip++] = 0;
   ip = compileSubObject(codeStream, ip, true);
   if(type != TypeReqUInt)
      codeStream[ip++] = conversionOp(TypeReqUInt, type);
   return ip;
}   
TypeReq ObjectDeclNode::getPreferredType()
{
   return TypeReqUInt;
}

//------------------------------------------------------------

U32 FunctionDeclStmtNode::precompileStmt(U32)
{
   // OP_FUNC_DECL
   // func name
   // namespace
   // package
   // func end ip
   // argc
   // ident array[argc]
   // code
   // OP_RETURN
   setCurrentStringTable(&getFunctionStringTable());
   setCurrentFloatTable(&getFunctionFloatTable());

#ifdef TGE_RPG
   
   CodeBlock::smInFunction = true;
   precompileIdent(fnName);
   precompileIdent(nameSpace);
   precompileIdent(package);

   argc = 0;
   for(VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext())
	{   
		argc++;
		//这里需要把形参注册,以便 V""格式能正常访问
		walk->precompile(TypeReqString);
	}
   
#else
   argc = 0;
   for(VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext())
      argc++;
   
   CodeBlock::smInFunction = true;
   
   precompileIdent(fnName);
   precompileIdent(nameSpace);
   precompileIdent(package);
#endif

   U32 subSize = precompileBlock(stmts, 0);
   
   #ifdef TORQUE_EXTRA_BREAKLINES      
      addBreakCount();   
   #endif

   CodeBlock::smInFunction = false;

   setCurrentStringTable(&getGlobalStringTable());
   setCurrentFloatTable(&getGlobalFloatTable());

   endOffset = argc + subSize + 8;
   return endOffset;
}

U32 FunctionDeclStmtNode::compileStmt(U32 *codeStream, U32 ip, U32, U32)
{
   U32 start = ip;
   codeStream[ip++] = OP_FUNC_DECL;
   codeStream[ip] = STEtoU32(fnName, ip);
   ip++;
   codeStream[ip] = STEtoU32(nameSpace, ip);
   ip++;
   codeStream[ip] = STEtoU32(package, ip);
   ip++;
   codeStream[ip++] = bool(stmts != NULL);
   codeStream[ip++] = start + endOffset;
   codeStream[ip++] = argc;
   for(VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext())
   {
      codeStream[ip] = STEtoU32(walk->varName, ip);
      ip++;
   }
   CodeBlock::smInFunction = true;
   ip = compileBlock(stmts, codeStream, ip, 0, 0);

   #ifdef TORQUE_EXTRA_BREAKLINES      
      addBreakLine(ip);   
   #endif

   CodeBlock::smInFunction = false;
   codeStream[ip++] = OP_RETURN;
   return ip;
}

⌨️ 快捷键说明

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