예제 #1
0
        //When an expression is parsed in Algo.
        public override object VisitExpr([NotNull] algoParser.ExprContext context)
        {
            //Is it an addition?
            if (context.ADD_OP() != null)
            {
                //Yes. Evaluate the left hand expression.
                AlgoValue left = (AlgoValue)VisitExpr(context.expr());

                //Evaluate the right hand term.
                AlgoValue right = (AlgoValue)VisitTerm(context.term());

                //Perform an add operation, based on type.
                return(AlgoOperators.Add(context, left, right));
            }
            else if (context.TAKE_OP() != null)
            {
                //Take operation.
                //Evaluate the left hand expression.
                AlgoValue left = (AlgoValue)VisitExpr(context.expr());

                //Evaluate the right hand term.
                AlgoValue right = (AlgoValue)VisitTerm(context.term());

                //Perform a take operation, based on type.
                return(AlgoOperators.Sub(context, left, right));
            }
            else
            {
                //No, just a term, evaluate.
                return((AlgoValue)VisitTerm(context.term()));
            }
        }
예제 #2
0
        //Less than.
        public static bool LessThan(ParserRuleContext context, AlgoValue left, AlgoValue right, bool equalTo)
        {
            //Get the values for both left and right in a specific format.
            //(Statements must be in order of casting heirarchy, top down).
            if (left.Type == AlgoValueType.Float || right.Type == AlgoValueType.Float)
            {
                //Convert both to float.
                AlgoValue leftConverted  = AlgoOperators.ConvertType(context, left, AlgoValueType.Float);
                AlgoValue rightConverted = AlgoOperators.ConvertType(context, right, AlgoValueType.Float);

                //Check if the left is less than the right.
                if (equalTo)
                {
                    return((BigFloat)left.Value <= (BigFloat)right.Value);
                }
                else
                {
                    return((BigFloat)left.Value < (BigFloat)right.Value);
                }
            }
            else if (left.Type == AlgoValueType.Rational || right.Type == AlgoValueType.Rational)
            {
                //Convert both to rational.
                AlgoValue leftConverted  = AlgoOperators.ConvertType(context, left, AlgoValueType.Rational);
                AlgoValue rightConverted = AlgoOperators.ConvertType(context, right, AlgoValueType.Rational);

                //Check if the left is less than the right.
                if (equalTo)
                {
                    return((BigRational)left.Value <= (BigRational)right.Value);
                }
                else
                {
                    return((BigRational)left.Value < (BigRational)right.Value);
                }
            }
            else if (left.Type == AlgoValueType.Integer || right.Type == AlgoValueType.Integer)
            {
                //Convert both to integer.
                AlgoValue leftConverted  = AlgoOperators.ConvertType(context, left, AlgoValueType.Integer);
                AlgoValue rightConverted = AlgoOperators.ConvertType(context, right, AlgoValueType.Integer);

                //Check if the left is less than the right.
                if (equalTo)
                {
                    return((BigInteger)left.Value <= (BigInteger)right.Value);
                }
                else
                {
                    return((BigInteger)left.Value < (BigInteger)right.Value);
                }
            }
            else
            {
                Error.Fatal(context, "Cannot compare values with type " + left.Type.ToString() + " and " + right.Type.ToString() + ".");
                return(false);
            }
        }
예제 #3
0
        //When a variable is modified using a postfix operator.
        public override object VisitStat_setvar_postfix([NotNull] algoParser.Stat_setvar_postfixContext context)
        {
            //Get variable name.
            AlgoValue oldValue = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle());

            if (oldValue == null)
            {
                Error.Fatal(context, "No value returned to modify with operator.");
                return(null);
            }

            //Switch on the operator type.
            int toAdd = 0;

            if (context.postfix_op().ADD_PFOP() != null)
            {
                //Increment.
                toAdd = 1;
            }
            else
            {
                //Decrement.
                toAdd = -1;
            }

            //Apply the operator.
            AlgoValue newValue = null;

            switch (oldValue.Type)
            {
            case AlgoValueType.Integer:
            case AlgoValueType.Float:
            case AlgoValueType.Rational:
                newValue = AlgoOperators.Add(context, oldValue, new AlgoValue()
                {
                    Type  = AlgoValueType.Integer,
                    Value = new BigInteger(toAdd)
                });

                break;

            default:
                Error.Fatal(context, "Cannot increment a variable of type " + oldValue.Type.ToString() + ".");
                return(null);
            }

            //Set the variable value.
            oldValue.Value = newValue.Value;
            oldValue.Type  = newValue.Type;
            return(null);
        }
