📄 astnodes.cc
字号:
}
TypeReq IntBinaryExprNode::getPreferredType()
{
return TypeReqUInt;
}
//------------------------------------------------------------
U32 StreqExprNode::precompile(TypeReq type)
{
// eval str left
// OP_ADVANCE_STR_NUL
// eval str right
// OP_COMPARE_STR
// optional conversion
U32 addSize = left->precompile(TypeReqString) + right->precompile(TypeReqString) + 2;
if(!eq)
addSize ++;
if(type != TypeReqUInt)
addSize ++;
return addSize;
}
U32 StreqExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = left->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_ADVANCE_STR_NUL;
ip = right->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_COMPARE_STR;
if(!eq)
codeStream[ip++] = OP_NOT;
if(type != TypeReqUInt)
codeStream[ip++] = conversionOp(TypeReqUInt, type);
return ip;
}
TypeReq StreqExprNode::getPreferredType()
{
return TypeReqUInt;
}
//------------------------------------------------------------
U32 StrcatExprNode::precompile(TypeReq type)
{
U32 addSize = left->precompile(TypeReqString) + right->precompile(TypeReqString) + 2;
if(appendChar)
addSize++;
if(type != TypeReqString)
addSize ++;
return addSize;
}
U32 StrcatExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = left->compile(codeStream, ip, TypeReqString);
if(!appendChar)
codeStream[ip++] = OP_ADVANCE_STR;
else
{
codeStream[ip++] = OP_ADVANCE_STR_APPENDCHAR;
codeStream[ip++] = appendChar;
}
ip = right->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_REWIND_STR;
if(type == TypeReqUInt)
codeStream[ip++] = OP_STR_TO_UINT;
else if(type == TypeReqFloat)
codeStream[ip++] = OP_STR_TO_FLT;
return ip;
}
TypeReq StrcatExprNode::getPreferredType()
{
return TypeReqString;
}
//------------------------------------------------------------
U32 CommaCatExprNode::precompile(TypeReq type)
{
U32 addSize = left->precompile(TypeReqString) + right->precompile(TypeReqString) + 2;
if(type != TypeReqString)
addSize ++;
return addSize;
}
U32 CommaCatExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = left->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_ADVANCE_STR_COMMA;
ip = right->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_REWIND_STR;
// At this point the stack has the concatenated string.
// But we're paranoid, so accept (but whine) if we get an oddity...
if(type == TypeReqUInt || type == TypeReqFloat)
Con::warnf(ConsoleLogEntry::General, "%s (%d): converting comma string to a number... probably wrong.", dbgFileName, dbgLineNumber);
if(type == TypeReqUInt)
codeStream[ip++] = OP_STR_TO_UINT;
else if(type == TypeReqFloat)
codeStream[ip++] = OP_STR_TO_FLT;
return ip;
}
TypeReq CommaCatExprNode::getPreferredType()
{
return TypeReqString;
}
//------------------------------------------------------------
U32 IntUnaryExprNode::precompile(TypeReq type)
{
integer = true;
TypeReq prefType = expr->getPreferredType();
if(op == '!' && prefType == TypeReqFloat || prefType == TypeReqString)
integer = false;
U32 exprSize = expr->precompile(integer ? TypeReqUInt : TypeReqFloat);
if(type != TypeReqUInt)
return exprSize + 2;
else
return exprSize + 1;
}
U32 IntUnaryExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = expr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat);
if(op == '!')
codeStream[ip++] = integer ? OP_NOT : OP_NOTF;
else if(op == '~')
codeStream[ip++] = OP_ONESCOMPLEMENT;
if(type != TypeReqUInt)
codeStream[ip++] =conversionOp(TypeReqUInt, type);
return ip;
}
TypeReq IntUnaryExprNode::getPreferredType()
{
return TypeReqUInt;
}
//------------------------------------------------------------
U32 FloatUnaryExprNode::precompile(TypeReq type)
{
U32 exprSize = expr->precompile(TypeReqFloat);
if(type != TypeReqFloat)
return exprSize + 2;
else
return exprSize + 1;
}
U32 FloatUnaryExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = expr->compile(codeStream, ip, TypeReqFloat);
codeStream[ip++] = OP_NEG;
if(type != TypeReqFloat)
codeStream[ip++] =conversionOp(TypeReqFloat, type);
return ip;
}
TypeReq FloatUnaryExprNode::getPreferredType()
{
return TypeReqFloat;
}
//------------------------------------------------------------
U32 VarNode::precompile(TypeReq type)
{
// if this has an arrayIndex...
// OP_LOADIMMED_IDENT
// varName
// OP_ADVANCE_STR
// evaluate arrayIndex TypeReqString
// OP_REWIND_STR
// OP_SETCURVAR_ARRAY
// OP_LOADVAR (type)
// else
// OP_SETCURVAR
// varName
// OP_LOADVAR (type)
if(type == TypeReqNone)
return 0;
precompileIdent(varName);
if(arrayIndex)
return arrayIndex->precompile(TypeReqString) + 6;
else
return 3;
}
U32 VarNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
if(type == TypeReqNone)
return ip;
codeStream[ip++] = arrayIndex ? OP_LOADIMMED_IDENT : OP_SETCURVAR;
codeStream[ip] = STEtoU32(varName, ip);
ip++;
if(arrayIndex)
{
codeStream[ip++] = OP_ADVANCE_STR;
ip = arrayIndex->compile(codeStream, ip, TypeReqString);
codeStream[ip++] = OP_REWIND_STR;
codeStream[ip++] = OP_SETCURVAR_ARRAY;
}
switch(type)
{
case TypeReqUInt:
codeStream[ip++] = OP_LOADVAR_UINT;
break;
case TypeReqFloat:
codeStream[ip++] = OP_LOADVAR_FLT;
break;
case TypeReqString:
codeStream[ip++] = OP_LOADVAR_STR;
break;
}
return ip;
}
TypeReq VarNode::getPreferredType()
{
return TypeReqNone; // no preferred type
}
//------------------------------------------------------------
U32 IntNode::precompile(TypeReq type)
{
if(type == TypeReqNone)
return 0;
if(type == TypeReqString)
index = getCurrentStringTable()->addIntString(value);
else if(type == TypeReqFloat)
index = getCurrentFloatTable()->add(value);
return 2;
}
U32 IntNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
switch(type)
{
case TypeReqUInt:
codeStream[ip++] = OP_LOADIMMED_UINT;
codeStream[ip++] = value;
break;
case TypeReqString:
codeStream[ip++] = OP_LOADIMMED_STR;
codeStream[ip++] = index;
break;
case TypeReqFloat:
codeStream[ip++] = OP_LOADIMMED_FLT;
codeStream[ip++] = index;
break;
}
return ip;
}
TypeReq IntNode::getPreferredType()
{
return TypeReqUInt;
}
//------------------------------------------------------------
U32 FloatNode::precompile(TypeReq type)
{
if(type == TypeReqNone)
return 0;
if(type == TypeReqString)
index = getCurrentStringTable()->addFloatString(value);
else if(type == TypeReqFloat)
index = getCurrentFloatTable()->add(value);
return 2;
}
U32 FloatNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
switch(type)
{
case TypeReqUInt:
codeStream[ip++] = OP_LOADIMMED_UINT;
codeStream[ip++] = U32(value);
break;
case TypeReqString:
codeStream[ip++] = OP_LOADIMMED_STR;
codeStream[ip++] = index;
break;
case TypeReqFloat:
codeStream[ip++] = OP_LOADIMMED_FLT;
codeStream[ip++] = index;
break;
}
return ip;
}
TypeReq FloatNode::getPreferredType()
{
return TypeReqFloat;
}
//------------------------------------------------------------
U32 StrConstNode::precompile(TypeReq type)
{
if(type == TypeReqString)
{
#ifdef TGE_RPG_SCRIPT
index = getCurrentStringTable()->add(str, true, uType==T_TAG);
#else
index = getCurrentStringTable()->add(str, true, tag);
#endif
return 2;
}
else if(type == TypeReqNone)
return 0;
fVal = consoleStringToNumber(str, dbgFileName, dbgLineNumber);
if(type == TypeReqFloat)
index = getCurrentFloatTable()->add(fVal);
return 2;
}
U32 StrConstNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
#ifdef TGE_RPG_SCRIPT
switch(type)
{
case TypeReqString:
codeStream[ip++] = (uType==T_TAG) ? OP_TAG_TO_STR : (uType==T_STRING) ?OP_LOADIMMED_STR : OP_LOAD_VSTRING;
codeStream[ip++] = index;
break;
case TypeReqUInt:
if(uType==T_VSTRING)
{
codeStream[ip++] = OP_LOAD_VSTRING;
codeStream[ip++] = OP_STR_TO_UINT;
}
else
{
codeStream[ip++] = OP_LOADIMMED_UINT;
codeStream[ip++] = U32(fVal);
}
break;
case TypeReqFloat:
if(uType==T_VSTRING)
{
codeStream[ip++] = OP_LOAD_VSTRING;
codeStream[ip++] = OP_STR_TO_FLT;
}
else
{
codeStream[ip++] = OP_LOADIMMED_FLT;
codeStream[ip++] = index;
}
break;
}
#else
switch(type)
{
case TypeReqString:
codeStream[ip++] = tag ? OP_TAG_TO_STR : OP_LOADIMMED_STR;
codeStream[ip++] = index;
break;
case TypeReqUInt:
codeStream[ip++] = OP_LOADIMMED_UINT;
codeStream[ip++] = U32(fVal);
break;
case TypeReqFloat:
codeStream[ip++] = OP_LOADIMMED_FLT;
codeStream[ip++] = index;
break;
}
#endif
return ip;
}
TypeReq StrConstNode::getPreferredType()
{
return TypeReqString;
}
//------------------------------------------------------------
U32 ConstantNode::precompile(TypeReq type)
{
//#ifdef TGE_RPG_SCRIPT
// if(m_uType == T_VARLOAD)
// {
// // OP_SETCURVAR
// // varName
// // OP_LOADVAR (type)
// if(type == TypeReqNone)
// return 0;
//
// precompileIdent(value);
// return 3;
// }
//#endif
if(type == TypeReqString)
{
precompileIdent(value);
return 2;
}
else if(type == TypeReqNone)
return 0;
fVal = consoleStringToNumber(value, dbgFileName, dbgLineNumber);
if(type == TypeReqFloat)
index = getCurrentFloatTable()->add(fVal);
return 2;
}
U32 ConstantNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
//#ifdef TGE_RPG_SCRIPT
// if(m_uType == T_VARLOAD)
// {
// if(type == TypeReqNone)
// return ip;
// codeStream[ip++] = OP_SETCURVAR;
// //codeStream[ip++] = OP_LOADIMMED_IDENT;
// codeStream[ip] = STEtoU32(value, ip);
// ip++;
//
// switch(type)
// {
// case TypeReqUInt:
// codeStream[ip++] = OP_LOADVAR_UINT;
// break;
// case TypeReqFloat:
// codeStream[ip++] = OP_LOADVAR_FLT;
// break;
// case TypeReqString:
// codeStream[ip++] = OP_LOADVAR_STR;
// break;
// }
// return ip;
// }
//#endif
switch(type)
{
case TypeReqString:
codeStream[ip++] = OP_LOADIMMED_IDENT;
codeStream[ip] = STEtoU32(value, ip);
ip++;
break;
case TypeReqUInt:
codeStream[ip++] = OP_LOADIMMED_UINT;
codeStream[ip++] = U32(fVal);
break;
case TypeReqFloat:
codeStream[ip++] = OP_LOADIMMED_FLT;
codeStream[ip++] = index;
break;
}
return ip;
}
TypeReq ConstantNode::getPreferredType()
{
//#ifdef TGE_RPG_SCRIPT
// if(m_uType == T_CONSTANT)
// return TypeReqString;
// return TypeReqNone; // no preferred type
//#else
return TypeReqString;
//#endif
}
//------------------------------------------------------------
U32 AssignExprNode::precompile(TypeReq type)
{
subType = expr->getPreferredType();
if(subType == TypeReqNone)
subType = type;
if(subType == TypeReqNone)
subType = TypeReqString;
// if it's an array expr, the formula is:
// eval expr
// (push and pop if it's TypeReqString) OP_ADVANCE_STR
// OP_LOADIMMED_IDENT
// varName
// OP_ADVANCE_STR
// eval array
// OP_REWIND_STR
// OP_SETCURVAR_ARRAY_CREATE
// OP_TERMINATE_REWIND_STR
// OP_SAVEVAR
//else
// eval expr
// OP_SETCURVAR_CREATE
// varname
// OP_SAVEVAR
U32 addSize = 0;
if(type != subType)
addSize = 1;
U32 retSize = expr->precompile(subType);
precompileIdent(varName);
if(arrayIndex)
{
if(subType == TypeReqString)
return arrayIndex->precompile(TypeReqString) + retSize + addSize + 8;
else
return arrayIndex->precompile(TypeReqString) + retSize + addSize + 6;
}
else
return retSize + addSize + 3;
}
U32 AssignExprNode::compile(U32 *codeStream, U32 ip, TypeReq type)
{
ip = expr->compile(codeStream, ip, subType);
if(arrayIndex)
{
if(subType == TypeReqString)
codeStream[ip++] = OP_ADVANCE_STR;
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;
if(subType == TypeReqString)
codeStream[ip++] = OP_TERMINATE_REWIND_STR;
}
else
{
codeStream[ip++] = OP_SETCURVAR_CREATE;
codeStream[ip] = STEtoU32(varName, ip);
ip++;
}
switch(subType)
{
case TypeReqString:
codeStream[ip++] = OP_SAVEVAR_STR;
break;
case TypeReqUInt:
codeStream[ip++] = OP_SAVEVAR_UINT;
break;
case TypeReqFloat:
codeStream[ip++] = OP_SAVEVAR_FLT;
break;
}
if(type != subType)
codeStream[ip++] = conversionOp(subType, type);
return ip;
}
TypeReq AssignExprNode::getPreferredType()
{
return expr->getPreferredType();
}
//------------------------------------------------------------
static void getAssignOpTypeOp(S32 op, TypeReq &type, U32 &operand)
{
switch(op)
{
case '+':
type = TypeReqFloat;
operand = OP_ADD;
break;
case '-':
type = TypeReqFloat;
operand = OP_SUB;
break;
case '*':
type = TypeReqFloat;
operand = OP_MUL;
break;
case '/':
type = TypeReqFloat;
operand = OP_DIV;
break;
case '%':
type = TypeReqUInt;
operand = OP_MOD;
break;
case '&':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -