示例#1
0
        private bool IsScriptReference(string expectedReturnType, int expectedParameterCount, HS_Gen1Parser.CallContext context)
        {
            string key = context.callID().GetTextSanitized();

            if(!_scriptLookup.ContainsKey(key))
            {
                if (expectedReturnType == TypeHelper.ScriptReference)
                {
                    throw new CompilerException($"The compiler expected a Script Reference but a Script with the name \"{key}\" could not be found. " +
                        "Please check your script declarations and your spelling.", context);
                }
                else
                {
                    return false;
                }
            }

            // Try to find a script, which satisfies all conditions.
            foreach(ScriptInfo info in _scriptLookup[key])
            {
                if(info.Parameters.Count != expectedParameterCount)
                {
                    continue;
                }

                string returnType = DetermineReturnType(info, expectedReturnType, context);

                if(!(returnType is null))
                {
                    // Check for equality functions.
                    EqualityPush(returnType);

                    // Push the parameters to the type stack.
                    if (expectedParameterCount > 0)
                    {
                        string[] parameterTypes = info.Parameters.Select(p => p.ReturnType).ToArray();
                        _expectedTypes.PushTypes(parameterTypes);
                    }

                    // Create a script reference node.
                    CreateScriptReference(info, _opcodes.GetTypeInfo(returnType).Opcode, context.GetCorrectTextPosition(_missingCarriageReturnPositions), GetLineNumber(context));
                    return true;
                }
            }

            return false;
        }
示例#2
0
        /// <summary>
        /// Processes function calls and script references. Links to a datum. Opens one or more datums. 
        /// Pops a value type. Pushes parameter types.
        /// </summary>
        /// <param name="context"></param>
        public override void EnterCall(HS_Gen1Parser.CallContext context)
        {
            if (_debug)
            {
                _logger.Call(context, CompilerContextAction.Enter);
            }

            LinkDatum();

            // Retrieve information from the context.
            string name = context.callID().GetTextSanitized();
            string expectedType = _expectedTypes.PopType();
            int contextParameterCount = context.expression().Length;

            // Handle script references.
            if (IsScriptReference(expectedType, contextParameterCount, context))
            {
                return;
            }

            // Handle functions.
            var functions = _opcodes.GetFunctionInfo(name);
            foreach(var func in functions)
            {
                if(!CheckParameterSanity(context, func))
                {
                    continue;
                }

                string returnType = DetermineReturnType(func, expectedType, context);

                // If a function, which satisfies the requirements, was found, perform the necessary push operations and create expression nodes.
                if (!(returnType is null))
                {
                    EqualityPush(func.ReturnType);
                    PushCallParameters(func, contextParameterCount, expectedType, context);
                    CreateFunctionCall(func, _opcodes.GetTypeInfo(returnType).Opcode, context.GetCorrectTextPosition(_missingCarriageReturnPositions), GetLineNumber(context));
                    return;
                }
            }

            string errorMessage = contextParameterCount == 1 ?
                    $"Failed to process the call {name} with 1 parameter." :
                    $"Failed to process the call {name} with {contextParameterCount} parameters.";
            throw new CompilerException(errorMessage + $" The expected return type was {expectedType}.", context);
        }