예제 #4
0
        //When a variable value is changed by a self modifying operator.
        public override object VisitStat_setvar_op([NotNull] algoParser.Stat_setvar_opContext context)
        {
            //Get variable reference.
            AlgoValue oldValue = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle());

            if (oldValue == null)
            {
                Error.Fatal(context, "No value returned to modify with operator.");
                return(null);
            }

            //Does, evaluate the expression to set the value.
            AlgoValue value = (AlgoValue)VisitExpr(context.expr());

            //Switching on selfmod value.
            AlgoValue newValue;

            if (context.selfmod_op().ADDFROM_OP() != null)
            {
                //Attempt to add.
                newValue = AlgoOperators.Add(context, oldValue, value);
            }
            else if (context.selfmod_op().DIVFROM_OP() != null)
            {
                //Attempt to divide.
                newValue = AlgoOperators.Div(context, oldValue, value);
            }
            else if (context.selfmod_op().MULFROM_OP() != null)
            {
                //Attempt to multiply.
                newValue = AlgoOperators.Mul(context, oldValue, value);
            }
            else if (context.selfmod_op().TAKEFROM_OP() != null)
            {
                //Attempt to subtract.
                newValue = AlgoOperators.Sub(context, oldValue, value);
            }
            else
            {
                //Invalid operator type, oopsie! Implemented in parser but not here.
                Error.Fatal(context, "Invalid operator given for self modifying variable, implemented in parser but not in interpreter.");
                return(null);
            }

            //Set the value of the variable.
            oldValue.Value = newValue.Value;
            oldValue.Type  = newValue.Type;
            return(null);
        }
예제 #5
0
        //Rational.
        public static AlgoValue ConvertRat(ParserRuleContext context, params AlgoValue[] args)
        {
            //Is it a string?
            if (args[0].Type == AlgoValueType.String)
            {
                //Return a parsed bigint.
                return(new AlgoValue()
                {
                    Type = AlgoValueType.Rational,
                    Value = BigRational.Parse((string)args[0].Value)
                });
            }

            //Nah, then just cast.
            return(AlgoOperators.ConvertType(context, args[0], AlgoValueType.Rational));
        }
예제 #6
0
        //When a single term is parsed in Algo.
        public override object VisitTerm([NotNull] algoParser.TermContext context)
        {
            //Is it a multiplication?
            if (context.MUL_OP() != null)
            {
                //Multiplication.
                //Evaluate the left side (term).
                AlgoValue left = (AlgoValue)VisitTerm(context.term());

                //Evaluate the right side.
                AlgoValue right = (AlgoValue)VisitFactor(context.factor());

                //Perform multiplication.
                return(AlgoOperators.Mul(context, left, right));
            }
            else if (context.DIV_OP() != null)
            {
                //Division.
                //Evaluate the left side (term).
                AlgoValue left = (AlgoValue)VisitTerm(context.term());

                //Evaluate the right side.
                AlgoValue right = (AlgoValue)VisitFactor(context.factor());

                //Perform division.
                return(AlgoOperators.Div(context, left, right));
            }
            else if (context.MOD_OP() != null)
            {
                //Modulus.
                AlgoValue left  = (AlgoValue)VisitTerm(context.term());
                AlgoValue right = (AlgoValue)VisitFactor(context.factor());

                //Perform modulus.
                return(AlgoOperators.Mod(context, left, right));
            }
            else
            {
                //No, just a factor, evaluate.
                return((AlgoValue)VisitFactor(context.factor()));
            }

            //Error.
            throw new Exception("Invalid expression type.");
        }
예제 #7
0
        //When a variable's value is changed.
        public override object VisitStat_setvar([NotNull] algoParser.Stat_setvarContext context)
        {
            //Get the variable/object reference.
            AlgoValue varToSet = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle());

            if (varToSet == null)
            {
                Error.Fatal(context, "No value returned to set.");
                return(null);
            }

            //Does, evaluate the expression to set the value.
            AlgoValue value = (AlgoValue)VisitExpr(context.expr());

            //Check if there's a rounding expression.
            if (context.rounding_expr() != null)
            {
                //Evaluate rounding number expression.
                AlgoValue roundingNum = (AlgoValue)VisitExpr(context.rounding_expr().expr());
                if (roundingNum.Type != AlgoValueType.Integer)
                {
                    Error.Warning(context, "Rounding expression did not return an integer to round by, so rounding was ignored.");
                }
                else if ((BigInteger)roundingNum.Value > int.MaxValue)
                {
                    Error.Warning(context, "Rounding number too large, so rounding was ignored.");
                }
                else
                {
                    //Getting rounding integer.
                    int roundingInt = int.Parse(((BigInteger)roundingNum.Value).ToString());

                    //Rounding the value, setting.
                    Scopes.SetVariable(context.IDENTIFIER().GetText(), AlgoOperators.Round(context, value, roundingInt));

                    return(null);
                }
            }

            //Set variable.
            varToSet.Value = value.Value;
            varToSet.Type  = value.Type;

            return(null);
        }
