2023-03-09 19:40:14 +00:00
|
|
|
namespace tlang
|
|
|
|
{
|
|
|
|
public class TInternalMethod : TObject, ICallable
|
|
|
|
{
|
2023-03-09 23:57:16 +00:00
|
|
|
public override bool AsBoolean => true;
|
2023-03-09 19:40:14 +00:00
|
|
|
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++)
|
|
|
|
{
|
2023-03-09 23:57:16 +00:00
|
|
|
env[Body.Arguments[i].TrimStart('$')] = args[i];
|
2023-03-09 19:40:14 +00:00
|
|
|
}
|
|
|
|
if(i==Body.Arguments.Count-1)
|
|
|
|
{
|
|
|
|
var tarray = new TArray();
|
2023-03-09 23:57:16 +00:00
|
|
|
env[Body.Arguments[i].TrimStart('$')] =tarray;
|
2023-03-09 19:40:14 +00:00
|
|
|
for(int j = i;j<args.Length;j++)
|
|
|
|
{
|
|
|
|
tarray.Items.Add(args[j]);
|
|
|
|
}
|
2023-03-09 23:57:16 +00:00
|
|
|
i = args.Length;
|
2023-03-09 19:40:14 +00:00
|
|
|
}
|
2023-03-09 23:57:16 +00:00
|
|
|
if(i<args.Length)
|
|
|
|
throw new Exception("too many arguments");
|
2023-03-09 19:40:14 +00:00
|
|
|
return Body.Node.Execute(env);
|
|
|
|
}
|
|
|
|
private int optionalArgs(int argLen)
|
|
|
|
{
|
|
|
|
for(int i =0;i<Body.Arguments.Count;i++)
|
|
|
|
{
|
2023-03-09 23:57:16 +00:00
|
|
|
if(Body.Arguments[i].StartsWith("$$"))
|
2023-03-09 19:40:14 +00:00
|
|
|
{
|
|
|
|
return Math.Min(argLen,i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Math.Min(argLen,Body.Arguments.Count);
|
|
|
|
}
|
|
|
|
private int requiredArguments()
|
|
|
|
{
|
|
|
|
for(int i =0;i<Body.Arguments.Count;i++)
|
|
|
|
{
|
2023-03-09 23:57:16 +00:00
|
|
|
if(Body.Arguments[i].StartsWith('$'))
|
2023-03-09 19:40:14 +00:00
|
|
|
{
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Body.Arguments.Count;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
public class TExternalMethod : TObject,ICallable
|
|
|
|
{
|
|
|
|
Func<TObject[],TObject> cb;
|
|
|
|
public TExternalMethod(Func<TObject[],TObject> func)
|
|
|
|
{
|
|
|
|
cb = func;
|
|
|
|
}
|
2023-03-09 23:57:16 +00:00
|
|
|
|
|
|
|
public override bool AsBoolean => true;
|
|
|
|
|
2023-03-09 19:40:14 +00:00
|
|
|
public TObject Call(params TObject[] args)
|
|
|
|
{
|
|
|
|
return cb(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface ICallable
|
|
|
|
{
|
|
|
|
TObject Call(params TObject[] args);
|
|
|
|
}
|
|
|
|
}
|