commit b74fd1d08354fa92a2cb0eea6ed272beabd19400 Author: Mike Nolan Date: Thu Mar 9 13:40:14 2023 -0600 Working on MemberGetVariableValue diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b956f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,133 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.svclog +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml +*.azurePubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +packages/ +## TODO: If the tool you use requires repositories.config, also uncomment the next line +!packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +![Ss]tyle[Cc]op.targets +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml + +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store + +_NCrunch* \ No newline at end of file diff --git a/AddNode.cs b/AddNode.cs new file mode 100644 index 0000000..18c949a --- /dev/null +++ b/AddNode.cs @@ -0,0 +1,37 @@ +namespace tlang +{ + internal class AddNode : Node + { + public Node Left {get;set;} + public Node Right {get;set;} + + public AddNode(Node left, Node right) + { + this.Left = left; + this.Right = right; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l=Left.Execute(nodeEnv); + 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; + + + if(lNum != null && rNum != null) + return new TNumber(lNum.Value + rNum.Value); + + if(lStr != null && rStr != null) + return new TString(lStr.Value + rStr.Value); + if(lStr != null && rNum != null) + return new TString(lStr.Value + rNum.Value.ToString()); + if(lNum != null && rStr != null) + return new TString(lNum.Value.ToString() + rStr.Value); + + return new TNull(); + } + } +} \ No newline at end of file diff --git a/ClosureNode.cs b/ClosureNode.cs new file mode 100644 index 0000000..2736870 --- /dev/null +++ b/ClosureNode.cs @@ -0,0 +1,20 @@ +namespace tlang +{ + public class ClosureNode : Node + { + //j=func(a,b,c,d) 4 + public ClosureNode(List args,Node node) + { + Arguments = args; + Node=node; + } + public Node Node {get;set;} + public List Arguments {get;set;} + + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + return new TInternalMethod(this,nodeEnv); + } + } +} \ No newline at end of file diff --git a/ConstNode.cs b/ConstNode.cs new file mode 100644 index 0000000..fe62d9a --- /dev/null +++ b/ConstNode.cs @@ -0,0 +1,17 @@ +namespace tlang +{ + internal class ConstNode : Node + { + public TObject Value {get;set;} + + public ConstNode(TObject value) + { + this.Value= value; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + return Value; + } + } +} \ No newline at end of file diff --git a/DivideNode.cs b/DivideNode.cs new file mode 100644 index 0000000..94728b2 --- /dev/null +++ b/DivideNode.cs @@ -0,0 +1,25 @@ +namespace tlang +{ + internal class DivideNode : Node + { + public Node Left {get;set;} + public Node Right {get;set;} + + public DivideNode(Node left, Node right) + { + this.Left = left; + this.Right = right; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Left.Execute(nodeEnv) as TNumber; + var r = Right.Execute(nodeEnv) as TNumber; + + if(l != null && r != null) + return new TNumber(l.Value / r.Value); + + return new TNull(); + } + } +} \ No newline at end of file diff --git a/EnvironmentNode.cs b/EnvironmentNode.cs new file mode 100644 index 0000000..3188325 --- /dev/null +++ b/EnvironmentNode.cs @@ -0,0 +1,23 @@ +namespace tlang +{ + internal class EnvironmentNode : Node + { + public List Nodes {get;set;}=new List(); + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + + TObject returnType = TObject.Null; + foreach(var node in Nodes) + { + if(node is EnvironmentNode) + { + returnType =node.Execute(nodeEnv.SubEnv); + }else{ + returnType = node.Execute(nodeEnv); + } + } + return returnType; + } + } +} \ No newline at end of file diff --git a/FunctionCallNode.cs b/FunctionCallNode.cs new file mode 100644 index 0000000..10038ea --- /dev/null +++ b/FunctionCallNode.cs @@ -0,0 +1,25 @@ +namespace tlang +{ + internal class FunctionCallNode : Node + { + public string Text {get;set;} + public List Args {get;set;} + + public FunctionCallNode(string text, List args) + { + this.Text = text; + this.Args = args; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var n = nodeEnv[Text] as ICallable; + if(n != null) + { + + return n.Call(Args.Select(e=>e.Execute(nodeEnv)).ToArray()); + } + return new TUninit(); + } + } +} \ No newline at end of file diff --git a/GetVariableValue.cs b/GetVariableValue.cs new file mode 100644 index 0000000..e0b6356 --- /dev/null +++ b/GetVariableValue.cs @@ -0,0 +1,34 @@ +namespace tlang +{ + internal class SetVariableNode : Node + { + public Node Value {get;set;} + public string Name {get;set;} + public SetVariableNode(string text,Node v) + { + Name=text; + Value=v; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var res=Value.Execute(nodeEnv); + nodeEnv[Name]=res; + return res; + } + } + public class GetVariableValue : Node + { + public string Name {get;set;} + + public GetVariableValue(string text) + { + this.Name = text; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + return nodeEnv[Name]; + } + } +} \ No newline at end of file diff --git a/IfNode.cs b/IfNode.cs new file mode 100644 index 0000000..0c4ff79 --- /dev/null +++ b/IfNode.cs @@ -0,0 +1,34 @@ +namespace tlang +{ + internal class IfNode : Node + { + public Node Condition {get;set;} + public Node Yes {get;set;} + public Node No {get;set;} + + public IfNode(Node condition, Node yes, Node no) + { + this.Condition = condition; + this.Yes = yes; + this.No = no; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var condition = Condition.Execute(nodeEnv); + var cInt = condition as TNumber; + + + bool condition_bool=false; + + if(cInt != null) + { + condition_bool=cInt.Value != 0; + } + + + + return condition_bool ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv); + } + } +} \ No newline at end of file diff --git a/LexToken.cs b/LexToken.cs new file mode 100644 index 0000000..4802d82 --- /dev/null +++ b/LexToken.cs @@ -0,0 +1,31 @@ +namespace tlang +{ + internal class LexToken + { + private LexToken(string text) + { + Text = text; + } + + public static LexToken FromGeneralToken(int c) + { + return new LexToken(((char)c).ToString()); + } + public static LexToken FromGeneralToken(string text) + { + return new LexToken(text); + } + public static LexToken FromString(string text) + { + return new LexToken(text){IsString = true}; + } + public static LexToken FromChar(string text) + { + return new LexToken(text){IsChar = true}; + } + public bool IsString {get;private set;}=false; + + public bool IsChar {get;private set;}=false; + public string Text {get;private set;} + } +} \ No newline at end of file diff --git a/Lexer.cs b/Lexer.cs new file mode 100644 index 0000000..52421d9 --- /dev/null +++ b/Lexer.cs @@ -0,0 +1,237 @@ +using System.Text; + +namespace tlang +{ + internal class Lexer + { + TextReader reader; + public Lexer(string fName) : this(new StreamReader(fName)) + { + + } + public Lexer(TextReader reader) + { + this.reader = reader; + } + List? tokens=null; + public List Tokens + { + get{ + if(tokens == null) + { + tokens = _getTokens(); + } + return tokens; + } + } + List _tokens = new List(); + StringBuilder b = new StringBuilder(); + private void FlushBuilder() + { + if(b.Length > 0) + { + _tokens.Add(LexToken.FromGeneralToken(b.ToString())); + b.Clear(); + } + } + bool escaped=false; + private char getChar() + { + int read = reader.Read(); + if(read == '\\') + { + escaped = true; + read = reader.Read(); + if(read == 'x') + { + return (char)Convert.FromHexString($"{(char)reader.Read()}{(char)reader.Read()}")[0]; + } + else if(read == 'n') + { + return '\n'; + } + else if(read == 't') + { + return '\t'; + } + else if(read == 'r') + { + return '\r'; + } + return (char)read; + } + escaped=false; + return (char)read; + } + private List _getTokens() + { + + int read; + while((read = reader.Read()) != -1) + { + int next=reader.Peek(); + switch(read) + { + case '\"': + FlushBuilder(); + //"Some \"Some String\" Is OK" + while(true) + { + char r = getChar(); + if(r == -1 || (!escaped && r == '\"')) + { + break; + } + b.Append(r); + } + _tokens.Add(LexToken.FromString(b.ToString())); + b.Clear(); + break; + case '\'': + FlushBuilder(); + LexToken.FromChar(getChar().ToString()); + reader.Read(); + break; + case '#': + while(true) + { + read = reader.Read(); + if(read == -1) return _tokens; + + if(read == '\n') + { + break; + } + + } + break; + case '/': + FlushBuilder(); + if(next == '=') + { + reader.Read(); + _tokens.Add(LexToken.FromGeneralToken($"{(char)read}{(char)next}")); + } + else if(next == '/') + { + reader.Read(); + + while(true) + { + read = reader.Read(); + if(read == -1) return _tokens; + + if(read == '\n') + { + break; + } + + } + } + else if(next == '*') + { + reader.Read(); + bool lastIsAstrick=false; + while(true) + { + read = reader.Read(); + if(read == -1) return _tokens; + if(read == '*') + { + lastIsAstrick=true; + continue; + } + else if(read == '/') + { + if(lastIsAstrick) + { + break; + } + } + lastIsAstrick=false; + } + } + else + { + _tokens.Add(LexToken.FromGeneralToken(read)); + } + + break; + case '^': + case '*': + case '%': + FlushBuilder(); + if(next == '=') + { + reader.Read(); + _tokens.Add(LexToken.FromGeneralToken($"{(char)read}{(char)next}")); + } + else + { + _tokens.Add(LexToken.FromGeneralToken(read)); + } + break; + case '|': + case '&': + case '<': + case '>': + case '+': + case '-': + 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 '}': + case '[': + case ']': + case '(': + case ')': + case '.': + 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': + case '\r': + FlushBuilder(); + break; + default: + b.Append((char)read); + break; + + } + + } + FlushBuilder(); + return _tokens; + } + } +} \ No newline at end of file diff --git a/MemberFunctionCallNode.cs b/MemberFunctionCallNode.cs new file mode 100644 index 0000000..182d980 --- /dev/null +++ b/MemberFunctionCallNode.cs @@ -0,0 +1,47 @@ +namespace tlang +{ + internal class MemberFunctionCallNode : FunctionCallNode + { + public Node Parent {get;set;} + + + + public MemberFunctionCallNode(Node parent, string name, List args) : base(name,args) + { + Parent = parent; + + } + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var res=Parent.Execute(nodeEnv); + + var dict = res as TDictionary; + var integer = res as TNumber; + + if(dict != null) + { + var n = dict[Text] as ICallable; + if(n != null) + { + return n.Call(Args.Select(e=>e.Execute(nodeEnv)).ToArray()); + } + } + else if(integer != null) + { + if(Text == "toString") + { + return new TString(integer.Value.ToString()); + } + if(Text == "abs") + { + return new TNumber(Math.Abs(integer.Value)); + } + } + + + if(Text == "toString") return new TString(""); + + return new TUninit(); + } + } +} \ No newline at end of file diff --git a/MemberGetValueNode.cs b/MemberGetValueNode.cs new file mode 100644 index 0000000..2c1fc35 --- /dev/null +++ b/MemberGetValueNode.cs @@ -0,0 +1,50 @@ +namespace tlang +{ + public class MemberGetVariableValue : GetVariableValue + { + public Node Parent {get;set;} + public MemberGetVariableValue(Node parent,string text) : base(text) + { + Parent = parent; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var res=Parent.Execute(nodeEnv); + + var dict = res as TDictionary; + var integer = res as TNumber; + var array = res as TArray; + if(array != null) + { + if(Name == "length" || Name == "count") + { + return new TNumber(array.Items.Count); + } + + } + if(dict != null) + { + if(dict.MemberExists($"get{Name}")) + { + var mbm= dict[$"get{Name}"] as ICallable; + if(mbm != null) + return mbm.Call(); + } + + if(dict.MemberExists(Name)) + { + return dict[Name]; + } + + } + + if(integer != null) + { + + } + + return new TUninit(); + } + } +} \ No newline at end of file diff --git a/ModuloNode.cs b/ModuloNode.cs new file mode 100644 index 0000000..76c8d4f --- /dev/null +++ b/ModuloNode.cs @@ -0,0 +1,25 @@ +namespace tlang +{ + internal class ModuloNode : Node + { + public Node Left {get;set;} + public Node Right {get;set;} + + public ModuloNode(Node left, Node right) + { + this.Left = left; + this.Right = right; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Left.Execute(nodeEnv) as TNumber; + var r = Right.Execute(nodeEnv) as TNumber; + + if(l != null && r != null) + return new TNumber(l.Value % r.Value); + + return new TNull(); + } + } +} \ No newline at end of file diff --git a/MultiplyNode.cs b/MultiplyNode.cs new file mode 100644 index 0000000..6c588fc --- /dev/null +++ b/MultiplyNode.cs @@ -0,0 +1,25 @@ +namespace tlang +{ + internal class MultiplyNode : Node + { + public Node Left {get;set;} + public Node Right {get;set;} + + public MultiplyNode(Node left, Node right) + { + this.Left = left; + this.Right = right; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Left.Execute(nodeEnv) as TNumber; + var r = Right.Execute(nodeEnv) as TNumber; + + if(l != null && r != null) + return new TNumber(l.Value * r.Value); + + return new TNull(); + } + } +} \ No newline at end of file diff --git a/Node.cs b/Node.cs new file mode 100644 index 0000000..d073cd1 --- /dev/null +++ b/Node.cs @@ -0,0 +1,7 @@ +namespace tlang +{ + public abstract class Node + { + public abstract TObject Execute(IScopeEnvironment nodeEnv); + } +} \ No newline at end of file diff --git a/Parser.cs b/Parser.cs new file mode 100644 index 0000000..1eedfda --- /dev/null +++ b/Parser.cs @@ -0,0 +1,247 @@ +namespace tlang +{ + internal class Parser + { + + public Parser() + { + + } + + public Node ParseExpression(List tokens,ref int i,bool isFirst=false) + { + if(tokens[i].Text == "{" || isFirst) + { + if(!isFirst) + i++; + ScopeNode scopeNode = new ScopeNode(); + 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 TNumber(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 tokens,ref int i) + { + Node myExpression = ParseValue(tokens,ref i); + while(i{ + foreach(var arg in args2) + { + Console.WriteLine(arg); + } + 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); + r=0; + Console.WriteLine(res); + + } +} diff --git a/ScopeEnvironment.cs b/ScopeEnvironment.cs new file mode 100644 index 0000000..f2bf78c --- /dev/null +++ b/ScopeEnvironment.cs @@ -0,0 +1,139 @@ +using System.Collections; +using System.Diagnostics.CodeAnalysis; + +namespace tlang +{ + public interface IScopeEnvironment : IEnumerable> + { + bool VariableExists(string name); + void SetVariable(string name,TObject obj); + TObject GetVariable(string names); + + IScopeEnvironment SubEnv {get;} + + IScopeEnvironment RootEnv {get;} + + TObject this[string variable] {get;set;} + } + public class SubEnvironment : IScopeEnvironment + { + Dictionary items = new Dictionary(); + + IScopeEnvironment root; + IScopeEnvironment parent; + + public SubEnvironment(IScopeEnvironment root,IScopeEnvironment parent) + { + this.root=root; + this.parent = parent; + } + + public TObject this[string variable] { get => GetVariable(variable); set => SetVariable(variable,value); } + + public IScopeEnvironment SubEnv => new SubEnvironment(root,this); + + public IScopeEnvironment RootEnv => root; + + public IEnumerator> GetEnumerator() + { + return getVars().GetEnumerator(); + } + + private IEnumerable> getVars() + { + foreach(var v in parent) + { + yield return v; + } + foreach(var item in items) + { + yield return item; + } + } + + public TObject GetVariable(string name) + { + if(parent.VariableExists(name)) + { + return parent[name]; + } + if(items.ContainsKey(name)) + { + return items[name]; + } + return TObject.Uninit; + } + + public void SetVariable(string name, TObject obj) + { + if(parent.VariableExists(name)) + { + parent.SetVariable(name,obj); + }else if(items.ContainsKey(name)) + { + items[name] = obj; + }else{ + items.Add(name,obj); + } + } + + public bool VariableExists(string name) + { + if(parent.VariableExists(name)) return true; + return items.ContainsKey(name); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return getVars().GetEnumerator(); + } + } + public class RootEnvironment : IScopeEnvironment + { + Dictionary items = new Dictionary(); + + public IScopeEnvironment SubEnv => new SubEnvironment(this,this); + + public IScopeEnvironment RootEnv => this; + + public IEnumerator> GetEnumerator() + { + return items.GetEnumerator(); + } + + public TObject GetVariable(string name) + { + if(items.ContainsKey(name)) + { + return items[name]; + }else{ + return TObject.Uninit; + } + } + + public void SetVariable(string name, TObject obj) + { + if(items.ContainsKey(name)) + { + items[name] = obj; + } + else + { + items.Add(name,obj); + } + } + + public bool VariableExists(string name) + { + return items.ContainsKey(name); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return items.GetEnumerator(); + } + public TObject this[string variable] { get => GetVariable(variable); set => SetVariable(variable,value); } + + } + +} \ No newline at end of file diff --git a/ScopeNode.cs b/ScopeNode.cs new file mode 100644 index 0000000..73d29fc --- /dev/null +++ b/ScopeNode.cs @@ -0,0 +1,17 @@ +namespace tlang +{ + public class ScopeNode : Node + { + public List Body {get;set;}= new List(); + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var sub = nodeEnv.SubEnv; + TObject obj=new TNull(); + foreach(var item in Body) + { + obj=item.Execute(sub); + } + return obj; + } + } +} \ No newline at end of file diff --git a/SubtractNode.cs b/SubtractNode.cs new file mode 100644 index 0000000..77ef934 --- /dev/null +++ b/SubtractNode.cs @@ -0,0 +1,25 @@ +namespace tlang +{ + internal class SubtractNode : Node + { + public Node Left {get;set;} + public Node Right {get;set;} + + public SubtractNode(Node left, Node right) + { + this.Left = left; + this.Right = right; + } + + public override TObject Execute(IScopeEnvironment nodeEnv) + { + var l = Left.Execute(nodeEnv) as TNumber; + var r = Right.Execute(nodeEnv) as TNumber; + + if(l != null && r != null) + return new TNumber(l.Value - r.Value); + + return new TNull(); + } + } +} \ No newline at end of file diff --git a/TArray.cs b/TArray.cs new file mode 100644 index 0000000..14a6efd --- /dev/null +++ b/TArray.cs @@ -0,0 +1,12 @@ +namespace tlang +{ + public class TArray : TObject + { + public TArray() + { + + } + + public List Items {get;set;}=new List(); + } +} \ No newline at end of file diff --git a/TDictionary.cs b/TDictionary.cs new file mode 100644 index 0000000..efaa9dc --- /dev/null +++ b/TDictionary.cs @@ -0,0 +1,42 @@ +namespace tlang +{ + public class TDictionary : TObject + { + public TDictionary() + { + + } + + Dictionary items {get;set;}=new Dictionary(); + + public TObject GetMember(string name) + { + if(items.ContainsKey(name)) + { + return items[name]; + }else{ + return TObject.Uninit; + } + } + + public void SetMember(string name, TObject obj) + { + if(items.ContainsKey(name)) + { + items[name] = obj; + } + else + { + items.Add(name,obj); + } + } + + public bool MemberExists(string name) + { + return items.ContainsKey(name); + } + public TObject this[string variable] { get => GetMember(variable); set => SetMember(variable,value); } + + + } +} \ No newline at end of file diff --git a/TInternalObject.cs b/TInternalObject.cs new file mode 100644 index 0000000..8486193 --- /dev/null +++ b/TInternalObject.cs @@ -0,0 +1,11 @@ +namespace tlang +{ + public class TInternalObject : TObject + { + public TInternalObject(object val) + { + Object=val; + } + public object Object {get;set;} + } +} \ No newline at end of file diff --git a/TMethod.cs b/TMethod.cs new file mode 100644 index 0000000..15f2eb8 --- /dev/null +++ b/TMethod.cs @@ -0,0 +1,81 @@ +namespace tlang +{ + public class TInternalMethod : TObject, ICallable + { + public TInternalMethod(ClosureNode node,IScopeEnvironment env) + { + Body = node; + Environment = env; + } + public ClosureNode Body {get;set;} + public IScopeEnvironment Environment {get;set;} + public TObject Call(params TObject[] args) + { + var env=Environment.SubEnv; + int argCountClosure = Body.Arguments.Count; + int argCountCaller = args.Length; + if(argCountCaller < requiredArguments()) + { + throw new Exception("not enough arguments"); + } + int i = 0; + for(;i cb; + public TExternalMethod(Func func) + { + cb = func; + } + + public TObject Call(params TObject[] args) + { + return cb(args); + } + + + } + + public interface ICallable + { + TObject Call(params TObject[] args); + } +} \ No newline at end of file diff --git a/TNull.cs b/TNull.cs new file mode 100644 index 0000000..adc5dcf --- /dev/null +++ b/TNull.cs @@ -0,0 +1,10 @@ +namespace tlang +{ + public class TNull : TObject + { + public override string ToString() + { + return "null"; + } + } +} \ No newline at end of file diff --git a/TNumber.cs b/TNumber.cs new file mode 100644 index 0000000..87a46b8 --- /dev/null +++ b/TNumber.cs @@ -0,0 +1,17 @@ +namespace tlang +{ + public class TNumber : TObject + { + public double Value {get;set;} + public TNumber(double number) + { + Value = number; + } + public override string ToString() + { + return Value.ToString(); + } + } + + +} \ No newline at end of file diff --git a/TObject.cs b/TObject.cs new file mode 100644 index 0000000..ee68f93 --- /dev/null +++ b/TObject.cs @@ -0,0 +1,9 @@ +namespace tlang +{ + public class TObject + { + + public static TObject Uninit => new TUninit(); + public static TObject Null => new TNull(); + } +} \ No newline at end of file diff --git a/TString.cs b/TString.cs new file mode 100644 index 0000000..f5ecbd6 --- /dev/null +++ b/TString.cs @@ -0,0 +1,15 @@ +namespace tlang +{ + public class TString : TObject + { + public string Value {get;set;} + public TString(string text) + { + Value = text; + } + public override string ToString() + { + return Value; + } + } +} \ No newline at end of file diff --git a/TUninit.cs b/TUninit.cs new file mode 100644 index 0000000..7b31b5d --- /dev/null +++ b/TUninit.cs @@ -0,0 +1,10 @@ +namespace tlang +{ + public class TUninit : TObject + { + public override string ToString() + { + return "undefined"; + } + } +} \ No newline at end of file diff --git a/file.tlang b/file.tlang new file mode 100644 index 0000000..4e686e2 --- /dev/null +++ b/file.tlang @@ -0,0 +1,7 @@ +/* + if(expression) expression else expression +*/ + +j = func() 42-43; + +printargs(j().abs()); \ No newline at end of file diff --git a/testString.tlang b/testString.tlang new file mode 100644 index 0000000..ce9eb0e --- /dev/null +++ b/testString.tlang @@ -0,0 +1,7 @@ +var s1="Some \"Some String\" Is Cool"; +var s2="My String Is Awesome"; +var s3="Demi\nLovato"; + +var main = (args)=>{ + ret 0; +}; \ No newline at end of file diff --git a/tlang.csproj b/tlang.csproj new file mode 100644 index 0000000..d439800 --- /dev/null +++ b/tlang.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + +