1708 lines
63 KiB
C#
1708 lines
63 KiB
C#
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
|
|
{
|
|
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<Math.Min(buffer.Length - offset,le);i++)
|
|
{
|
|
var abyte = data.Items[i] as TNumber;
|
|
if(abyte != null)
|
|
{
|
|
buffer[i+offset] = (byte)abyte.Value;
|
|
}
|
|
}
|
|
return le;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
{
|
|
switch(origin)
|
|
{
|
|
|
|
case SeekOrigin.Current:
|
|
return Position += offset;
|
|
case SeekOrigin.End:
|
|
return Length - offset;
|
|
default:
|
|
return Position = offset;
|
|
|
|
}
|
|
}
|
|
|
|
public override void SetLength(long value)
|
|
{
|
|
var pos = dict.GetMember("setlength") as ICallable;
|
|
if(pos != null)
|
|
{
|
|
pos.Call(TNumber.Number(value));
|
|
}
|
|
}
|
|
public override void Close()
|
|
{
|
|
var pos = dict.GetMember("close") as ICallable;
|
|
if(pos != null)
|
|
{
|
|
pos.Call();
|
|
}
|
|
}
|
|
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
{
|
|
var write = dict.GetMember("write") as ICallable;
|
|
|
|
if(write != null)
|
|
{
|
|
var data = TObject.Array();
|
|
for(int i = 0;i<Math.Min(buffer.Length - offset,count);i++)
|
|
{
|
|
data.Items.Add(TObject.Number(buffer[i+offset]));
|
|
|
|
}
|
|
|
|
write.Call(data,TObject.Number(count));
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
public class Parser
|
|
{
|
|
|
|
public Parser(List<LexToken> tokens)
|
|
{
|
|
int i=0;
|
|
Node = ParseExpression(tokens,ref i,true);
|
|
}
|
|
public Node Node {get;set;}
|
|
|
|
public TObject Execute(IScopeEnvironment env)
|
|
{
|
|
var res=Node.Execute(env);
|
|
return res;
|
|
}
|
|
private Node ParseExpression(List<LexToken> tokens,ref int i,bool isFirst=false)
|
|
{
|
|
if(i>= tokens.Count) return new ConstNode(TObject.Number(0));
|
|
if(tokens[i].Text == "{" || isFirst)
|
|
{
|
|
if(!isFirst)
|
|
i++;
|
|
ScopeNode scopeNode = new ScopeNode(){First=isFirst};
|
|
while(i<tokens.Count && tokens[i].Text != "}")
|
|
{
|
|
scopeNode.Body.Add(ParseExpression(tokens,ref i));
|
|
if(i<tokens.Count && tokens[i].Text == ";")
|
|
{
|
|
i++;
|
|
}
|
|
|
|
}
|
|
i++;
|
|
return scopeNode;
|
|
}else{
|
|
return ParseAssignable(tokens,ref i);
|
|
}
|
|
}
|
|
private Node ParseAssignable(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseLOR(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "=" || tokens[i].Text == "+=" || tokens[i].Text == "-=" || tokens[i].Text == "*=" || tokens[i].Text == "/=" || tokens[i].Text == "%=" || tokens[i].Text == "^=" || tokens[i].Text == "|=" || tokens[i].Text == "&=") )
|
|
{
|
|
if(i<tokens.Count && tokens[i].Text == "=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,ParseLOR(tokens,ref i));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "+=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new AddNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "-=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new SubtractNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "*=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new MultiplyNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "/=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new DivideNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "%=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new ModuloNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "^=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new XOrNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "|=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new BitwiseOrNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "&=")
|
|
{
|
|
i++;
|
|
var gvar = myExpression as GetVariableValue;
|
|
if(gvar != null)
|
|
{
|
|
myExpression= new SetVariableNode(gvar,new BitwiseAndNode(gvar,ParseLOR(tokens,ref i)));
|
|
|
|
}
|
|
}
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseLOR(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseLAnd(tokens,ref i);
|
|
while(i<tokens.Count && tokens[i].Text == "||")
|
|
{
|
|
|
|
|
|
i++;
|
|
myExpression = new LogicalOrNode(myExpression,ParseLAnd(tokens,ref i));
|
|
|
|
|
|
|
|
}
|
|
|
|
return myExpression;
|
|
}
|
|
private Node ParseLAnd(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseBOr(tokens,ref i);
|
|
while(i<tokens.Count && tokens[i].Text == "&&")
|
|
{
|
|
|
|
|
|
i++;
|
|
myExpression = new LogicalAndNode(myExpression,ParseBOr(tokens,ref i));
|
|
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseBOr(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseXOr(tokens,ref i);
|
|
while(i<tokens.Count && tokens[i].Text == "|")
|
|
{
|
|
|
|
|
|
i++;
|
|
myExpression = new BitwiseOrNode(myExpression,ParseXOr(tokens,ref i));
|
|
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseXOr(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseBAnd(tokens,ref i);
|
|
while(i<tokens.Count && tokens[i].Text == "^")
|
|
{
|
|
|
|
|
|
i++;
|
|
myExpression = new XOrNode(myExpression,ParseBAnd(tokens,ref i));
|
|
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseBAnd(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseEq(tokens,ref i);
|
|
while(i<tokens.Count && tokens[i].Text == "&")
|
|
{
|
|
|
|
|
|
i++;
|
|
myExpression = new BitwiseAndNode(myExpression,ParseEq(tokens,ref i));
|
|
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseEq(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseRo(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "!=" || tokens[i].Text == "=="))
|
|
{
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "!="){
|
|
i++;
|
|
myExpression = new NotEqualsNode(myExpression,ParseRo(tokens,ref i));
|
|
}
|
|
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "==")
|
|
{
|
|
i++;
|
|
|
|
myExpression = new EqualsNode(myExpression,ParseRo(tokens,ref i));
|
|
}
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseRo(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseShift(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "<=" || tokens[i].Text == ">=" || tokens[i].Text == "<" || tokens[i].Text == ">"))
|
|
{
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "<="){
|
|
i++;
|
|
myExpression = new LessThanEqualsNode(myExpression,ParseShift(tokens,ref i));
|
|
}
|
|
|
|
|
|
if(i<tokens.Count && tokens[i].Text == ">=")
|
|
{
|
|
i++;
|
|
myExpression = new GreaterThanEqualsNode(myExpression,ParseShift(tokens,ref i));
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "<"){
|
|
i++;
|
|
myExpression = new LessThanNode(myExpression,ParseShift(tokens,ref i));
|
|
}
|
|
|
|
|
|
if(i<tokens.Count && tokens[i].Text == ">")
|
|
{
|
|
i++;
|
|
myExpression = new GreaterThanNode(myExpression,ParseShift(tokens,ref i));
|
|
}
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
|
|
private Node ParseShift(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseSum(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "<<" || tokens[i].Text == ">>"))
|
|
{
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "<<"){
|
|
i++;
|
|
myExpression = new LeftShiftNode(myExpression,ParseSum(tokens,ref i));
|
|
}
|
|
|
|
|
|
if(i<tokens.Count && tokens[i].Text == ">>")
|
|
{
|
|
i++;
|
|
myExpression = new RightShiftNode(myExpression,ParseSum(tokens,ref i));
|
|
}
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
|
|
|
|
private Node ParseSum(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseFactor(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "+" || tokens[i].Text == "-"))
|
|
{
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "+"){
|
|
i++;
|
|
myExpression = new AddNode(myExpression,ParseFactor(tokens,ref i));
|
|
}
|
|
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "-")
|
|
{
|
|
i++;
|
|
myExpression = new SubtractNode(myExpression,ParseFactor(tokens,ref i));
|
|
}
|
|
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
private Node ParseValue(List<LexToken> tokens,ref int i)
|
|
{
|
|
var token=tokens[i++];
|
|
if(token.IsString) return new ConstNode(TObject.String(token.Text));
|
|
if(token.IsChar)
|
|
{
|
|
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))
|
|
{
|
|
if(i<tokens.Count && tokens[i].Text == "." && !tokens[i].IsChar && !tokens[i].IsString)
|
|
{
|
|
i++;
|
|
if(i<tokens.Count)
|
|
{
|
|
var token2=tokens[i++];
|
|
double dblR;
|
|
if(double.TryParse($"{val}.{token2.Text}",out dblR))
|
|
{
|
|
return new ConstNode(TObject.Number(dblR));
|
|
}
|
|
}
|
|
}else{
|
|
return new ConstNode(TObject.Number( val ));
|
|
}
|
|
}
|
|
else {
|
|
if(i<tokens.Count && tokens[i].Text=="(")
|
|
{
|
|
if(token.Text == "func")
|
|
{
|
|
List<string> args = new List<string>();
|
|
i++;
|
|
while(i<tokens.Count && tokens[i].Text != ")")
|
|
{
|
|
|
|
if(tokens[i].Text == ",") {i++;continue;}
|
|
|
|
if(i<tokens.Count)
|
|
{
|
|
var exp = ParseExpression(tokens,ref i);
|
|
var gvExp = exp as GetVariableValue;
|
|
if(gvExp != null)
|
|
{
|
|
args.Add(gvExp.Name);
|
|
}else{
|
|
throw new Exception("not a getvariablenode");
|
|
}
|
|
}
|
|
|
|
}
|
|
i++;
|
|
return new ClosureNode(args,ParseExpression(tokens,ref i));
|
|
}
|
|
else if(token.Text == "for")
|
|
{
|
|
i++;
|
|
//init;condition;inc)
|
|
|
|
Node init = new ConstNode(new TUninit());
|
|
Node condition = new ConstNode(new TUninit());
|
|
Node inc = new ConstNode(new TUninit());
|
|
Node body = new ConstNode(new TUninit());
|
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
|
{
|
|
init = ParseExpression(tokens,ref i);
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == ";")
|
|
i++;
|
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
|
{
|
|
condition = ParseExpression(tokens,ref i);
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == ";")
|
|
i++;
|
|
if(i<tokens.Count && (tokens[i].Text != ")" || tokens[i].Text != ";"))
|
|
{
|
|
inc = ParseExpression(tokens,ref i);
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == ")")
|
|
i++;
|
|
if(i<tokens.Count)
|
|
body = ParseExpression(tokens,ref i);
|
|
|
|
return new ForLoop(init,condition,inc,body);
|
|
}
|
|
else if(token.Text == "each")
|
|
{
|
|
i++;
|
|
Node ls = ParseExpression(tokens,ref i);
|
|
var name = new GetVariableValue("item");
|
|
if(i<tokens.Count && tokens[i].Text == ":")
|
|
{
|
|
i++;
|
|
var n=ls as GetVariableValue;
|
|
if(n != null) name = n;
|
|
ls = ParseExpression(tokens,ref i);
|
|
}
|
|
i++;
|
|
if(i<tokens.Count)
|
|
{
|
|
return new EachLoop(name,ls,ParseExpression(tokens,ref i));
|
|
}
|
|
}
|
|
else if(token.Text == "while")
|
|
{
|
|
i++;
|
|
var condition=ParseExpression(tokens,ref i);
|
|
i++;
|
|
Node yes = new ConstNode(new TUninit());
|
|
if(i<tokens.Count && tokens[i].Text != ";")
|
|
yes = ParseExpression(tokens,ref i);
|
|
return new WhileLoop(condition,yes,false);
|
|
}
|
|
else if(token.Text == "do")
|
|
{
|
|
i++;
|
|
var condition=ParseExpression(tokens,ref i);
|
|
i++;
|
|
Node yes = new ConstNode(new TUninit());
|
|
if(i<tokens.Count && tokens[i].Text != ";")
|
|
yes = ParseExpression(tokens,ref i);
|
|
return new WhileLoop(condition,yes,true);
|
|
}
|
|
else if(token.Text == "if")
|
|
{
|
|
i++;
|
|
var condition=ParseExpression(tokens,ref i);
|
|
i++;
|
|
Node yes = new ConstNode(new TUninit());
|
|
Node no = new ConstNode(new TUninit());
|
|
if(i<tokens.Count && tokens[i].Text != "else")
|
|
yes=ParseExpression(tokens,ref i);
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "else")
|
|
{
|
|
i++;
|
|
no = ParseExpression(tokens,ref i);
|
|
}
|
|
|
|
return new IfNode(condition,yes,no);
|
|
}
|
|
else{
|
|
i++;
|
|
List<Node> args = new List<Node>();
|
|
//function call baby
|
|
while(i<tokens.Count && tokens[i].Text != ")")
|
|
{
|
|
|
|
if(tokens[i].Text == ",") {i++;continue;}
|
|
|
|
if(i<tokens.Count)
|
|
{
|
|
args.Add(ParseExpression(tokens,ref i));
|
|
}
|
|
|
|
}
|
|
i++;
|
|
Node ret = new FunctionCallNode(token.Text,args);
|
|
while(i<tokens.Count && tokens[i].Text == "[")
|
|
{
|
|
|
|
i++;
|
|
var arg = ParseExpression(tokens,ref i);
|
|
i++;
|
|
ret = new ArraySubscriptNode(ret,token.Text,arg);
|
|
}
|
|
while(i<tokens.Count && tokens[i].Text == ".")
|
|
{
|
|
i++;
|
|
|
|
var token2 = tokens[i++];
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "(")
|
|
{
|
|
i++;
|
|
args = new List<Node>();
|
|
//function call baby
|
|
while(i<tokens.Count && tokens[i].Text != ")")
|
|
{
|
|
|
|
if(tokens[i].Text == ",") {i++;continue;}
|
|
|
|
if(i<tokens.Count)
|
|
{
|
|
args.Add(ParseExpression(tokens,ref i));
|
|
}
|
|
|
|
}
|
|
i++;
|
|
ret = new MemberFunctionCallNode(ret,token2.Text,args);
|
|
}
|
|
else if(i<tokens.Count && tokens[i].Text == "[")
|
|
{
|
|
i++;
|
|
var arg = ParseExpression(tokens,ref i);
|
|
i++;
|
|
ret = new ArraySubscriptNode(ret,token2.Text,arg);
|
|
}
|
|
else{
|
|
ret = new MemberGetVariableValue(ret,token2.Text);
|
|
}
|
|
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "++")
|
|
{
|
|
var mgvn = ret as GetVariableValue;
|
|
i++;
|
|
if(mgvn != null)
|
|
{
|
|
return new PostfixIncrementVariableNode(mgvn);
|
|
}
|
|
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "--")
|
|
{
|
|
var mgvn = ret as GetVariableValue;
|
|
i++;
|
|
if(mgvn != null)
|
|
{
|
|
return new PostfixDecrementVariableNode(mgvn);
|
|
}
|
|
|
|
}
|
|
return ret;
|
|
}
|
|
}else{
|
|
Node ret;
|
|
switch(token.Text)
|
|
{
|
|
case "null":
|
|
ret= new ConstNode(TObject.Null);
|
|
break;
|
|
case "undefined":
|
|
ret= new ConstNode(TObject.Uninit);
|
|
break;
|
|
case "true":
|
|
ret= new ConstNode(TObject.True);
|
|
break;
|
|
case "false":
|
|
ret= new ConstNode(TObject.False);
|
|
break;
|
|
default:
|
|
ret= new GetVariableValue(token.Text);
|
|
break;
|
|
}
|
|
while(i<tokens.Count && tokens[i].Text == "[")
|
|
{
|
|
|
|
i++;
|
|
var arg = ParseExpression(tokens,ref i);
|
|
i++;
|
|
ret = new ArraySubscriptNode(ret,token.Text,arg);
|
|
}
|
|
|
|
while(i<tokens.Count && tokens[i].Text == ".")
|
|
{
|
|
i++;
|
|
|
|
var token2 = tokens[i++];
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "(")
|
|
{
|
|
i++;
|
|
var args = new List<Node>();
|
|
//function call baby
|
|
while(i<tokens.Count && tokens[i].Text != ")")
|
|
{
|
|
|
|
if(tokens[i].Text == ",") {i++;continue;}
|
|
|
|
if(i<tokens.Count)
|
|
{
|
|
args.Add(ParseExpression(tokens,ref i));
|
|
}
|
|
|
|
}
|
|
i++;
|
|
ret = new MemberFunctionCallNode(ret,token2.Text,args);
|
|
}
|
|
else if(i<tokens.Count && tokens[i].Text == "[")
|
|
{
|
|
i++;
|
|
var arg = ParseExpression(tokens,ref i);
|
|
i++;
|
|
ret = new ArraySubscriptNode(ret,token2.Text,arg);
|
|
}
|
|
else{
|
|
ret = new MemberGetVariableValue(ret,token2.Text);
|
|
}
|
|
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "++")
|
|
{
|
|
var mgvn = ret as GetVariableValue;
|
|
i++;
|
|
if(mgvn != null)
|
|
{
|
|
return new PostfixIncrementVariableNode(mgvn);
|
|
}
|
|
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "--")
|
|
{
|
|
var mgvn = ret as GetVariableValue;
|
|
i++;
|
|
if(mgvn != null)
|
|
{
|
|
return new PostfixDecrementVariableNode(mgvn);
|
|
}
|
|
|
|
}
|
|
return ret;
|
|
|
|
}
|
|
}
|
|
|
|
throw new Exception();
|
|
}
|
|
|
|
private Node ParseFactor(List<LexToken> tokens,ref int i)
|
|
{
|
|
Node myExpression = ParseValue(tokens,ref i);
|
|
while(i<tokens.Count && (tokens[i].Text == "*" || tokens[i].Text == "/" || tokens[i].Text == "%"))
|
|
{
|
|
|
|
if(i<tokens.Count && tokens[i].Text == "*"){
|
|
i++;
|
|
myExpression = new MultiplyNode(myExpression,ParseValue(tokens,ref i));
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "/")
|
|
{
|
|
i++;
|
|
myExpression = new DivideNode(myExpression,ParseValue(tokens,ref i));
|
|
}
|
|
if(i<tokens.Count && tokens[i].Text == "%")
|
|
{
|
|
i++;
|
|
myExpression = new ModuloNode(myExpression,ParseValue(tokens,ref i));
|
|
}
|
|
|
|
}
|
|
return myExpression;
|
|
}
|
|
public static TObject CreateStream(Stream strm)
|
|
{
|
|
TDictionary dict = TObject.Dictionary();
|
|
dict["setposition"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length ==1)
|
|
{
|
|
var pos = args2[0] as TNumber;
|
|
if(pos != null)
|
|
{
|
|
strm.Position = (long)pos.Value;
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
dict["getposition"] = new TExternalMethod((args2)=>{
|
|
return TObject.Number(strm.Position);
|
|
});
|
|
dict["getlength"] = new TExternalMethod((args2)=>{
|
|
return TObject.Number(strm.Length);
|
|
});
|
|
dict["getcount"] = new TExternalMethod((args2)=>{
|
|
return TObject.Number(strm.Length);
|
|
});
|
|
dict["getcanread"] = new TExternalMethod((args2)=>{
|
|
return TObject.Boolean(strm.CanRead);
|
|
});
|
|
dict["getcanwrite"] = new TExternalMethod((args2)=>{
|
|
return TObject.Boolean(strm.CanWrite);
|
|
});
|
|
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)
|
|
{
|
|
var bufAr = args2[0] as TArray;
|
|
|
|
|
|
|
|
if(args2.Length == 3)
|
|
{
|
|
//buffer,offset,len
|
|
var _offset = args2[2] as TNumber;
|
|
var _len = args2[1] as TNumber;
|
|
|
|
if(bufAr != null && _offset != null && _len != null)
|
|
{
|
|
int count = (int)_len.Value;
|
|
int offset = (int)_offset.Value;
|
|
int totalRead = Math.Min(bufAr.Items.Count - offset,count);
|
|
byte[] buffer = new byte[totalRead];
|
|
|
|
for(int i = 0;i<totalRead;i++)
|
|
{
|
|
var item = bufAr.Items[i+offset];
|
|
var c = item as TChar;
|
|
var n = item as TNumber;
|
|
if(c != null) buffer[i] = (byte)c.Value;
|
|
if(n != null) buffer[i] = (byte)n.Value;
|
|
|
|
}
|
|
|
|
strm.Write(buffer,0,buffer.Length);
|
|
return TObject.Number(totalRead);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var _len = args2[1] as TNumber;
|
|
|
|
if(bufAr != null && _len != null)
|
|
{
|
|
int count = (int)_len.Value;
|
|
|
|
int totalRead = Math.Min(bufAr.Items.Count,count);
|
|
byte[] buffer = new byte[totalRead];
|
|
|
|
for(int i = 0;i<totalRead;i++)
|
|
{
|
|
var item = bufAr.Items[i];
|
|
var c = item as TChar;
|
|
var n = item as TNumber;
|
|
if(c != null) buffer[i] = (byte)c.Value;
|
|
if(n != null) buffer[i] = (byte)n.Value;
|
|
|
|
}
|
|
|
|
strm.Write(buffer,0,buffer.Length);
|
|
return TObject.Number(totalRead);
|
|
}
|
|
}
|
|
|
|
}return TObject.Number(0);
|
|
});
|
|
|
|
dict["read"] = new TExternalMethod((args2)=>{
|
|
|
|
|
|
|
|
if(args2.Length >= 2)
|
|
{
|
|
var bufAr = args2[0] as TArray;
|
|
|
|
|
|
|
|
if(args2.Length == 3)
|
|
{
|
|
//buffer,offset,len
|
|
var _offset = args2[2] as TNumber;
|
|
var _len = args2[1] as TNumber;
|
|
|
|
if(bufAr != null && _offset != null && _len != null)
|
|
{
|
|
int count = (int)_len.Value;
|
|
int offset = (int)_offset.Value;
|
|
int totalRead = Math.Min(bufAr.Items.Count - offset,count);
|
|
byte[] buffer = new byte[totalRead];
|
|
totalRead=strm.Read(buffer,0,buffer.Length);
|
|
for(int i = 0;i<totalRead;i++)
|
|
{
|
|
bufAr.Items[i+offset] = TObject.Number(buffer[i]);
|
|
}
|
|
return TObject.Number(totalRead);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var _len = args2[1] as TNumber;
|
|
|
|
if(bufAr != null && _len != null)
|
|
{
|
|
int count = (int)_len.Value;
|
|
|
|
int totalRead = Math.Min(bufAr.Items.Count,count);
|
|
byte[] buffer = new byte[totalRead];
|
|
totalRead=strm.Read(buffer,0,buffer.Length);
|
|
for(int i = 0;i<totalRead;i++)
|
|
{
|
|
bufAr.Items[i] = TObject.Number(buffer[i]);
|
|
}
|
|
return TObject.Number(totalRead);
|
|
}
|
|
}
|
|
|
|
}return TObject.Number(0);
|
|
|
|
|
|
});
|
|
dict["close"] = new TExternalMethod((args2)=>{
|
|
strm.Dispose();
|
|
return TObject.Uninit;
|
|
});
|
|
dict["flush"] = new TExternalMethod((args2)=>{
|
|
strm.Flush();
|
|
return TObject.Uninit;
|
|
});
|
|
|
|
var ssl = strm as SslStream;
|
|
|
|
if(ssl != null)
|
|
{
|
|
dict["as_client"] = new TExternalMethod((args)=>{
|
|
|
|
if(args.Length >0 )
|
|
|
|
ssl.AuthenticateAsClient(args[0].ToString());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
return dict;
|
|
}
|
|
public void LoadEnvironment(RootEnvironment env)
|
|
{
|
|
TDictionary fs = TObject.Dictionary();
|
|
fs["file_exists"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
if(File.Exists(fileName)) return TObject.Number(1);
|
|
}catch(Exception ex)
|
|
{
|
|
_=ex;
|
|
|
|
}
|
|
}
|
|
}
|
|
return TObject.Number(0);
|
|
});
|
|
fs["dir_exists"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
if(Directory.Exists(fileName)) return TObject.Number(1);
|
|
}catch(Exception ex)
|
|
{
|
|
_=ex;
|
|
|
|
}
|
|
}
|
|
}
|
|
return TObject.Number(0);
|
|
});
|
|
fs["mkdir"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
if(Directory.Exists(fileName)) return TObject.Number(2);
|
|
Directory.CreateDirectory(fileName);
|
|
return TObject.Number(1);
|
|
}catch(Exception ex)
|
|
{
|
|
_=ex;
|
|
|
|
}
|
|
}
|
|
}
|
|
return TObject.Number(0);
|
|
});
|
|
fs["create"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
return CreateStream(File.Create(fileName));
|
|
}catch(Exception ex){
|
|
_=ex;
|
|
}
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
fs["openread"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
return CreateStream(File.OpenRead(fileName));
|
|
}catch(Exception ex){
|
|
Console.WriteLine(ex.Message);
|
|
_=ex;
|
|
}
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
fs["openwrite"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
return CreateStream(File.OpenWrite(fileName));
|
|
}catch(Exception ex){
|
|
_=ex;
|
|
}
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
fs["append"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
return CreateStream(File.Open(fileName,FileMode.Append));
|
|
}catch(Exception ex){
|
|
_=ex;
|
|
}
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
|
|
fs["readalltext"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
try{
|
|
if(!File.Exists(fileName)) return TObject.Null;
|
|
return TObject.String(File.ReadAllText(fileName));
|
|
}catch(Exception ex)
|
|
|
|
{
|
|
_=ex;
|
|
|
|
}
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
fs["writealltext"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length >= 2)
|
|
{
|
|
var fileName=args2[0].ToString();
|
|
var text = args2[1].ToString();
|
|
if(!string.IsNullOrWhiteSpace(fileName) && text != null)
|
|
{
|
|
try{
|
|
File.WriteAllText(fileName,text);
|
|
return TObject.Number(1);
|
|
}catch(Exception ex)
|
|
{
|
|
_=ex;
|
|
}
|
|
}
|
|
}
|
|
return TObject.Number(0);
|
|
});
|
|
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 = TObject.Dictionary();
|
|
dict["getittr"] = new TExternalMethod((args2)=>{
|
|
var enumerable=Directory.EnumerateFiles(fileName).GetEnumerator();
|
|
TDictionary dict2 = TObject.Dictionary();
|
|
|
|
dict2["movenext"] = new TExternalMethod((args3)=>{
|
|
|
|
return TObject.Boolean(enumerable.MoveNext());
|
|
});
|
|
dict2["getcurrent"] = new TExternalMethod((args3)=>{
|
|
return TObject.String(Path.GetFileName(enumerable.Current));
|
|
});
|
|
|
|
return dict2;
|
|
});
|
|
return dict;
|
|
}
|
|
}
|
|
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<TObject,string>(e=>e.ToString()).ToArray()));
|
|
}
|
|
}
|
|
return TObject.String(Path.Combine(args.Select<TObject,string>(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 = TObject.Dictionary();
|
|
dict["getittr"] = new TExternalMethod((args2)=>{
|
|
var enumerable=Directory.EnumerateDirectories(fileName).GetEnumerator();
|
|
TDictionary dict2 = TObject.Dictionary();
|
|
|
|
dict2["movenext"] = new TExternalMethod((args3)=>{
|
|
|
|
return TObject.Boolean(enumerable.MoveNext() );
|
|
});
|
|
dict2["getcurrent"] = new TExternalMethod((args3)=>{
|
|
return TObject.String(Path.GetFileName(enumerable.Current));
|
|
});
|
|
|
|
return dict2;
|
|
});
|
|
return dict;
|
|
}
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
env["fs"]=fs;
|
|
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)
|
|
{
|
|
var str = args2[0] as TString;
|
|
if(str != null)
|
|
{
|
|
Lexer lexer = new Lexer(new StringReader(str.Value));
|
|
try{
|
|
Parser _parser=new Parser(lexer.Tokens);
|
|
|
|
|
|
RootEnvironment env2 = new RootEnvironment();
|
|
TDictionary rootDict = new TRootDict(env2);
|
|
LoadEnvironment(env2);
|
|
TDictionary parseCodeVal = TObject.Dictionary();
|
|
List<TObject> _args=new List<TObject>();
|
|
parseCodeVal["root"] = rootDict;
|
|
parseCodeVal["add"] = new TExternalMethod((args4)=>{
|
|
foreach(var arg in args4)
|
|
{
|
|
_args.Add(arg);
|
|
}
|
|
});
|
|
parseCodeVal["run"] = new TExternalMethod((args4)=>{
|
|
//run()
|
|
try{
|
|
return _parser.Execute(env);
|
|
}catch(Exception ex)
|
|
{
|
|
|
|
_=ex;
|
|
return TObject.Null;
|
|
}
|
|
});
|
|
return parseCodeVal;
|
|
|
|
}catch(Exception ex)
|
|
{
|
|
_=ex;
|
|
return TObject.Null;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
return TObject.Uninit;
|
|
|
|
});
|
|
|
|
env["reflection"] = reflection;
|
|
|
|
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<JToken>(s));
|
|
});
|
|
env["json"] = json;
|
|
var con = TObject.Dictionary();
|
|
con["write"] = new TExternalMethod((args2)=>{
|
|
foreach(var arg in args2)
|
|
{
|
|
Console.Write(arg);
|
|
}
|
|
return TObject.Number(args2.Length);
|
|
});
|
|
con["writeln"] = new TExternalMethod((args2)=>{
|
|
foreach(var arg in args2)
|
|
{
|
|
Console.Write(arg);
|
|
}
|
|
Console.WriteLine();
|
|
return TObject.Number(args2.Length);
|
|
});
|
|
|
|
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 TObject.Array(count);
|
|
});
|
|
instance["dict"] = new TExternalMethod((args2)=>{
|
|
return TObject.Dictionary();
|
|
});
|
|
instance["mutex"] = new TExternalMethod((args2)=>{
|
|
TDictionary dictionary=TObject.Dictionary();
|
|
Mutex mtx = new Mutex();
|
|
dictionary["lock"]=new TExternalMethod((args3)=>{
|
|
mtx.WaitOne();
|
|
return TObject.Uninit;
|
|
});
|
|
dictionary["unlock"] = new TExternalMethod((args3)=>{
|
|
mtx.ReleaseMutex();
|
|
return TObject.Uninit;
|
|
});
|
|
return dictionary;
|
|
});
|
|
instance["thread"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 0)
|
|
{
|
|
var callable = args2[0] as ICallable;
|
|
|
|
if(callable !=null){
|
|
Thread thread=new Thread(()=>{
|
|
|
|
callable.Call();
|
|
});
|
|
thread.Start();
|
|
}
|
|
|
|
}
|
|
return TObject.Uninit;
|
|
});
|
|
env["create"] =instance;
|
|
env["console"]=con;
|
|
env["int"] = new TExternalMethod((args2)=>{
|
|
|
|
if(args2.Length == 1)
|
|
{
|
|
var arg = args2[0];
|
|
var sArg = arg as TString;
|
|
var dArg = arg as TNumber;
|
|
if(sArg != null)
|
|
{
|
|
long val;
|
|
if(long.TryParse(sArg.Value,out val))
|
|
{
|
|
return TObject.Number(val);
|
|
}
|
|
}
|
|
if(dArg != null)
|
|
{
|
|
return TObject.Number(Math.Round(dArg.Value));
|
|
}
|
|
|
|
}
|
|
return TObject.Null;
|
|
});
|
|
TDictionary net = TObject.Dictionary();
|
|
net["tcpclient"] = new TExternalMethod((args2)=>{
|
|
if(args2.Length > 1)
|
|
{
|
|
var ipOrFQDN = args2[0] as TString;
|
|
var port = args2[1] as TNumber;
|
|
if(ipOrFQDN!= null && port != null)
|
|
{
|
|
var c = new TcpClient(ipOrFQDN.Value,(int)port.Value);
|
|
|
|
return CreateStream(c.GetStream());
|
|
}
|
|
}
|
|
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;
|
|
});
|
|
}
|
|
|
|
|
|
}
|
|
}
|