예제 #1
0
        private static ExpressionValue EvalPrimAppl(PrimitiveApplication application, ExpressionValue x1, Expression x2Exp, Valuation env)
        {
            try
            {
                ExpressionValue x2;
                switch (application.Operator)
                {
                case "<":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(((IntConstant)x1).Value < ((IntConstant)x2).Value));

                case "<=":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(((IntConstant)x1).Value <= ((IntConstant)x2).Value));

                case ">":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(((IntConstant)x1).Value > ((IntConstant)x2).Value));

                case ">=":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(((IntConstant)x1).Value >= ((IntConstant)x2).Value));

                case "==":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(x1.ExpressionID == x2.ExpressionID));

                case "!=":
                    x2 = Evaluate(x2Exp, env);
                    //return new BoolConstant(((IntConstant)x1).Value != ((IntConstant)x2).Value);
                    return(new BoolConstant(x1.ExpressionID != x2.ExpressionID));

                case "&&":
                    if (((BoolConstant)x1).Value)
                    {
                        x2 = Evaluate(x2Exp, env);
                        return(new BoolConstant(((BoolConstant)x2).Value));
                    }
                    else
                    {
                        return(new BoolConstant(false));
                    }

                case "||":
                    if (!((BoolConstant)x1).Value)
                    {
                        x2 = Evaluate(x2Exp, env);
                        return(new BoolConstant(((BoolConstant)x2).Value));
                    }
                    else
                    {
                        return(new BoolConstant(true));
                    }

                case "xor":
                    x2 = Evaluate(x2Exp, env);
                    return(new BoolConstant(((BoolConstant)x1).Value ^ ((BoolConstant)x2).Value));

                case "!":
                    return(new BoolConstant(!((BoolConstant)x1).Value));

                case "+":
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value + ((IntConstant)x2).Value));

                case "-":
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value - ((IntConstant)x2).Value));

                case "*":
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value * ((IntConstant)x2).Value));

                case "/":
                    x2 = Evaluate(x2Exp, env);
                    if (((IntConstant)x2).Value == 0)
                    {
                        throw new ArithmeticException("Divide by Zero on " + application.ToString());
                    }
                    else
                    {
                        return(new IntConstant(((IntConstant)x1).Value / ((IntConstant)x2).Value));
                    }

                case "mod":
                    x2 = Evaluate(x2Exp, env);
                    if (((IntConstant)x2).Value == 0)
                    {
                        throw new ArithmeticException("Modulo by Zero on " + application.ToString());
                    }
                    else
                    {
                        int int_X1 = ((IntConstant)x1).Value;
                        int int_X2 = ((IntConstant)x2).Value;

                        int tmp = int_X1 % int_X2;

                        return(new IntConstant((tmp >= 0) ? tmp : (tmp + int_X2)));
                    }

                //case "empty" :
                //    return new Value(((RecordValue) x1).Empty);
                //case "hasproperty":
                //    return new Value(((RecordValue)x1).HasProperty(((PropertyValue)x2).PropertyName));
                case ".":
                    RecordValue record = (RecordValue)x1;
                    x2 = Evaluate(x2Exp, env);
                    int index = ((IntConstant)x2).Value;
                    if (index < 0)
                    {
                        throw new NegativeArraySizeException("Access negative index " + index + " for variable " + application.Argument1.ToString() + " in expression " + application.ToString());
                    }
                    else if (index >= record.Associations.Length)
                    {
                        throw new IndexOutOfBoundsException("Index " + index + " is out of range for variable " + application.Argument1.ToString() + " in expression " + application.ToString());
                    }

                    return(record.Associations[index]);

                case "~":
                    return(new IntConstant(-((IntConstant)x1).Value));

                //Bitwise operators used by NESC module
                case "<<":    //bitwise left shift
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value << ((IntConstant)x2).Value));

                case ">>":    //bitwise right shift
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value >> ((IntConstant)x2).Value));

                case "&":    //bitwise AND
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value & ((IntConstant)x2).Value));

                case "^":    //bitwise XOR
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value ^ ((IntConstant)x2).Value));

                case "|":    //bitwise OR
                    x2 = Evaluate(x2Exp, env);
                    return(new IntConstant(((IntConstant)x1).Value | ((IntConstant)x2).Value));
                }
            }
            catch (InvalidCastException ex)
            {
                throw new RuntimeException("Invalid Cast Exception for " + application.ToString() + ": " + ex.Message.Replace("PAT.Common.Classes.Expressions.ExpressionClass.", ""));
            }
            //catch (Exception ex1)
            //{
            //    throw new RuntimeException("Invalid Primitive Operation: " + application.ToString() + "!");
            //}

            throw new RuntimeException("Invalid Primitive Operation: " + application.ToString() + "!");
        }