Blamite.Blam.Scripting.Compiler.ScriptCompiler.PushCallParameters C# (CSharp) Метод

PushCallParameters() приватный Метод

Calculates the value types for the parameters of a function and pushes them to the stack.
private PushCallParameters ( FunctionInfo info, int contextParameterCount, string expectedReturnType, HS_Gen1Parser.CallContext context ) : void
info FunctionInfo The function's ScriptFunctionInfo
contextParameterCount int
expectedReturnType string
context HS_Gen1Parser.CallContext The call contect
Результат void
        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
        }