private IValue doFunctionCall([NotNull] ClepsParser.FunctionCallContext context, IValue target, ClepsType targetType, bool allowVoidReturn) { string targetFunctionName = context.FunctionName.GetText(); List <IValue> parameters = context._FunctionParameters.Select(p => Visit(p) as IValue).ToList(); return(doFunctionCall(context, targetFunctionName, parameters, target, targetType, allowVoidReturn)); }
/// <summary> /// Exit a parse tree produced by <see cref="ClepsParser.functionCall"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitFunctionCall([NotNull] ClepsParser.FunctionCallContext context) { }
/// <summary> /// Visit a parse tree produced by <see cref="ClepsParser.functionCall"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitFunctionCall([NotNull] ClepsParser.FunctionCallContext context) { return(VisitChildren(context)); }
private IValue doFunctionCall(ClepsParser.FunctionCallContext functionCall, ClepsType targetType, bool isMemberFunctionsAccessible, bool allowVoidReturn) { ClepsClass targetClepsClass; if (targetType is BasicClepsType) { targetClepsClass = ClassManager.GetClass(targetType.GetClepsTypeString()); } else if (targetType is BasicStaticClepsType) { targetClepsClass = ClassManager.GetClass(targetType.GetClepsTypeString()); isMemberFunctionsAccessible = false; } else { throw new NotImplementedException("Function calls on non basic types not supported"); } string targetFunctionName = functionCall.FunctionName.GetText(); List <IValue> parameters = functionCall._FunctionParameters.Select(p => Visit(p) as IValue).ToList(); ClepsType functionType = null; if (targetClepsClass.StaticMemberMethods.ContainsKey(targetFunctionName)) { functionType = targetClepsClass.StaticMemberMethods[targetFunctionName]; } else if (isMemberFunctionsAccessible && targetClepsClass.MemberMethods.ContainsKey(targetFunctionName)) { functionType = targetClepsClass.MemberMethods[targetFunctionName]; } if (functionType == null) { string errorMessage = String.Format("Class {0} does not contain a function called {1}", targetClepsClass.FullyQualifiedName, targetFunctionName); Status.AddError(new CompilerError(FileName, functionCall.Start.Line, functionCall.Start.Column, errorMessage)); //Just return something to avoid stalling compilation return(CodeGenerator.CreateByte(0)); } List <ClepsType> functionOverloads = new List <ClepsType> { functionType }; int matchedPosition; string fnMatchErrorMessage; if (!FunctionOverloadManager.FindMatchingFunctionType(functionOverloads, parameters, out matchedPosition, out fnMatchErrorMessage)) { Status.AddError(new CompilerError(FileName, functionCall.Start.Line, functionCall.Start.Column, fnMatchErrorMessage)); //Just return something to avoid stalling compilation return(CodeGenerator.CreateByte(0)); } FunctionClepsType chosenFunctionType = functionOverloads[matchedPosition] as FunctionClepsType; if (!allowVoidReturn && chosenFunctionType.ReturnType == VoidType.GetVoidType()) { string errorMessage = String.Format("Function {0} does not return a value", targetFunctionName); Status.AddError(new CompilerError(FileName, functionCall.Start.Line, functionCall.Start.Column, errorMessage)); //Just return something to avoid stalling compilation return(CodeGenerator.CreateByte(0)); } IValue returnValue = CodeGenerator.GetFunctionCallReturnValue(FullyQualifiedClassName, targetFunctionName, chosenFunctionType, parameters); return(returnValue); }