Minimum Viable Product

This commit is contained in:
Mike Nolan 2023-03-09 17:57:16 -06:00
parent b74fd1d083
commit fd57d7998c
31 changed files with 948 additions and 75 deletions

View File

@ -19,8 +19,21 @@ namespace tlang
var rNum = r as TNumber;
var lStr = l as TString;
var rStr = r as TString;
var dleft = l as TDictionary;
if(dleft != null)
{
if(dleft.MemberExists("add"))
{
var mbm = dleft["add"] as ICallable;
if(mbm != null)
{
return mbm.Call(r);
}
}
}
if(lNum != null && rNum != null)
return new TNumber(lNum.Value + rNum.Value);
@ -31,6 +44,8 @@ namespace tlang
if(lNum != null && rStr != null)
return new TString(lNum.Value.ToString() + rStr.Value);
return new TNull();
}
}

86
ArraySubscriptNode.cs Normal file
View File

@ -0,0 +1,86 @@
namespace tlang
{
internal class ArraySubscriptNode : MemberGetVariableValue
{
public Node Argument {get;set;}
public ArraySubscriptNode(Node parent, string text, Node arg) : base(parent,text)
{
Argument = arg;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var arg = Argument.Execute(nodeEnv);
var p=Parent.Execute(nodeEnv);
var dict = p as TDictionary;
var ls = p as TArray;
var str = p as TString;
if(dict != null)
{
var sArg = arg as TString;
var at = dict["at"] as ICallable;
if(at != null)
{
return at.Call(arg);
}
if(sArg != null)
{
return dict[sArg.Value];
}
}
if(ls != null)
{
var nArg = arg as TNumber;
if(nArg != null && nArg.Value < ls.Items.Count)
{
return ls.Items[(int)nArg.Value];
}
}
if(str != null)
{
var nArg = arg as TNumber;
if(nArg != null && nArg.Value < str.Value.Length)
{
return new TChar(str.Value[(int)nArg.Value]);
}
}
return TObject.Uninit;
}
public override void SetValue(IScopeEnvironment nodeEnv, TObject value)
{
var arg = Argument.Execute(nodeEnv);
var p=Parent.Execute(nodeEnv);
var dict = p as TDictionary;
var ls = p as TArray;
var str = p as TString;
if(dict != null)
{
var sArg = arg as TString;
var at = dict["setAt"] as ICallable;
if(at != null)
{
at.Call(arg,value);
}
else
if(sArg != null)
{
dict[sArg.Value] = value;
}
}
if(ls != null)
{
var nArg = arg as TNumber;
if(nArg != null && nArg.Value < ls.Items.Count)
{
ls.Items[(int)nArg.Value] = value;
}
}
}
}
}

View File

@ -13,11 +13,26 @@ namespace tlang
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var l = Left.Execute(nodeEnv) as TNumber;
var r = Right.Execute(nodeEnv) as TNumber;
var l = Left.Execute(nodeEnv);
var r = Right.Execute(nodeEnv);
var lnum = l as TNumber;
var rnum = r as TNumber;
var dleft = l as TDictionary;
if(l != null && r != null)
return new TNumber(l.Value / r.Value);
if(dleft != null)
{
if(dleft.MemberExists("divide"))
{
var mbm = dleft["divide"] as ICallable;
if(mbm != null)
{
return mbm.Call(r);
}
}
}
if(lnum != null && rnum != null)
return new TNumber(lnum.Value / rnum.Value);
return new TNull();
}

90
EachLoop.cs Normal file
View File

