protected override ScriptVariable CalculateInternal(ScriptExecutionEnvironment env)
        {
            ScriptVariable left = this.Left.Calculate(env);

            // ショートサーキット演算子
            switch (this.Operator)
            {
            case OperatorType.And:
                if (left == null)
                {
                    return(null);
                }
                if (!left.ToBoolean())
                {
                    return(new BooleanVariable(false));
                }
                return(this.Right.Calculate(env));

            case OperatorType.Or:
                if (left == null)
                {
                    return(null);
                }
                if (left.ToBoolean())
                {
                    return(new BooleanVariable(true));
                }
                return(this.Right.Calculate(env));
            }
            // 右辺
            ScriptVariable right = this.Right.Calculate(env);

            if (left == null || right == null)
            {
                // 片方nullの場合は等価比較演算以外はnull
                switch (this.Operator)
                {
                case OperatorType.Eq:
                    return(new BooleanVariable(left == right));

                case OperatorType.Ne:
                    return(new BooleanVariable(left != right));

                default:
                    return(null);
                }
            }
            // 普通の二項演算
            switch (this.Operator)
            {
            case OperatorType.Cross:
                return(left.Multiply(right));

            case OperatorType.Plus:
                return(left.Add(right));

            case OperatorType.Minus:
                return(left.Subtract(right));

            case OperatorType.Slash:
                return(left.Divide(right));

            case OperatorType.Percent:
                return(left.Remainder(right));
            }
            // 比較演算子
            int?tmp = left.CompareTo(right);

            if (tmp.HasValue)
            {
                int value = tmp.Value;
                switch (this.Operator)
                {
                case OperatorType.Eq:
                    return(new BooleanVariable(value == 0));

                case OperatorType.Ne:
                    return(new BooleanVariable(value != 0));

                case OperatorType.Gt:
                    return(new BooleanVariable(value > 0));

                case OperatorType.Ge:
                    return(new BooleanVariable(value >= 0));

                case OperatorType.Lt:
                    return(new BooleanVariable(value < 0));

                case OperatorType.Le:
                    return(new BooleanVariable(value <= 0));
                }
            }
            return(null);
        }