public Empty Visit(DekiScriptGeneratorForeachKeyValue expr, DekiScriptGeneratorEvaluationState state) { DekiScriptLiteral collection = Eval(expr.Collection, state); // retrieve collection Dictionary <string, DekiScriptLiteral> map; if (collection is DekiScriptMap) { // loop over map key-value pairs map = ((DekiScriptMap)collection).Value; } else if (collection is DekiScriptNil) { // nothing to do map = new Dictionary <string, DekiScriptLiteral>(); } else { throw new DekiScriptBadTypeException(expr.Location, collection.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.NIL }); } // store state of variables var previousKey = state.State.Env.Vars[expr.Key]; var previousValue = state.State.Env.Vars[expr.Value]; var previousIndex = state.State.Env.Vars[DekiScriptRuntime.INDEX_ID]; try { // loop over collection int index = 0; foreach (KeyValuePair <string, DekiScriptLiteral> entry in map) { // set the environment variable state.State.Env.Vars.Add(expr.Key, DekiScriptExpression.Constant(entry.Key)); state.State.Env.Vars.Add(expr.Value, entry.Value); state.State.Env.Vars.Add(DekiScriptRuntime.INDEX_ID, DekiScriptExpression.Constant(index)); // iterate over block statements EvalNext(expr, state); ++index; } } finally { state.State.Env.Vars.Add(expr.Key, previousKey); state.State.Env.Vars.Add(expr.Value, previousValue); state.State.Env.Vars.Add(DekiScriptRuntime.INDEX_ID, previousIndex); } return(Empty.Value); }
public Empty Visit(DekiScriptGeneratorForeachKeyValue expr, DekiScriptGeneratorEvaluationState state) { DekiScriptLiteral collection = expr.Collection.VisitWith(DekiScriptExpressionEvaluation.Instance, state.Env); // retrieve collection Dictionary <string, DekiScriptLiteral> map; if (collection is DekiScriptMap) { // loop over map key-value pairs map = ((DekiScriptMap)collection).Value; } else if (collection is DekiScriptNil) { // nothing to do map = new Dictionary <string, DekiScriptLiteral>(); } else { throw new DekiScriptBadTypeException(expr.Line, expr.Column, collection.ScriptType, new DekiScriptType[] { DekiScriptType.MAP, DekiScriptType.NIL }); } // loop over collection int index = 0; foreach (KeyValuePair <string, DekiScriptLiteral> entry in map) { // set the environment variable state.Env.Locals.Add(expr.Key, DekiScriptString.New(entry.Key)); state.Env.Locals.Add(expr.Value, entry.Value); state.Env.Locals.Add(DekiScriptRuntime.INDEX_ID, DekiScriptNumber.New(index)); // iterate over block statements Generate(expr, state); ++index; } return(Empty.Value); }
void GeneratorHead(out DekiScriptGenerator gen) { Location location = Location.None; Location wherelocation = Location.None; DekiScriptExpression where = null; List<string> names = new List<string>(); DekiScriptExpression expr = null; string value = null; gen = null; Expect(19); location = t.Location; Expect(1); names.Add(t.val); if (la.kind == 31) { Get(); Expect(1); value = t.val; Expect(52); Expression(out expr); if (la.kind == 70) { Get(); wherelocation = t.Location; Expression(out where); } } else if (la.kind == 20 || la.kind == 52) { while (la.kind == 20) { Get(); Expect(1); names.Add(t.val); } Expect(52); Expression(out expr); if (la.kind == 70) { Get(); wherelocation = t.Location; Expression(out where); } } else SynErr(80); if (la.kind == 20) { Get(); GeneratorNext(out gen); } if(where != null) gen = new DekiScriptGeneratorIf(wherelocation, where, gen); if(value == null) gen = new DekiScriptGeneratorForeachValue(location, names.ToArray(), expr, gen); else gen = new DekiScriptGeneratorForeachKeyValue(location, names[0], value, expr, gen); }