@ -0,0 +1,90 @@
namespace tlang
{
public class EachLoop : Node
{
public GetVariableValue Name {get;set;}
public Node List {get;set;}
public Node Body {get;set;}
public EachLoop(GetVariableValue name, Node ls,Node body)
{
Name = name;
List = ls;
Body=body;
}
private IEnumerable<TObject> CreateItterator(IScopeEnvironment env,TObject ls)
{
var dict = ls as TDictionary;
var str = ls as TString;
var array = ls as TArray;
if(dict!= null)
{
var gIttrVar = dict["ittr"] as TDictionary;
var gIttrProp = dict["getIttr"] as ICallable;
if(gIttrProp != null)
{
var myObj= gIttrProp.Call() as TDictionary;
if(myObj != null)
{
var reset = myObj["reset"] as ICallable;
var moveNext = myObj["movenext"] as ICallable;
var getCurrent = myObj["getCurrent"] as ICallable;
if(reset != null) reset.Call();
if(moveNext != null)
while(moveNext.Call().AsBoolean)
{
if(getCurrent != null)
{
yield return getCurrent.Call();
}
else
{
var current = myObj["current"];
yield return current;
}
}
}
}
}
else if(array != null)
{
foreach(var item in array.Items)
{
yield return item;
}
}
else if(str != null)
{
foreach(var c in str.Value)
{
yield return new TChar(c);
}
}
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var env = nodeEnv.SubEnv;
var ls = List.Execute(env);
bool isRunning=true;
env["last_ittr"]= new TExternalMethod((args)=>{
isRunning=false;
return new TNumber(1);
});
TObject last = TObject.Uninit;
var enumerator=CreateItterator(env,ls).GetEnumerator();
while(isRunning && enumerator.MoveNext())
{
Name.SetValue(env,enumerator.Current);
Body.Execute(env);
}
return last;
}
}
}

36
ForLoop.cs Normal file
View File

@ -0,0 +1,36 @@
namespace tlang
{
internal class ForLoop : Node
{
public Node Init {get;set;}
public Node Condition {get;set;}
public Node Increment {get;set;}
public Node Body {get;set;}
public ForLoop(Node init, Node condition, Node inc, Node body)
{
Init = init;
Condition = condition;
Increment = inc;
Body = body;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var env = nodeEnv.SubEnv;
bool isRunning=true;
env["last_ittr"]= new TExternalMethod((args)=>{
isRunning=false;
return new TNumber(1);
});
Init.Execute(env);
TObject obj=new TUninit();
while(Condition.Execute(env).AsBoolean && isRunning)
{
obj=Body.Execute(env);
Increment.Execute(env);
}
return obj;
}
}
}

View File

@ -3,19 +3,20 @@ namespace tlang
internal class SetVariableNode : Node
{
public Node Value {get;set;}
public string Name {get;set;}
public SetVariableNode(string text,Node v)
public GetVariableValue Name {get;set;}
public SetVariableNode(GetVariableValue gvn,Node v)
{
Name=text;
Name=gvn;
Value=v;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var res=Value.Execute(nodeEnv);
nodeEnv[Name]=res;
Name.SetValue(nodeEnv,res);
return res;
}
}
public class GetVariableValue : Node
{
@ -30,5 +31,9 @@ namespace tlang
{
return nodeEnv[Name];
}
public virtual void SetValue(IScopeEnvironment nodeEnv,TObject value)
{
nodeEnv[Name] = value;
}
}
}

View File

@ -16,19 +16,13 @@ namespace tlang
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);
return condition.AsBoolean ? Yes.Execute(nodeEnv) : No.Execute(nodeEnv);
}
}
}

View File

