From a469aa87207c45763fa0cae29bc99e8c64bbab56 Mon Sep 17 00:00:00 2001 From: Mike Nolan Date: Thu, 8 Jun 2023 13:14:35 -0500 Subject: [PATCH] Still working on language --- tlang/code.tlang | 11 +- tlang/tlang.csproj | 3 +- tlanglib/AddNode.cs | 16 +- tlanglib/ArraySubscriptNode.cs | 2 +- tlanglib/BitwiseAndNode.cs | 6 +- tlanglib/BitwiseNot.cs | 37 ++ tlanglib/BitwiseOrNode.cs | 4 +- tlanglib/ClosureNode.cs | 4 + tlanglib/DivideNode.cs | 6 +- tlanglib/EachLoop.cs | 24 +- tlanglib/EnvironmentNode.cs | 2 +- tlanglib/EqualsNode.cs | 31 +- tlanglib/ForLoop.cs | 5 +- tlanglib/FunctionCallNode.cs | 7 +- tlanglib/GetVariableValue.cs | 3 + tlanglib/GreaterThanEquals.cs | 6 +- tlanglib/GreaterThanNode.cs | 6 +- tlanglib/IfNode.cs | 5 - tlanglib/LeftShift.cs | 4 +- tlanglib/LessThanEqualsNode.cs | 4 +- tlanglib/LessThanNode.cs | 4 +- tlanglib/Lexer.cs | 16 +- tlanglib/LogicalAndNode.cs | 2 +- tlanglib/LogicalOrNode.cs | 2 +- tlanglib/MemberFunctionCallNode.cs | 156 +++-- tlanglib/MemberGetValueNode.cs | 63 +- tlanglib/ModuloNode.cs | 6 +- tlanglib/MultiplyNode.cs | 6 +- tlanglib/NegativeNode.cs | 38 ++ tlanglib/Node.cs | 4 + tlanglib/Not.cs | 37 ++ tlanglib/NotEqualsNode.cs | 33 +- tlanglib/Parser.cs | 766 ++++++++++++++++++++--- tlanglib/PostfixDecrementVariableNode.cs | 4 +- tlanglib/PostfixIncrementVariableNode.cs | 2 +- tlanglib/Program.cs | 4 +- tlanglib/RightShift.cs | 4 +- tlanglib/ScopeNode.cs | 4 +- tlanglib/SubtractNode.cs | 6 +- tlanglib/TArray.cs | 63 +- tlanglib/TBoolean.cs | 24 + tlanglib/TChar.cs | 12 +- tlanglib/TDictionary.cs | 59 +- tlanglib/TInternalObject.cs | 6 + tlanglib/TLangTemplateEngine.cs | 170 +++++ tlanglib/TMethod.cs | 33 +- tlanglib/TNull.cs | 6 + tlanglib/TNumber.cs | 46 ++ tlanglib/TObject.cs | 252 ++++++++ tlanglib/TString.cs | 11 + tlanglib/TUninit.cs | 8 + tlanglib/WhileLoop.cs | 11 +- tlanglib/XOrNode.cs | 4 +- tlanglib/launcher/launcher.tlang | 30 +- tlanglib/tlanglib.csproj | 5 + 55 files changed, 1859 insertions(+), 224 deletions(-) create mode 100644 tlanglib/BitwiseNot.cs create mode 100644 tlanglib/NegativeNode.cs create mode 100644 tlanglib/Not.cs create mode 100644 tlanglib/TBoolean.cs create mode 100644 tlanglib/TLangTemplateEngine.cs diff --git a/tlang/code.tlang b/tlang/code.tlang index a38485d..56a79c3 100644 --- a/tlang/code.tlang +++ b/tlang/code.tlang @@ -1,11 +1,18 @@ - +main = func($$args){ + /*each(arg : args) + { ls = create.array(); -each(v : "GET /api/AddItem/https://www.youtube.com/watch?v=U1jjngDGd_Y HTTP/1.1\r\nHost: 192.168.0.112:3252\r\n\r\n") +each(v : "GET /api/AddItem/" + arg + "HTTP/1.1\r\nHost: 192.168.0.112:3252\r\n\r\n") { ls.add(v); } netstrm=net.tcpclient("192.168.0.112",3252); netstrm.write(ls,ls.length); netstrm.close(); + }*/ + + console.readln(); + +} \ No newline at end of file diff --git a/tlang/tlang.csproj b/tlang/tlang.csproj index 3b3d8c4..a9b23aa 100644 --- a/tlang/tlang.csproj +++ b/tlang/tlang.csproj @@ -5,8 +5,7 @@ - - + diff --git a/tlanglib/AddNode.cs b/tlanglib/AddNode.cs index e3b5e50..3933967 100644 --- a/tlanglib/AddNode.cs +++ b/tlanglib/AddNode.cs @@ -1,7 +1,10 @@ +using System.IO; + namespace tlang { internal class AddNode : Node { + public Node Left {get;set;} public Node Right {get;set;} @@ -35,18 +38,21 @@ namespace tlang if(lNum != null && rNum != null) - return new TNumber(lNum.Value + rNum.Value); + return TObject.Number(lNum.Value + rNum.Value); if(lStr != null && rStr != null) - return new TString(lStr.Value + rStr.Value); + return TObject.String(lStr.Value + rStr.Value); if(lStr != null && rNum != null) - return new TString(lStr.Value + rNum.Value.ToString()); + return TObject.String(lStr.Value + rNum.Value.ToString()); if(lNum != null && rStr != null) - return new TString(lNum.Value.ToString() + rStr.Value); + return TObject.String(lNum.Value.ToString() + rStr.Value); - return new TNull(); + return TObject.Null; } + + + } } \ No newline at end of file diff --git a/tlanglib/ArraySubscriptNode.cs b/tlanglib/ArraySubscriptNode.cs index 9dc2a33..3f33240 100644 --- a/tlanglib/ArraySubscriptNode.cs +++ b/tlanglib/ArraySubscriptNode.cs @@ -45,7 +45,7 @@ namespace tlang var nArg = arg as TNumber; if(nArg != null && nArg.Value < str.Value.Length) { - return new TChar(str.Value[(int)nArg.Value]); + return TObject.Char(str.Value[(int)nArg.Value]); } } return TObject.Uninit; diff --git a/tlanglib/BitwiseAndNode.cs b/tlanglib/BitwiseAndNode.cs index 60b353c..615406a 100644 --- a/tlanglib/BitwiseAndNode.cs +++ b/tlanglib/BitwiseAndNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber((long)lnum.Value & (long)rnum.Value); + return TObject.Number((long)lnum.Value & (long)rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/BitwiseNot.cs b/tlanglib/BitwiseNot.cs new file mode 100644 index 0000000..dc2cc1d --- /dev/null +++ b/tlanglib/BitwiseNot.cs @@ -0,0 +1,37 @@ +namespace tlang +{ + public class BitwiseNot : Node + { + public Node Node {get;set;} + + public BitwiseNot(Node node) + { + this.Node = node; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Node.Execute(nodeEnv); + + var lnum = l as TNumber; + + var dleft = l as TDictionary; + + if(dleft != null) + { + if(dleft.MemberExists("bnot")) + { + var mbm = dleft["bnot"] as ICallable; + if(mbm != null) + { + return mbm.Call(); + } + } + } + + if(lnum != null) + return TObject.Number(~(long)lnum.Value); + return TObject.Null; + } + } +} \ No newline at end of file diff --git a/tlanglib/BitwiseOrNode.cs b/tlanglib/BitwiseOrNode.cs index 4f9a9c9..27d4d79 100644 --- a/tlanglib/BitwiseOrNode.cs +++ b/tlanglib/BitwiseOrNode.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber((long)lnum.Value | (long)rnum.Value); + return TObject.Number((long)lnum.Value | (long)rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/ClosureNode.cs b/tlanglib/ClosureNode.cs index 1e9221a..139cb85 100644 --- a/tlanglib/ClosureNode.cs +++ b/tlanglib/ClosureNode.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; +using System.IO; namespace tlang { + public class ClosureNode : Node { //j=func(a,b,c,d) 4 @@ -18,5 +20,7 @@ namespace tlang { return new TInternalMethod(this,nodeEnv); } + + } } \ No newline at end of file diff --git a/tlanglib/DivideNode.cs b/tlanglib/DivideNode.cs index c7ff7e2..ca7d1f0 100644 --- a/tlanglib/DivideNode.cs +++ b/tlanglib/DivideNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value / rnum.Value); + return TObject.Number(lnum.Value / rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/EachLoop.cs b/tlanglib/EachLoop.cs index 0a6e639..1e515c4 100644 --- a/tlanglib/EachLoop.cs +++ b/tlanglib/EachLoop.cs @@ -22,16 +22,24 @@ namespace tlang if(dict!= null) { var gIttrVar = dict["ittr"] as TDictionary; - var gIttrProp = dict["getIttr"] as ICallable; + var gIttrProp = dict["getittr"] as ICallable; + var myObj = gIttrVar; if(gIttrProp != null) { - var myObj= gIttrProp.Call() as TDictionary; - if(myObj != 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; + var getCurrent = myObj["getcurrent"] as ICallable; if(reset != null) reset.Call(); if(moveNext != null) while(moveNext.Call().AsBoolean) @@ -48,7 +56,8 @@ namespace tlang } } - } + + } else if(array != null) { @@ -61,7 +70,7 @@ namespace tlang { foreach(var c in str.Value) { - yield return new TChar(c); + yield return TObject.Char(c); } } @@ -73,8 +82,9 @@ namespace tlang var ls = List.Execute(env); bool isRunning=true; env["last_ittr"]= new TExternalMethod((args)=>{ + isRunning=false; - return new TNumber(1); + return TObject.True; }); TObject last = TObject.Uninit; diff --git a/tlanglib/EnvironmentNode.cs b/tlanglib/EnvironmentNode.cs index b89b54a..911a185 100644 --- a/tlanglib/EnvironmentNode.cs +++ b/tlanglib/EnvironmentNode.cs @@ -14,7 +14,7 @@ namespace tlang { if(node is EnvironmentNode) { - returnType =node.Execute(nodeEnv.SubEnv); + returnType = node.Execute(nodeEnv.SubEnv); }else{ returnType = node.Execute(nodeEnv); } diff --git a/tlanglib/EqualsNode.cs b/tlanglib/EqualsNode.cs index 1ef8147..e649e2b 100644 --- a/tlanglib/EqualsNode.cs +++ b/tlanglib/EqualsNode.cs @@ -17,6 +17,12 @@ namespace tlang var r = Right.Execute(nodeEnv); var lnum = l as TNumber; var rnum = r as TNumber; + var lstr = l as TString; + var rstr = r as TString; + var lbool = l as TBoolean; + var rbool = r as TBoolean; + var lchar = l as TChar; + var rchar = r as TChar; var dleft = l as TDictionary; if(dleft != null) @@ -28,13 +34,34 @@ namespace tlang { return mbm.Call(r); } + else { + var dright = r as TDictionary; + if(dright != null) + { + return TObject.Boolean(dleft == dright); + } + } } + else { + var dright = r as TDictionary; + if(dright != null) + { + return TObject.Boolean(dleft == dright); + } + } } if(lnum != null && rnum != null) - return new TNumber(lnum.Value == rnum.Value ? 1 : 0); + return TObject.Boolean(lnum.Value == rnum.Value); + if(lbool != null && rbool != null) + return TObject.Boolean(lbool.Value == rbool.Value); + if(lstr != null && rstr != null) + return TObject.Boolean(lstr.Value == rstr.Value); + if(lchar != null && rchar != null) + return TObject.Boolean(lchar.Value == rchar.Value); - return new TNull(); + + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/ForLoop.cs b/tlanglib/ForLoop.cs index 44b2694..a6a35aa 100644 --- a/tlanglib/ForLoop.cs +++ b/tlanglib/ForLoop.cs @@ -20,11 +20,12 @@ namespace tlang var env = nodeEnv.SubEnv; bool isRunning=true; env["last_ittr"]= new TExternalMethod((args)=>{ + isRunning=false; - return new TNumber(1); + return TObject.True; }); Init.Execute(env); - TObject obj=new TUninit(); + TObject obj= TObject.Uninit; while(Condition.Execute(env).AsBoolean && isRunning) { obj=Body.Execute(env); diff --git a/tlanglib/FunctionCallNode.cs b/tlanglib/FunctionCallNode.cs index 0309ce9..586a4f9 100644 --- a/tlanglib/FunctionCallNode.cs +++ b/tlanglib/FunctionCallNode.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.IO; using System.Linq; namespace tlang @@ -22,7 +23,9 @@ namespace tlang return n.Call(Args.Select(e=>e.Execute(nodeEnv)).ToArray()); } - return new TUninit(); + return TObject.Uninit; } + } -} \ No newline at end of file + + } \ No newline at end of file diff --git a/tlanglib/GetVariableValue.cs b/tlanglib/GetVariableValue.cs index 414bee6..51b6006 100644 --- a/tlanglib/GetVariableValue.cs +++ b/tlanglib/GetVariableValue.cs @@ -16,6 +16,7 @@ namespace tlang Name.SetValue(nodeEnv,res); return res; } + } public class GetVariableValue : Node @@ -35,5 +36,7 @@ namespace tlang { nodeEnv[Name] = value; } + + } } \ No newline at end of file diff --git a/tlanglib/GreaterThanEquals.cs b/tlanglib/GreaterThanEquals.cs index 372fed7..d0cc72a 100644 --- a/tlanglib/GreaterThanEquals.cs +++ b/tlanglib/GreaterThanEquals.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value >= rnum.Value ? 1 : 0); + return TObject.Boolean(lnum.Value >= rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/GreaterThanNode.cs b/tlanglib/GreaterThanNode.cs index 9e420ba..8d2df22 100644 --- a/tlanglib/GreaterThanNode.cs +++ b/tlanglib/GreaterThanNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value > rnum.Value ? 1 : 0); + return TObject.Boolean(lnum.Value > rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/IfNode.cs b/tlanglib/IfNode.cs index a220f5a..9bda3c2 100644 --- a/tlanglib/IfNode.cs +++ b/tlanglib/IfNode.cs @@ -17,11 +17,6 @@ namespace tlang { var condition = Condition.Execute(nodeEnv); - - - - - return condition.AsBoolean ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv); } } diff --git a/tlanglib/LeftShift.cs b/tlanglib/LeftShift.cs index ab94d15..f5d18b6 100644 --- a/tlanglib/LeftShift.cs +++ b/tlanglib/LeftShift.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber((long)lnum.Value << (int)rnum.Value); + return TObject.Number((long)lnum.Value << (int)rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/LessThanEqualsNode.cs b/tlanglib/LessThanEqualsNode.cs index 792c6e5..0d1609b 100644 --- a/tlanglib/LessThanEqualsNode.cs +++ b/tlanglib/LessThanEqualsNode.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value <= rnum.Value ? 1 : 0); + return TObject.Boolean(lnum.Value <= rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/LessThanNode.cs b/tlanglib/LessThanNode.cs index e16ab6d..37f5674 100644 --- a/tlanglib/LessThanNode.cs +++ b/tlanglib/LessThanNode.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value < rnum.Value ? 1 : 0); + return TObject.Boolean(lnum.Value < rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/Lexer.cs b/tlanglib/Lexer.cs index 06063fa..44e2d80 100644 --- a/tlanglib/Lexer.cs +++ b/tlanglib/Lexer.cs @@ -205,9 +205,21 @@ namespace tlang case ':': case ',': case ';': - case '=': - FlushBuilder(); + FlushBuilder(); _tokens.Add(LexToken.FromGeneralToken(read)); + break; + case '=': + + FlushBuilder(); + if(next == read) + { + reader.Read(); + _tokens.Add(LexToken.FromGeneralToken($"{(char)read}{(char)next}")); + } + else + { + _tokens.Add(LexToken.FromGeneralToken(read)); + } break; case ' ': case '\n': diff --git a/tlanglib/LogicalAndNode.cs b/tlanglib/LogicalAndNode.cs index 0d54fb6..c701840 100644 --- a/tlanglib/LogicalAndNode.cs +++ b/tlanglib/LogicalAndNode.cs @@ -25,7 +25,7 @@ namespace tlang return lor.Call(r); } } - return new TNumber(l.AsBoolean && r.AsBoolean ? 1 : 0); + return TObject.Boolean(l.AsBoolean && r.AsBoolean); } } } \ No newline at end of file diff --git a/tlanglib/LogicalOrNode.cs b/tlanglib/LogicalOrNode.cs index 4b9ed67..7b3b7c6 100644 --- a/tlanglib/LogicalOrNode.cs +++ b/tlanglib/LogicalOrNode.cs @@ -25,7 +25,7 @@ namespace tlang return lor.Call(r); } } - return new TNumber(l.AsBoolean || r.AsBoolean ? 1 : 0); + return TObject.Boolean(l.AsBoolean || r.AsBoolean); } } } \ No newline at end of file diff --git a/tlanglib/MemberFunctionCallNode.cs b/tlanglib/MemberFunctionCallNode.cs index 7d24cce..540c4c6 100644 --- a/tlanglib/MemberFunctionCallNode.cs +++ b/tlanglib/MemberFunctionCallNode.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; namespace tlang { @@ -17,6 +18,7 @@ namespace tlang } public override TObject Execute(IScopeEnvironment nodeEnv) { + var res=Parent.Execute(nodeEnv); @@ -25,6 +27,12 @@ namespace tlang var str = res as TString; var chr = res as TChar; var array = res as TArray; + var myBool = res as TBoolean; + + if(Text == "toChar2") + { + throw new Exception(res.GetType().Name); + } if(dict != null) { var n = dict[Text] as ICallable; @@ -32,35 +40,53 @@ namespace tlang { return n.Call(Args.Select(e=>e.Execute(nodeEnv)).ToArray()); } - }else if(chr != null) + }else if(myBool != null) { - if(Text == "toUpper") + //branch + + if(Text == "toChar") { - 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()); + return TObject.Char(myBool.Value ? 'y' : 'n'); } if(Text == "toNumber") { - return new TNumber(chr.Value); + return TObject.Number(myBool.Value ? 1 : 0); + } + } + else if(chr != null) + { + if(Text == "toUpper") + { + return TObject.Char(char.ToUpper(chr.Value)); + } + if(Text == "toLower") + { + return TObject.Char(char.ToLower(chr.Value)); + } + + if(Text == "toNumber") + { + return TObject.Number(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; + return res; + } + } + if(Text == "remove") + { + if(Args.Count == 1) + { + TObject obj = Args[0].Execute(nodeEnv); + array.Items.Remove(obj); + return res; } } if(Text == "at") @@ -97,33 +123,62 @@ namespace tlang } return value; } - if(Text == "length" || Text == "count") - { - return new TNumber(array.Items.Count); - } + } else if(integer != null) { - if(Text == "toString") + if(Text == "int") { - return new TString(integer.Value.ToString()); + return TObject.Number(Math.Round(integer.Value)); } if(Text == "abs") { - return new TNumber(Math.Abs(integer.Value)); + return TObject.Number(Math.Abs(integer.Value)); } if(Text == "toChar") { - return new TChar((char)integer.Value); + + return TObject.Char((char)integer.Value); } }else if(str != null) { + if(Text == "toArray") + { + var _array=TObject.Array(); + foreach(var c in str.Value) + { + _array.Items.Add(TObject.Char(c)); + } + } if(Text == "replace") { //todo fill this method out + if(Args.Count >= 2) + return TObject.String(str.Value.Replace(Args[0].Execute(nodeEnv).ToString(),Args[1].Execute(nodeEnv).ToString())); } if(Text == "split") { + if(Args.Count >= 1) + { + var text= str.Value; + var splitOn = Args[0].Execute(nodeEnv).ToString(); + int count = int.MaxValue; + bool splitOp = false; + if(Args.Count >= 2) + { + splitOp = Args[1].Execute(nodeEnv).AsBoolean; + } + if(Args.Count >= 3) + { + var n = Args[2].Execute(nodeEnv) as TNumber; + if(n != null) count = (int)n.Value; + } + + var array1=TObject.Array(); + + array1.Items.AddRange(text.Split(new string[]{splitOn},count,splitOp ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None).Select(e=>TObject.String(e))); + return array1; + } //todo fill this method out //str.Value.Split(,,StringSplitOptions.TrimEntries); } @@ -131,28 +186,36 @@ namespace tlang { 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(); + val = Args[0].Execute(nodeEnv).ToString(); + } - return new TNumber(str.Value.StartsWith(val) ? 1 : 0); + return TObject.Boolean(str.Value.StartsWith(val)); + + } + if(Text == "endsWith") + { + string val = " "; + if(Args.Count > 0){ + val = Args[0].Execute(nodeEnv).ToString(); + + } + + + + return TObject.Boolean(str.Value.EndsWith(val)); } if(Text == "trimStart") { if(Args.Count == 0) { - return new TString(str.Value.TrimStart()); + return TObject.String(str.Value.TrimStart()); }else{ - return new TString(str.Value.TrimStart(Args.Select(n=>{ + return TObject.String(str.Value.TrimStart(Args.Select(n=>{ var nV=n.Execute(nodeEnv) as TChar; if(nV != null) { @@ -167,10 +230,10 @@ namespace tlang //trimend() if(Args.Count == 0) { - return new TString(str.Value.TrimEnd()); + return TObject.String(str.Value.TrimEnd()); }else{ - return new TString(str.Value.TrimEnd(Args.Select(n=>{ + return TObject.String(str.Value.TrimEnd(Args.Select(n=>{ var nV=n.Execute(nodeEnv) as TChar; if(nV != null) { @@ -180,19 +243,28 @@ namespace tlang }).ToArray())); } } - if(Text == "toString") - { - return str; - } + } - - if(Text == "toString") return new TString(""); + if(dict == null) + { + if(Text == "toString") + { + return TObject.String(res.ToString()); + } + if(Text == "toBool") + { + return TObject.Boolean(res.AsBoolean); + } + } + if(Text == "toString") return TObject.String(""); - return new TUninit(); + return TObject.Uninit; } + + } -} \ No newline at end of file +} diff --git a/tlanglib/MemberGetValueNode.cs b/tlanglib/MemberGetValueNode.cs index bfde1c5..7015b32 100644 --- a/tlanglib/MemberGetValueNode.cs +++ b/tlanglib/MemberGetValueNode.cs @@ -42,9 +42,26 @@ namespace tlang { if(Name == "length" || Name == "count") { - return new TNumber(array.Items.Count); + return TObject.Number(array.Items.Count); + } + if(Name == "ittr") + { + var ittr = TObject.Dictionary(); + var enumerator=array.Items.GetEnumerator(); + ittr["getcurrent"] = new TExternalMethod(()=>{ + return enumerator.Current; + }); + ittr["movenext"] = new TExternalMethod(()=>{ + return TObject.Boolean(enumerator.MoveNext()); + }); + ittr["reset"] = new TExternalMethod(()=>{ + + }); + ittr["dispose"] = new TExternalMethod(()=>{ + enumerator.Dispose(); + }); + return ittr; } - } if(dict != null) { @@ -66,11 +83,11 @@ namespace tlang { if(Name == "abs") { - return new TNumber(Math.Abs(integer.Value)); + return TObject.Number(Math.Abs(integer.Value)); } if(Name == "int") { - return new TNumber(Math.Round(integer.Value)); + return TObject.Number(Math.Round(integer.Value)); } } if(str != null) @@ -78,24 +95,44 @@ namespace tlang if(Name == "number") { - + double value; + if(double.TryParse(str.Value,out value)) + { + return TObject.Number(value); + } + return TObject.Null; } if(Name == "ittr") { - + var ittr = TObject.Dictionary(); + var enumerator=str.Value.GetEnumerator(); + ittr["getcurrent"] = new TExternalMethod(()=>{ + return TObject.Char(enumerator.Current); + }); + ittr["movenext"] = new TExternalMethod(()=>{ + return TObject.Boolean(enumerator.MoveNext()); + }); + ittr["reset"] = new TExternalMethod(()=>{ + enumerator.Reset(); + }); + ittr["dispose"] = new TExternalMethod(()=>{ + enumerator.Dispose(); + }); + return ittr; + } + if(Name == "boolean") + { + return TObject.Boolean(str.Value.ToLower() == "true"); } if(Name == "length" || Name == "count") { - return new TNumber(str.Value.Length); - } - if(Name == "list") - { - + return TObject.Number(str.Value.Length); } + } - return new TUninit(); + return TObject.Uninit; } } -} \ No newline at end of file +} diff --git a/tlanglib/ModuloNode.cs b/tlanglib/ModuloNode.cs index 424c262..bebcf87 100644 --- a/tlanglib/ModuloNode.cs +++ b/tlanglib/ModuloNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value % rnum.Value); + return TObject.Number(lnum.Value % rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/MultiplyNode.cs b/tlanglib/MultiplyNode.cs index 3aec5e7..5d8853d 100644 --- a/tlanglib/MultiplyNode.cs +++ b/tlanglib/MultiplyNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value * rnum.Value); + return TObject.Number(lnum.Value * rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/NegativeNode.cs b/tlanglib/NegativeNode.cs new file mode 100644 index 0000000..ab0aa06 --- /dev/null +++ b/tlanglib/NegativeNode.cs @@ -0,0 +1,38 @@ +namespace tlang +{ + public class NegativeNode : Node + { + public Node Node {get;set;} + + public NegativeNode(Node node) + { + this.Node = node; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Node.Execute(nodeEnv); + + var lnum = l as TNumber; + + var dleft = l as TDictionary; + + if(dleft != null) + { + if(dleft.MemberExists("neg")) + { + var mbm = dleft["neg"] as ICallable; + if(mbm != null) + { + return mbm.Call(); + } + } + } + + if(lnum != null) + return TObject.Number(-lnum.Value); + + return TObject.Null; + } + } +} \ No newline at end of file diff --git a/tlanglib/Node.cs b/tlanglib/Node.cs index d073cd1..e16f25d 100644 --- a/tlanglib/Node.cs +++ b/tlanglib/Node.cs @@ -1,7 +1,11 @@ +using System; +using System.IO; + namespace tlang { public abstract class Node { public abstract TObject Execute(IScopeEnvironment nodeEnv); + } } \ No newline at end of file diff --git a/tlanglib/Not.cs b/tlanglib/Not.cs new file mode 100644 index 0000000..7da886a --- /dev/null +++ b/tlanglib/Not.cs @@ -0,0 +1,37 @@ +namespace tlang +{ + public class NotNode : Node + { + public Node Node {get;set;} + + public NotNode(Node node) + { + this.Node = node; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Node.Execute(nodeEnv); + + + var dleft = l as TDictionary; + + if(dleft != null) + { + if(dleft.MemberExists("not")) + { + var mbm = dleft["not"] as ICallable; + if(mbm != null) + { + return mbm.Call(); + } + } + } + + + return TObject.Boolean(!l.AsBoolean); + + + } + } +} \ No newline at end of file diff --git a/tlanglib/NotEqualsNode.cs b/tlanglib/NotEqualsNode.cs index bfb5989..7cf071a 100644 --- a/tlanglib/NotEqualsNode.cs +++ b/tlanglib/NotEqualsNode.cs @@ -15,8 +15,14 @@ namespace tlang { var l = Left.Execute(nodeEnv); var r = Right.Execute(nodeEnv); - var lnum = l as TNumber; + var lnum = l as TNumber; var rnum = r as TNumber; + var lstr = l as TString; + var rstr = r as TString; + var lbool = l as TBoolean; + var rbool = r as TBoolean; + var lchar = l as TChar; + var rchar = r as TChar; var dleft = l as TDictionary; if(dleft != null) @@ -27,14 +33,31 @@ namespace tlang if(mbm != null) { return mbm.Call(r); + }else { + var dright = r as TDictionary; + if(dright != null) + { + return TObject.Boolean(dleft != dright); + } + } + } else { + var dright = r as TDictionary; + if(dright != null) + { + return TObject.Boolean(dleft != dright); + } } - } } if(lnum != null && rnum != null) - return new TNumber(lnum.Value != rnum.Value ? 1 : 0); - - return new TNull(); + return TObject.Boolean(lnum.Value != rnum.Value); + if(lbool != null && rbool != null) + return TObject.Boolean(lbool.Value != rbool.Value); + if(lstr != null && rstr != null) + return TObject.Boolean(lstr.Value != rstr.Value); + if(lchar != null && rchar != null) + return TObject.Boolean(lchar.Value != rchar.Value); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/Parser.cs b/tlanglib/Parser.cs index 4a7a230..55ff8a3 100644 --- a/tlanglib/Parser.cs +++ b/tlanglib/Parser.cs @@ -2,14 +2,165 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; +using System.Net.Security; using System.Net.Sockets; +using System.Security.Cryptography; using System.Threading; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace tlang { - internal class Parser + public class TDictStrm : Stream { + TDictionary dict; + public TDictStrm(TDictionary dict) + { + this.dict = dict; + } + + public override bool CanRead {get{var cr = dict.GetMember("getcanread") as ICallable; return cr != null && dict.GetMember("read") is ICallable && cr.Call().AsBoolean; }} + + public override bool CanSeek {get{var cr = dict.GetMember("getcanseek") as ICallable; return cr != null && dict.GetMember("setposition") is ICallable && cr.Call().AsBoolean; }} + + public override bool CanWrite {get{var cr = dict.GetMember("getcanwrite") as ICallable; return cr != null && dict.GetMember("write") is ICallable && cr.Call().AsBoolean; }} + + public override long Length + { + get + { + var pos = dict.GetMember("getlength") as ICallable; + if(pos != null) + { + var d = pos.Call() as TNumber; + if(d != null) + { + return (long)d.Value; + } + } + return 0; + } + } + + public override long Position + { + get + { + var pos = dict.GetMember("getposition") as ICallable; + if(pos != null) + { + var d = pos.Call() as TNumber; + if(d != null) + { + return (long)d.Value; + } + } + return 0; + + } + set + { + var setpos = dict.GetMember("setposition") as ICallable; + if(setpos != null) + { + setpos.Call(TObject.Number(value)); + } + } + } + + public override void Flush() + { + var pos = dict.GetMember("flush") as ICallable; + if(pos != null) + { + pos.Call(); + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + var read = dict.GetMember("read") as ICallable; + + if(read != null) + { + var data = TObject.Array(count); + var len=read.Call(data,TObject.Number(count)) as TNumber; + if(len != null){ + int le=(int)len.Value; + for(int i = 0;i tokens) { int i=0; @@ -17,19 +168,14 @@ namespace tlang } public Node Node {get;set;} - public TObject Execute(IScopeEnvironment env,params TObject[] args) + public TObject Execute(IScopeEnvironment env) { var res=Node.Execute(env); - var main = env["main"] as ICallable; - if(main != null) - { - res=main.Call(args); - } return res; } private Node ParseExpression(List tokens,ref int i,bool isFirst=false) { - if(i>= tokens.Count) return new ConstNode(new TNumber(0)); + if(i>= tokens.Count) return new ConstNode(TObject.Number(0)); if(tokens[i].Text == "{" || isFirst) { if(!isFirst) @@ -53,7 +199,7 @@ namespace tlang private Node ParseAssignable(List tokens,ref int i) { Node myExpression = ParseLOR(tokens,ref i); - while(i{ if(args2.Length ==1) { @@ -608,22 +845,28 @@ namespace tlang return TObject.Null; }); dict["getposition"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.Position); + return TObject.Number(strm.Position); }); dict["getlength"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.Length); + return TObject.Number(strm.Length); }); dict["getcount"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.Length); + return TObject.Number(strm.Length); }); - dict["canread"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.CanRead ? 1 : 0); + dict["getcanread"] = new TExternalMethod((args2)=>{ + return TObject.Boolean(strm.CanRead); }); - dict["canwrite"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.CanWrite ? 1 : 0); + dict["getcanwrite"] = new TExternalMethod((args2)=>{ + return TObject.Boolean(strm.CanWrite); }); - dict["canseek"] = new TExternalMethod((args2)=>{ - return new TNumber(strm.CanSeek ? 1 : 0); + dict["getcanseek"] = new TExternalMethod((args2)=>{ + return TObject.Boolean(strm.CanSeek); + }); + dict["readbyte"]=new TExternalMethod(()=>{ + return TObject.Number(strm.ReadByte()); + }); + dict["getnextbyte"]=new TExternalMethod(()=>{ + return TObject.Number(strm.ReadByte()); }); dict["write"] = new TExternalMethod((args2)=>{ if(args2.Length >= 2) @@ -635,8 +878,8 @@ namespace tlang if(args2.Length == 3) { //buffer,offset,len - var _offset = args2[1] as TNumber; - var _len = args2[2] as TNumber; + var _offset = args2[2] as TNumber; + var _len = args2[1] as TNumber; if(bufAr != null && _offset != null && _len != null) { @@ -656,7 +899,7 @@ namespace tlang } strm.Write(buffer,0,buffer.Length); - return new TNumber(totalRead); + return TObject.Number(totalRead); } } else @@ -681,12 +924,13 @@ namespace tlang } strm.Write(buffer,0,buffer.Length); - return new TNumber(totalRead); + return TObject.Number(totalRead); } } - }return new TNumber(0); + }return TObject.Number(0); }); + dict["read"] = new TExternalMethod((args2)=>{ @@ -700,8 +944,8 @@ namespace tlang if(args2.Length == 3) { //buffer,offset,len - var _offset = args2[1] as TNumber; - var _len = args2[2] as TNumber; + var _offset = args2[2] as TNumber; + var _len = args2[1] as TNumber; if(bufAr != null && _offset != null && _len != null) { @@ -712,9 +956,9 @@ namespace tlang totalRead=strm.Read(buffer,0,buffer.Length); for(int i = 0;i{ + + if(args.Length >0 ) + + ssl.AuthenticateAsClient(args[0].ToString()); + + }); + + } + + return dict; } public void LoadEnvironment(RootEnvironment env) { - TDictionary fs = new TDictionary(); + TDictionary fs = TObject.Dictionary(); fs["file_exists"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) { @@ -760,7 +1020,7 @@ namespace tlang if(!string.IsNullOrWhiteSpace(fileName)) { try{ - if(File.Exists(fileName)) return new TNumber(1); + if(File.Exists(fileName)) return TObject.Number(1); }catch(Exception ex) { _=ex; @@ -768,7 +1028,7 @@ namespace tlang } } } - return new TNumber(0); + return TObject.Number(0); }); fs["dir_exists"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) @@ -777,7 +1037,7 @@ namespace tlang if(!string.IsNullOrWhiteSpace(fileName)) { try{ - if(Directory.Exists(fileName)) return new TNumber(1); + if(Directory.Exists(fileName)) return TObject.Number(1); }catch(Exception ex) { _=ex; @@ -785,7 +1045,7 @@ namespace tlang } } } - return new TNumber(0); + return TObject.Number(0); }); fs["mkdir"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) @@ -794,9 +1054,9 @@ namespace tlang if(!string.IsNullOrWhiteSpace(fileName)) { try{ - if(Directory.Exists(fileName)) return new TNumber(2); + if(Directory.Exists(fileName)) return TObject.Number(2); Directory.CreateDirectory(fileName); - return new TNumber(1); + return TObject.Number(1); }catch(Exception ex) { _=ex; @@ -804,7 +1064,7 @@ namespace tlang } } } - return new TNumber(0); + return TObject.Number(0); }); fs["create"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) @@ -830,6 +1090,7 @@ namespace tlang try{ return CreateStream(File.OpenRead(fileName)); }catch(Exception ex){ + Console.WriteLine(ex.Message); _=ex; } } @@ -875,8 +1136,9 @@ namespace tlang { try{ if(!File.Exists(fileName)) return TObject.Null; - return new TString(File.ReadAllText(fileName)); + return TObject.String(File.ReadAllText(fileName)); }catch(Exception ex) + { _=ex; @@ -894,33 +1156,33 @@ namespace tlang { try{ File.WriteAllText(fileName,text); - return new TNumber(1); + return TObject.Number(1); }catch(Exception ex) { _=ex; } } } - return new TNumber(0); + return TObject.Number(0); }); - fs["home"] = new TString(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + fs["home"] = TObject.String(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); 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 dict = TObject.Dictionary(); + dict["getittr"] = new TExternalMethod((args2)=>{ var enumerable=Directory.EnumerateFiles(fileName).GetEnumerator(); - TDictionary dict2 = new TDictionary(); + TDictionary dict2 = TObject.Dictionary(); dict2["movenext"] = new TExternalMethod((args3)=>{ - return new TNumber(enumerable.MoveNext() ? 1 : 0); + return TObject.Boolean(enumerable.MoveNext()); }); - dict2["getCurrent"] = new TExternalMethod((args3)=>{ - return new TString(enumerable.Current); + dict2["getcurrent"] = new TExternalMethod((args3)=>{ + return TObject.String(Path.GetFileName(enumerable.Current)); }); return dict2; @@ -930,24 +1192,96 @@ namespace tlang } return TObject.Null; }); - + fs["parent"]=new TExternalMethod((args)=>{ + if(args.Length > 0) + { + var file = args[0].ToString(); + var dir=Path.GetDirectoryName(file); + if(string.IsNullOrWhiteSpace(dir)) + { + dir = file; + } + return TObject.String(dir); + + } + return TObject.Null; + }); + fs["combine"]=new TExternalMethod((args)=>{ + if(args.Length == 1) + { + var a = args[0] as TArray; + if(a != null) + { + return TObject.String(Path.Combine(a.Items.Select(e=>e.ToString()).ToArray())); + } + } + return TObject.String(Path.Combine(args.Select(e=>e.ToString()).ToArray())); + }); + fs["relative_to"]=new TExternalMethod((args)=>{ + if(args.Length > 1) + { + var relpath = args[1].ToString(); + if(!Path.IsPathRooted(relpath)) + { + string file=Path.GetFullPath(args[0].ToString()); + + return TObject.String(Path.Combine(file,relpath)); + }else{ + return TObject.String(relpath); + } + } + return TObject.Null; + }); + fs["get_filename"]=new TExternalMethod((args)=>{ + if(args.Length > 0) + { + return TObject.String(Path.GetFileName(args[0].ToString())); + } + return TObject.Null; + }); + fs["get_extension"]=new TExternalMethod((args)=>{ + if(args.Length > 0) + { + return TObject.String(Path.GetExtension(args[0].ToString())); + } + return TObject.Null; + }); + fs["relative_to_parent_of"] = new TExternalMethod((args)=>{ + if(args.Length > 1) + { + var relpath = args[1].ToString(); + if(!Path.IsPathRooted(relpath)) + { + string file=Path.GetFullPath(args[0].ToString()); + var dir=Path.GetDirectoryName(file); + if(string.IsNullOrWhiteSpace(dir)) + { + dir = file; + } + return TObject.String(Path.Combine(dir,relpath)); + }else{ + return TObject.String(relpath); + } + } + 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 dict = TObject.Dictionary(); + dict["getittr"] = new TExternalMethod((args2)=>{ var enumerable=Directory.EnumerateDirectories(fileName).GetEnumerator(); - TDictionary dict2 = new TDictionary(); + TDictionary dict2 = TObject.Dictionary(); dict2["movenext"] = new TExternalMethod((args3)=>{ - return new TNumber(enumerable.MoveNext() ? 1 : 0); + return TObject.Boolean(enumerable.MoveNext() ); }); - dict2["getCurrent"] = new TExternalMethod((args3)=>{ - return new TString(enumerable.Current); + dict2["getcurrent"] = new TExternalMethod((args3)=>{ + return TObject.String(Path.GetFileName(enumerable.Current)); }); return dict2; @@ -958,7 +1292,76 @@ namespace tlang return TObject.Null; }); env["fs"]=fs; - TDictionary reflection = new TDictionary(); + TDictionary reflection = TObject.Dictionary(); + reflection["get_dict_entries"] = new TExternalMethod((args2)=>{ + TArray array = TObject.Array(); + if(args2.Length == 1) + { + var dict=args2[0] as TDictionary; + if(dict != null) + { + array.Items.AddRange(dict.GetMembers()); + } + } + return array; + }); + reflection["set_dict_entry"] = new TExternalMethod((args2)=>{ + if(args2.Length == 3) + { + var dict = args2[0] as TDictionary; + var key = args2[1].ToString(); + + var value = args2[2]; + if(dict != null) + { + dict[key] = value; + } + } + }); + reflection["get_dict_entry"] = new TExternalMethod((args2)=>{ + if(args2.Length == 2) + { + var dict = args2[0] as TDictionary; + var key = args2[1].ToString(); + + if(dict != null) + { + return dict[key]; + } + } + return TObject.Null; + }); + reflection["typeof"] = new TExternalMethod((args2)=>{ + TDictionary dict = TObject.Dictionary(); + var filled = args2.Length == 1; + dict["has_data"] = TObject.Boolean(filled); + if(filled) + { + var arg = args2[0]; + bool isString = arg is TString; + bool isUndefined = arg is TUninit; + bool isNull = arg is TNull; + bool isNumber = arg is TNumber; + bool isArray = arg is TArray; + bool isDict = arg is TDictionary; + bool isExternalMethod = arg is TExternalMethod; + var internalMethod = arg as TInternalMethod; + + + dict["is_string"] = TObject.Boolean(isString); + dict["is_undefined"] = TObject.Boolean(isUndefined); + dict["is_null"] = TObject.Boolean(isNull ); + dict["is_number"] = TObject.Boolean(isNumber ); + dict["is_array"] = TObject.Boolean(isArray ); + dict["is_dict"] = TObject.Boolean(isDict ); + dict["is_external_method"]= TObject.Boolean(isExternalMethod ); + dict["is_internal_method"] = TObject.Boolean(internalMethod != null); + dict["is_method"] = TObject.Boolean(internalMethod != null || isExternalMethod ); + dict["param_count"] = TObject.Number(internalMethod != null ? internalMethod.Body.Arguments.Count : 0); + + } + return dict; + }); reflection["parse_code"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) @@ -974,14 +1377,19 @@ namespace tlang RootEnvironment env2 = new RootEnvironment(); TDictionary rootDict = new TRootDict(env2); LoadEnvironment(env2); - TDictionary parseCodeVal = new TDictionary(); - var argsArray= new TArray(); + TDictionary parseCodeVal = TObject.Dictionary(); + List _args=new List(); parseCodeVal["root"] = rootDict; - parseCodeVal["args"] = argsArray; + parseCodeVal["add"] = new TExternalMethod((args4)=>{ + foreach(var arg in args4) + { + _args.Add(arg); + } + }); parseCodeVal["run"] = new TExternalMethod((args4)=>{ //run() try{ - return _parser.Execute(env2,argsArray.Items.ToArray()); + return _parser.Execute(env); }catch(Exception ex) { @@ -1006,13 +1414,32 @@ namespace tlang }); env["reflection"] = reflection; - var con = new TDictionary(); + + var json = TObject.Dictionary(); + json["encode"] = new TExternalMethod((args2)=>{ + if(args2.Length <= 0) + { + return JsonConvert.SerializeObject(null); + } + return JsonConvert.SerializeObject(args2[0].AsToken()); + }); + json["decode"] = new TExternalMethod((args2)=>{ + if(args2.Length <= 0) + { + return TObject.Uninit; + } + var s=args2[0] as TString; + if(s ==null) return TObject.Uninit; + return TObject.FromToken(JsonConvert.DeserializeObject(s)); + }); + env["json"] = json; + var con = TObject.Dictionary(); con["write"] = new TExternalMethod((args2)=>{ foreach(var arg in args2) { Console.Write(arg); } - return new TNumber(args2.Length); + return TObject.Number(args2.Length); }); con["writeln"] = new TExternalMethod((args2)=>{ foreach(var arg in args2) @@ -1020,20 +1447,35 @@ namespace tlang Console.Write(arg); } Console.WriteLine(); - return new TNumber(args2.Length); + return TObject.Number(args2.Length); }); - - var instance = new TDictionary(); - instance["array"] = new TExternalMethod((args2)=>{ + + con["readln"] = new TExternalMethod(()=>{ + var str=Console.ReadLine(); + if(!string.IsNullOrWhiteSpace(str)) + return TObject.String(str); + return TObject.Uninit; + }); + var instance = TObject.Dictionary(); + instance["array"] = new TExternalMethod((args2)=>{ + int count = 0; + if(args2.Length > 0) + { + var arg = args2[0] as TNumber; + if(arg != null) + { + count = (int)arg.Value; + } + } - return new TArray(); + return TObject.Array(count); }); instance["dict"] = new TExternalMethod((args2)=>{ - return new TDictionary(); + return TObject.Dictionary(); }); instance["mutex"] = new TExternalMethod((args2)=>{ - TDictionary dictionary=new TDictionary(); + TDictionary dictionary=TObject.Dictionary(); Mutex mtx = new Mutex(); dictionary["lock"]=new TExternalMethod((args3)=>{ mtx.WaitOne(); @@ -1048,10 +1490,11 @@ namespace tlang instance["thread"] = new TExternalMethod((args2)=>{ if(args2.Length > 0) { - ICallable callable = args2[0] as ICallable; + var callable = args2[0] as ICallable; if(callable !=null){ Thread thread=new Thread(()=>{ + callable.Call(); }); thread.Start(); @@ -1074,18 +1517,18 @@ namespace tlang long val; if(long.TryParse(sArg.Value,out val)) { - return new TNumber(val); + return TObject.Number(val); } } if(dArg != null) { - return new TNumber(Math.Round(dArg.Value)); + return TObject.Number(Math.Round(dArg.Value)); } } return TObject.Null; }); - TDictionary net = new TDictionary(); + TDictionary net = TObject.Dictionary(); net["tcpclient"] = new TExternalMethod((args2)=>{ if(args2.Length > 1) { @@ -1100,20 +1543,165 @@ namespace tlang } return TObject.Uninit; }); - net["sslclient"] = new TExternalMethod((args2)=>{ - - return TObject.Uninit; - }); + + net["tcpserver"] = new TExternalMethod((args2)=>{ + if(args2.Length > 1) + { + var ip = args2[0] as TString; + var port = args2[1] as TNumber; + if(ip!= null && port != null) + { + IPAddress address; + if(IPAddress.TryParse(ip.Value,out address)) + { + TcpListener listener = new TcpListener(address,(int)port.Value); + + TDictionary dict = TObject.Dictionary(); + dict["getlocal"] = new TExternalMethod(()=>{ + var ipE= listener.LocalEndpoint as IPEndPoint; + if(ipE == null) return TObject.Uninit; + TDictionary dict2=TObject.Dictionary(); + dict2["getip"] = new TExternalMethod(()=>{ + return TObject.String(ipE.Address.ToString()); + }); + dict2["getport"] = new TExternalMethod(()=>{ + return TObject.Number(ipE.Port); + }); + return dict2; + }); + dict["getpending"] = new TExternalMethod(()=>{ + return TObject.Boolean(listener.Pending() ); + }); + dict["start"]= new TExternalMethod(()=>{ + listener.Start(); + }); + dict["stop"]=new TExternalMethod(()=>{ + listener.Stop(); + }); + dict["getclient"]= new TExternalMethod(()=>{ + var clt=listener.AcceptTcpClient(); + + TDictionary dict3 = TObject.Dictionary(); + dict3["getlocal"] = new TExternalMethod(()=>{ + var ipE= clt.Client.LocalEndPoint as IPEndPoint; + if(ipE == null) return TObject.Uninit; + TDictionary dict2=TObject.Dictionary(); + dict2["getip"] = new TExternalMethod(()=>{ + return TObject.String(ipE.Address.ToString()); + }); + dict2["getport"] = new TExternalMethod(()=>{ + return TObject.Number(ipE.Port); + }); + return dict2; + }); + dict3["getremote"] = new TExternalMethod(()=>{ + var ipE= clt.Client.RemoteEndPoint as IPEndPoint; + if(ipE == null) return TObject.Uninit; + TDictionary dict2=TObject.Dictionary(); + dict2["getip"] = new TExternalMethod(()=>{ + return TObject.String(ipE.Address.ToString()); + }); + dict2["getport"] = new TExternalMethod(()=>{ + return TObject.Number(ipE.Port); + }); + return dict2; + }); + dict3["getstream"]= new TExternalMethod(()=>{ + return CreateStream(clt.GetStream()); + }); + return dict3; + }); + return dict; + } + + } + } return TObject.Uninit; }); env["net"] =net; - + var security = TObject.Dictionary(); + security["sslstream"] = new TExternalMethod((args)=>{ + if(args.Length >= 3) + { + + //STRM,INNEROPEN,ALWAYSTRUST + var firstArgStrm = args[0] as TDictionary; + if(firstArgStrm != null){ + Stream srcstrm=new TDictStrm(firstArgStrm); + SslStream strm; + if(args[2].AsBoolean) + { + strm = new SslStream(srcstrm,args[1].AsBoolean,(a,b,c,d)=>true); + } + else + { + strm = new SslStream(srcstrm,args[1].AsBoolean); + } + return CreateStream(strm); + } + } + return TObject.Null; + }); + var sha1 = TObject.Dictionary(); + sha1["hash_bytes"] = new TExternalMethod((args)=>{ + using(var s = SHA1Managed.Create()){ + if(args.Length > 0) + { + var a = args[0] as TArray; + if(a!=null) + { + byte[] hash = s.ComputeHash(a.ToBytes()); + return TArray.FromBytes(hash,0,hash.Length); + } + } + return TObject.Null; + } + + }); + sha1["hash_strm"] = new TExternalMethod((args)=>{ + using(var s = SHA1Managed.Create()){ + if(args.Length > 0) + { + var a = args[0] as TDictionary; + if(a!=null) + { + byte[] hash = s.ComputeHash(new TDictStrm(a)); + return TArray.FromBytes(hash,0,hash.Length); + } + } + return TObject.Null; + } + }); + + security["sha1"]=sha1; + env["security"]=security; + env["buffered"]=new TExternalMethod((args)=>{ + if(args.Length >=1) + { + var strm = args[0] as TDictionary; + + if(strm != null) + { + double sz=4096; + if(args.Length >= 2) + { + var bsize = args[1] as TNumber; + if(bsize != null) + { + sz = bsize.Value; + } + } + return CreateStream(new BufferedStream(new TDictStrm(strm))); + } + } + return TObject.Null; + }); } } -} \ No newline at end of file +} diff --git a/tlanglib/PostfixDecrementVariableNode.cs b/tlanglib/PostfixDecrementVariableNode.cs index aaf83d6..61306ee 100644 --- a/tlanglib/PostfixDecrementVariableNode.cs +++ b/tlanglib/PostfixDecrementVariableNode.cs @@ -14,7 +14,7 @@ namespace tlang var obj=Node.Execute(nodeEnv); - var newVal=new SubtractNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv); + var newVal=new SubtractNode(new ConstNode(obj),new ConstNode(TObject.Number(1))).Execute(nodeEnv); Node.SetValue(nodeEnv,newVal); @@ -23,4 +23,4 @@ namespace tlang return obj; } } -} \ No newline at end of file +} diff --git a/tlanglib/PostfixIncrementVariableNode.cs b/tlanglib/PostfixIncrementVariableNode.cs index 0964f55..56c71d4 100644 --- a/tlanglib/PostfixIncrementVariableNode.cs +++ b/tlanglib/PostfixIncrementVariableNode.cs @@ -14,7 +14,7 @@ namespace tlang var obj=Node.Execute(nodeEnv); - var newVal=new AddNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv); + var newVal=new AddNode(new ConstNode(obj),new ConstNode(TObject.Number(1))).Execute(nodeEnv); Node.SetValue(nodeEnv,newVal); diff --git a/tlanglib/Program.cs b/tlanglib/Program.cs index 1cd7236..9cd1b69 100644 --- a/tlanglib/Program.cs +++ b/tlanglib/Program.cs @@ -30,10 +30,10 @@ public class ApplicationRunner List args2=new List(); foreach(var argument in args) { - args2.Add(new TString(argument)); + args2.Add(TObject.String(argument)); } - var res= parser.Execute(env,args2.ToArray()) as TNumber; + var res= parser.Execute(env/*,args2.ToArray()*/) as TNumber; diff --git a/tlanglib/RightShift.cs b/tlanglib/RightShift.cs index a2345f4..2c865f6 100644 --- a/tlanglib/RightShift.cs +++ b/tlanglib/RightShift.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber((long)lnum.Value >> (int)rnum.Value); + return TObject.Number((long)lnum.Value >> (int)rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/ScopeNode.cs b/tlanglib/ScopeNode.cs index 6daf5b7..9c98e52 100644 --- a/tlanglib/ScopeNode.cs +++ b/tlanglib/ScopeNode.cs @@ -9,12 +9,14 @@ namespace tlang public override TObject Execute(IScopeEnvironment nodeEnv) { var sub = First ? nodeEnv : nodeEnv.SubEnv; - TObject obj=new TNull(); + TObject obj=TObject.Null; foreach(var item in Body) { obj=item.Execute(sub); } return obj; } + + } } \ No newline at end of file diff --git a/tlanglib/SubtractNode.cs b/tlanglib/SubtractNode.cs index 80d8024..9038de2 100644 --- a/tlanglib/SubtractNode.cs +++ b/tlanglib/SubtractNode.cs @@ -32,9 +32,11 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber(lnum.Value - rnum.Value); + return TObject.Number(lnum.Value - rnum.Value); - return new TNull(); + return TObject.Null; } + + } } \ No newline at end of file diff --git a/tlanglib/TArray.cs b/tlanglib/TArray.cs index 2450037..54b4741 100644 --- a/tlanglib/TArray.cs +++ b/tlanglib/TArray.cs @@ -1,15 +1,70 @@ +using System; using System.Collections.Generic; +using System.Text; +using Newtonsoft.Json.Linq; namespace tlang { public class TArray : TObject { - public override bool AsBoolean => Items.Count > 0; - public TArray() + public override JToken AsToken() { - + var ls = new JArray(); + foreach(var item in Items) + { + ls.Add(item.AsToken()); + } + return ls; + } + + public byte[] ToBytes() + { + byte[] data = new byte[Items.Count]; + SetBytes(data,0,data.Length); + return data; + } + public void SetBytes(byte[] data,int offset,int count) + { + count = Math.Min(data.Length - offset,count); + for(int i = 0;i Items.Count > 0; + public TArray(int sz=0) + { + Items =new List(); + for(int i = 0;i Items {get;set;}=new List(); + public List Items {get;set;} } } \ No newline at end of file diff --git a/tlanglib/TBoolean.cs b/tlanglib/TBoolean.cs new file mode 100644 index 0000000..486a999 --- /dev/null +++ b/tlanglib/TBoolean.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json.Linq; + +namespace tlang +{ + public class TBoolean : TObject + { + public override JToken AsToken() + { + return JValue.FromObject(Value); + } + public bool Value {get;set;} + + public override bool AsBoolean => Value; + + public TBoolean(bool value) + { + Value = value; + } + public override string ToString() + { + return Value ? "true" : "false"; + } + } +} \ No newline at end of file diff --git a/tlanglib/TChar.cs b/tlanglib/TChar.cs index 9a0c22f..ebd4e89 100644 --- a/tlanglib/TChar.cs +++ b/tlanglib/TChar.cs @@ -1,7 +1,17 @@ +using Newtonsoft.Json.Linq; + namespace tlang { - internal class TChar : TObject + public class TChar : TObject { + public override JToken AsToken() + { + return JValue.FromObject(Value); + } + public static implicit operator char(TChar c) + { + return c.Value; + } public override bool AsBoolean => Value != '\0'; public char Value {get;set;} public TChar(char v) diff --git a/tlanglib/TDictionary.cs b/tlanglib/TDictionary.cs index e244bd1..74cf61d 100644 --- a/tlanglib/TDictionary.cs +++ b/tlanglib/TDictionary.cs @@ -1,9 +1,13 @@ +using System; using System.Collections.Generic; +using System.Text; +using Newtonsoft.Json.Linq; namespace tlang { public class TRootDict : TDictionary { + IScopeEnvironment env; public TRootDict(IScopeEnvironment env) { @@ -24,6 +28,19 @@ namespace tlang } public class TDictionary : TObject { + public override JToken AsToken() + { + if(this.TryGetTimeSpan(out var ts)) + { + return JValue.FromObject(ts); + } + JObject obj=new JObject(); + foreach(var item in this.items) + { + obj.Add(item.Key,item.Value.AsToken()); + } + return obj; + } public override bool AsBoolean {get =>true;} public TDictionary() { @@ -53,11 +70,51 @@ namespace tlang items.Add(name,obj); } } - + public override string ToString() + { + if(items.ContainsKey("toString")) + { + var tostr = items["toString"] as ICallable; + if(tostr != null) + { + var res= tostr.Call().ToString(); + return res; + } + } + StringBuilder b = new StringBuilder(); + b.AppendLine("Dictionary Items:"); + foreach(var item in items) + { + b.AppendLine($"{item.Key}={item.Value.ToString()}"); + } + return b.ToString(); + } public virtual bool MemberExists(string name) { return items.ContainsKey(name); } + + internal IEnumerable GetMembers() + { + foreach(var item in items) + { + TDictionary dict = TObject.Dictionary(); + dict["getname"] = new TExternalMethod(()=>{ + return TObject.String(item.Key); + }); + dict["getvalue"] = new TExternalMethod(()=>{ + return item.Value; + }); + dict["setvalue"] = new TExternalMethod((args)=>{ + if(args.Length == 1) + { + items[item.Key] = args[0]; + } + }); + yield return dict; + } + } + public TObject this[string variable] { get => GetMember(variable); set => SetMember(variable,value); } diff --git a/tlanglib/TInternalObject.cs b/tlanglib/TInternalObject.cs index f0737f1..60a56d3 100644 --- a/tlanglib/TInternalObject.cs +++ b/tlanglib/TInternalObject.cs @@ -1,7 +1,13 @@ +using Newtonsoft.Json.Linq; + namespace tlang { public class TInternalObject : TObject { + public override JToken AsToken() + { + return JValue.FromObject((object)null); + } public override bool AsBoolean => true; public TInternalObject(object val) { diff --git a/tlanglib/TLangTemplateEngine.cs b/tlanglib/TLangTemplateEngine.cs new file mode 100644 index 0000000..19efa88 --- /dev/null +++ b/tlanglib/TLangTemplateEngine.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace tlang { +public class TLangGenerator +{ + Lazy<(List Tokens,string Source)> srcCode; + public TLangGenerator(string src) + { + srcCode=new Lazy<(List Tokens,string Source)>(()=>{ + string text = Lex(src); + Lexer lexer=new Lexer(new StringReader(text)); + + return (lexer.Tokens,text); + }); + } + public string SourceCode + { + get => srcCode.Value.Source; + } + public string Execute(Action parser) + { + + Parser p = new Parser(srcCode.Value.Tokens); + RootEnvironment env=new RootEnvironment(); + p.LoadEnvironment(env); + StringBuilder builder=new StringBuilder(); + env.SetVariable("__writer",new TExternalMethod((args)=>{ + if(args.Length >= 1) + { + foreach(var arg in args) + { + builder.Append(arg.ToString()); + } + } + return TObject.Null; + })); + parser?.Invoke(env); + + p.Execute(env); + + + // + return builder.ToString(); + } + + private string Lex(string text) + { + StringBuilder tlangFile = new StringBuilder(); + StringBuilder b=new StringBuilder(); + + bool lastInCode=true; + bool inCode=false; + int i = 0; + bool isDone = false; + Action appendChar = (c)=>{ + if((lastInCode != inCode || isDone) && b.Length > 0) + { + if(inCode ^ (isDone && !inCode)) + { + tlangFile.Append("__writer(\""); + b.Replace("\n","\\n").Replace("\t","\\t").Replace("\r","\\r").Replace("\"","\\\"").Replace("\'","\\\'"); + foreach(var _c in b.ToString()) + { + if(_c < 32 || _c > 126) + { + tlangFile.Append($"\\x{((int)_c).ToString("X2")}"); + }else{ + tlangFile.Append(_c); + } + } + b.Clear(); + + tlangFile.Append("\");"); + } + if(!inCode ^ (isDone && inCode)) + { + if(b.Length > 0) + { + tlangFile.Append(b); + } + b.Clear(); + } + } + + if(c != -1) + { + b.Append((char)c); + } + + lastInCode = inCode; + }; + bool escapedByAt = false; + while(i < text.Length) + { + char curChar = text[i++]; + int nextChar = i true; public TInternalMethod(ClosureNode node,IScopeEnvironment env) { @@ -28,7 +33,7 @@ namespace tlang } if(i==Body.Arguments.Count-1) { - var tarray = new TArray(); + var tarray = TObject.Array(); env[Body.Arguments[i].TrimStart('$')] =tarray; for(int j = i;j cb; public TExternalMethod(Func func) { cb = func; } + public TExternalMethod(Action func) + { + cb = (args)=>{ + func(args); + return Uninit; + }; + } + public TExternalMethod(Func func) + { + cb = (args)=>{ + return func(); + }; + } + public TExternalMethod(Action func) + { + cb = (args)=>{ + func(); + return Uninit; + }; + } + public override bool AsBoolean => true; public TObject Call(params TObject[] args) diff --git a/tlanglib/TNull.cs b/tlanglib/TNull.cs index 8e4b1af..441bba1 100644 --- a/tlanglib/TNull.cs +++ b/tlanglib/TNull.cs @@ -1,3 +1,5 @@ +using Newtonsoft.Json.Linq; + namespace tlang { public class TNull : TObject @@ -7,5 +9,9 @@ namespace tlang { return "null"; } + public override JToken AsToken() + { + return JValue.CreateNull(); + } } } \ No newline at end of file diff --git a/tlanglib/TNumber.cs b/tlanglib/TNumber.cs index 018d531..280c467 100644 --- a/tlanglib/TNumber.cs +++ b/tlanglib/TNumber.cs @@ -1,7 +1,49 @@ +using Newtonsoft.Json.Linq; + namespace tlang { public class TNumber : TObject { + public static implicit operator double(TNumber n) + { + return n.Value; + } + public static explicit operator long(TNumber n) + { + return (long)n.Value; + } + public static explicit operator float(TNumber n) + { + return (float)n.Value; + } + public static explicit operator int(TNumber n) + { + return (int)n.Value; + } + public static explicit operator short(TNumber n) + { + return (short)n.Value; + } + public static explicit operator ushort(TNumber n) + { + return (ushort)n.Value; + } + public static explicit operator uint(TNumber n) + { + return (uint)n.Value; + } + public static explicit operator ulong(TNumber n) + { + return (ulong)n.Value; + } + public static explicit operator byte(TNumber n) + { + return (byte)n.Value; + } + public static explicit operator sbyte(TNumber n) + { + return (sbyte)n.Value; + } public double Value {get;set;} public override bool AsBoolean => Value != 0; @@ -14,6 +56,10 @@ namespace tlang { return Value.ToString(); } + public override JToken AsToken() + { + return new JValue(Value); + } } diff --git a/tlanglib/TObject.cs b/tlanglib/TObject.cs index 30a6914..b0207d9 100644 --- a/tlanglib/TObject.cs +++ b/tlanglib/TObject.cs @@ -1,9 +1,261 @@ +using System; +using System.IO; +using Newtonsoft.Json.Linq; + namespace tlang { + public static class TObjectExtensions + { + public static bool TryGetFieldOrProperty(this TObject obj,string key,out TObject val) + { + val=TObject.Uninit; + var dict = obj as TDictionary; + if(dict != null) + { + if(dict.MemberExists($"get{key}")) + { + var p= dict[$"get{key}"] as ICallable; + if(p != null) + { + val = p.Call(); + return true; + } + } + if(dict.MemberExists(key)) + { + val = dict[key]; + return true; + } + } + return false; + } + public static string GetExtObjType(this TObject obj) + { + var dict = obj as TDictionary; + if(dict != null) + { + if(!dict.MemberExists("_extobjtype")) return ""; + var _extobjtype=dict["_extobjtype"] as TString; + if(_extobjtype != null) return _extobjtype.Value; + } + return ""; + } + public static TDictionary ToTObject(this TimeSpan ts) + { + var dict = TObject.Dictionary(); + dict["_extobjtype"] ="timespan"; + dict["h"] = ts.Hours; + dict["m"] = ts.Minutes; + dict["s"] = ts.Seconds; + dict["totalseconds"] = ts.TotalSeconds; + return dict; + } + public static bool TryGetTimeSpan(this TObject obj,out TimeSpan ts) + { + ts=TimeSpan.Zero; + var dict = obj as TDictionary; + if(dict != null) + { + if(dict.GetExtObjType() != "timespan") return false; + if(obj.TryGetFieldOrProperty("totalseconds",out var v)) + { + var _totalSecond = v as TNumber; + double totalSeconds = 0; + if(_totalSecond != null) totalSeconds = _totalSecond.Value; + ts = TimeSpan.FromSeconds(totalSeconds); + return true; + } + if(obj.TryGetFieldOrProperty("h",out var h) && obj.TryGetFieldOrProperty("m",out var m) && obj.TryGetFieldOrProperty("s",out var s)) + { + var _h = h as TNumber; + var _m = m as TNumber; + var _s = s as TNumber; + int __h=0; + int __m=0; + int __s=0; + if(_h != null) __h = (int)_h.Value; + if(_m != null) __m = (int)_m.Value; + if(_s != null) __s = (int)_s.Value; + + ts=new TimeSpan(__h,__m,__s); + return true; + } + + } + return false; + } + } public abstract class TObject { + public static explicit operator bool(TObject obj) + { + return obj.AsBoolean; + } + public static implicit operator TObject(double dbl) + { + return Number(dbl); + } + public static implicit operator TObject(Func o) + { + return new TExternalMethod(o); + } + public static implicit operator TObject(string str) + { + return String(str); + } + public static implicit operator TObject(bool b) + { + return Boolean(b); + } + public static implicit operator TObject(int n) + { + return Number(n); + } + public static implicit operator TObject(long n) + { + return Number(n); + } + public static implicit operator TObject(short n) + { + return Number(n); + } + public static implicit operator TObject(TimeSpan ts) + { + return ts.ToTObject(); + } + public static implicit operator TObject(float f) + { + return Number(f); + } + public static implicit operator TObject(ushort s) + { + return Number(s); + } + public static implicit operator TObject(uint s) + { + return Number(s); + } + public static implicit operator TObject(ulong l) + { + return Number(l); + } + public static implicit operator TObject(char c) + { + return Char(c); + } + public static implicit operator TObject(Stream strm) + { + return Parser.CreateStream(strm); + } + public static implicit operator TObject(TObject[] array) + { + var a=Array(); + a.Items.AddRange(array); + return a; + } + public static implicit operator TObject(byte b) + { + return Number(b); + } + public static implicit operator TObject(sbyte b) + { + return Number(b); + } + public static TObject FromToken(JToken token) + { + var obj = token as JObject; + var val = token as JValue; + var arr = token as JArray; + if(obj != null) + { + var dict = Dictionary(); + foreach(var item in obj) + { + dict.SetMember(item.Key,FromToken(item.Value)); + } + return dict; + } + if(arr != null) + { + var array = Array(); + foreach(var item in arr) + { + array.Items.Add(FromToken(item)); + } + return array; + } + if(val != null) + { + if(val.Type == JTokenType.Integer) + { + return Number(val.ToObject()); + } + if(val.Type == JTokenType.Float) + { + return Number(val.ToObject()); + } + if(val.Type == JTokenType.String) + { + return String(val.ToObject()); + } + if(val.Type == JTokenType.Null) + { + return Null; + } + if(val.Type == JTokenType.Undefined) + { + return Uninit; + } + if(val.Type == JTokenType.TimeSpan) + { + //h:m:s + var tdict=Dictionary(); + tdict["_extobjtype"] = String("timespan"); + + } + if(val.Type == JTokenType.Boolean) + { + return TObject.Boolean(val.ToObject()); + } + } + return Uninit; + } + public abstract JToken AsToken(); + public override string ToString() + { + return "TObject"; + } public abstract bool AsBoolean {get;} public static TObject Uninit => new TUninit(); public static TObject Null => new TNull(); + + public static TObject True => new TBoolean(true); + public static TObject False => new TBoolean(false); + + public static TChar Char(char c) + { + return new TChar(c); + } + public static TNumber Number(double dbl) + { + return new TNumber(dbl); + } + public static TString String(string text) + { + return new TString(text); + } + public static TDictionary Dictionary() + { + return new TDictionary(); + } + public static TArray Array(int bufferSize=0) + { + return new TArray(bufferSize); + } + + public static TObject Boolean(bool v) + { + return new TBoolean(v); + } } } \ No newline at end of file diff --git a/tlanglib/TString.cs b/tlanglib/TString.cs index 55ed317..4a512b8 100644 --- a/tlanglib/TString.cs +++ b/tlanglib/TString.cs @@ -1,7 +1,13 @@ +using Newtonsoft.Json.Linq; + namespace tlang { public class TString : TObject { + public static implicit operator string(TString s) + { + return s.Value; + } public string Value {get;set;} public override bool AsBoolean => Value.Length > 0; @@ -14,5 +20,10 @@ namespace tlang { return Value; } + + public override JToken AsToken() + { + return JValue.FromObject(Value); + } } } \ No newline at end of file diff --git a/tlanglib/TUninit.cs b/tlanglib/TUninit.cs index 14c396e..dc64d73 100644 --- a/tlanglib/TUninit.cs +++ b/tlanglib/TUninit.cs @@ -1,8 +1,16 @@ +using Newtonsoft.Json.Linq; + namespace tlang { public class TUninit : TObject { public override bool AsBoolean {get=>false;} + + public override JToken AsToken() + { + return JValue.CreateUndefined(); + } + public override string ToString() { return "undefined"; diff --git a/tlanglib/WhileLoop.cs b/tlanglib/WhileLoop.cs index 3477e36..a3b644c 100644 --- a/tlanglib/WhileLoop.cs +++ b/tlanglib/WhileLoop.cs @@ -19,20 +19,27 @@ namespace tlang var env = nodeEnv.SubEnv; env["last_ittr"]= new TExternalMethod((args)=>{ + if(args.Length > 0) + { + return TObject.Boolean(!args[0].AsBoolean || !isRunning); + } isRunning=false; - return new TNumber(1); + return TObject.True; }); - TObject obj=new TUninit(); + TObject obj=TObject.Uninit; if(!DoLoop) isRunning = Condition.Execute(env).AsBoolean; while(isRunning) { obj=Body.Execute(env); + if(isRunning) isRunning = Condition.Execute(env).AsBoolean; } return obj; } + + } } \ No newline at end of file diff --git a/tlanglib/XOrNode.cs b/tlanglib/XOrNode.cs index bab6d89..a2705b8 100644 --- a/tlanglib/XOrNode.cs +++ b/tlanglib/XOrNode.cs @@ -32,9 +32,9 @@ namespace tlang } if(lnum != null && rnum != null) - return new TNumber((long)lnum.Value ^ (long)rnum.Value); + return TObject.Number((long)lnum.Value ^ (long)rnum.Value); - return new TNull(); + return TObject.Null; } } } \ No newline at end of file diff --git a/tlanglib/launcher/launcher.tlang b/tlanglib/launcher/launcher.tlang index 00f3606..bf40b07 100644 --- a/tlanglib/launcher/launcher.tlang +++ b/tlanglib/launcher/launcher.tlang @@ -1,7 +1,35 @@ main = func($$args){ + + ____load = func(file) + { + ___code_txt=""; + if(file.endsWith(".txt")) + { + each(fs.readalltext(file).split('\n')) + { + ___code_txt = ___code_txt + ____load(fs.relative_to_parent_of(file,item)) + "\n"; + + } + + }else{ + if(!fs.file_exists(file)) console.writeln("WARN: " + file + " Does not exist"); + ___code_txt=fs.readalltext(file); + + } + ___code_txt; + } if(fs.file_exists(args[0])) { - code = reflection.parse_code(fs.readalltext(args[0])); + code_txt = ____load(args[0]); + + + code=reflection.parse_code(code_txt); + for(i = 1;i"); } }; \ No newline at end of file diff --git a/tlanglib/tlanglib.csproj b/tlanglib/tlanglib.csproj index 2c95dfd..9bb09f4 100644 --- a/tlanglib/tlanglib.csproj +++ b/tlanglib/tlanglib.csproj @@ -12,4 +12,9 @@ + + + + +