mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +00:00
- implemented array-style syntax for Random calls.
- implemented handling of the basic math operators so that heretic/beast.txt can be processed. This is working, aside from still needing the type casts to properly transform the strings to class pointers.
This commit is contained in:
parent
2c7c04e803
commit
59ab8b7ccd
3 changed files with 73 additions and 26 deletions
|
@ -3796,15 +3796,15 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
if (CheckArgSize(MethodName, ArgList, 1, -1, ScriptPosition))
|
if (CheckArgSize(MethodName, ArgList, 1, -1, ScriptPosition))
|
||||||
{
|
{
|
||||||
func = new FxRandomPick(RNG, *ArgList, MethodName == NAME_FRandomPick, ScriptPosition, ctx.FromDecorate);
|
func = new FxRandomPick(RNG, *ArgList, MethodName == NAME_FRandomPick, ScriptPosition, ctx.FromDecorate);
|
||||||
for (auto &i : *ArgList) i = nullptr; // Ownership of items is transferred to FxMinMax but not ownership of the array itself, so Clear cannot be called here.
|
for (auto &i : *ArgList) i = nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NAME_Random2:
|
case NAME_Random2:
|
||||||
if (CheckArgSize(NAME_Random2, ArgList, 1, 1, ScriptPosition))
|
if (CheckArgSize(NAME_Random2, ArgList, 0, 1, ScriptPosition))
|
||||||
{
|
{
|
||||||
func = new FxRandom2(RNG, (*ArgList)[0], ScriptPosition, ctx.FromDecorate);
|
func = new FxRandom2(RNG, ArgList->Size() == 0? nullptr : (*ArgList)[0], ScriptPosition, ctx.FromDecorate);
|
||||||
(*ArgList)[0] = nullptr;
|
if (ArgList->Size() > 0) (*ArgList)[0] = nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3813,7 +3813,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
if (CheckArgSize(MethodName, ArgList, 2, -1, ScriptPosition))
|
if (CheckArgSize(MethodName, ArgList, 2, -1, ScriptPosition))
|
||||||
{
|
{
|
||||||
func = new FxMinMax(*ArgList, MethodName, ScriptPosition);
|
func = new FxMinMax(*ArgList, MethodName, ScriptPosition);
|
||||||
for (auto &i : *ArgList) i = nullptr; // Ownership of items is transferred to FxMinMax but not ownership of the array itself, so Clear cannot be called here.
|
for (auto &i : *ArgList) i = nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,6 @@
|
||||||
|
|
||||||
FxExpression *ConvertFunctionCall(ZCC_Expression *function, FArgumentList *args, PClass *cls, FScriptPosition &sc)
|
FxExpression *ConvertFunctionCall(ZCC_Expression *function, FArgumentList *args, PClass *cls, FScriptPosition &sc)
|
||||||
{
|
{
|
||||||
// function names can either be
|
|
||||||
// - plain identifiers
|
|
||||||
// - class members
|
|
||||||
// - array syntax for random() calls.
|
|
||||||
|
|
||||||
switch(function->NodeType)
|
switch(function->NodeType)
|
||||||
{
|
{
|
||||||
|
@ -63,10 +59,6 @@ FxExpression *ConvertFunctionCall(ZCC_Expression *function, FArgumentList *args,
|
||||||
|
|
||||||
case AST_ExprBinary:
|
case AST_ExprBinary:
|
||||||
// Array access syntax is wrapped into a ZCC_ExprBinary object.
|
// Array access syntax is wrapped into a ZCC_ExprBinary object.
|
||||||
if (fcall->Function->Operation == PEX_ArrayAccess)
|
|
||||||
{
|
|
||||||
return ConvertArrayFunctionCall(fcall);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -2300,10 +2300,40 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
case AST_ExprFuncCall:
|
case AST_ExprFuncCall:
|
||||||
{
|
{
|
||||||
auto fcall = static_cast<ZCC_ExprFuncCall *>(ast);
|
auto fcall = static_cast<ZCC_ExprFuncCall *>(ast);
|
||||||
assert(fcall->Function->NodeType == AST_ExprID); // of course this cannot remain. Right now nothing more complex can come along but later this will have to be decomposed into 'self' and the actual function name.
|
|
||||||
auto fname = static_cast<ZCC_ExprID *>(fcall->Function)->Identifier;
|
// function names can either be
|
||||||
return new FxFunctionCall(fname, NAME_None, ConvertNodeList(fcall->Parameters), *ast);
|
// - plain identifiers
|
||||||
//return ConvertFunctionCall(fcall->Function, ConvertNodeList(fcall->Parameters), ConvertClass, *ast);
|
// - class members
|
||||||
|
// - array syntax for random() calls.
|
||||||
|
// Everything else coming here is a syntax error.
|
||||||
|
switch (fcall->Function->NodeType)
|
||||||
|
{
|
||||||
|
case AST_ExprID:
|
||||||
|
// The function name is a simple identifier.
|
||||||
|
return new FxFunctionCall(static_cast<ZCC_ExprID *>(fcall->Function)->Identifier, NAME_None, ConvertNodeList(fcall->Parameters), *ast);
|
||||||
|
|
||||||
|
case AST_ExprMemberAccess:
|
||||||
|
// calling a class member through its pointer
|
||||||
|
// todo.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_ExprBinary:
|
||||||
|
// Array syntax for randoms. They are internally stored as ExprBinary with both an identifier on the left and right side.
|
||||||
|
if (fcall->Function->Operation == PEX_ArrayAccess)
|
||||||
|
{
|
||||||
|
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(fcall->Parameters), *ast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fall through if this isn't an array access node.
|
||||||
|
|
||||||
|
default:
|
||||||
|
Error(fcall, "Invalid function identifier");
|
||||||
|
return new FxNop(*ast); // return something so that the compiler can continue.
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AST_FuncParm:
|
case AST_FuncParm:
|
||||||
|
@ -2346,22 +2376,47 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
case AST_ExprBinary:
|
||||||
// only for development. I_Error is more convenient here than a normal error.
|
{
|
||||||
I_Error("ConvertNode encountered unsupported node of type %d", ast->NodeType);
|
auto binary = static_cast<ZCC_ExprBinary *>(ast);
|
||||||
return nullptr;
|
auto left = ConvertNode(binary->Left);
|
||||||
|
auto right = ConvertNode(binary->Right);
|
||||||
|
auto op = binary->Operation;
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case PEX_Add:
|
||||||
|
case PEX_Sub:
|
||||||
|
return new FxAddSub(op == PEX_Add ? '+' : '-', left, right);
|
||||||
|
|
||||||
|
case PEX_Mul:
|
||||||
|
case PEX_Div:
|
||||||
|
case PEX_Mod:
|
||||||
|
return new FxMulDiv(op == PEX_Mul ? '*' : op == PEX_Div ? '/' : '%', left, right);
|
||||||
|
|
||||||
|
default:
|
||||||
|
I_Error("Binary operator %d not implemented yet", op);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only for development. I_Error is more convenient here than a normal error.
|
||||||
|
I_Error("ConvertNode encountered unsupported node of type %d", ast->NodeType);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FArgumentList *ZCCCompiler::ConvertNodeList(ZCC_TreeNode *head)
|
FArgumentList *ZCCCompiler::ConvertNodeList(ZCC_TreeNode *head)
|
||||||
{
|
{
|
||||||
FArgumentList *list = new FArgumentList;
|
FArgumentList *list = new FArgumentList;
|
||||||
auto node = head;
|
if (head != nullptr)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
list->Push(ConvertNode(node));
|
auto node = head;
|
||||||
node = node->SiblingNext;
|
do
|
||||||
} while (node != head);
|
{
|
||||||
|
list->Push(ConvertNode(node));
|
||||||
|
node = node->SiblingNext;
|
||||||
|
} while (node != head);
|
||||||
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
Loading…
Reference in a new issue