@ -17,7 +17,9 @@ namespace tlang
var dict = res as TDictionary;
var integer = res as TNumber;
var str = res as TString;
var chr = res as TChar;
var array = res as TArray;
if(dict != null)
{
var n = dict[Text] as ICallable;
@ -25,6 +27,74 @@ namespace tlang
{
return n.Call(Args.Select<Node,TObject>(e=>e.Execute(nodeEnv)).ToArray());
}
}else if(chr != null)
{
if(Text == "toUpper")
{
return new TChar(char.ToUpper(chr.Value));
}
if(Text == "toLower")
{
return new TChar(char.ToLower(chr.Value));
}
if(Text == "toString")
{
return new TString(chr.Value.ToString());
}
if(Text == "toNumber")
{
return new TNumber(chr.Value);
}
}
else if(array != null)
{
if(Text == "add")
{
if(Args.Count == 1)
{
TObject obj = Args[0].Execute(nodeEnv);
array.Items.Add(obj);
return obj;
}
}
if(Text == "at")
{
//at(index)
if(Args.Count == 1)
{
var index=Args[0].Execute(nodeEnv) as TNumber;
if(index != null)
{
if(index.Value < array.Items.Count)
return array.Items[(int)index.Value];
}
}
}
if(Text == "setAt")
{
TObject value = TObject.Null;
//setAt(index,value)
//setAt(index) //null
if(Args.Count == 2)
{
value=Args[1].Execute(nodeEnv);
}
if(Args.Count > 0)
{
var index=Args[0].Execute(nodeEnv) as TNumber;
if(index != null)
{
if(index.Value < array.Items.Count)
array.Items[(int)index.Value]=value;
}
}
return value;
}
if(Text == "length" || Text == "count")
{
return new TNumber(array.Items.Count);
}
}
else if(integer != null)
{
@ -36,6 +106,79 @@ namespace tlang
{
return new TNumber(Math.Abs(integer.Value));
}
if(Text == "toChar")
{
return new TChar((char)integer.Value);
}
}else if(str != null)
{
if(Text == "replace")
{
//todo fill this method out
}
if(Text == "split")
{
//todo fill this method out
//str.Value.Split(,,StringSplitOptions.TrimEntries);
}
if(Text == "startsWith")
{
string val = " ";
if(Args.Count > 0){
var firstArg = Args[0].Execute(nodeEnv);
var c = firstArg as TChar;
var mystr = firstArg as TString;
var mynum = firstArg as TNumber;
if(c!=null) val = c.Value.ToString();
if(mystr != null) val = mystr.Value.ToString();
if(mynum != null) val = mynum.Value.ToString();
}
return new TNumber(str.Value.StartsWith(val) ? 1 : 0);
}
if(Text == "trimStart")
{
if(Args.Count == 0)
{
return new TString(str.Value.TrimStart());
}else{
return new TString(str.Value.TrimStart(Args.Select<Node,char>(n=>{
var nV=n.Execute(nodeEnv) as TChar;
if(nV != null)
{
return nV.Value;
}
return ' ';
}).ToArray()));
}
}
if(Text == "trimEnd")
{
//trimend()
if(Args.Count == 0)
{
return new TString(str.Value.TrimEnd());
}else{
return new TString(str.Value.TrimEnd(Args.Select<Node,char>(n=>{
var nV=n.Execute(nodeEnv) as TChar;
if(nV != null)
{
return nV.Value;
}
return ' ';
}).ToArray()));
}
}
if(Text == "toString")
{
return str;
}
}
@ -44,4 +187,6 @@ namespace tlang
return new TUninit();
}
}
}

View File

@ -7,7 +7,26 @@ namespace tlang
{
Parent = parent;
}
public override void SetValue(IScopeEnvironment nodeEnv, TObject value)
{
var res=Parent.Execute(nodeEnv);
var dict = res as TDictionary;
if(dict != null)
{
if(dict.MemberExists($"set{Name}"))
{
var mbm= dict[$"set{Name}"] as ICallable;
if(mbm != null)
{
mbm.Call(value);
}
}else{
dict[Name] = value;
}
}
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var res=Parent.Execute(nodeEnv);
@ -15,6 +34,8 @@ namespace tlang
var dict = res as TDictionary;
var integer = res as TNumber;
var array = res as TArray;
var str = res as TString;
if(array != null)
{
if(Name == "length" || Name == "count")
@ -41,8 +62,36 @@ namespace tlang
if(integer != null)
{
if(Name == "abs")
{
return new TNumber(Math.Abs(integer.Value));
}
if(Name == "int")
{
return new TNumber(Math.Round(integer.Value));
}
}
if(str != null)
{
if(Name == "number")
{
}
if(Name == "ittr")
{
}
if(Name == "length" || Name == "count")
{
return new TNumber(str.Value.Length);
}
if(Name == "list")
{
}
}
return new TUninit();
}

View File

@ -13,11 +13,26 @@ namespace tlang
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var l = Left.Execute(nodeEnv) as TNumber;
var r = Right.Execute(nodeEnv) as TNumber;
var l = Left.Execute(nodeEnv);
var r = Right.Execute(nodeEnv);
var lnum = l as TNumber;
var rnum = r as TNumber;
var dleft = l as TDictionary;
if(l != null && r != null)
return new TNumber(l.Value % r.Value);
if(dleft != null)
{
if(dleft.MemberExists("mod"))
{
var mbm = dleft["mod"] as ICallable;
if(mbm != null)
{
return mbm.Call(r);
}
}
}
if(lnum != null && rnum != null)
return new TNumber(lnum.Value % rnum.Value);
return new TNull();
}

