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; }
/// <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); }