tlang-interperter-cs/tlanglib/EachLoop.cs

102 lines
3.0 KiB
C#

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<TObject> 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;
}
}
}