View File

@ -13,11 +13,26 @@ namespace tlang
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var l = Left.Execute(nodeEnv) as TNumber;
var r = Right.Execute(nodeEnv) as TNumber;
var l = Left.Execute(nodeEnv);
var r = Right.Execute(nodeEnv);
var lnum = l as TNumber;
var rnum = r as TNumber;
var dleft = l as TDictionary;
if(l != null && r != null)
return new TNumber(l.Value * r.Value);
if(dleft != null)
{
if(dleft.MemberExists("times"))
{
var mbm = dleft["times"] as ICallable;
if(mbm != null)
{
return mbm.Call(r);
}
}
}
if(lnum != null && rnum != null)
return new TNumber(lnum.Value * rnum.Value);
return new TNull();
}

265
Parser.cs
View File

@ -10,11 +10,12 @@ namespace tlang
public Node ParseExpression(List<LexToken> 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();
ScopeNode scopeNode = new ScopeNode(){First=isFirst};
while(i<tokens.Count && tokens[i].Text != "}")
{
scopeNode.Body.Add(ParseExpression(tokens,ref i));
@ -41,8 +42,8 @@ namespace tlang
GetVariableValue? gvar = myExpression as GetVariableValue;
if(gvar != null)
{
myExpression= new SetVariableNode(gvar.Name,ParseSum(tokens,ref i));
myExpression= new SetVariableNode(gvar,ParseSum(tokens,ref i));
}
}
@ -77,7 +78,7 @@ namespace tlang
if(token.IsString) return new ConstNode(new TString(token.Text));
if(token.IsChar)
{
return new ConstNode(new TNumber(token.Text.SingleOrDefault()));
return new ConstNode(new TChar(token.Text.SingleOrDefault()));
}
long val;
@ -126,7 +127,78 @@ namespace tlang
}
i++;
return new ClosureNode(args,ParseExpression(tokens,ref i));
} else if(token.Text == "if")
}
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);
GetVariableValue? 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);
@ -160,7 +232,15 @@ namespace tlang
}
i++;
var ret = new FunctionCallNode(token.Text,args);
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++;
@ -171,7 +251,7 @@ namespace tlang
{
i++;
args = new List<Node>();
//function call baby
//function call baby
while(i<tokens.Count && tokens[i].Text != ")")
{
@ -188,30 +268,125 @@ namespace tlang
}
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":
return new ConstNode(TObject.Null);
ret= new ConstNode(TObject.Null);
break;
case "undefined":
return new ConstNode(TObject.Uninit);
ret= new ConstNode(TObject.Uninit);
break;
case "true":
return new ConstNode(new TNumber(1));
ret= new ConstNode(new TNumber(1));
break;
case "false":
return new ConstNode(new TNumber(0));
ret= new ConstNode(new TNumber(0));
break;
default:
return new GetVariableValue(token.Text);
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;
}
}
@ -243,5 +418,67 @@ namespace tlang
}
return myExpression;
}
public void LoadEnvironment(RootEnvironment env)
{
TDictionary fs = new TDictionary();
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;
}
}
}

View File

