diff --git a/AddNode.cs b/AddNode.cs index 18c949a..e3b5e50 100644 --- a/AddNode.cs +++ b/AddNode.cs @@ -19,8 +19,21 @@ namespace tlang var rNum = r as TNumber; var lStr = l 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) return new TNumber(lNum.Value + rNum.Value); @@ -31,6 +44,8 @@ namespace tlang if(lNum != null && rStr != null) return new TString(lNum.Value.ToString() + rStr.Value); + + return new TNull(); } } diff --git a/ArraySubscriptNode.cs b/ArraySubscriptNode.cs new file mode 100644 index 0000000..9dc2a33 --- /dev/null +++ b/ArraySubscriptNode.cs @@ -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; + } + } + } + } +} \ No newline at end of file diff --git a/DivideNode.cs b/DivideNode.cs index 94728b2..c7ff7e2 100644 --- a/DivideNode.cs +++ b/DivideNode.cs @@ -13,11 +13,26 @@ namespace tlang public override TObject Execute(IScopeEnvironment nodeEnv) { - var l = Left.Execute(nodeEnv) as TNumber; - var r = Right.Execute(nodeEnv) as TNumber; + var l = Left.Execute(nodeEnv); + 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) - return new TNumber(l.Value / r.Value); + if(dleft != null) + { + 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(); } diff --git a/EachLoop.cs b/EachLoop.cs new file mode 100644 index 0000000..5072d5a --- /dev/null +++ b/EachLoop.cs @@ -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 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; + } + } +} \ No newline at end of file diff --git a/ForLoop.cs b/ForLoop.cs new file mode 100644 index 0000000..44b2694 --- /dev/null +++ b/ForLoop.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/GetVariableValue.cs b/GetVariableValue.cs index e0b6356..414bee6 100644 --- a/GetVariableValue.cs +++ b/GetVariableValue.cs @@ -3,19 +3,20 @@ namespace tlang internal class SetVariableNode : Node { public Node Value {get;set;} - public string Name {get;set;} - public SetVariableNode(string text,Node v) + public GetVariableValue Name {get;set;} + public SetVariableNode(GetVariableValue gvn,Node v) { - Name=text; + Name=gvn; Value=v; } public override TObject Execute(IScopeEnvironment nodeEnv) { var res=Value.Execute(nodeEnv); - nodeEnv[Name]=res; + Name.SetValue(nodeEnv,res); return res; } + } public class GetVariableValue : Node { @@ -30,5 +31,9 @@ namespace tlang { return nodeEnv[Name]; } + public virtual void SetValue(IScopeEnvironment nodeEnv,TObject value) + { + nodeEnv[Name] = value; + } } } \ No newline at end of file diff --git a/IfNode.cs b/IfNode.cs index 0c4ff79..a220f5a 100644 --- a/IfNode.cs +++ b/IfNode.cs @@ -16,19 +16,13 @@ namespace tlang public override TObject Execute(IScopeEnvironment 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_bool ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv); + return condition.AsBoolean ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv); } } } \ No newline at end of file diff --git a/MemberFunctionCallNode.cs b/MemberFunctionCallNode.cs index 182d980..4bd2201 100644 --- a/MemberFunctionCallNode.cs +++ b/MemberFunctionCallNode.cs @@ -17,7 +17,9 @@ namespace tlang var dict = res as TDictionary; var integer = res as TNumber; - + var str = res as TString; + var chr = res as TChar; + var array = res as TArray; if(dict != null) { var n = dict[Text] as ICallable; @@ -25,6 +27,74 @@ namespace tlang { return n.Call(Args.Select(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) { @@ -36,6 +106,79 @@ namespace tlang { 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(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(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(); } } + + } \ No newline at end of file diff --git a/MemberGetValueNode.cs b/MemberGetValueNode.cs index 2c1fc35..097b206 100644 --- a/MemberGetValueNode.cs +++ b/MemberGetValueNode.cs @@ -7,7 +7,26 @@ namespace tlang { 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) { var res=Parent.Execute(nodeEnv); @@ -15,6 +34,8 @@ namespace tlang var dict = res as TDictionary; var integer = res as TNumber; var array = res as TArray; + var str = res as TString; + if(array != null) { if(Name == "length" || Name == "count") @@ -41,8 +62,36 @@ namespace tlang 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(); } diff --git a/ModuloNode.cs b/ModuloNode.cs index 76c8d4f..424c262 100644 --- a/ModuloNode.cs +++ b/ModuloNode.cs @@ -13,11 +13,26 @@ namespace tlang public override TObject Execute(IScopeEnvironment nodeEnv) { - var l = Left.Execute(nodeEnv) as TNumber; - var r = Right.Execute(nodeEnv) as TNumber; + var l = Left.Execute(nodeEnv); + 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) - return new TNumber(l.Value % r.Value); + if(dleft != null) + { + 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(); } diff --git a/MultiplyNode.cs b/MultiplyNode.cs index 6c588fc..3aec5e7 100644 --- a/MultiplyNode.cs +++ b/MultiplyNode.cs @@ -13,11 +13,26 @@ namespace tlang public override TObject Execute(IScopeEnvironment nodeEnv) { - var l = Left.Execute(nodeEnv) as TNumber; - var r = Right.Execute(nodeEnv) as TNumber; + var l = Left.Execute(nodeEnv); + 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) - return new TNumber(l.Value * r.Value); + if(dleft != null) + { + 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(); } diff --git a/Parser.cs b/Parser.cs index 1eedfda..5fe961e 100644 --- a/Parser.cs +++ b/Parser.cs @@ -10,11 +10,12 @@ namespace tlang public Node ParseExpression(List tokens,ref int i,bool isFirst=false) { + if(i>= tokens.Count) return new ConstNode(new TNumber(0)); if(tokens[i].Text == "{" || isFirst) { if(!isFirst) i++; - ScopeNode scopeNode = new ScopeNode(); + ScopeNode scopeNode = new ScopeNode(){First=isFirst}; while(i(); - //function call baby + //function call baby while(i(); + //function call baby + while(i{ + 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; + } + + } } \ No newline at end of file diff --git a/PostfixDecrementVariableNode.cs b/PostfixDecrementVariableNode.cs new file mode 100644 index 0000000..aaf83d6 --- /dev/null +++ b/PostfixDecrementVariableNode.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/PostfixIncrementVariableNode.cs b/PostfixIncrementVariableNode.cs new file mode 100644 index 0000000..0964f55 --- /dev/null +++ b/PostfixIncrementVariableNode.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index 73eb09f..b8ac8f4 100644 --- a/Program.cs +++ b/Program.cs @@ -1,7 +1,7 @@ namespace tlang; class Program { - static void Main(string[] args) + static int Main(string[] args) { //Lexer lexer = new Lexer("testString.tlang"); @@ -9,13 +9,27 @@ class Program //parser.Add(lexer.Tokens); int r=0; RootEnvironment env=new RootEnvironment(); - env["mol"] = new TNumber(42); - env["printargs"] = new TExternalMethod((args2)=>{ + parser.LoadEnvironment(env); + 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) { - Console.WriteLine(arg); + Console.Write(arg); } 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)=>{ @@ -90,9 +104,25 @@ class Program }); Lexer lexer =new Lexer(new StreamReader("file.tlang")); - var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env); - r=0; - Console.WriteLine(res); + var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env) as TNumber; + var main = env["main"] as ICallable; + + if(main != null) + { + List args2=new List(); + 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; } } diff --git a/ScopeEnvironment.cs b/ScopeEnvironment.cs index f2bf78c..6901590 100644 --- a/ScopeEnvironment.cs +++ b/ScopeEnvironment.cs @@ -53,6 +53,10 @@ namespace tlang public TObject GetVariable(string name) { + if(name == "last_ittr" && items.ContainsKey("last_ittr")) + { + return items["last_ittr"]; + } if(parent.VariableExists(name)) { return parent[name]; @@ -66,8 +70,9 @@ namespace tlang public void SetVariable(string name, TObject obj) { - if(parent.VariableExists(name)) + if(parent.VariableExists(name) && name != "last_ittr") { + parent.SetVariable(name,obj); }else if(items.ContainsKey(name)) { diff --git a/ScopeNode.cs b/ScopeNode.cs index 73d29fc..064d2f3 100644 --- a/ScopeNode.cs +++ b/ScopeNode.cs @@ -2,10 +2,11 @@ namespace tlang { public class ScopeNode : Node { + public bool First {get;set;} public List Body {get;set;}= new List(); public override TObject Execute(IScopeEnvironment nodeEnv) { - var sub = nodeEnv.SubEnv; + var sub = First ? nodeEnv : nodeEnv.SubEnv; TObject obj=new TNull(); foreach(var item in Body) { diff --git a/SubtractNode.cs b/SubtractNode.cs index 77ef934..80d8024 100644 --- a/SubtractNode.cs +++ b/SubtractNode.cs @@ -13,11 +13,26 @@ namespace tlang public override TObject Execute(IScopeEnvironment nodeEnv) { - var l = Left.Execute(nodeEnv) as TNumber; - var r = Right.Execute(nodeEnv) as TNumber; + var l = Left.Execute(nodeEnv); + 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) - return new TNumber(l.Value - r.Value); + if(dleft != null) + { + 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(); } diff --git a/TArray.cs b/TArray.cs index 14a6efd..b44ec9c 100644 --- a/TArray.cs +++ b/TArray.cs @@ -2,6 +2,7 @@ namespace tlang { public class TArray : TObject { + public override bool AsBoolean => Items.Count > 0; public TArray() { diff --git a/TChar.cs b/TChar.cs new file mode 100644 index 0000000..9a0c22f --- /dev/null +++ b/TChar.cs @@ -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(); + } + } + + +} + \ No newline at end of file diff --git a/TDictionary.cs b/TDictionary.cs index efaa9dc..6804d17 100644 --- a/TDictionary.cs +++ b/TDictionary.cs @@ -2,6 +2,7 @@ namespace tlang { public class TDictionary : TObject { + public override bool AsBoolean {get =>true;} public TDictionary() { diff --git a/TInternalObject.cs b/TInternalObject.cs index 8486193..f0737f1 100644 --- a/TInternalObject.cs +++ b/TInternalObject.cs @@ -2,6 +2,7 @@ namespace tlang { public class TInternalObject : TObject { + public override bool AsBoolean => true; public TInternalObject(object val) { Object=val; diff --git a/TMethod.cs b/TMethod.cs index 15f2eb8..80a4bd0 100644 --- a/TMethod.cs +++ b/TMethod.cs @@ -2,6 +2,7 @@ namespace tlang { public class TInternalMethod : TObject, ICallable { + public override bool AsBoolean => true; public TInternalMethod(ClosureNode node,IScopeEnvironment env) { Body = node; @@ -21,24 +22,27 @@ namespace tlang int i = 0; for(;i true; + public TObject Call(params TObject[] args) { return cb(args); diff --git a/TNull.cs b/TNull.cs index adc5dcf..8e4b1af 100644 --- a/TNull.cs +++ b/TNull.cs @@ -2,6 +2,7 @@ namespace tlang { public class TNull : TObject { + public override bool AsBoolean => false; public override string ToString() { return "null"; diff --git a/TNumber.cs b/TNumber.cs index 87a46b8..018d531 100644 --- a/TNumber.cs +++ b/TNumber.cs @@ -3,6 +3,9 @@ namespace tlang public class TNumber : TObject { public double Value {get;set;} + + public override bool AsBoolean => Value != 0; + public TNumber(double number) { Value = number; diff --git a/TObject.cs b/TObject.cs index ee68f93..30a6914 100644 --- a/TObject.cs +++ b/TObject.cs @@ -1,8 +1,8 @@ namespace tlang { - public class TObject + public abstract class TObject { - + public abstract bool AsBoolean {get;} public static TObject Uninit => new TUninit(); public static TObject Null => new TNull(); } diff --git a/TString.cs b/TString.cs index f5ecbd6..55ed317 100644 --- a/TString.cs +++ b/TString.cs @@ -3,6 +3,9 @@ namespace tlang public class TString : TObject { public string Value {get;set;} + + public override bool AsBoolean => Value.Length > 0; + public TString(string text) { Value = text; diff --git a/TUninit.cs b/TUninit.cs index 7b31b5d..14c396e 100644 --- a/TUninit.cs +++ b/TUninit.cs @@ -2,6 +2,7 @@ namespace tlang { public class TUninit : TObject { + public override bool AsBoolean {get=>false;} public override string ToString() { return "undefined"; diff --git a/WhileLoop.cs b/WhileLoop.cs new file mode 100644 index 0000000..3477e36 --- /dev/null +++ b/WhileLoop.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/file.tlang b/file.tlang index 4e686e2..10a4d6a 100644 --- a/file.tlang +++ b/file.tlang @@ -1,7 +1,8 @@ -/* - if(expression) expression else expression -*/ - -j = func() 42-43; - -printargs(j().abs()); \ No newline at end of file +each(dir : fs.enumerate_dirs(fs.home)) +{ + println(dir); +} +each(file : fs.enumerate_files(fs.home)) +{ + println(file); +} \ No newline at end of file diff --git a/testString.tlang b/testString.tlang deleted file mode 100644 index ce9eb0e..0000000 --- a/testString.tlang +++ /dev/null @@ -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; -}; \ No newline at end of file