mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-03-21 18:31:10 +00:00
add foreach k,v loop for maps
* make FxFunctionCall and FxMemberFunctionCall take a temporary for args, since they always move it * fix type for cast
This commit is contained in:
parent
d2867841b1
commit
c58bd6efb5
9 changed files with 230 additions and 20 deletions
|
@ -2728,7 +2728,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
{
|
||||
FArgumentList args;
|
||||
args.Push(Right);
|
||||
auto call = new FxMemberFunctionCall(Base, NAME_Copy, args, ScriptPosition);
|
||||
auto call = new FxMemberFunctionCall(Base, NAME_Copy, std::move(args), ScriptPosition);
|
||||
Right = Base = nullptr;
|
||||
delete this;
|
||||
return call->Resolve(ctx);
|
||||
|
@ -2756,7 +2756,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
{
|
||||
FArgumentList args;
|
||||
args.Push(Right);
|
||||
auto call = new FxMemberFunctionCall(Base, NAME_Copy, args, ScriptPosition);
|
||||
auto call = new FxMemberFunctionCall(Base, NAME_Copy, std::move(args), ScriptPosition);
|
||||
Right = Base = nullptr;
|
||||
delete this;
|
||||
return call->Resolve(ctx);
|
||||
|
@ -8202,7 +8202,7 @@ static bool CheckFunctionCompatiblity(FScriptPosition &ScriptPosition, PFunction
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &args, const FScriptPosition &pos)
|
||||
FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &&args, const FScriptPosition &pos)
|
||||
: FxExpression(EFX_FunctionCall, pos)
|
||||
{
|
||||
MethodName = methodname;
|
||||
|
@ -8629,7 +8629,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxMemberFunctionCall::FxMemberFunctionCall(FxExpression *self, FName methodname, FArgumentList &args, const FScriptPosition &pos)
|
||||
FxMemberFunctionCall::FxMemberFunctionCall(FxExpression *self, FName methodname, FArgumentList &&args, const FScriptPosition &pos)
|
||||
: FxExpression(EFX_MemberFunctionCall, pos)
|
||||
{
|
||||
Self = self;
|
||||
|
@ -9174,7 +9174,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (a->IsMap())
|
||||
{
|
||||
// Copy and Move must turn their parameter into a pointer to the backing struct type.
|
||||
auto o = static_cast<PMapIterator*>(a->ValueType);
|
||||
auto o = static_cast<PMap*>(a->ValueType);
|
||||
auto backingtype = o->BackingType;
|
||||
if (mapKeyType != o->KeyType || mapValueType != o->ValueType)
|
||||
{
|
||||
|
@ -11416,9 +11416,9 @@ FxExpression* FxForEachLoop::DoResolve(FCompileContext& ctx)
|
|||
|
||||
FName sizevar = "@size";
|
||||
FName itvar = "@i";
|
||||
FArgumentList al;
|
||||
|
||||
auto block = new FxCompoundStatement(ScriptPosition);
|
||||
auto arraysize = new FxMemberFunctionCall(Array, NAME_Size, al, ScriptPosition);
|
||||
auto arraysize = new FxMemberFunctionCall(Array, NAME_Size, {}, ScriptPosition);
|
||||
auto size = new FxLocalVariableDeclaration(TypeSInt32, sizevar, arraysize, 0, ScriptPosition);
|
||||
auto it = new FxLocalVariableDeclaration(TypeSInt32, itvar, new FxConstant(0, ScriptPosition), 0, ScriptPosition);
|
||||
block->Add(size);
|
||||
|
@ -11446,6 +11446,130 @@ FxExpression* FxForEachLoop::DoResolve(FCompileContext& ctx)
|
|||
return block->Resolve(ctx);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxMapForEachLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxMapForEachLoop::FxMapForEachLoop(FName kv, FName vv, FxExpression* mapexpr, FxExpression* mapexpr2, FxExpression* mapexpr3, FxExpression* mapexpr4, FxExpression* code, const FScriptPosition& pos)
|
||||
: FxExpression(EFX_MapForEachLoop,pos), keyVarName(kv), valueVarName(vv), MapExpr(mapexpr), MapExpr2(mapexpr2), MapExpr3(mapexpr3), MapExpr4(mapexpr4), Code(code)
|
||||
{
|
||||
ValueType = TypeVoid;
|
||||
if (MapExpr != nullptr) MapExpr->NeedResult = false;
|
||||
if (MapExpr2 != nullptr) MapExpr2->NeedResult = false;
|
||||
if (MapExpr3 != nullptr) MapExpr3->NeedResult = false;
|
||||
if (MapExpr4 != nullptr) MapExpr4->NeedResult = false;
|
||||
if (Code != nullptr) Code->NeedResult = false;
|
||||
}
|
||||
|
||||
FxMapForEachLoop::~FxMapForEachLoop()
|
||||
{
|
||||
SAFE_DELETE(MapExpr);
|
||||
SAFE_DELETE(MapExpr2);
|
||||
SAFE_DELETE(MapExpr3);
|
||||
SAFE_DELETE(MapExpr4);
|
||||
SAFE_DELETE(Code);
|
||||
}
|
||||
|
||||
FxExpression *FxMapForEachLoop::Resolve(FCompileContext &ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(MapExpr, ctx);
|
||||
SAFE_RESOLVE(MapExpr2, ctx);
|
||||
SAFE_RESOLVE(MapExpr3, ctx);
|
||||
SAFE_RESOLVE(MapExpr4, ctx);
|
||||
|
||||
bool is_iterator = false;
|
||||
|
||||
if(!(MapExpr->ValueType->isMap() || (is_iterator = MapExpr->ValueType->isMapIterator())))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "foreach( k, v : m ) - 'm' must be a map or a map iterator, but is a %s",MapExpr->ValueType->DescriptiveName());
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
auto keyType = is_iterator ? static_cast<PMapIterator*>(MapExpr->ValueType)->KeyType : static_cast<PMap*>(MapExpr->ValueType)->KeyType;
|
||||
auto valType = is_iterator ? static_cast<PMapIterator*>(MapExpr->ValueType)->ValueType : static_cast<PMap*>(MapExpr->ValueType)->ValueType;
|
||||
|
||||
auto block = new FxCompoundStatement(ScriptPosition);
|
||||
auto k = new FxLocalVariableDeclaration(keyType, keyVarName, nullptr, 0, ScriptPosition);
|
||||
auto v = new FxLocalVariableDeclaration(valType, valueVarName, nullptr, 0, ScriptPosition);
|
||||
|
||||
block->Add(k);
|
||||
block->Add(v);
|
||||
|
||||
if(MapExpr->ValueType->isMapIterator())
|
||||
{
|
||||
/*
|
||||
{
|
||||
KeyType k;
|
||||
ValueType v;
|
||||
if(it.ReInit()) while(it.Next())
|
||||
{
|
||||
k = it.GetKey();
|
||||
v = it.GetValue();
|
||||
body
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
auto inner_block = new FxCompoundStatement(ScriptPosition);
|
||||
|
||||
inner_block->Add(new FxAssign(new FxIdentifier(keyVarName, ScriptPosition), new FxMemberFunctionCall(MapExpr, "GetKey", {}, ScriptPosition), true));
|
||||
inner_block->Add(new FxAssign(new FxIdentifier(valueVarName, ScriptPosition), new FxMemberFunctionCall(MapExpr2, "GetValue", {}, ScriptPosition), true));
|
||||
inner_block->Add(Code);
|
||||
|
||||
auto reInit = new FxMemberFunctionCall(MapExpr3, "ReInit", {}, ScriptPosition);
|
||||
block->Add(new FxIfStatement(reInit, new FxWhileLoop(new FxMemberFunctionCall(MapExpr4, "Next", {}, ScriptPosition), inner_block, ScriptPosition), nullptr, ScriptPosition));
|
||||
|
||||
MapExpr = MapExpr2 = MapExpr3 = MapExpr4 = Code = nullptr;
|
||||
delete this;
|
||||
return block->Resolve(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
{
|
||||
KeyType k;
|
||||
ValueType v;
|
||||
MapIterator<KeyType, ValueType> @it;
|
||||
@it.Init(map);
|
||||
while(@it.Next())
|
||||
{
|
||||
k = @it.GetKey();
|
||||
v = @it.GetValue();
|
||||
body
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
PType * itType = NewMapIterator(keyType, valType);
|
||||
auto it = new FxLocalVariableDeclaration(itType, "@it", nullptr, 0, ScriptPosition);
|
||||
block->Add(it);
|
||||
|
||||
FArgumentList al_map;
|
||||
al_map.Push(MapExpr);
|
||||
|
||||
block->Add(new FxMemberFunctionCall(new FxIdentifier("@it", ScriptPosition), "Init", std::move(al_map), ScriptPosition));
|
||||
|
||||
auto inner_block = new FxCompoundStatement(ScriptPosition);
|
||||
|
||||
inner_block->Add(new FxAssign(new FxIdentifier(keyVarName, ScriptPosition), new FxMemberFunctionCall(new FxIdentifier("@it", ScriptPosition), "GetKey", {}, ScriptPosition), true));
|
||||
inner_block->Add(new FxAssign(new FxIdentifier(valueVarName, ScriptPosition), new FxMemberFunctionCall(new FxIdentifier("@it", ScriptPosition), "GetValue", {}, ScriptPosition), true));
|
||||
inner_block->Add(Code);
|
||||
|
||||
block->Add(new FxWhileLoop(new FxMemberFunctionCall(new FxIdentifier("@it", ScriptPosition), "Next", {}, ScriptPosition), inner_block, ScriptPosition));
|
||||
|
||||
delete MapExpr2;
|
||||
delete MapExpr3;
|
||||
delete MapExpr4;
|
||||
MapExpr = MapExpr2 = MapExpr3 = MapExpr4 = Code = nullptr;
|
||||
delete this;
|
||||
return block->Resolve(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -12288,8 +12412,7 @@ FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx)
|
|||
if (IsDynamicArray())
|
||||
{
|
||||
auto stackVar = new FxStackVariable(ValueType, StackOffset, ScriptPosition);
|
||||
FArgumentList argsList;
|
||||
clearExpr = new FxMemberFunctionCall(stackVar, "Clear", argsList, ScriptPosition);
|
||||
clearExpr = new FxMemberFunctionCall(stackVar, "Clear", {}, ScriptPosition);
|
||||
SAFE_RESOLVE(clearExpr, ctx);
|
||||
}
|
||||
|
||||
|
@ -12607,10 +12730,9 @@ FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
|||
else
|
||||
{
|
||||
FArgumentList argsList;
|
||||
argsList.Clear();
|
||||
argsList.Push(v);
|
||||
|
||||
FxExpression *funcCall = new FxMemberFunctionCall(stackVar, NAME_Push, argsList, (const FScriptPosition) v->ScriptPosition);
|
||||
FxExpression *funcCall = new FxMemberFunctionCall(stackVar, NAME_Push, std::move(argsList), (const FScriptPosition) v->ScriptPosition);
|
||||
SAFE_RESOLVE(funcCall, ctx);
|
||||
|
||||
v = funcCall;
|
||||
|
|
|
@ -275,6 +275,7 @@ enum EFxType
|
|||
EFX_DoWhileLoop,
|
||||
EFX_ForLoop,
|
||||
EFX_ForEachLoop,
|
||||
EFX_MapForEachLoop,
|
||||
EFX_JumpStatement,
|
||||
EFX_ReturnStatement,
|
||||
EFX_ClassTypeCast,
|
||||
|
@ -1621,7 +1622,7 @@ public:
|
|||
FName MethodName;
|
||||
FArgumentList ArgList;
|
||||
|
||||
FxFunctionCall(FName methodname, FName rngname, FArgumentList &args, const FScriptPosition &pos);
|
||||
FxFunctionCall(FName methodname, FName rngname, FArgumentList &&args, const FScriptPosition &pos);
|
||||
~FxFunctionCall();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
};
|
||||
|
@ -1638,10 +1639,11 @@ class FxMemberFunctionCall : public FxExpression
|
|||
FxExpression *Self;
|
||||
FName MethodName;
|
||||
FArgumentList ArgList;
|
||||
bool ResolveSelf;
|
||||
|
||||
public:
|
||||
|
||||
FxMemberFunctionCall(FxExpression *self, FName methodname, FArgumentList &args, const FScriptPosition &pos);
|
||||
FxMemberFunctionCall(FxExpression *self, FName methodname, FArgumentList &&args, const FScriptPosition &pos);
|
||||
~FxMemberFunctionCall();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
};
|
||||
|
@ -2080,6 +2082,29 @@ public:
|
|||
FxExpression* DoResolve(FCompileContext&);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxMapForEachLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FxMapForEachLoop : public FxExpression
|
||||
{
|
||||
FName keyVarName;
|
||||
FName valueVarName;
|
||||
FxExpression* MapExpr;
|
||||
FxExpression* MapExpr2;
|
||||
FxExpression* MapExpr3;
|
||||
FxExpression* MapExpr4;
|
||||
FxExpression* Code;
|
||||
|
||||
public:
|
||||
FxMapForEachLoop(FName kv, FName vv, FxExpression* mapexpr, FxExpression* mapexpr2, FxExpression* mapexpr3, FxExpression* mapexpr4, FxExpression* code, const FScriptPosition& pos);
|
||||
~FxMapForEachLoop();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
//ExpEmit Emit(VMFunctionBuilder *build); This node is transformed, so it won't ever be emitted itself
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FxJumpStatement
|
||||
|
|
|
@ -983,6 +983,21 @@ static void PrintArrayIterationStmt(FLispString &out, const ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintMapIterationStmt(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
auto inode = (ZCC_MapIterationStmt *)node;
|
||||
out.Break();
|
||||
out.Open("map-iteration-stmt");
|
||||
PrintVarName(out, inode->ItKey);
|
||||
out.Break();
|
||||
PrintVarName(out, inode->ItValue);
|
||||
out.Break();
|
||||
PrintNodes(out, inode->ItMap);
|
||||
out.Break();
|
||||
PrintNodes(out, inode->LoopStatement);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static const NodePrinterFunc TreeNodePrinter[] =
|
||||
{
|
||||
PrintIdentifier,
|
||||
|
@ -1050,6 +1065,7 @@ static const NodePrinterFunc TreeNodePrinter[] =
|
|||
PrintMixinDef,
|
||||
PrintMixinStmt,
|
||||
PrintArrayIterationStmt,
|
||||
PrintMapIterationStmt,
|
||||
};
|
||||
|
||||
FString ZCC_PrintAST(const ZCC_TreeNode *root)
|
||||
|
|
|
@ -1956,6 +1956,7 @@ statement(X) ::= expression_statement(A) SEMICOLON. { X = A; /*X-overwrites-A*/
|
|||
statement(X) ::= selection_statement(X).
|
||||
statement(X) ::= iteration_statement(X).
|
||||
statement(X) ::= array_iteration_statement(X).
|
||||
statement(X) ::= map_iteration_statement(X).
|
||||
statement(X) ::= jump_statement(X).
|
||||
statement(X) ::= assign_statement(A) SEMICOLON. { X = A; /*X-overwrites-A*/ }
|
||||
statement(X) ::= assign_decl_statement(A) SEMICOLON.{ X = A; /*X-overwrites-A*/ }
|
||||
|
@ -2125,6 +2126,18 @@ array_iteration_statement(X) ::= FOREACH(T) LPAREN variable_name(IN) COLON expr(
|
|||
X = iter;
|
||||
}
|
||||
|
||||
%type map_iteration_statement{ZCC_Statement *}
|
||||
|
||||
map_iteration_statement(X) ::= FOREACH(T) LPAREN variable_name(KEY) COMMA variable_name(VAL) COLON expr(EX) RPAREN statement(ST).
|
||||
{
|
||||
NEW_AST_NODE(MapIterationStmt, iter, T);
|
||||
iter->ItKey = KEY;
|
||||
iter->ItValue = VAL;
|
||||
iter->ItMap = EX;
|
||||
iter->LoopStatement = ST;
|
||||
X = iter;
|
||||
}
|
||||
|
||||
while_or_until(X) ::= WHILE(T).
|
||||
{
|
||||
X.Int = ZCC_WHILE;
|
||||
|
|
|
@ -2999,12 +2999,12 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
|
|||
{
|
||||
case AST_ExprID:
|
||||
// The function name is a simple identifier.
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(fcall->Function)->Identifier, NAME_None, ConvertNodeList(args, fcall->Parameters), *ast);
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(fcall->Function)->Identifier, NAME_None, std::move(ConvertNodeList(args, fcall->Parameters)), *ast);
|
||||
|
||||
case AST_ExprMemberAccess:
|
||||
{
|
||||
auto ema = static_cast<ZCC_ExprMemberAccess *>(fcall->Function);
|
||||
return new FxMemberFunctionCall(ConvertNode(ema->Left, true), ema->Right, ConvertNodeList(args, fcall->Parameters), *ast);
|
||||
return new FxMemberFunctionCall(ConvertNode(ema->Left, true), ema->Right, std::move(ConvertNodeList(args, fcall->Parameters)), *ast);
|
||||
}
|
||||
|
||||
case AST_ExprBinary:
|
||||
|
@ -3014,7 +3014,7 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
|
|||
auto binary = static_cast<ZCC_ExprBinary *>(fcall->Function);
|
||||
if (binary->Left->NodeType == AST_ExprID && binary->Right->NodeType == AST_ExprID)
|
||||
{
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(binary->Left)->Identifier, static_cast<ZCC_ExprID *>(binary->Right)->Identifier, ConvertNodeList(args, fcall->Parameters), *ast);
|
||||
return new FxFunctionCall(static_cast<ZCC_ExprID *>(binary->Left)->Identifier, static_cast<ZCC_ExprID *>(binary->Right)->Identifier, std::move(ConvertNodeList(args, fcall->Parameters)), *ast);
|
||||
}
|
||||
}
|
||||
// fall through if this isn't an array access node.
|
||||
|
@ -3391,7 +3391,19 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute)
|
|||
FxExpression* const itArray2 = ConvertNode(iter->ItArray); // the handler needs two copies of this - here's the easiest place to create them.
|
||||
FxExpression* const body = ConvertImplicitScopeNode(ast, iter->LoopStatement);
|
||||
return new FxForEachLoop(iter->ItName->Name, itArray, itArray2, body, *ast);
|
||||
}
|
||||
|
||||
case AST_MapIterationStmt:
|
||||
{
|
||||
auto iter = static_cast<ZCC_MapIterationStmt*>(ast);
|
||||
auto key = iter->ItKey->Name;
|
||||
auto var = iter->ItValue->Name;
|
||||
FxExpression* const itMap = ConvertNode(iter->ItMap);
|
||||
FxExpression* const itMap2 = ConvertNode(iter->ItMap);
|
||||
FxExpression* const itMap3 = ConvertNode(iter->ItMap);
|
||||
FxExpression* const itMap4 = ConvertNode(iter->ItMap);
|
||||
FxExpression* const body = ConvertImplicitScopeNode(ast, iter->LoopStatement);
|
||||
return new FxMapForEachLoop(key, var, itMap, itMap2, itMap3, itMap4, body, *ast);
|
||||
}
|
||||
|
||||
case AST_IterationStmt:
|
||||
|
|
|
@ -1177,6 +1177,19 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
|
|||
break;
|
||||
}
|
||||
|
||||
case AST_MapIterationStmt:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(MapIterationStmt);
|
||||
|
||||
// ZCC_MapIterationStmt
|
||||
copy->ItKey = static_cast<ZCC_VarName*>(TreeNodeDeepCopy_Internal(ast, origCasted->ItKey, true, copiedNodesList));
|
||||
copy->ItValue = static_cast<ZCC_VarName*>(TreeNodeDeepCopy_Internal(ast, origCasted->ItValue, true, copiedNodesList));
|
||||
copy->LoopStatement = static_cast<ZCC_Statement*>(TreeNodeDeepCopy_Internal(ast, origCasted->LoopStatement, true, copiedNodesList));
|
||||
copy->ItMap = static_cast<ZCC_Expression*>(TreeNodeDeepCopy_Internal(ast, origCasted->ItMap, true, copiedNodesList));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_IfStmt:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(IfStmt);
|
||||
|
|
|
@ -145,6 +145,7 @@ enum EZCCTreeNodeType
|
|||
AST_MixinDef,
|
||||
AST_MixinStmt,
|
||||
AST_ArrayIterationStmt,
|
||||
AST_MapIterationStmt,
|
||||
|
||||
NUM_AST_NODE_TYPES
|
||||
};
|
||||
|
@ -532,6 +533,14 @@ struct ZCC_ArrayIterationStmt : ZCC_Statement
|
|||
ZCC_Statement* LoopStatement;
|
||||
};
|
||||
|
||||
struct ZCC_MapIterationStmt : ZCC_Statement
|
||||
{
|
||||
ZCC_VarName* ItKey;
|
||||
ZCC_VarName* ItValue;
|
||||
ZCC_Expression* ItMap;
|
||||
ZCC_Statement* LoopStatement;
|
||||
};
|
||||
|
||||
struct ZCC_IfStmt : ZCC_Statement
|
||||
{
|
||||
ZCC_Expression *Condition;
|
||||
|
|
|
@ -477,7 +477,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
{
|
||||
FArgumentList args;
|
||||
args.Push(exp);
|
||||
exp = new FxFunctionCall(NAME_ResolveState, NAME_None, args, sc);
|
||||
exp = new FxFunctionCall(NAME_ResolveState, NAME_None, std::move(args), sc);
|
||||
}
|
||||
sc.MustGetToken(')');
|
||||
return exp;
|
||||
|
@ -512,7 +512,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
ParseFunctionParameters(sc, cls, args, func, "", nullptr);
|
||||
}
|
||||
// FxVMFunctionCall cannot be used here as it lacks some important checks
|
||||
return new FxFunctionCall(identifier, NAME_None, args, sc);
|
||||
return new FxFunctionCall(identifier, NAME_None, std::move(args), sc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -543,7 +543,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
|||
while (sc.CheckToken(','));
|
||||
sc.MustGetToken(')');
|
||||
}
|
||||
return new FxFunctionCall(identifier, NAME_None, args, sc);
|
||||
return new FxFunctionCall(identifier, NAME_None, std::move(args), sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -578,7 +578,7 @@ FxExpression* ParseAction(FScanner &sc, FState state, FString statestring, Bagga
|
|||
{
|
||||
FArgumentList args;
|
||||
ParseFunctionParameters(sc, bag.Info, args, afd, statestring, &bag.statedef);
|
||||
call = new FxFunctionCall(symname, NAME_None, args, sc);
|
||||
call = new FxFunctionCall(symname, NAME_None, std::move(args), sc);
|
||||
return call;
|
||||
}
|
||||
sc.ScriptError("Invalid parameter '%s'\n", sc.String);
|
||||
|
|
Loading…
Reference in a new issue