public DekiScriptOutputBuffer.Range Visit(DekiScriptForeach expr, DekiScriptExpressionEvaluationState state)
        {
            state.ThrowIfTimedout();
            int marker = state.Buffer.Marker;

            try {
                DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    // iterate over block statements
                    try {
                        expr.Body.VisitWith(this, state.With(subEnv));
                    } catch (DekiScriptContinueException) {
                        // ignore continue exceptions
                    }
                }, state);
            } catch (DekiScriptBreakException) {
                // ignore break exceptions
            }
            return(state.Buffer.Since(marker));
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state)
        {
            DekiScriptMap result = new DekiScriptMap();

            if (expr.Generator == null)
            {
                foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                {
                    DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state));

                    // check that key is a simple type
                    string text = key.AsString();
                    if (text != null)
                    {
                        DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state));
                        result.Add(text, value);
                    }
                }
            }
            else
            {
                DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) {
                    foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields)
                    {
                        DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state.With(subEnv)));

                        // check that key is a simple type
                        string text = key.AsString();
                        if (text != null)
                        {
                            DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state.With(subEnv)));
                            result.Add(text, value);
                        }
                    }
                }, state);
            }
            return(state.Push(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));
        }