Exemplo n.º 1
0
        /// <summary>
        /// Evaluates a given particle, and returns the result.
        /// </summary>
        public override object VisitParticle([NotNull] algoParser.ParticleContext context)
        {
            //Get the last result of the particle before this.
            AlgoValue current = Particles.GetParticleResult();

            if (current == null)
            {
                Error.Internal("Particle chain started without setting an initial value.");
                return(null);
            }

            //Prepare an "old" scope for swapping.
            AlgoScopeCollection oldScope = null;

            //What type of particle is it?

            //CHILD VARIABLE
            if (context.IDENTIFIER() != null)
            {
                //Sub-variable. Attempt to get from the object.
                if (current.Type != AlgoValueType.Object)
                {
                    Error.Fatal(context, "Cannot access children when given variable is not an object, and has no children to access.");
                    return(null);
                }

                //Does the sub-variable exist?
                AlgoObject curObj = (AlgoObject)current.Value;
                AlgoValue  newObj = curObj.ObjectScopes.GetVariable(context.IDENTIFIER().GetText());
                if (newObj == null)
                {
                    Error.Fatal(context, "No child of the given object exists with name '" + context.IDENTIFIER().GetText() + "'.");
                    return(null);
                }

                //Yes, set result and return.
                Particles.SetParticleInput(newObj);
                return(null);
            }

            //ARRAY ACCESS
            else if (context.array_access_particle() != null)
            {
                var aap = context.array_access_particle();

                //Indexing.
                //For each index, iterate over.
                AlgoValue currentLV = current;
                foreach (var index in aap.literal_params().expr())
                {
                    //Is the current list value a list?
                    if (currentLV.Type != AlgoValueType.List)
                    {
                        Error.Fatal(context, "Cannot index into variable that is not a list or indexable object.");
                        return(null);
                    }

                    //Need to switch scopes for evaluating indexes?
                    if (Particles.funcArgumentScopes != null)
                    {
                        oldScope = Scopes;
                        Scopes   = Particles.funcArgumentScopes;
                    }

                    //Evaluate the expression.
                    AlgoValue indexVal = (AlgoValue)VisitExpr(index);

                    //Back to normal.
                    if (Particles.funcArgumentScopes != null)
                    {
                        Scopes = oldScope;
                    }

                    //Valid?
                    if (indexVal.Type != AlgoValueType.Integer)
                    {
                        Error.Fatal(context, "Index value provided is not an integer. Indexes must be whole integer values.");
                        return(null);
                    }

                    //Is the index outside of the bounds of the array?
                    if (((List <AlgoValue>)currentLV.Value).Count <= (BigInteger)indexVal.Value)
                    {
                        Error.Fatal(context, "Index provided is outside the bounds of the array.");
                        return(null);
                    }

                    //Index into it, set the current value.
                    currentLV = ((List <AlgoValue>)currentLV.Value)[(int)((BigInteger)indexVal.Value)];
                }

                //Set result.
                Particles.SetParticleInput(currentLV);
                return(null);
            }

            //CHILD FUNCTION
            else if (context.functionCall_particle() != null)
            {
                //Function call.
                if (current.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   = current.Value as AlgoObject;
                string     funcName  = context.functionCall_particle().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);
                var result = VisitFunctionCall_particle(context.functionCall_particle());
                if (result == null)
                {
                    Particles.ResetParticleInput(); //Returned no result.
                }
                else
                {
                    //A result came back, set input for the next particle.
                    Particles.SetParticleInput((AlgoValue)result);
                }

                return(null);
            }
            else
            {
                //Unrecognized!
                Error.Internal("Unrecognized particle type to parse, implementation either unfinished or incorrect.");
                return(null);
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="algoParser.particle"/>.
 /// <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 VisitParticle([NotNull] algoParser.ParticleContext context)
 {
     return(VisitChildren(context));
 }
Exemplo n.º 3
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="algoParser.particle"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitParticle([NotNull] algoParser.ParticleContext context)
 {
 }