@ -0,0 +1,26 @@
namespace tlang
{
public class PostfixDecrementVariableNode : Node
{
public GetVariableValue Node {get;set;}
public PostfixDecrementVariableNode(GetVariableValue ret)
{
Node = ret;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var obj=Node.Execute(nodeEnv);
var newVal=new SubtractNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv);
Node.SetValue(nodeEnv,newVal);
return obj;
}
}
}

View File

@ -0,0 +1,26 @@
namespace tlang
{
public class PostfixIncrementVariableNode : Node
{
public GetVariableValue Node {get;set;}
public PostfixIncrementVariableNode(GetVariableValue ret)
{
Node = ret;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var obj=Node.Execute(nodeEnv);
var newVal=new AddNode(new ConstNode(obj),new ConstNode(new TNumber(1))).Execute(nodeEnv);
Node.SetValue(nodeEnv,newVal);
return obj;
}
}
}

View File

@ -1,7 +1,7 @@
namespace tlang;
class Program
{
static void Main(string[] args)
static int Main(string[] args)
{
//Lexer lexer = new Lexer("testString.tlang");
@ -9,13 +9,27 @@ class Program
//parser.Add(lexer.Tokens);
int r=0;
RootEnvironment env=new RootEnvironment();
env["mol"] = new TNumber(42);
env["printargs"] = new TExternalMethod((args2)=>{
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.WriteLine(arg);
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)=>{
@ -90,9 +104,25 @@ class Program
});
Lexer lexer =new Lexer(new StreamReader("file.tlang"));
var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env);
r=0;
Console.WriteLine(res);
var res=parser.ParseExpression(lexer.Tokens,ref r,true).Execute(env) as TNumber;
var main = env["main"] as ICallable;
if(main != null)
{
List<TString> args2=new List<TString>();
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;
}
}

View File

