📄 astnodes.cc
字号:
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 + -