Esempio n. 1
0
        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);
            }
        }