Example #1
0
        //When a function is called.
        public override object VisitStat_functionCall([NotNull] algoParser.Stat_functionCallContext context)
        {
            //If there are particles, get the last value.
            AlgoValue currentVal = null; bool isLibraryTopLevelCall = false;

            if (context.IDENTIFIER() != null)
            {
                //Is the identifier a library and has no particles?
                if (!Scopes.VariableExists(context.IDENTIFIER().GetText()) &&
                    Scopes.LibraryExists(context.IDENTIFIER().GetText()) &&
                    (context.particle() == null || context.particle().Length == 0))
                {
                    //Library top level call, so don't evaluate like normal particles.
                    isLibraryTopLevelCall = true;

                    //Just get the very last function like a normal variable, but from the library.
                    string libName = context.IDENTIFIER().GetText();
                    string name    = context.functionCall_particle().IDENTIFIER().GetText();
                    var    lib     = Scopes.GetLibrary(libName);

                    if (!lib.VariableExists(name))
                    {
                        Error.Fatal(context, "No variable named '" + name + "' exists in library '" + libName + "'.");
                        return(null);
                    }

                    currentVal = lib.GetVariable(name);
                }
                else
                {
                    //Not a library top level call, so execute like a normal particle block.
                    currentVal = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle());
                }
            }
            else
            {
                //No particles, just grab the value as an identifier.
                string name = context.functionCall_particle().IDENTIFIER().GetText();
                if (!Scopes.VariableExists(name))
                {
                    Error.Fatal(context, "No function exists with name '" + name + "'.");
                    return(null);
                }

                currentVal = Scopes.GetVariable(name);
            }

            //Attempt to execute the final function on the result.
            if (context.IDENTIFIER() == null || isLibraryTopLevelCall)
            {
                //Visit and execute THIS value, not a child value (this was a straight normal call).
                Particles.SetParticleInput(currentVal);
                return(VisitFunctionCall_particle(context.functionCall_particle()));
            }
            else
            {
                //There were particles, visit and execute CHILD value.
                if (currentVal.Type != AlgoValueType.Object)
                {
                    Error.Fatal(context, "Cannot call a child function on a value with no children (given value was not an object).");
                    return(null);
                }

                //Get the child, see if it's a function.
                AlgoObject thisObj   = currentVal.Value as AlgoObject;
                string     funcName  = context.IDENTIFIER().GetText();
                AlgoValue  childFunc = thisObj.ObjectScopes.GetVariable(funcName);
                if (childFunc == null || (childFunc.Type != AlgoValueType.Function && childFunc.Type != AlgoValueType.EmulatedFunction))
                {
                    Error.Fatal(context, "No child function exists with name '" + funcName + "'.");
                    return(null);
                }

                //Set the particle result as the function value, call the function call particle.
                Particles.SetParticleInput(childFunc);
                return(VisitFunctionCall_particle(context.functionCall_particle()));
            }
        }