tlang-interperter-cs/tlanglib/TMethod.cs

120 lines
3.2 KiB
C#

using System;
using Newtonsoft.Json.Linq;
namespace tlang
{
public class TInternalMethod : TObject, ICallable
{
public override JToken AsToken()
{
return new JValue((object)null);
}
public override bool AsBoolean => true;
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<optionalArgs(args.Length);i++)
{
env[Body.Arguments[i].TrimStart('$')] = args[i];
}
if(i==Body.Arguments.Count-1)
{
var tarray = TObject.Array();
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("$$"))
{
return Math.Min(argLen,i);
}
}
return Math.Min(argLen,Body.Arguments.Count);
}
private int requiredArguments()
{
for(int i =0;i<Body.Arguments.Count;i++)
{
if(Body.Arguments[i].StartsWith("$"))
{
return i;
}
}
return Body.Arguments.Count;
}
}
public class TExternalMethod : TObject,ICallable
{
public override JToken AsToken()
{
return new JValue((object)null);
}
Func<TObject[],TObject> cb;
public TExternalMethod(Func<TObject[],TObject> func)
{
cb = func;
}
public TExternalMethod(Action<TObject[]> func)
{
cb = (args)=>{
func(args);
return Uninit;
};
}
public TExternalMethod(Func<TObject> func)
{
cb = (args)=>{
return func();
};
}
public TExternalMethod(Action func)
{
cb = (args)=>{
func();
return Uninit;
};
}
public override bool AsBoolean => true;
public TObject Call(params TObject[] args)
{
return cb(args);
}
}
public interface ICallable
{
TObject Call(params TObject[] args);
}
}