@ -53,6 +53,10 @@ namespace tlang
public TObject GetVariable(string name)
{
if(name == "last_ittr" && items.ContainsKey("last_ittr"))
{
return items["last_ittr"];
}
if(parent.VariableExists(name))
{
return parent[name];
@ -66,8 +70,9 @@ namespace tlang
public void SetVariable(string name, TObject obj)
{
if(parent.VariableExists(name))
if(parent.VariableExists(name) && name != "last_ittr")
{
parent.SetVariable(name,obj);
}else if(items.ContainsKey(name))
{

View File

@ -2,10 +2,11 @@ namespace tlang
{
public class ScopeNode : Node
{
public bool First {get;set;}
public List<Node> Body {get;set;}= new List<Node>();
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var sub = nodeEnv.SubEnv;
var sub = First ? nodeEnv : nodeEnv.SubEnv;
TObject obj=new TNull();
foreach(var item in Body)
{

View File

@ -13,11 +13,26 @@ namespace tlang
public override TObject Execute(IScopeEnvironment nodeEnv)
{
var l = Left.Execute(nodeEnv) as TNumber;
var r = Right.Execute(nodeEnv) as TNumber;
var l = Left.Execute(nodeEnv);
var r = Right.Execute(nodeEnv);
var lnum = l as TNumber;
var rnum = r as TNumber;
var dleft = l as TDictionary;
if(l != null && r != null)
return new TNumber(l.Value - r.Value);
if(dleft != null)
{
if(dleft.MemberExists("sub"))
{
var mbm = dleft["sub"] as ICallable;
if(mbm != null)
{
return mbm.Call(r);
}
}
}
if(lnum != null && rnum != null)
return new TNumber(lnum.Value - rnum.Value);
return new TNull();
}

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TArray : TObject
{
public override bool AsBoolean => Items.Count > 0;
public TArray()
{

19
TChar.cs Normal file
View File

@ -0,0 +1,19 @@
namespace tlang
{
internal class TChar : TObject
{
public override bool AsBoolean => Value != '\0';
public char Value {get;set;}
public TChar(char v)
{
Value = v;
}
public override string ToString()
{
return Value.ToString();
}
}
}

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TDictionary : TObject
{
public override bool AsBoolean {get =>true;}
public TDictionary()
{

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TInternalObject : TObject
{
public override bool AsBoolean => true;
public TInternalObject(object val)
{
Object=val;

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TInternalMethod : TObject, ICallable
{
public override bool AsBoolean => true;
public TInternalMethod(ClosureNode node,IScopeEnvironment env)
{
Body = node;
@ -21,24 +22,27 @@ namespace tlang
int i = 0;
for(;i<optionalArgs(args.Length);i++)
{
env[Body.Arguments[i].TrimStart('.')] = args[i];
env[Body.Arguments[i].TrimStart('$')] = args[i];
}
if(i==Body.Arguments.Count-1)
{
var tarray = new TArray();
env[Body.Arguments[i].TrimStart('.')] =tarray;
env[Body.Arguments[i].TrimStart('$')] =tarray;
for(int j = i;j<args.Length;j++)
{
tarray.Items.Add(args[j]);
}
i = args.Length;
}
if(i<args.Length)
throw new Exception("too many arguments");
return Body.Node.Execute(env);
}
private int optionalArgs(int argLen)
{
for(int i =0;i<Body.Arguments.Count;i++)
{
if(Body.Arguments[i].StartsWith("..."))
if(Body.Arguments[i].StartsWith("$$"))
{
return Math.Min(argLen,i);
}
@ -49,7 +53,7 @@ namespace tlang
{
for(int i =0;i<Body.Arguments.Count;i++)
{
if(Body.Arguments[i].StartsWith('.'))
if(Body.Arguments[i].StartsWith('$'))
{
return i;
}
@ -65,7 +69,9 @@ namespace tlang
{
cb = func;
}
public override bool AsBoolean => true;
public TObject Call(params TObject[] args)
{
return cb(args);

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TNull : TObject
{
public override bool AsBoolean => false;
public override string ToString()
{
return "null";

View File

@ -3,6 +3,9 @@ namespace tlang
public class TNumber : TObject
{
public double Value {get;set;}
public override bool AsBoolean => Value != 0;
public TNumber(double number)
{
Value = number;

View File

@ -1,8 +1,8 @@
namespace tlang
{
public class TObject
public abstract class TObject
{
public abstract bool AsBoolean {get;}
public static TObject Uninit => new TUninit();
public static TObject Null => new TNull();
}

View File

@ -3,6 +3,9 @@ namespace tlang
public class TString : TObject
{
public string Value {get;set;}
public override bool AsBoolean => Value.Length > 0;
public TString(string text)
{
Value = text;

View File

@ -2,6 +2,7 @@ namespace tlang
{
public class TUninit : TObject
{
public override bool AsBoolean {get=>false;}
public override string ToString()
{
return "undefined";

38
WhileLoop.cs Normal file
View File

@ -0,0 +1,38 @@
namespace tlang
{
public class WhileLoop : Node
{
public Node Condition {get;set;}
public Node Body {get;set;}
public bool DoLoop {get;set;}
public WhileLoop(Node condition, Node yes, bool v)
{
Condition = condition;
Body = yes;
DoLoop = v;
}
public override TObject Execute(IScopeEnvironment nodeEnv)
{
bool isRunning=true;
var env = nodeEnv.SubEnv;
env["last_ittr"]= new TExternalMethod((args)=>{
isRunning=false;
return new TNumber(1);
});
TObject obj=new TUninit();
if(!DoLoop) isRunning = Condition.Execute(env).AsBoolean;
while(isRunning)
{
obj=Body.Execute(env);
isRunning = Condition.Execute(env).AsBoolean;
}
return obj;
}
}
}

View File

@ -1,7 +1,8 @@
/*
if(expression) expression else expression
*/
j = func() 42-43;
printargs(j().abs());
each(dir : fs.enumerate_dirs(fs.home))
{
println(dir);
}
each(file : fs.enumerate_files(fs.home))
{
println(file);
}

View File

@ -1,7 +0,0 @@
var s1="Some \"Some String\" Is Cool";
var s2="My String Is Awesome";
var s3="Demi\nLovato";
var main = (args)=>{
ret 0;
};