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 tokens,ref int i)
{
var token=tokens[i++];
- if(token.IsString) return new ConstNode(new TString(token.Text));
+ if(token.IsString) return new ConstNode(TObject.String(token.Text));
if(token.IsChar)
{
- return new ConstNode(new TChar(token.Text.SingleOrDefault()));
+ return new ConstNode(TObject.Char(token.Text.SingleOrDefault()));
+ }
+ if(token.Text == "-")
+ {
+ return new NegativeNode(ParseValue(tokens,ref i));
+ }
+ if(token.Text == "~")
+ {
+ return new BitwiseNot(ParseValue(tokens,ref i));
+ }
+ if(token.Text == "!")
+ {
+ return new NotNode(ParseValue(tokens,ref i));
}
-
long val;
if(long.TryParse(token.Text,out val))
{
@@ -268,11 +505,11 @@ namespace tlang
double dblR;
if(double.TryParse($"{val}.{token2.Text}",out dblR))
{
- return new ConstNode(new TNumber(dblR));
+ return new ConstNode(TObject.Number(dblR));
}
}
}else{
- return new ConstNode(new TNumber( val ));
+ return new ConstNode(TObject.Number( val ));
}
}
else {
@@ -486,10 +723,10 @@ namespace tlang
ret= new ConstNode(TObject.Uninit);
break;
case "true":
- ret= new ConstNode(new TNumber(1));
+ ret= new ConstNode(TObject.True);
break;
case "false":
- ret= new ConstNode(new TNumber(0));
+ ret= new ConstNode(TObject.False);
break;
default:
ret= new GetVariableValue(token.Text);
@@ -593,9 +830,9 @@ namespace tlang
}
return myExpression;
}
- private TObject CreateStream(Stream strm)
+ public static TObject CreateStream(Stream strm)
{
- TDictionary dict = new TDictionary();
+ TDictionary dict = TObject.Dictionary();
dict["setposition"] = new TExternalMethod((args2)=>{
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 @@
+
+
+
+
+