public override GamaValueRef VisitExprFQTN([NotNull] GamaParser.ExprFQTNContext context) { var names = context.fqtn().Symbol().Select(node => node.GetText()).ToArray(); // Variables/Function if (names.Length == 1) { var val = Parent.Top.FindValueRecursive(names[0]); if (val == null) { // If no target type is given //if (IsEmptyTT) //{ var list = Parent.NamespaceContext.FindFunctionRefGlobal(names); if (list != null) { PushCall(list); } return(null); //} /* * var target = TopTT; * if (target is GamaFunction fnty) * { * var fn = Parent.NamespaceContext.FindFunctionRefGlobal(names); * if (fn != null) * { * GamaFunctionRef cb; * // Not always return target type is available * // For example when searching for a callback, expression compiler might not set return type, only parameter types are necessary anyway * // But in case of delegates, return types are necessary too. * if (fnty.ReturnType == null) * cb = fn.FindFunction(fnty.ParameterTypes); * else * cb = fn.FindFunction(fnty.ReturnType, fnty.ParameterTypes); * * if (cb == null) * { * Parent.NamespaceContext.Context.AddError(new ErrorNoViableOverride(context)); * return null; * } * return cb; * } * } */ Parent.NamespaceContext.Context.AddError(new ErrorIdentifierNotFound(context)); return(null); } /* LLVM */ var block = Parent.CurrentBlock; var builder = Parent.Builder; // A load is happening? if (!IsEmptyLoad) { if (!TopLoad) { return(val); } // A load happaning. if (val.Type is GamaPointer ptr) { block.PositionBuilderAtEnd(builder); var load = builder.BuildLoad(val.Value); return(new GamaValueRef(ptr.BaseType, load, true)); // Pointers are modifiable LValues } /* Code tried to load a non-pointer expression. Eg: *10, *some_function_pointer */ /* Function pointers are not loadable either */ Parent.NamespaceContext.Context.AddError(new ErrorNonPointerLoad(context)); return(null); } block.PositionBuilderAtEnd(builder); if (val.IsModifiableLValue) // Variable { var load = builder.BuildLoad(val.Value); return(new GamaValueRef(val.Type, load, false)); } // If its not a pointer and not a variable // Then it must be a parameter, If not god save me. TODO: test this theory later // Just send it return(val); /* oh yah 80% it says * // I hope this doesnt happen. I am 80% sure this won't hit. * // You can never be sure enough: #if DEBUG * Console.WriteLine("it happened"); #endif * Parent.NamespaceContext.Context.AddError(new ErrorNonPointerLoad(context)); * return null; */ } // Functions/Types else { var fn = Parent.NamespaceContext.FindFunctionRefGlobal(names); if (fn == null) { Parent.NamespaceContext.Context.AddError(new ErrorTypeMismatch(context)); return(null); } if (IsEmptyTT) { var list = Parent.NamespaceContext.FindFunctionRefGlobal(names); if (list != null) { PushCall(list); } return(null); } var target = TopTT; if (target == null) { // This shouldn't happen, this time I'm 90% sure this won't hit #if DEBUG Console.WriteLine("yooooo"); #endif return(null); } if (!(target is GamaFunction fnty)) { Parent.NamespaceContext.Context.AddError(new ErrorTypeMismatch(context)); return(null); } var cb = fn.FindFunction(fnty.ParameterTypes); if (cb == null) { Parent.NamespaceContext.Context.AddError(new ErrorNoViableOverride(context)); return(null); } return(cb); } }