public DekiScriptExpression Visit(DekiScriptTernary expr, DekiScriptExpressionEvaluationState state)
        {
            DekiScriptExpression test = expr.Test.VisitWith(this, state);
            DekiScriptExpression result;

            // check which branch should be executed
            if (test is DekiScriptLiteral)
            {
                if (((DekiScriptLiteral)test).IsNilFalseZero)
                {
                    result = expr.Right.VisitWith(this, state);
                }
                else
                {
                    result = expr.Left.VisitWith(this, state);
                }
            }
            else
            {
                var left  = expr.Left.VisitWith(this, state);
                var right = expr.Right.VisitWith(this, state);
                result = expr.IsIfElse ? DekiScriptExpression.IfElseStatement(expr.Location, test, left, right) : DekiScriptExpression.TernaryOp(expr.Location, test, left, right);
            }
            return(result);
        }
        public DekiScriptExpression Visit(DekiScriptTernary expr, DekiScriptOptimizerState state)
        {
            var mode = state.Mode;
            var env  = state.Env;
            DekiScriptExpression test = expr.Test.VisitWith(this, state);
            DekiScriptExpression result;

            // check if a local variable scope needs to be created
            if (expr.IsIfElse)
            {
                env = env.NewLocalScope();
            }

            // check which branch should be executed
            if (test is DekiScriptLiteral)
            {
                if (((DekiScriptLiteral)test).IsNilFalseZero)
                {
                    result = expr.Right.VisitWith(this, new DekiScriptOptimizerState(mode, env));
                }
                else
                {
                    result = expr.Left.VisitWith(this, new DekiScriptOptimizerState(mode, env));
                }
            }
            else
            {
                result = new DekiScriptTernary(expr.Line, expr.Column, test, expr.Left.VisitWith(this, new DekiScriptOptimizerState(mode, env)), expr.Right.VisitWith(this, new DekiScriptOptimizerState(mode, env)), expr.IsIfElse);
            }
            return(result);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptTernary expr, DekiScriptExpressionEvaluationState state)
        {
            DekiScriptLiteral test = state.Pop(expr.Test.VisitWith(this, state));
            DekiScriptLiteral result;

            // check which branch should be executed
            if (!test.IsNilFalseZero)
            {
                return(expr.Left.VisitWith(this, state));
            }
            else
            {
                return(expr.Right.VisitWith(this, state));
            }
        }
        public DekiScriptLiteral Visit(DekiScriptTernary expr, DekiScriptEnv env)
        {
            DekiScriptLiteral test = expr.Test.VisitWith(this, env);
            DekiScriptLiteral result;

            // check if a local variable scope needs to be created
            if (expr.IsIfElse)
            {
                env = env.NewLocalScope();
            }

            // check which branch should be executed
            if (!test.IsNilFalseZero)
            {
                result = expr.Left.VisitWith(this, env);
            }
            else
            {
                result = expr.Right.VisitWith(this, env);
            }
            return(result);
        }