diff --git a/Program.cs b/Program.cs deleted file mode 100644 index b8ac8f4..0000000 --- a/Program.cs +++ /dev/null @@ -1,128 +0,0 @@ -namespace tlang; -class Program -{ - static int Main(string[] args) - { - - //Lexer lexer = new Lexer("testString.tlang"); - Parser parser = new Parser(); - //parser.Add(lexer.Tokens); - int r=0; - RootEnvironment env=new RootEnvironment(); - parser.LoadEnvironment(env); - env["array"] = new TExternalMethod((args2)=>{ - return new TArray(); - }); - env["dict"] = new TExternalMethod((args2)=>{ - return new TDictionary(); - }); - env["print"] = new TExternalMethod((args2)=>{ - foreach(var arg in args2) - { - Console.Write(arg); - } - return new TNumber(args2.Length); - }); - env["println"] = new TExternalMethod((args2)=>{ - foreach(var arg in args2) - { - Console.Write(arg); - } - Console.WriteLine(); - return new TNumber(args2.Length); - }); - env["int"] = new TExternalMethod((args2)=>{ - - 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; - }); - - env["filecreate"]=new TExternalMethod((args2)=>{ - - if(args2.Length == 1) - { - var fileName = args2[0] as TString; - if(fileName != null) - { - return new TInternalObject(File.Create(fileName.Value)); - } - } - return new TNull(); - }); - env["streamwritestr"]=new TExternalMethod((args2)=>{ - if(args2.Length == 2) - { - var internalObj = args2[0] as TInternalObject; - if(internalObj != null) - { - var strm = internalObj.Object as Stream; - if(strm != null) - { - var str = args2[1] as TString; - if(str != null) - { - var bytes=System.Text.Encoding.UTF8.GetBytes(str.Value); - strm.Write(bytes,0,bytes.Length); - } - } - } - } - return TObject.Null; - }); - env["streamclose"]=new TExternalMethod((args2)=>{ - if(args2.Length == 1) - { - var internalObj = args2[0] as TInternalObject; - if(internalObj != null) - { - var strm = internalObj.Object as Stream; - if(strm != null) - { - strm.Dispose(); - } - } - } - return TObject.Null; - }); - - Lexer lexer =new Lexer(new StreamReader("file.tlang")); - var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env) as TNumber; - var main = env["main"] as ICallable; - - if(main != null) - { - List args2=new List(); - foreach(var argument in args) - { - args2.Add(new TString(argument)); - } - res=main.Call(args2.ToArray()) as TNumber; - } - - if(res != null) - { - return (int)res.Value; - } - - return 0; - - } -} diff --git a/file.tlang b/file.tlang deleted file mode 100644 index 10a4d6a..0000000 --- a/file.tlang +++ /dev/null @@ -1,8 +0,0 @@ -each(dir : fs.enumerate_dirs(fs.home)) -{ - println(dir); -} -each(file : fs.enumerate_files(fs.home)) -{ - println(file); -} \ No newline at end of file diff --git a/tlang/Program.cs b/tlang/Program.cs new file mode 100644 index 0000000..d38f663 --- /dev/null +++ b/tlang/Program.cs @@ -0,0 +1,9 @@ +using tlang; + +List tokens; +using(var sr = new StreamReader(ApplicationRunner.GetLauncherScript())) +{ + var lexer=new Lexer(sr); + tokens=lexer.Tokens; +} +Environment.Exit(ApplicationRunner.Run(tokens,args)); \ No newline at end of file diff --git a/tlang/code.tlang b/tlang/code.tlang new file mode 100644 index 0000000..6c663ec --- /dev/null +++ b/tlang/code.tlang @@ -0,0 +1 @@ +console.writeln(42); diff --git a/tlang.csproj b/tlang/tlang.csproj similarity index 68% rename from tlang.csproj rename to tlang/tlang.csproj index d439800..7144fcf 100644 --- a/tlang.csproj +++ b/tlang/tlang.csproj @@ -1,5 +1,10 @@ + + + + + Exe net7.0 diff --git a/AddNode.cs b/tlanglib/AddNode.cs similarity index 100% rename from AddNode.cs rename to tlanglib/AddNode.cs diff --git a/ArraySubscriptNode.cs b/tlanglib/ArraySubscriptNode.cs similarity index 100% rename from ArraySubscriptNode.cs rename to tlanglib/ArraySubscriptNode.cs diff --git a/ClosureNode.cs b/tlanglib/ClosureNode.cs similarity index 100% rename from ClosureNode.cs rename to tlanglib/ClosureNode.cs diff --git a/ConstNode.cs b/tlanglib/ConstNode.cs similarity index 100% rename from ConstNode.cs rename to tlanglib/ConstNode.cs diff --git a/DivideNode.cs b/tlanglib/DivideNode.cs similarity index 100% rename from DivideNode.cs rename to tlanglib/DivideNode.cs diff --git a/EachLoop.cs b/tlanglib/EachLoop.cs similarity index 100% rename from EachLoop.cs rename to tlanglib/EachLoop.cs diff --git a/EnvironmentNode.cs b/tlanglib/EnvironmentNode.cs similarity index 100% rename from EnvironmentNode.cs rename to tlanglib/EnvironmentNode.cs diff --git a/ForLoop.cs b/tlanglib/ForLoop.cs similarity index 100% rename from ForLoop.cs rename to tlanglib/ForLoop.cs diff --git a/FunctionCallNode.cs b/tlanglib/FunctionCallNode.cs similarity index 100% rename from FunctionCallNode.cs rename to tlanglib/FunctionCallNode.cs diff --git a/GetVariableValue.cs b/tlanglib/GetVariableValue.cs similarity index 100% rename from GetVariableValue.cs rename to tlanglib/GetVariableValue.cs diff --git a/IfNode.cs b/tlanglib/IfNode.cs similarity index 100% rename from IfNode.cs rename to tlanglib/IfNode.cs diff --git a/LexToken.cs b/tlanglib/LexToken.cs similarity index 96% rename from LexToken.cs rename to tlanglib/LexToken.cs index 4802d82..50ee174 100644 --- a/LexToken.cs +++ b/tlanglib/LexToken.cs @@ -1,6 +1,6 @@ namespace tlang { - internal class LexToken + public class LexToken { private LexToken(string text) { diff --git a/Lexer.cs b/tlanglib/Lexer.cs similarity index 90% rename from Lexer.cs rename to tlanglib/Lexer.cs index 52421d9..703b368 100644 --- a/Lexer.cs +++ b/tlanglib/Lexer.cs @@ -2,7 +2,7 @@ using System.Text; namespace tlang { - internal class Lexer + public class Lexer { TextReader reader; public Lexer(string fName) : this(new StreamReader(fName)) @@ -13,17 +13,19 @@ namespace tlang { this.reader = reader; } - List? tokens=null; + List tokens=new List(); public List Tokens { get{ - if(tokens == null) + if(!set) { + set=true; tokens = _getTokens(); } return tokens; } } + bool set=false; List _tokens = new List(); StringBuilder b = new StringBuilder(); private void FlushBuilder() @@ -44,7 +46,8 @@ namespace tlang read = reader.Read(); if(read == 'x') { - return (char)Convert.FromHexString($"{(char)reader.Read()}{(char)reader.Read()}")[0]; + + return (char)short.Parse($"0x{(char)reader.Read()}{(char)reader.Read()}",System.Globalization.NumberStyles.AllowHexSpecifier); } else if(read == 'n') { @@ -89,7 +92,7 @@ namespace tlang break; case '\'': FlushBuilder(); - LexToken.FromChar(getChar().ToString()); + _tokens.Add(LexToken.FromChar(getChar().ToString())); reader.Read(); break; case '#': @@ -200,23 +203,10 @@ namespace tlang case ':': case ',': case ';': + case '=': FlushBuilder(); _tokens.Add(LexToken.FromGeneralToken(read)); break; - case '=': - FlushBuilder(); - if(next == read || next == '>') - { - reader.Read(); - _tokens.Add(LexToken.FromGeneralToken($"{(char)read}{(char)next}")); - } - else - { - _tokens.Add(LexToken.FromGeneralToken(read)); - } - break; - - case ' ': case '\n': case '\t': diff --git a/MemberFunctionCallNode.cs b/tlanglib/MemberFunctionCallNode.cs similarity index 99% rename from MemberFunctionCallNode.cs rename to tlanglib/MemberFunctionCallNode.cs index 4bd2201..e24aafe 100644 --- a/MemberFunctionCallNode.cs +++ b/tlanglib/MemberFunctionCallNode.cs @@ -13,6 +13,7 @@ namespace tlang } public override TObject Execute(IScopeEnvironment nodeEnv) { + var res=Parent.Execute(nodeEnv); var dict = res as TDictionary; @@ -48,6 +49,7 @@ namespace tlang } else if(array != null) { + if(Text == "add") { if(Args.Count == 1) diff --git a/MemberGetValueNode.cs b/tlanglib/MemberGetValueNode.cs similarity index 100% rename from MemberGetValueNode.cs rename to tlanglib/MemberGetValueNode.cs diff --git a/ModuloNode.cs b/tlanglib/ModuloNode.cs similarity index 100% rename from ModuloNode.cs rename to tlanglib/ModuloNode.cs diff --git a/MultiplyNode.cs b/tlanglib/MultiplyNode.cs similarity index 100% rename from MultiplyNode.cs rename to tlanglib/MultiplyNode.cs diff --git a/Node.cs b/tlanglib/Node.cs similarity index 100% rename from Node.cs rename to tlanglib/Node.cs diff --git a/Parser.cs b/tlanglib/Parser.cs similarity index 54% rename from Parser.cs rename to tlanglib/Parser.cs index c7d7990..61d7e7d 100644 --- a/Parser.cs +++ b/tlanglib/Parser.cs @@ -3,12 +3,24 @@ namespace tlang internal class Parser { - public Parser() + public Parser(List tokens) { - + int i=0; + Node = ParseExpression(tokens,ref i,true); } + public Node Node {get;set;} - public Node ParseExpression(List tokens,ref int i,bool isFirst=false) + 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) @@ -39,7 +51,7 @@ namespace tlang if(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) @@ -477,6 +795,105 @@ namespace tlang 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; + }); } diff --git a/PostfixDecrementVariableNode.cs b/tlanglib/PostfixDecrementVariableNode.cs similarity index 100% rename from PostfixDecrementVariableNode.cs rename to tlanglib/PostfixDecrementVariableNode.cs diff --git a/PostfixIncrementVariableNode.cs b/tlanglib/PostfixIncrementVariableNode.cs similarity index 100% rename from PostfixIncrementVariableNode.cs rename to tlanglib/PostfixIncrementVariableNode.cs diff --git a/tlanglib/Program.cs b/tlanglib/Program.cs new file mode 100644 index 0000000..869438b --- /dev/null +++ b/tlanglib/Program.cs @@ -0,0 +1,48 @@ +namespace tlang +{ +public class ApplicationRunner +{ + public static Stream GetLauncherScript() + { + var fileName = System.Environment.GetEnvironmentVariable("TLANG_LAUNCHER_SCRIPT"); + if(!string.IsNullOrWhiteSpace(fileName)) + { + return File.OpenRead(fileName); + } + return typeof(ApplicationRunner).Assembly.GetManifestResourceStream("tlanglib.launcher.launcher.tlang"); + + } + public static int Run(List code,string[] args) + { + + + + RootEnvironment env=new RootEnvironment(); + + + + Parser parser=new Parser(code); + parser.LoadEnvironment(env); + List args2=new List(); + foreach(var argument in args) + { + args2.Add(new TString(argument)); + } + + var res= parser.Execute(env,args2.ToArray()) as TNumber; + + + + + + + if(res != null) + { + return (int)res.Value; + } + + return 0; + + } +} +} \ No newline at end of file diff --git a/ScopeEnvironment.cs b/tlanglib/ScopeEnvironment.cs similarity index 100% rename from ScopeEnvironment.cs rename to tlanglib/ScopeEnvironment.cs diff --git a/ScopeNode.cs b/tlanglib/ScopeNode.cs similarity index 100% rename from ScopeNode.cs rename to tlanglib/ScopeNode.cs diff --git a/SubtractNode.cs b/tlanglib/SubtractNode.cs similarity index 100% rename from SubtractNode.cs rename to tlanglib/SubtractNode.cs diff --git a/TArray.cs b/tlanglib/TArray.cs similarity index 100% rename from TArray.cs rename to tlanglib/TArray.cs diff --git a/TChar.cs b/tlanglib/TChar.cs similarity index 100% rename from TChar.cs rename to tlanglib/TChar.cs diff --git a/TDictionary.cs b/tlanglib/TDictionary.cs similarity index 53% rename from TDictionary.cs rename to tlanglib/TDictionary.cs index 6804d17..fbb1449 100644 --- a/TDictionary.cs +++ b/tlanglib/TDictionary.cs @@ -1,5 +1,25 @@ namespace tlang { + public class TRootDict : TDictionary + { + IScopeEnvironment env; + public TRootDict(IScopeEnvironment env) + { + this.env=env; + } + public override TObject GetMember(string name) + { + return env.GetVariable(name); + } + public override void SetMember(string name, TObject obj) + { + env.SetVariable(name,obj); + } + public override bool MemberExists(string name) + { + return env.VariableExists(name); + } + } public class TDictionary : TObject { public override bool AsBoolean {get =>true;} @@ -10,7 +30,7 @@ namespace tlang Dictionary items {get;set;}=new Dictionary(); - public TObject GetMember(string name) + public virtual TObject GetMember(string name) { if(items.ContainsKey(name)) { @@ -20,7 +40,7 @@ namespace tlang } } - public void SetMember(string name, TObject obj) + public virtual void SetMember(string name, TObject obj) { if(items.ContainsKey(name)) { @@ -32,7 +52,7 @@ namespace tlang } } - public bool MemberExists(string name) + public virtual bool MemberExists(string name) { return items.ContainsKey(name); } diff --git a/TInternalObject.cs b/tlanglib/TInternalObject.cs similarity index 100% rename from TInternalObject.cs rename to tlanglib/TInternalObject.cs diff --git a/TMethod.cs b/tlanglib/TMethod.cs similarity index 97% rename from TMethod.cs rename to tlanglib/TMethod.cs index 80a4bd0..0cdc251 100644 --- a/TMethod.cs +++ b/tlanglib/TMethod.cs @@ -53,7 +53,7 @@ namespace tlang { for(int i =0;i + + + + netstandard2.0 + enable + + 10.0 + + + + + + +