public DekiScriptExpression Visit(DekiScriptListConstructor expr, DekiScriptExpressionEvaluationState state)
        {
            // TODO (steveb): need to figure out how to optimize lists with generators
            if (expr.Generator != null)
            {
                return(expr);
            }

            // optimize each item in the list
            DekiScriptExpression[] list = new DekiScriptExpression[expr.Items.Length];
            bool isLiteral = true;

            for (int i = 0; i < expr.Items.Length; i++)
            {
                DekiScriptExpression item = expr.Items[i].VisitWith(this, state);
                list[i]   = item;
                isLiteral = isLiteral && (item is DekiScriptLiteral);
            }
            if (!isLiteral)
            {
                return(DekiScriptExpression.List(expr.Location, list));
            }

            // convert expression to a list
            DekiScriptList result = new DekiScriptList();

            foreach (DekiScriptLiteral literal in list)
            {
                result.Add(literal);
            }
            return(result);
        }
        public DekiScriptLiteral Visit(DekiScriptListConstructor expr, DekiScriptEnv env)
        {
            DekiScriptList result = new DekiScriptList();

            if (expr.Generator == null)
            {
                foreach (DekiScriptExpression item in expr.Items)
                {
                    result.Add(item.VisitWith(this, env));
                }
            }
            else
            {
                DekiScriptGeneratorEvaluation.Instance.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    foreach (DekiScriptExpression item in expr.Items)
                    {
                        result.Add(item.VisitWith(this, subEnv));
                    }
                }, env.NewLocalScope());
            }
            return(result);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptListConstructor expr, DekiScriptExpressionEvaluationState state)
        {
            DekiScriptList result = new DekiScriptList();

            if (expr.Generator == null)
            {
                foreach (DekiScriptExpression item in expr.Items)
                {
                    result.Add(state.Pop(item.VisitWith(this, state)));
                }
            }
            else
            {
                DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    foreach (DekiScriptExpression item in expr.Items)
                    {
                        var eval = state.Pop(item.VisitWith(this, state.With(subEnv)));
                        result.Add(eval);
                    }
                }, state);
            }
            return(state.Push(result));
        }