예제 #8
0
파일: AlgoIO.cs 프로젝트: c272/algo-lang
        //A "print" statement.
        public override object VisitStat_print([NotNull] algoParser.Stat_printContext context)
        {
            //Evaluate the expression.
            AlgoValue toPrint = (AlgoValue)VisitExpr(context.expr());

            //Depending on the type, set string accordingly via. casts.
            string printString = "";

            printString = AlgoConversion.GetStringRepresentation(toPrint);

            //Check if a rounding expression is present.
            if (context.rounding_expr() != null)
            {
                //Evaluate the rounding expression.
                AlgoValue roundingNum = (AlgoValue)VisitExpr(context.rounding_expr().expr());

                //Check if it's an integer.
                if (roundingNum.Type != AlgoValueType.Integer)
                {
                    Error.Warning(context, "Given rounding expression is not an integer, so can't round. Rounding was ignored.");
                }
                else
                {
                    //Check if the rounding value is too large.
                    if ((BigInteger)roundingNum.Value > int.MaxValue)
                    {
                        Error.Warning(context, "Given rounding number is too large to process, so rounding was ignored.");
                    }
                    else
                    {
                        //Round the actual value.
                        int roundingInt = int.Parse(((BigInteger)roundingNum.Value).ToString());
                        toPrint = AlgoOperators.Round(context, toPrint, roundingInt);

                        //Set print string.
                        printString = AlgoConversion.GetStringRepresentation(toPrint);
                    }
                }
            }

            //Print and return.
            Console.WriteLine(printString);
            return(null);
        }
예제 #9
0
        public void NullConversion()
        {
            //Create a test conversion for all of types from null.
            AlgoValue nullVal = AlgoValue.Null;

            ANTLRDebug.EnterTestMode();

            //Test all conversions (these are expected to throw).
            for (int i = 0; i < Enum.GetNames(typeof(AlgoValueType)).Length; i++)
            {
                try
                {
                    var attemptConv = AlgoOperators.ConvertType(null, nullVal, (AlgoValueType)i);
                }
                catch { Assert.Pass(); }
            }

            Assert.Fail();
        }
예제 #10
0
        public void StringConversions()
        {
            //Create test conversions for strings.
            AlgoValue stringVal = new AlgoValue()
            {
                Type  = AlgoValueType.String,
                Value = "the quick brown fox jumps over the lazy dog"
            };

            ANTLRDebug.EnterTestMode();

            //Values that should pass.
            AlgoValue testVal;

            try
            {
                testVal = AlgoOperators.ConvertType(null, stringVal, AlgoValueType.String);
            }
            catch
            {
                Assert.Fail();
            }

            //Values that should fail.
            for (int i = 0; i < Enum.GetNames(typeof(AlgoValueType)).Length; i++)
            {
                if ((AlgoValueType)i == AlgoValueType.String)
                {
                    continue;
                }

                try
                {
                    testVal = AlgoOperators.ConvertType(null, stringVal, (AlgoValueType)i);
                    Assert.Fail();
                }
                catch { }
            }

            Assert.Pass();
        }
예제 #11
0
        //When a single factor is parsed in Algo.
        public override object VisitFactor([NotNull] algoParser.FactorContext context)
        {
            //Is there a power?
            if (context.POW_OP() != null)
            {
                //Yes.
                //Evaluate left factor.
                AlgoValue left = (AlgoValue)VisitFactor(context.factor());

                //Evaluate right sub.
                AlgoValue right = (AlgoValue)VisitSub(context.sub());

                //Perform a power.
                return(AlgoOperators.Pow(context, left, right));
            }
            else
            {
                //No, just evaluate the sub.
                return((AlgoValue)VisitSub(context.sub()));
            }

            //Error.
            throw new Exception("Invalid expression type.");
        }
예제 #12
0
 //Bytes
 public static AlgoValue ConvertBytes(ParserRuleContext context, params AlgoValue[] args)
 {
     //Just return convertType, no special cases here.
     return(AlgoOperators.ConvertType(context, args[0], AlgoValueType.Bytes));
 }