in Iris/IrisCompiler/FrontEnd/Translator.cs [885:974]
private IrisType ProcessCall(FilePosition fp, Symbol symbol, bool skipArgList)
{
ParsedCallSyntax = true;
IrisType symbolType = symbol.Type;
if (!symbolType.IsMethod)
{
// Variables can have the same name as functions. If the symbol is not a method,
// try looking up the same name in the global scope. If the global symbol is a
// method, use it instead.
Symbol globalSym = _symbolTable.LookupGlobal(symbol.Name);
if (globalSym != null && globalSym.Type.IsMethod)
{
symbol = globalSym;
symbolType = symbol.Type;
}
}
IrisType resultType = IrisType.Invalid;
bool semanticError = symbolType == IrisType.Invalid;
if (!symbolType.IsMethod && !semanticError)
{
semanticError = true;
AddError(fp, string.Format("Symbol '{0}' is not a procedure or function.", _lexeme));
}
string symbolTypeName = symbolType.IsFunction ? "function" : "procedure";
Method method = symbolType as Method;
Variable[] methodParams = method?.GetParameters();
int count = 0;
if (!skipArgList && !Accept(Token.ChrCloseParen))
{
do
{
FilePosition argPosition = _lexer.TokenStartPosition;
if (methodParams != null && count < methodParams.Length)
{
Variable param = methodParams[count];
IrisType paramType = param.Type;
IrisType argType = ParseExpression(paramType.IsByRef ? SymbolLoadMode.Address : SymbolLoadMode.Dereference);
if (paramType != IrisType.Invalid && argType != IrisType.Invalid && paramType != argType)
{
if (paramType.IsByRef && !argType.IsByRef)
{
AddError(argPosition, "Cannot take address of constant, call, or expression.");
}
else
{
AddError(argPosition, string.Format(
"Argument type doesn't match parameter '{0}' of {1} '{2}'",
param.Name,
symbolTypeName,
symbol.Name));
}
}
}
else
{
// Undefined method or too many arguments. Parse the argument without validation.
ParseExpression();
}
count++;
}
while (Accept(Token.ChrComma));
Expect(Token.ChrCloseParen);
}
// Verify argument count
if (methodParams != null && methodParams.Length != count)
{
AddError(fp, string.Format(
"Wrong number of arguments for {0} '{1}'. {2} expected. {3} provided.",
symbolTypeName,
symbol.Name,
methodParams.Length,
count));
}
if (!semanticError)
{
MethodGenerator.Call(symbol);
resultType = symbolType.IsFunction ? ((Function)symbolType).ReturnType : IrisType.Void;
}
return resultType;
}