namespace tlang { internal class Parser { public Parser(List tokens) { int i=0; Node = ParseExpression(tokens,ref i,true); } public Node Node {get;set;} public TObject Execute(IScopeEnvironment env,params TObject[] args) { 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(tokens[i].Text == "{" || isFirst) { if(!isFirst) i++; ScopeNode scopeNode = new ScopeNode(){First=isFirst}; while(i tokens,ref int i) { Node myExpression = ParseSum(tokens,ref i); while(i tokens,ref int i) { Node myExpression = ParseFactor(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.IsChar) { return new ConstNode(new TChar(token.Text.SingleOrDefault())); } long val; if(long.TryParse(token.Text,out val)) { if(i args = new List(); i++; while(i args = new List(); //function call baby while(i(); //function call baby while(i(); //function call baby while(i tokens,ref int i) { Node myExpression = ParseValue(tokens,ref i); while(i{ 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 new TNumber(strm.Position); }); dict["getlength"] = new TExternalMethod((args2)=>{ return new TNumber(strm.Length); }); dict["getcount"] = new TExternalMethod((args2)=>{ return new TNumber(strm.Length); }); dict["canread"] = new TExternalMethod((args2)=>{ return new TNumber(strm.CanRead ? 1 : 0); }); dict["canwrite"] = new TExternalMethod((args2)=>{ return new TNumber(strm.CanWrite ? 1 : 0); }); dict["canseek"] = new TExternalMethod((args2)=>{ return new TNumber(strm.CanSeek ? 1 : 0); }); 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[1] as TNumber; var _len = args2[2] 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{ if(args2.Length >= 2) { var bufAr = args2[0] as TArray; if(args2.Length == 3) { //buffer,offset,len var _offset = args2[1] as TNumber; var _len = args2[2] 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{ strm.Dispose(); return TObject.Uninit; }); dict["flush"] = new TExternalMethod((args2)=>{ strm.Flush(); return TObject.Uninit; }); return dict; } public void LoadEnvironment(RootEnvironment env) { TDictionary fs = new TDictionary(); 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 new TNumber(1); }catch(Exception ex) { _=ex; } } } return new TNumber(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 new TNumber(1); }catch(Exception ex) { _=ex; } } } return new TNumber(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 new TNumber(2); Directory.CreateDirectory(fileName); return new TNumber(1); }catch(Exception ex) { _=ex; } } } return new TNumber(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){ _=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 new TString(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 new TNumber(1); }catch(Exception ex) { _=ex; } } } return new TNumber(0); }); fs["home"] = new TString(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 enumerable=Directory.EnumerateFiles(fileName).GetEnumerator(); TDictionary dict2 = new TDictionary(); dict2["movenext"] = new TExternalMethod((args3)=>{ return new TNumber(enumerable.MoveNext() ? 1 : 0); }); dict2["getCurrent"] = new TExternalMethod((args3)=>{ return new TString(enumerable.Current); }); return dict2; }); return dict; } } return TObject.Null; }); fs["enumerate_dirs"] = new TExternalMethod((args)=>{ if(args.Length > 0) { var fileName=args[0].ToString(); if(!string.IsNullOrWhiteSpace(fileName) && Directory.Exists(fileName)) { var dict = new TDictionary(); dict["getIttr"] = new TExternalMethod((args2)=>{ var enumerable=Directory.EnumerateDirectories(fileName).GetEnumerator(); TDictionary dict2 = new TDictionary(); dict2["movenext"] = new TExternalMethod((args3)=>{ return new TNumber(enumerable.MoveNext() ? 1 : 0); }); dict2["getCurrent"] = new TExternalMethod((args3)=>{ return new TString(enumerable.Current); }); return dict2; }); return dict; } } return TObject.Null; }); env["fs"]=fs; TDictionary reflection = new TDictionary(); 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 = new TDictionary(); var argsArray= new TArray(); parseCodeVal["root"] = rootDict; parseCodeVal["args"] = argsArray; parseCodeVal["run"] = new TExternalMethod((args4)=>{ //run() try{ return _parser.Execute(env2,argsArray.Items.ToArray()); }catch(Exception ex) { _=ex; return TObject.Null; } }); return parseCodeVal; }catch(Exception ex) { _=ex; return TObject.Null; } } } return TObject.Uninit; }); env["reflection"] = reflection; var con = new TDictionary(); con["write"] = new TExternalMethod((args2)=>{ foreach(var arg in args2) { Console.Write(arg); } return new TNumber(args2.Length); }); con["writeln"] = new TExternalMethod((args2)=>{ foreach(var arg in args2) { Console.Write(arg); } Console.WriteLine(); return new TNumber(args2.Length); }); var instance = new TDictionary(); instance["array"] = new TExternalMethod((args2)=>{ return new TArray(); }); instance["dict"] = new TExternalMethod((args2)=>{ return new TDictionary(); }); 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 new TNumber(val); } } if(dArg != null) { return new TNumber(Math.Round(dArg.Value)); } } return TObject.Null; }); } } }