private void PushCallParameters(FunctionInfo info, int contextParameterCount, string expectedReturnType, HS_Gen1Parser.CallContext context)
{
int expectedParamCount = info.ParameterTypes.Count();
// Handle regular functions.
if (expectedParamCount > 0)
{
if (contextParameterCount != expectedParamCount)
{
throw new CompilerException($"The function \"{context.callID().GetTextSanitized()}\" has an unexpected number of arguments. Expected: \"{expectedParamCount}\" Encountered: \"{contextParameterCount}\".", context);
}
_expectedTypes.PushTypes(info.ParameterTypes);
}
// TODO: Throw exceptions if a wrong number of parameters is detected.
// Handle special functions.
#region special functions
else
{
bool validNumberOfArgs = false;
switch (info.Group)
{
// Any number of arguments.
case "Begin":
validNumberOfArgs = true;
if (info.Name.Contains("random"))
{
_expectedTypes.PushTypes(expectedReturnType, contextParameterCount);
}
else
{
// the last evaluated expression.
_expectedTypes.PushType(expectedReturnType);
_expectedTypes.PushTypes("void", contextParameterCount - 1);
}
break;
// Any number of arguments.
case "BeginCount":
validNumberOfArgs = true;
_expectedTypes.PushTypes(expectedReturnType, contextParameterCount - 1);
_expectedTypes.PushType("long");
break;
// 2 or 3 arguments?
case "If":
validNumberOfArgs = contextParameterCount == 2 || contextParameterCount == 3;
if(expectedReturnType == TypeHelper.Any)
{
_expectedTypes.PushTypes("void", contextParameterCount - 1);
}
else
{
_expectedTypes.PushTypes(expectedReturnType, contextParameterCount - 1);
}
_expectedTypes.PushType("boolean");
break;
// Cond has it's own parser rule and should be handled elsewhere.
case "Cond":
throw new CompilerException("A cond call was not recognized by the parser.", context);
// Two arguments.
case "Set":
validNumberOfArgs = contextParameterCount == 2;
_expectedTypes.PushType(TypeHelper.GlobalsReference);
// The second parameter will be pushed once we have determined the return type of the global.
_set = true;
break;
// Any number of arguments.
case "Logical":
validNumberOfArgs = contextParameterCount >= 1;
_expectedTypes.PushTypes("boolean", contextParameterCount);
break;
// Depends on the function. Some accept only two arguments.
case "Arithmetic":
validNumberOfArgs = contextParameterCount >= 1;
_expectedTypes.PushTypes("real", contextParameterCount);
break;
// TODO: Change inequality to only accept NUMBER or maybe real arguments?
// Two arguments.
case "Equality":
case "Inequality":
validNumberOfArgs = contextParameterCount == 2;
_expectedTypes.PushType("ANY");
_equality = true;
break;
// One or two arguments.
case "Sleep":
validNumberOfArgs = contextParameterCount == 1 || contextParameterCount == 2;
if (contextParameterCount == 2)
{
_expectedTypes.PushType("script");
}
_expectedTypes.PushType("short");
break;
// Zero or one argument(s).
case "SleepForever":
validNumberOfArgs = contextParameterCount == 0 || contextParameterCount == 1;
if (contextParameterCount == 1)
{
_expectedTypes.PushType("script");
}
break;
// One, two or three arguments.
case "SleepUntil":
validNumberOfArgs = contextParameterCount >= 1 || contextParameterCount <= 3;
if (contextParameterCount == 3)
{
_expectedTypes.PushTypes("short", "long");
}
else if(contextParameterCount == 2)
{
_expectedTypes.PushType("short");
}
_expectedTypes.PushType("boolean");
break;
// Probably two arguments.
case "SleepUntilGameTicks":
validNumberOfArgs = contextParameterCount == 2;
if (contextParameterCount != 2)
{
throw new CompilerException("The Compiler encountered a \"sleep_until_game_ticks\" call, which didn't have exactly two arguments.", context);
}
_expectedTypes.PushTypes("boolean", "short");
break;
// Probably one argument.
case "CinematicSleep":
validNumberOfArgs = contextParameterCount == 1;
if (contextParameterCount != 1)
{
throw new CompilerException("The Compiler encountered a \"sleep_until_game_ticks\" call, which didn't have exactly one argument.", context);
}
_expectedTypes.PushType("short");
break;
// One argument.
case "Wake":
validNumberOfArgs = contextParameterCount == 1;
_expectedTypes.PushType("script");
break;
// One argument.
case "Inspect":
validNumberOfArgs = contextParameterCount == 1;
_expectedTypes.PushType("ANY");
break;
// Branch has it's own parser rule and should be handled elsewhere.
case "Branch":
throw new CompilerException("A branch call was not identified by the parser.", context);
// One argument.
case "ObjectCast":
validNumberOfArgs = contextParameterCount == 1;
_expectedTypes.PushType("object");
break;
// What is this?
case null:
return;
default:
throw new CompilerException($"Unimplemented function group: \"{info.Group}\".", context);
}
if(!validNumberOfArgs)
{
throw new CompilerException($"The special function \"{info.Name}\" has an invalid number of arguments: \"{contextParameterCount}\".", context);
}
}
#endregion
}