using System.Collections.Generic; namespace tlang { public class EachLoop : Node { public GetVariableValue Name {get;set;} public Node List {get;set;} public Node Body {get;set;} public EachLoop(GetVariableValue name, Node ls,Node body) { Name = name; List = ls; Body=body; } private IEnumerable CreateItterator(IScopeEnvironment env,TObject ls) { var dict = ls as TDictionary; var str = ls as TString; var array = ls as TArray; if(dict!= null) { var gIttrVar = dict["ittr"] as TDictionary; var gIttrProp = dict["getittr"] as ICallable; var myObj = gIttrVar; if(gIttrProp != null) { var _myObj= gIttrProp.Call() as TDictionary; if(_myObj != null) { myObj = _myObj; } } if(myObj != null) { var reset = myObj["reset"] as ICallable; var moveNext = myObj["movenext"] as ICallable; var getCurrent = myObj["getcurrent"] as ICallable; if(reset != null) reset.Call(); if(moveNext != null) while(moveNext.Call().AsBoolean) { if(getCurrent != null) { yield return getCurrent.Call(); } else { var current = myObj["current"]; yield return current; } } } } else if(array != null) { foreach(var item in array.Items) { yield return item; } } else if(str != null) { foreach(var c in str.Value) { yield return TObject.Char(c); } } } public override TObject Execute(IScopeEnvironment nodeEnv) { var env = nodeEnv.SubEnv; var ls = List.Execute(env); bool isRunning=true; env["last_ittr"]= new TExternalMethod((args)=>{ isRunning=false; return TObject.True; }); TObject last = TObject.Uninit; var enumerator=CreateItterator(env,ls).GetEnumerator(); while(isRunning && enumerator.MoveNext()) { Name.SetValue(env,enumerator.Current); Body.Execute(env); } return last; } } }