Esempio n. 1
0
        //When a function is defined.
        public override object VisitStat_functionDef([NotNull] algoParser.Stat_functionDefContext context)
        {
            //Does a variable with this name already exist?
            if (Scopes.VariableExistsLowest(context.IDENTIFIER().GetText()))
            {
                Error.Fatal(context, "A variable with this name already exists, cannot create function with this name.");
                return(null);
            }

            //Getting parameters.
            List <string> params_ = new List <string>();

            if (context.abstract_params() != null)
            {
                foreach (var param in context.abstract_params().IDENTIFIER())
                {
                    //Check if param already exists.
                    if (params_.Contains(param.GetText()))
                    {
                        Error.Fatal(context, "The parameter with name '" + param.GetText() + "' is already defined in the function.");
                        return(null);
                    }

                    params_.Add(param.GetText());
                }
            }

            //No, it doesn't exist. Define it.
            AlgoFunction func      = new AlgoFunction(context.statement().ToList(), params_, context.IDENTIFIER().GetText());
            AlgoValue    funcValue = new AlgoValue()
            {
                Type  = AlgoValueType.Function,
                Value = func
            };

            //Add to scope.
            Scopes.AddVariable(context.IDENTIFIER().GetText(), funcValue);
            return(null);
        }
Esempio n. 2
0
        //When a single value is visited in Algo.
        public override object VisitValue([NotNull] algoParser.ValueContext context)
        {
            //Check what type the value is.
            if (context.INTEGER() != null)
            {
                //INTEGER
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Integer,
                    Value = BigInteger.Parse(context.INTEGER().GetText()),
                });
            }
            else if (context.FLOAT() != null)
            {
                //FLOAT
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Float,
                    Value = BigFloat.Parse(context.FLOAT().GetText()),
                });
            }
            else if (context.STRING() != null)
            {
                //STRING
                return(new AlgoValue()
                {
                    Type = AlgoValueType.String,
                    Value = context.STRING().GetText().Substring(1, context.STRING().GetText().Length - 2)
                            //text escape codes
                            .Replace("\\n", "\n")
                            .Replace("\\t", "\t")
                            .Replace("\\r", "\r")
                            .Replace("\\q", "\"")
                });
            }
            else if (context.RATIONAL() != null)
            {
                //RATIONAL
                //Get the two integer halves from the rational.
                string[] halves      = context.RATIONAL().GetText().Split('/');
                string   numerator   = halves[0];
                string   denominator = halves[1];

                return(new AlgoValue()
                {
                    Type = AlgoValueType.Rational,
                    Value = new BigRational(BigInteger.Zero, new Fraction(BigInteger.Parse(numerator), BigInteger.Parse(denominator))),
                });
            }
            else if (context.BOOLEAN() != null)
            {
                //BOOLEAN
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Boolean,
                    Value = (context.BOOLEAN().GetText() == "true"),
                });
            }
            else if (context.HEX() != null)
            {
                //BYTES
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Bytes,
                    Value = context.HEX().GetText().ToByteArray()
                });
            }
            else if (context.NULL() != null)
            {
                //NULL VALUE
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Null,
                    Value = null,
                });
            }
            else if (context.IDENTIFIER() != null)
            {
                //VARIABLE/OBJECT
                return(Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle()));
            }
            else if (context.stat_functionCall() != null)
            {
                //FUNCTION CALL
                AlgoValue value = (AlgoValue)VisitStat_functionCall(context.stat_functionCall());
                if (value != null)
                {
                    return(value);
                }
                else
                {
                    //Return a null value.
                    return(new AlgoValue()
                    {
                        Type = AlgoValueType.Null,
                        Value = null,
                    });
                }
            }
            else if (context.array() != null)
            {
                //LIST.

                //Evaluate all list items as expressions.
                List <AlgoValue> list = new List <AlgoValue>();
                foreach (var item in context.array().value())
                {
                    list.Add((AlgoValue)VisitValue(item));
                }

                //Return as a single value.
                return(new AlgoValue()
                {
                    Type = AlgoValueType.List,
                    Value = list
                });
            }
            else if (context.@object() != null)
            {
                //OBJECT DEFINITION

                //Create a new object.
                AlgoObject toReturn = new AlgoObject();

                //Anything to enumerate?
                if (context.@object().obj_child_definitions() == null)
                {
                    //Nope.
                    return(new AlgoValue()
                    {
                        Type = AlgoValueType.Object,
                        Value = toReturn
                    });
                }

                //Enumerate through all the define statements and evaluate their values.
                foreach (var value in context.@object().obj_child_definitions().obj_vardefine())
                {
                    //Check if the variable already exists.
                    if (toReturn.ObjectScopes.VariableExists(value.IDENTIFIER().GetText()))
                    {
                        Error.Fatal(context, "The variable with name '" + value.IDENTIFIER().GetText() + "' is defined twice or more in an object.");
                        return(null);
                    }

                    //Evaluate the value on the right.
                    AlgoValue evaluated = (AlgoValue)VisitExpr(value.expr());

                    //Add the variable to scope.
                    toReturn.ObjectScopes.AddVariable(value.IDENTIFIER().GetText(), evaluated);
                }

                //Enumerate through all functions and define them.
                foreach (var value in context.@object().obj_child_definitions().obj_funcdefine())
                {
                    //Check if the variable already exists.
                    if (toReturn.ObjectScopes.VariableExists(value.IDENTIFIER().GetText()))
                    {
                        Error.Fatal(context, "The variable with name '" + value.IDENTIFIER().GetText() + "' is defined twice or more in an object.");
                        return(null);
                    }

                    //Create a list of parameters.
                    List <string> params_ = new List <string>();
                    if (value.abstract_params() != null)
                    {
                        foreach (var param in value.abstract_params().IDENTIFIER())
                        {
                            //Check if param already exists.
                            if (params_.Contains(param.GetText()))
                            {
                                Error.Fatal(context, "The parameter with name '" + param.GetText() + "' is already defined in the function.");
                                return(null);
                            }

                            params_.Add(param.GetText());
                        }
                    }

                    //Create a function, push.
                    AlgoFunction func      = new AlgoFunction(value.statement().ToList(), params_, value.IDENTIFIER().GetText());
                    AlgoValue    funcValue = new AlgoValue()
                    {
                        Type  = AlgoValueType.Function,
                        Value = func,
                    };

                    toReturn.ObjectScopes.AddVariable(value.IDENTIFIER().GetText(), funcValue);
                }

                //Enumerate all external functions defined.
                foreach (var ext in context.@object().obj_child_definitions().obj_externdefine())
                {
                    //Get the value of the function.
                    var       loadFuncStat = ext.stat_loadFuncExt();
                    AlgoValue func         = Plugins.GetEmulatedFuncValue(loadFuncStat);

                    //Check if a variable with this name already exists.
                    if (toReturn.ObjectScopes.VariableExists(loadFuncStat.IDENTIFIER()[0].GetText()))
                    {
                        Error.Fatal(context, "A variable with the name '" + loadFuncStat.IDENTIFIER()[0].GetText() + "' already exists in this object. Cannot duplicate.");
                        return(null);
                    }

                    //Add that function to the return object.
                    toReturn.ObjectScopes.AddVariable(loadFuncStat.IDENTIFIER()[0].GetText(), func);
                }

                //Return the object.
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Object,
                    Value = toReturn
                });
            }
            else
            {
                //No proper detected value type.
                Error.Fatal(context, "Unknown or invalid type given for value.");
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Null,
                    Value = null
                });
            }
        }