Minimum Viable Product
This commit is contained in:
parent
b74fd1d083
commit
fd57d7998c
15
AddNode.cs
15
AddNode.cs
|
@ -19,8 +19,21 @@ namespace tlang
|
||||||
var rNum = r as TNumber;
|
var rNum = r as TNumber;
|
||||||
var lStr = l as TString;
|
var lStr = l as TString;
|
||||||
var rStr = r as TString;
|
var rStr = r as TString;
|
||||||
|
var dleft = l as TDictionary;
|
||||||
|
|
||||||
|
if(dleft != null)
|
||||||
|
{
|
||||||
|
if(dleft.MemberExists("add"))
|
||||||
|
{
|
||||||
|
var mbm = dleft["add"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
return mbm.Call(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(lNum != null && rNum != null)
|
if(lNum != null && rNum != null)
|
||||||
return new TNumber(lNum.Value + rNum.Value);
|
return new TNumber(lNum.Value + rNum.Value);
|
||||||
|
|
||||||
|
@ -31,6 +44,8 @@ namespace tlang
|
||||||
if(lNum != null && rStr != null)
|
if(lNum != null && rStr != null)
|
||||||
return new TString(lNum.Value.ToString() + rStr.Value);
|
return new TString(lNum.Value.ToString() + rStr.Value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return new TNull();
|
return new TNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
internal class ArraySubscriptNode : MemberGetVariableValue
|
||||||
|
{
|
||||||
|
public Node Argument {get;set;}
|
||||||
|
|
||||||
|
public ArraySubscriptNode(Node parent, string text, Node arg) : base(parent,text)
|
||||||
|
{
|
||||||
|
|
||||||
|
Argument = arg;
|
||||||
|
}
|
||||||
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
|
{
|
||||||
|
var arg = Argument.Execute(nodeEnv);
|
||||||
|
var p=Parent.Execute(nodeEnv);
|
||||||
|
var dict = p as TDictionary;
|
||||||
|
var ls = p as TArray;
|
||||||
|
var str = p as TString;
|
||||||
|
if(dict != null)
|
||||||
|
{
|
||||||
|
var sArg = arg as TString;
|
||||||
|
var at = dict["at"] as ICallable;
|
||||||
|
|
||||||
|
if(at != null)
|
||||||
|
{
|
||||||
|
return at.Call(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sArg != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
return dict[sArg.Value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ls != null)
|
||||||
|
{
|
||||||
|
var nArg = arg as TNumber;
|
||||||
|
if(nArg != null && nArg.Value < ls.Items.Count)
|
||||||
|
{
|
||||||
|
return ls.Items[(int)nArg.Value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(str != null)
|
||||||
|
{
|
||||||
|
var nArg = arg as TNumber;
|
||||||
|
if(nArg != null && nArg.Value < str.Value.Length)
|
||||||
|
{
|
||||||
|
return new TChar(str.Value[(int)nArg.Value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TObject.Uninit;
|
||||||
|
}
|
||||||
|
public override void SetValue(IScopeEnvironment nodeEnv, TObject value)
|
||||||
|
{
|
||||||
|
var arg = Argument.Execute(nodeEnv);
|
||||||
|
var p=Parent.Execute(nodeEnv);
|
||||||
|
var dict = p as TDictionary;
|
||||||
|
var ls = p as TArray;
|
||||||
|
var str = p as TString;
|
||||||
|
if(dict != null)
|
||||||
|
{
|
||||||
|
var sArg = arg as TString;
|
||||||
|
var at = dict["setAt"] as ICallable;
|
||||||
|
|
||||||
|
if(at != null)
|
||||||
|
{
|
||||||
|
at.Call(arg,value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(sArg != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
dict[sArg.Value] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ls != null)
|
||||||
|
{
|
||||||
|
var nArg = arg as TNumber;
|
||||||
|
if(nArg != null && nArg.Value < ls.Items.Count)
|
||||||
|
{
|
||||||
|
ls.Items[(int)nArg.Value] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,11 +13,26 @@ namespace tlang
|
||||||
|
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var l = Left.Execute(nodeEnv) as TNumber;
|
var l = Left.Execute(nodeEnv);
|
||||||
var r = Right.Execute(nodeEnv) as TNumber;
|
var r = Right.Execute(nodeEnv);
|
||||||
|
var lnum = l as TNumber;
|
||||||
|
var rnum = r as TNumber;
|
||||||
|
var dleft = l as TDictionary;
|
||||||
|
|
||||||
if(l != null && r != null)
|
if(dleft != null)
|
||||||
return new TNumber(l.Value / r.Value);
|
{
|
||||||
|
if(dleft.MemberExists("divide"))
|
||||||
|
{
|
||||||
|
var mbm = dleft["divide"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
return mbm.Call(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lnum != null && rnum != null)
|
||||||
|
return new TNumber(lnum.Value / rnum.Value);
|
||||||
|
|
||||||
return new TNull();
|
return new TNull();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
if(gIttrProp != null)
|
||||||
|
{
|
||||||
|
var myObj= gIttrProp.Call() as TDictionary;
|
||||||
|
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 new TChar(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 new TNumber(1);
|
||||||
|
});
|
||||||
|
TObject last = TObject.Uninit;
|
||||||
|
|
||||||
|
var enumerator=CreateItterator(env,ls).GetEnumerator();
|
||||||
|
while(isRunning && enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
Name.SetValue(env,enumerator.Current);
|
||||||
|
Body.Execute(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
internal class ForLoop : Node
|
||||||
|
{
|
||||||
|
public Node Init {get;set;}
|
||||||
|
public Node Condition {get;set;}
|
||||||
|
public Node Increment {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
|
||||||
|
public ForLoop(Node init, Node condition, Node inc, Node body)
|
||||||
|
{
|
||||||
|
Init = init;
|
||||||
|
Condition = condition;
|
||||||
|
Increment = inc;
|
||||||
|
Body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
|
{
|
||||||
|
var env = nodeEnv.SubEnv;
|
||||||
|
bool isRunning=true;
|
||||||
|
env["last_ittr"]= new TExternalMethod((args)=>{
|
||||||
|
isRunning=false;
|
||||||
|
return new TNumber(1);
|
||||||
|
});
|
||||||
|
Init.Execute(env);
|
||||||
|
TObject obj=new TUninit();
|
||||||
|
while(Condition.Execute(env).AsBoolean && isRunning)
|
||||||
|
{
|
||||||
|
obj=Body.Execute(env);
|
||||||
|
Increment.Execute(env);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,19 +3,20 @@ namespace tlang
|
||||||
internal class SetVariableNode : Node
|
internal class SetVariableNode : Node
|
||||||
{
|
{
|
||||||
public Node Value {get;set;}
|
public Node Value {get;set;}
|
||||||
public string Name {get;set;}
|
public GetVariableValue Name {get;set;}
|
||||||
public SetVariableNode(string text,Node v)
|
public SetVariableNode(GetVariableValue gvn,Node v)
|
||||||
{
|
{
|
||||||
Name=text;
|
Name=gvn;
|
||||||
Value=v;
|
Value=v;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var res=Value.Execute(nodeEnv);
|
var res=Value.Execute(nodeEnv);
|
||||||
nodeEnv[Name]=res;
|
Name.SetValue(nodeEnv,res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public class GetVariableValue : Node
|
public class GetVariableValue : Node
|
||||||
{
|
{
|
||||||
|
@ -30,5 +31,9 @@ namespace tlang
|
||||||
{
|
{
|
||||||
return nodeEnv[Name];
|
return nodeEnv[Name];
|
||||||
}
|
}
|
||||||
|
public virtual void SetValue(IScopeEnvironment nodeEnv,TObject value)
|
||||||
|
{
|
||||||
|
nodeEnv[Name] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
12
IfNode.cs
12
IfNode.cs
|
@ -16,19 +16,13 @@ namespace tlang
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var condition = Condition.Execute(nodeEnv);
|
var condition = Condition.Execute(nodeEnv);
|
||||||
var cInt = condition as TNumber;
|
|
||||||
|
|
||||||
|
|
||||||
bool condition_bool=false;
|
|
||||||
|
|
||||||
if(cInt != null)
|
|
||||||
{
|
|
||||||
condition_bool=cInt.Value != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
return condition.AsBoolean ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv);
|
||||||
return condition_bool ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,9 @@ namespace tlang
|
||||||
|
|
||||||
var dict = res as TDictionary;
|
var dict = res as TDictionary;
|
||||||
var integer = res as TNumber;
|
var integer = res as TNumber;
|
||||||
|
var str = res as TString;
|
||||||
|
var chr = res as TChar;
|
||||||
|
var array = res as TArray;
|
||||||
if(dict != null)
|
if(dict != null)
|
||||||
{
|
{
|
||||||
var n = dict[Text] as ICallable;
|
var n = dict[Text] as ICallable;
|
||||||
|
@ -25,6 +27,74 @@ namespace tlang
|
||||||
{
|
{
|
||||||
return n.Call(Args.Select<Node,TObject>(e=>e.Execute(nodeEnv)).ToArray());
|
return n.Call(Args.Select<Node,TObject>(e=>e.Execute(nodeEnv)).ToArray());
|
||||||
}
|
}
|
||||||
|
}else if(chr != null)
|
||||||
|
{
|
||||||
|
if(Text == "toUpper")
|
||||||
|
{
|
||||||
|
return new TChar(char.ToUpper(chr.Value));
|
||||||
|
}
|
||||||
|
if(Text == "toLower")
|
||||||
|
{
|
||||||
|
return new TChar(char.ToLower(chr.Value));
|
||||||
|
}
|
||||||
|
if(Text == "toString")
|
||||||
|
{
|
||||||
|
return new TString(chr.Value.ToString());
|
||||||
|
}
|
||||||
|
if(Text == "toNumber")
|
||||||
|
{
|
||||||
|
return new TNumber(chr.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(array != null)
|
||||||
|
{
|
||||||
|
if(Text == "add")
|
||||||
|
{
|
||||||
|
if(Args.Count == 1)
|
||||||
|
{
|
||||||
|
TObject obj = Args[0].Execute(nodeEnv);
|
||||||
|
array.Items.Add(obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Text == "at")
|
||||||
|
{
|
||||||
|
//at(index)
|
||||||
|
if(Args.Count == 1)
|
||||||
|
{
|
||||||
|
var index=Args[0].Execute(nodeEnv) as TNumber;
|
||||||
|
if(index != null)
|
||||||
|
{
|
||||||
|
if(index.Value < array.Items.Count)
|
||||||
|
return array.Items[(int)index.Value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Text == "setAt")
|
||||||
|
{
|
||||||
|
TObject value = TObject.Null;
|
||||||
|
|
||||||
|
//setAt(index,value)
|
||||||
|
//setAt(index) //null
|
||||||
|
if(Args.Count == 2)
|
||||||
|
{
|
||||||
|
value=Args[1].Execute(nodeEnv);
|
||||||
|
}
|
||||||
|
if(Args.Count > 0)
|
||||||
|
{
|
||||||
|
var index=Args[0].Execute(nodeEnv) as TNumber;
|
||||||
|
if(index != null)
|
||||||
|
{
|
||||||
|
if(index.Value < array.Items.Count)
|
||||||
|
array.Items[(int)index.Value]=value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if(Text == "length" || Text == "count")
|
||||||
|
{
|
||||||
|
return new TNumber(array.Items.Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(integer != null)
|
else if(integer != null)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +106,79 @@ namespace tlang
|
||||||
{
|
{
|
||||||
return new TNumber(Math.Abs(integer.Value));
|
return new TNumber(Math.Abs(integer.Value));
|
||||||
}
|
}
|
||||||
|
if(Text == "toChar")
|
||||||
|
{
|
||||||
|
return new TChar((char)integer.Value);
|
||||||
|
}
|
||||||
|
}else if(str != null)
|
||||||
|
{
|
||||||
|
if(Text == "replace")
|
||||||
|
{
|
||||||
|
//todo fill this method out
|
||||||
|
}
|
||||||
|
if(Text == "split")
|
||||||
|
{
|
||||||
|
//todo fill this method out
|
||||||
|
//str.Value.Split(,,StringSplitOptions.TrimEntries);
|
||||||
|
}
|
||||||
|
if(Text == "startsWith")
|
||||||
|
{
|
||||||
|
string val = " ";
|
||||||
|
if(Args.Count > 0){
|
||||||
|
var firstArg = Args[0].Execute(nodeEnv);
|
||||||
|
var c = firstArg as TChar;
|
||||||
|
var mystr = firstArg as TString;
|
||||||
|
var mynum = firstArg as TNumber;
|
||||||
|
if(c!=null) val = c.Value.ToString();
|
||||||
|
if(mystr != null) val = mystr.Value.ToString();
|
||||||
|
if(mynum != null) val = mynum.Value.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return new TNumber(str.Value.StartsWith(val) ? 1 : 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(Text == "trimStart")
|
||||||
|
{
|
||||||
|
if(Args.Count == 0)
|
||||||
|
{
|
||||||
|
return new TString(str.Value.TrimStart());
|
||||||
|
}else{
|
||||||
|
|
||||||
|
return new TString(str.Value.TrimStart(Args.Select<Node,char>(n=>{
|
||||||
|
var nV=n.Execute(nodeEnv) as TChar;
|
||||||
|
if(nV != null)
|
||||||
|
{
|
||||||
|
return nV.Value;
|
||||||
|
}
|
||||||
|
return ' ';
|
||||||
|
}).ToArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Text == "trimEnd")
|
||||||
|
{
|
||||||
|
//trimend()
|
||||||
|
if(Args.Count == 0)
|
||||||
|
{
|
||||||
|
return new TString(str.Value.TrimEnd());
|
||||||
|
}else{
|
||||||
|
|
||||||
|
return new TString(str.Value.TrimEnd(Args.Select<Node,char>(n=>{
|
||||||
|
var nV=n.Execute(nodeEnv) as TChar;
|
||||||
|
if(nV != null)
|
||||||
|
{
|
||||||
|
return nV.Value;
|
||||||
|
}
|
||||||
|
return ' ';
|
||||||
|
}).ToArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Text == "toString")
|
||||||
|
{
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,4 +187,6 @@ namespace tlang
|
||||||
return new TUninit();
|
return new TUninit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,7 +7,26 @@ namespace tlang
|
||||||
{
|
{
|
||||||
Parent = parent;
|
Parent = parent;
|
||||||
}
|
}
|
||||||
|
public override void SetValue(IScopeEnvironment nodeEnv, TObject value)
|
||||||
|
{
|
||||||
|
var res=Parent.Execute(nodeEnv);
|
||||||
|
var dict = res as TDictionary;
|
||||||
|
if(dict != null)
|
||||||
|
{
|
||||||
|
if(dict.MemberExists($"set{Name}"))
|
||||||
|
{
|
||||||
|
var mbm= dict[$"set{Name}"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
mbm.Call(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
dict[Name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var res=Parent.Execute(nodeEnv);
|
var res=Parent.Execute(nodeEnv);
|
||||||
|
@ -15,6 +34,8 @@ namespace tlang
|
||||||
var dict = res as TDictionary;
|
var dict = res as TDictionary;
|
||||||
var integer = res as TNumber;
|
var integer = res as TNumber;
|
||||||
var array = res as TArray;
|
var array = res as TArray;
|
||||||
|
var str = res as TString;
|
||||||
|
|
||||||
if(array != null)
|
if(array != null)
|
||||||
{
|
{
|
||||||
if(Name == "length" || Name == "count")
|
if(Name == "length" || Name == "count")
|
||||||
|
@ -41,8 +62,36 @@ namespace tlang
|
||||||
|
|
||||||
if(integer != null)
|
if(integer != null)
|
||||||
{
|
{
|
||||||
|
if(Name == "abs")
|
||||||
|
{
|
||||||
|
return new TNumber(Math.Abs(integer.Value));
|
||||||
|
}
|
||||||
|
if(Name == "int")
|
||||||
|
{
|
||||||
|
return new TNumber(Math.Round(integer.Value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(str != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(Name == "number")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if(Name == "ittr")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if(Name == "length" || Name == "count")
|
||||||
|
{
|
||||||
|
return new TNumber(str.Value.Length);
|
||||||
|
}
|
||||||
|
if(Name == "list")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return new TUninit();
|
return new TUninit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,26 @@ namespace tlang
|
||||||
|
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var l = Left.Execute(nodeEnv) as TNumber;
|
var l = Left.Execute(nodeEnv);
|
||||||
var r = Right.Execute(nodeEnv) as TNumber;
|
var r = Right.Execute(nodeEnv);
|
||||||
|
var lnum = l as TNumber;
|
||||||
|
var rnum = r as TNumber;
|
||||||
|
var dleft = l as TDictionary;
|
||||||
|
|
||||||
if(l != null && r != null)
|
if(dleft != null)
|
||||||
return new TNumber(l.Value % r.Value);
|
{
|
||||||
|
if(dleft.MemberExists("mod"))
|
||||||
|
{
|
||||||
|
var mbm = dleft["mod"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
return mbm.Call(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lnum != null && rnum != null)
|
||||||
|
return new TNumber(lnum.Value % rnum.Value);
|
||||||
|
|
||||||
return new TNull();
|
return new TNull();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,26 @@ namespace tlang
|
||||||
|
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var l = Left.Execute(nodeEnv) as TNumber;
|
var l = Left.Execute(nodeEnv);
|
||||||
var r = Right.Execute(nodeEnv) as TNumber;
|
var r = Right.Execute(nodeEnv);
|
||||||
|
var lnum = l as TNumber;
|
||||||
|
var rnum = r as TNumber;
|
||||||
|
var dleft = l as TDictionary;
|
||||||
|
|
||||||
if(l != null && r != null)
|
if(dleft != null)
|
||||||
return new TNumber(l.Value * r.Value);
|
{
|
||||||
|
if(dleft.MemberExists("times"))
|
||||||
|
{
|
||||||
|
var mbm = dleft["times"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
return mbm.Call(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lnum != null && rnum != null)
|
||||||
|
return new TNumber(lnum.Value * rnum.Value);
|
||||||
|
|
||||||
return new TNull();
|
return new TNull();
|
||||||
}
|
}
|
||||||
|
|
265
Parser.cs
265
Parser.cs
|
@ -10,11 +10,12 @@ namespace tlang
|
||||||
|
|
||||||
public Node ParseExpression(List<LexToken> tokens,ref int i,bool isFirst=false)
|
public Node ParseExpression(List<LexToken> tokens,ref int i,bool isFirst=false)
|
||||||
{
|
{
|
||||||
|
if(i>= tokens.Count) return new ConstNode(new TNumber(0));
|
||||||
if(tokens[i].Text == "{" || isFirst)
|
if(tokens[i].Text == "{" || isFirst)
|
||||||
{
|
{
|
||||||
if(!isFirst)
|
if(!isFirst)
|
||||||
i++;
|
i++;
|
||||||
ScopeNode scopeNode = new ScopeNode();
|
ScopeNode scopeNode = new ScopeNode(){First=isFirst};
|
||||||
while(i<tokens.Count && tokens[i].Text != "}")
|
while(i<tokens.Count && tokens[i].Text != "}")
|
||||||
{
|
{
|
||||||
scopeNode.Body.Add(ParseExpression(tokens,ref i));
|
scopeNode.Body.Add(ParseExpression(tokens,ref i));
|
||||||
|
@ -41,8 +42,8 @@ namespace tlang
|
||||||
GetVariableValue? gvar = myExpression as GetVariableValue;
|
GetVariableValue? gvar = myExpression as GetVariableValue;
|
||||||
if(gvar != null)
|
if(gvar != null)
|
||||||
{
|
{
|
||||||
myExpression= new SetVariableNode(gvar.Name,ParseSum(tokens,ref i));
|
myExpression= new SetVariableNode(gvar,ParseSum(tokens,ref i));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ namespace tlang
|
||||||
if(token.IsString) return new ConstNode(new TString(token.Text));
|
if(token.IsString) return new ConstNode(new TString(token.Text));
|
||||||
if(token.IsChar)
|
if(token.IsChar)
|
||||||
{
|
{
|
||||||
return new ConstNode(new TNumber(token.Text.SingleOrDefault()));
|
return new ConstNode(new TChar(token.Text.SingleOrDefault()));
|
||||||
}
|
}
|
||||||
|
|
||||||
long val;
|
long val;
|
||||||
|
@ -126,7 +127,78 @@ namespace tlang
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
return new ClosureNode(args,ParseExpression(tokens,ref i));
|
return new ClosureNode(args,ParseExpression(tokens,ref i));
|
||||||
} else if(token.Text == "if")
|
}
|
||||||
|
else if(token.Text == "for")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
//init;condition;inc)
|
||||||
|
|
||||||
|
Node init = new ConstNode(new TUninit());
|
||||||
|
Node condition = new ConstNode(new TUninit());
|
||||||
|
Node inc = new ConstNode(new TUninit());
|
||||||
|
Node body = new ConstNode(new TUninit());
|
||||||
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
||||||
|
{
|
||||||
|
init = ParseExpression(tokens,ref i);
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == ";")
|
||||||
|
i++;
|
||||||
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
||||||
|
{
|
||||||
|
condition = ParseExpression(tokens,ref i);
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == ";")
|
||||||
|
i++;
|
||||||
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
||||||
|
{
|
||||||
|
inc = ParseExpression(tokens,ref i);
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == ")")
|
||||||
|
i++;
|
||||||
|
if(i<tokens.Count)
|
||||||
|
body = ParseExpression(tokens,ref i);
|
||||||
|
|
||||||
|
return new ForLoop(init,condition,inc,body);
|
||||||
|
}
|
||||||
|
else if(token.Text == "each")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
Node ls = ParseExpression(tokens,ref i);
|
||||||
|
GetVariableValue? name = new GetVariableValue("item");
|
||||||
|
if(i<tokens.Count && tokens[i].Text == ":")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var n=ls as GetVariableValue;
|
||||||
|
if(n != null) name = n;
|
||||||
|
ls = ParseExpression(tokens,ref i);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if(i<tokens.Count)
|
||||||
|
{
|
||||||
|
return new EachLoop(name,ls,ParseExpression(tokens,ref i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token.Text == "while")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var condition=ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
Node yes = new ConstNode(new TUninit());
|
||||||
|
if(i<tokens.Count && tokens[i].Text != ";")
|
||||||
|
yes = ParseExpression(tokens,ref i);
|
||||||
|
return new WhileLoop(condition,yes,false);
|
||||||
|
}
|
||||||
|
else if(token.Text == "do")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var condition=ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
Node yes = new ConstNode(new TUninit());
|
||||||
|
if(i<tokens.Count && tokens[i].Text != ";")
|
||||||
|
yes = ParseExpression(tokens,ref i);
|
||||||
|
return new WhileLoop(condition,yes,true);
|
||||||
|
}
|
||||||
|
else if(token.Text == "if")
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
var condition=ParseExpression(tokens,ref i);
|
var condition=ParseExpression(tokens,ref i);
|
||||||
|
@ -160,7 +232,15 @@ namespace tlang
|
||||||
|
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
var ret = new FunctionCallNode(token.Text,args);
|
Node ret = new FunctionCallNode(token.Text,args);
|
||||||
|
while(i<tokens.Count && tokens[i].Text == "[")
|
||||||
|
{
|
||||||
|
|
||||||
|
i++;
|
||||||
|
var arg = ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
ret = new ArraySubscriptNode(ret,token.Text,arg);
|
||||||
|
}
|
||||||
while(i<tokens.Count && tokens[i].Text == ".")
|
while(i<tokens.Count && tokens[i].Text == ".")
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
|
@ -171,7 +251,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
args = new List<Node>();
|
args = new List<Node>();
|
||||||
//function call baby
|
//function call baby
|
||||||
while(i<tokens.Count && tokens[i].Text != ")")
|
while(i<tokens.Count && tokens[i].Text != ")")
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -188,30 +268,125 @@ namespace tlang
|
||||||
}
|
}
|
||||||
else if(i<tokens.Count && tokens[i].Text == "[")
|
else if(i<tokens.Count && tokens[i].Text == "[")
|
||||||
{
|
{
|
||||||
|
i++;
|
||||||
|
var arg = ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
ret = new ArraySubscriptNode(ret,token2.Text,arg);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
ret = new MemberGetVariableValue(ret,token2.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == "++")
|
||||||
|
{
|
||||||
|
var mgvn = ret as GetVariableValue;
|
||||||
|
i++;
|
||||||
|
if(mgvn != null)
|
||||||
|
{
|
||||||
|
return new PostfixIncrementVariableNode(mgvn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == "--")
|
||||||
|
{
|
||||||
|
var mgvn = ret as GetVariableValue;
|
||||||
|
i++;
|
||||||
|
if(mgvn != null)
|
||||||
|
{
|
||||||
|
return new PostfixDecrementVariableNode(mgvn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
Node ret;
|
||||||
switch(token.Text)
|
switch(token.Text)
|
||||||
{
|
{
|
||||||
case "null":
|
case "null":
|
||||||
return new ConstNode(TObject.Null);
|
ret= new ConstNode(TObject.Null);
|
||||||
|
break;
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return new ConstNode(TObject.Uninit);
|
ret= new ConstNode(TObject.Uninit);
|
||||||
|
break;
|
||||||
case "true":
|
case "true":
|
||||||
return new ConstNode(new TNumber(1));
|
ret= new ConstNode(new TNumber(1));
|
||||||
|
break;
|
||||||
case "false":
|
case "false":
|
||||||
return new ConstNode(new TNumber(0));
|
ret= new ConstNode(new TNumber(0));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return new GetVariableValue(token.Text);
|
ret= new GetVariableValue(token.Text);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
while(i<tokens.Count && tokens[i].Text == "[")
|
||||||
|
{
|
||||||
|
|
||||||
|
i++;
|
||||||
|
var arg = ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
ret = new ArraySubscriptNode(ret,token.Text,arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(i<tokens.Count && tokens[i].Text == ".")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
|
||||||
|
var token2 = tokens[i++];
|
||||||
|
|
||||||
|
if(i<tokens.Count && tokens[i].Text == "(")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var args = new List<Node>();
|
||||||
|
//function call baby
|
||||||
|
while(i<tokens.Count && tokens[i].Text != ")")
|
||||||
|
{
|
||||||
|
|
||||||
|
if(tokens[i].Text == ",") {i++;continue;}
|
||||||
|
|
||||||
|
if(i<tokens.Count)
|
||||||
|
{
|
||||||
|
args.Add(ParseExpression(tokens,ref i));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
ret = new MemberFunctionCallNode(ret,token2.Text,args);
|
||||||
|
}
|
||||||
|
else if(i<tokens.Count && tokens[i].Text == "[")
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var arg = ParseExpression(tokens,ref i);
|
||||||
|
i++;
|
||||||
|
ret = new ArraySubscriptNode(ret,token2.Text,arg);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ret = new MemberGetVariableValue(ret,token2.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == "++")
|
||||||
|
{
|
||||||
|
var mgvn = ret as GetVariableValue;
|
||||||
|
i++;
|
||||||
|
if(mgvn != null)
|
||||||
|
{
|
||||||
|
return new PostfixIncrementVariableNode(mgvn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(i<tokens.Count && tokens[i].Text == "--")
|
||||||
|
{
|
||||||
|
var mgvn = ret as GetVariableValue;
|
||||||
|
i++;
|
||||||
|
if(mgvn != null)
|
||||||
|
{
|
||||||
|
return new PostfixDecrementVariableNode(mgvn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,5 +418,67 @@ namespace tlang
|
||||||
}
|
}
|
||||||
return myExpression;
|
return myExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadEnvironment(RootEnvironment env)
|
||||||
|
{
|
||||||
|
TDictionary fs = new TDictionary();
|
||||||
|
|
||||||
|
fs["enumerate_files"] = new TExternalMethod((args)=>{
|
||||||
|
if(args.Length > 0)
|
||||||
|
{
|
||||||
|
var fileName=args[0].ToString();
|
||||||
|
if(!string.IsNullOrWhiteSpace(fileName) && Directory.Exists(fileName))
|
||||||
|
{
|
||||||
|
var dict = new TDictionary();
|
||||||
|
dict["getIttr"] = new TExternalMethod((args2)=>{
|
||||||
|
var enumerable=Directory.EnumerateFiles(fileName).GetEnumerator();
|
||||||
|
TDictionary dict2 = new TDictionary();
|
||||||
|
|
||||||
|
dict2["movenext"] = new TExternalMethod((args3)=>{
|
||||||
|
|
||||||
|
return new TNumber(enumerable.MoveNext() ? 1 : 0);
|
||||||
|
});
|
||||||
|
dict2["getCurrent"] = new TExternalMethod((args3)=>{
|
||||||
|
return new TString(enumerable.Current);
|
||||||
|
});
|
||||||
|
|
||||||
|
return dict2;
|
||||||
|
});
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TObject.Null;
|
||||||
|
});
|
||||||
|
|
||||||
|
fs["enumerate_dirs"] = new TExternalMethod((args)=>{
|
||||||
|
if(args.Length > 0)
|
||||||
|
{
|
||||||
|
var fileName=args[0].ToString();
|
||||||
|
if(!string.IsNullOrWhiteSpace(fileName) && Directory.Exists(fileName))
|
||||||
|
{
|
||||||
|
var dict = new TDictionary();
|
||||||
|
dict["getIttr"] = new TExternalMethod((args2)=>{
|
||||||
|
var enumerable=Directory.EnumerateDirectories(fileName).GetEnumerator();
|
||||||
|
TDictionary dict2 = new TDictionary();
|
||||||
|
|
||||||
|
dict2["movenext"] = new TExternalMethod((args3)=>{
|
||||||
|
|
||||||
|
return new TNumber(enumerable.MoveNext() ? 1 : 0);
|
||||||
|
});
|
||||||
|
dict2["getCurrent"] = new TExternalMethod((args3)=>{
|
||||||
|
return new TString(enumerable.Current);
|
||||||
|
});
|
||||||
|
|
||||||
|
return dict2;
|
||||||
|
});
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TObject.Null;
|
||||||
|
});
|
||||||
|
env["fs"]=fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
public class PostfixDecrementVariableNode : Node
|
||||||
|
{
|
||||||
|
public GetVariableValue Node {get;set;}
|
||||||
|
|
||||||
|
public PostfixDecrementVariableNode(GetVariableValue ret)
|
||||||
|
{
|
||||||
|
Node = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
|
{
|
||||||
|
|
||||||
|
var obj=Node.Execute(nodeEnv);
|
||||||
|
|
||||||
|
var newVal=new SubtractNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv);
|
||||||
|
|
||||||
|
Node.SetValue(nodeEnv,newVal);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
public class PostfixIncrementVariableNode : Node
|
||||||
|
{
|
||||||
|
public GetVariableValue Node {get;set;}
|
||||||
|
|
||||||
|
public PostfixIncrementVariableNode(GetVariableValue ret)
|
||||||
|
{
|
||||||
|
Node = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
|
{
|
||||||
|
|
||||||
|
var obj=Node.Execute(nodeEnv);
|
||||||
|
|
||||||
|
var newVal=new AddNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv);
|
||||||
|
|
||||||
|
|
||||||
|
Node.SetValue(nodeEnv,newVal);
|
||||||
|
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Program.cs
44
Program.cs
|
@ -1,7 +1,7 @@
|
||||||
namespace tlang;
|
namespace tlang;
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Lexer lexer = new Lexer("testString.tlang");
|
//Lexer lexer = new Lexer("testString.tlang");
|
||||||
|
@ -9,13 +9,27 @@ class Program
|
||||||
//parser.Add(lexer.Tokens);
|
//parser.Add(lexer.Tokens);
|
||||||
int r=0;
|
int r=0;
|
||||||
RootEnvironment env=new RootEnvironment();
|
RootEnvironment env=new RootEnvironment();
|
||||||
env["mol"] = new TNumber(42);
|
parser.LoadEnvironment(env);
|
||||||
env["printargs"] = new TExternalMethod((args2)=>{
|
env["array"] = new TExternalMethod((args2)=>{
|
||||||
|
return new TArray();
|
||||||
|
});
|
||||||
|
env["dict"] = new TExternalMethod((args2)=>{
|
||||||
|
return new TDictionary();
|
||||||
|
});
|
||||||
|
env["print"] = new TExternalMethod((args2)=>{
|
||||||
foreach(var arg in args2)
|
foreach(var arg in args2)
|
||||||
{
|
{
|
||||||
Console.WriteLine(arg);
|
Console.Write(arg);
|
||||||
}
|
}
|
||||||
return new TNumber(args2.Length);
|
return new TNumber(args2.Length);
|
||||||
|
});
|
||||||
|
env["println"] = new TExternalMethod((args2)=>{
|
||||||
|
foreach(var arg in args2)
|
||||||
|
{
|
||||||
|
Console.Write(arg);
|
||||||
|
}
|
||||||
|
Console.WriteLine();
|
||||||
|
return new TNumber(args2.Length);
|
||||||
});
|
});
|
||||||
env["int"] = new TExternalMethod((args2)=>{
|
env["int"] = new TExternalMethod((args2)=>{
|
||||||
|
|
||||||
|
@ -90,9 +104,25 @@ class Program
|
||||||
});
|
});
|
||||||
|
|
||||||
Lexer lexer =new Lexer(new StreamReader("file.tlang"));
|
Lexer lexer =new Lexer(new StreamReader("file.tlang"));
|
||||||
var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env);
|
var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env) as TNumber;
|
||||||
r=0;
|
var main = env["main"] as ICallable;
|
||||||
Console.WriteLine(res);
|
|
||||||
|
if(main != null)
|
||||||
|
{
|
||||||
|
List<TString> args2=new List<TString>();
|
||||||
|
foreach(var argument in args)
|
||||||
|
{
|
||||||
|
args2.Add(new TString(argument));
|
||||||
|
}
|
||||||
|
res=main.Call(args2.ToArray()) as TNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res != null)
|
||||||
|
{
|
||||||
|
return (int)res.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ namespace tlang
|
||||||
|
|
||||||
public TObject GetVariable(string name)
|
public TObject GetVariable(string name)
|
||||||
{
|
{
|
||||||
|
if(name == "last_ittr" && items.ContainsKey("last_ittr"))
|
||||||
|
{
|
||||||
|
return items["last_ittr"];
|
||||||
|
}
|
||||||
if(parent.VariableExists(name))
|
if(parent.VariableExists(name))
|
||||||
{
|
{
|
||||||
return parent[name];
|
return parent[name];
|
||||||
|
@ -66,8 +70,9 @@ namespace tlang
|
||||||
|
|
||||||
public void SetVariable(string name, TObject obj)
|
public void SetVariable(string name, TObject obj)
|
||||||
{
|
{
|
||||||
if(parent.VariableExists(name))
|
if(parent.VariableExists(name) && name != "last_ittr")
|
||||||
{
|
{
|
||||||
|
|
||||||
parent.SetVariable(name,obj);
|
parent.SetVariable(name,obj);
|
||||||
}else if(items.ContainsKey(name))
|
}else if(items.ContainsKey(name))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,10 +2,11 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class ScopeNode : Node
|
public class ScopeNode : Node
|
||||||
{
|
{
|
||||||
|
public bool First {get;set;}
|
||||||
public List<Node> Body {get;set;}= new List<Node>();
|
public List<Node> Body {get;set;}= new List<Node>();
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var sub = nodeEnv.SubEnv;
|
var sub = First ? nodeEnv : nodeEnv.SubEnv;
|
||||||
TObject obj=new TNull();
|
TObject obj=new TNull();
|
||||||
foreach(var item in Body)
|
foreach(var item in Body)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,11 +13,26 @@ namespace tlang
|
||||||
|
|
||||||
public override TObject Execute(IScopeEnvironment nodeEnv)
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
{
|
{
|
||||||
var l = Left.Execute(nodeEnv) as TNumber;
|
var l = Left.Execute(nodeEnv);
|
||||||
var r = Right.Execute(nodeEnv) as TNumber;
|
var r = Right.Execute(nodeEnv);
|
||||||
|
var lnum = l as TNumber;
|
||||||
|
var rnum = r as TNumber;
|
||||||
|
var dleft = l as TDictionary;
|
||||||
|
|
||||||
if(l != null && r != null)
|
if(dleft != null)
|
||||||
return new TNumber(l.Value - r.Value);
|
{
|
||||||
|
if(dleft.MemberExists("sub"))
|
||||||
|
{
|
||||||
|
var mbm = dleft["sub"] as ICallable;
|
||||||
|
if(mbm != null)
|
||||||
|
{
|
||||||
|
return mbm.Call(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lnum != null && rnum != null)
|
||||||
|
return new TNumber(lnum.Value - rnum.Value);
|
||||||
|
|
||||||
return new TNull();
|
return new TNull();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TArray : TObject
|
public class TArray : TObject
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean => Items.Count > 0;
|
||||||
public TArray()
|
public TArray()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
internal class TChar : TObject
|
||||||
|
{
|
||||||
|
public override bool AsBoolean => Value != '\0';
|
||||||
|
public char Value {get;set;}
|
||||||
|
public TChar(char v)
|
||||||
|
{
|
||||||
|
Value = v;
|
||||||
|
}
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TDictionary : TObject
|
public class TDictionary : TObject
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean {get =>true;}
|
||||||
public TDictionary()
|
public TDictionary()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TInternalObject : TObject
|
public class TInternalObject : TObject
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean => true;
|
||||||
public TInternalObject(object val)
|
public TInternalObject(object val)
|
||||||
{
|
{
|
||||||
Object=val;
|
Object=val;
|
||||||
|
|
16
TMethod.cs
16
TMethod.cs
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TInternalMethod : TObject, ICallable
|
public class TInternalMethod : TObject, ICallable
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean => true;
|
||||||
public TInternalMethod(ClosureNode node,IScopeEnvironment env)
|
public TInternalMethod(ClosureNode node,IScopeEnvironment env)
|
||||||
{
|
{
|
||||||
Body = node;
|
Body = node;
|
||||||
|
@ -21,24 +22,27 @@ namespace tlang
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(;i<optionalArgs(args.Length);i++)
|
for(;i<optionalArgs(args.Length);i++)
|
||||||
{
|
{
|
||||||
env[Body.Arguments[i].TrimStart('.')] = args[i];
|
env[Body.Arguments[i].TrimStart('$')] = args[i];
|
||||||
}
|
}
|
||||||
if(i==Body.Arguments.Count-1)
|
if(i==Body.Arguments.Count-1)
|
||||||
{
|
{
|
||||||
var tarray = new TArray();
|
var tarray = new TArray();
|
||||||
env[Body.Arguments[i].TrimStart('.')] =tarray;
|
env[Body.Arguments[i].TrimStart('$')] =tarray;
|
||||||
for(int j = i;j<args.Length;j++)
|
for(int j = i;j<args.Length;j++)
|
||||||
{
|
{
|
||||||
tarray.Items.Add(args[j]);
|
tarray.Items.Add(args[j]);
|
||||||
}
|
}
|
||||||
|
i = args.Length;
|
||||||
}
|
}
|
||||||
|
if(i<args.Length)
|
||||||
|
throw new Exception("too many arguments");
|
||||||
return Body.Node.Execute(env);
|
return Body.Node.Execute(env);
|
||||||
}
|
}
|
||||||
private int optionalArgs(int argLen)
|
private int optionalArgs(int argLen)
|
||||||
{
|
{
|
||||||
for(int i =0;i<Body.Arguments.Count;i++)
|
for(int i =0;i<Body.Arguments.Count;i++)
|
||||||
{
|
{
|
||||||
if(Body.Arguments[i].StartsWith("..."))
|
if(Body.Arguments[i].StartsWith("$$"))
|
||||||
{
|
{
|
||||||
return Math.Min(argLen,i);
|
return Math.Min(argLen,i);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +53,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
for(int i =0;i<Body.Arguments.Count;i++)
|
for(int i =0;i<Body.Arguments.Count;i++)
|
||||||
{
|
{
|
||||||
if(Body.Arguments[i].StartsWith('.'))
|
if(Body.Arguments[i].StartsWith('$'))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,9 @@ namespace tlang
|
||||||
{
|
{
|
||||||
cb = func;
|
cb = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool AsBoolean => true;
|
||||||
|
|
||||||
public TObject Call(params TObject[] args)
|
public TObject Call(params TObject[] args)
|
||||||
{
|
{
|
||||||
return cb(args);
|
return cb(args);
|
||||||
|
|
1
TNull.cs
1
TNull.cs
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TNull : TObject
|
public class TNull : TObject
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean => false;
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "null";
|
return "null";
|
||||||
|
|
|
@ -3,6 +3,9 @@ namespace tlang
|
||||||
public class TNumber : TObject
|
public class TNumber : TObject
|
||||||
{
|
{
|
||||||
public double Value {get;set;}
|
public double Value {get;set;}
|
||||||
|
|
||||||
|
public override bool AsBoolean => Value != 0;
|
||||||
|
|
||||||
public TNumber(double number)
|
public TNumber(double number)
|
||||||
{
|
{
|
||||||
Value = number;
|
Value = number;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
namespace tlang
|
namespace tlang
|
||||||
{
|
{
|
||||||
public class TObject
|
public abstract class TObject
|
||||||
{
|
{
|
||||||
|
public abstract bool AsBoolean {get;}
|
||||||
public static TObject Uninit => new TUninit();
|
public static TObject Uninit => new TUninit();
|
||||||
public static TObject Null => new TNull();
|
public static TObject Null => new TNull();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@ namespace tlang
|
||||||
public class TString : TObject
|
public class TString : TObject
|
||||||
{
|
{
|
||||||
public string Value {get;set;}
|
public string Value {get;set;}
|
||||||
|
|
||||||
|
public override bool AsBoolean => Value.Length > 0;
|
||||||
|
|
||||||
public TString(string text)
|
public TString(string text)
|
||||||
{
|
{
|
||||||
Value = text;
|
Value = text;
|
||||||
|
|
|
@ -2,6 +2,7 @@ namespace tlang
|
||||||
{
|
{
|
||||||
public class TUninit : TObject
|
public class TUninit : TObject
|
||||||
{
|
{
|
||||||
|
public override bool AsBoolean {get=>false;}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "undefined";
|
return "undefined";
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
namespace tlang
|
||||||
|
{
|
||||||
|
public class WhileLoop : Node
|
||||||
|
{
|
||||||
|
public Node Condition {get;set;}
|
||||||
|
public Node Body {get;set;}
|
||||||
|
public bool DoLoop {get;set;}
|
||||||
|
|
||||||
|
public WhileLoop(Node condition, Node yes, bool v)
|
||||||
|
{
|
||||||
|
Condition = condition;
|
||||||
|
Body = yes;
|
||||||
|
DoLoop = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TObject Execute(IScopeEnvironment nodeEnv)
|
||||||
|
{
|
||||||
|
bool isRunning=true;
|
||||||
|
var env = nodeEnv.SubEnv;
|
||||||
|
|
||||||
|
env["last_ittr"]= new TExternalMethod((args)=>{
|
||||||
|
isRunning=false;
|
||||||
|
return new TNumber(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
TObject obj=new TUninit();
|
||||||
|
|
||||||
|
if(!DoLoop) isRunning = Condition.Execute(env).AsBoolean;
|
||||||
|
while(isRunning)
|
||||||
|
{
|
||||||
|
|
||||||
|
obj=Body.Execute(env);
|
||||||
|
isRunning = Condition.Execute(env).AsBoolean;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
file.tlang
15
file.tlang
|
@ -1,7 +1,8 @@
|
||||||
/*
|
each(dir : fs.enumerate_dirs(fs.home))
|
||||||
if(expression) expression else expression
|
{
|
||||||
*/
|
println(dir);
|
||||||
|
}
|
||||||
j = func() 42-43;
|
each(file : fs.enumerate_files(fs.home))
|
||||||
|
{
|
||||||
printargs(j().abs());
|
println(file);
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
var s1="Some \"Some String\" Is Cool";
|
|
||||||
var s2="My String Is Awesome";
|
|
||||||
var s3="Demi\nLovato";
|
|
||||||
|
|
||||||
var main = (args)=>{
|
|
||||||
ret 0;
|
|
||||||
};
|
|
Loading…
Reference in New Issue