gpt4 book ai didi

c# - 如何提高我的 ECMAScript 实现的递归能力?

转载 作者:太空狗 更新时间:2023-10-29 23:42:18 30 4
gpt4 key购买 nike

经过一些重新测试后,我发现我的实现无法处理太多的递归。虽然在 Firefox 中运行了几次测试后我发现这可能比我原先想象的更常见。我相信基本问题是我的实现需要 3 次调用才能进行函数调用。第一次调用是对名为 Call 的方法进行的,该方法确保调用是对可调用对象进行的,并获取作为引用的任何参数的值。第二次调用是在 ICallable 接口(interface)中定义的名为 Call 的方法。此方法创建新的执行上下文并构建 lambda 表达式(如果尚未创建)。最后调用函数对象封装的 lambda。显然,进行函数调用非常繁重,但我确信,在使用此实现时,通过一些调整,我可以使递归成为一个可行的工具。

public static object Call(ExecutionContext context, object value, object[] args)
{
var func = Reference.GetValue(value) as ICallable;
if (func == null)
{
throw new TypeException();
}
if (args != null && args.Length > 0)
{
for (int i = 0; i < args.Length; i++)
{
args[i] = Reference.GetValue(args[i]);
}
}
var reference = value as Reference;
if (reference != null)
{
if (reference.IsProperty)
{
return func.Call(reference.Value, args);
}
else
{
return func.Call(((EnviromentRecord)reference.Value).ImplicitThisValue(), args);
}
}
return func.Call(Undefined.Value, args);
}

public object Call(object thisObject, object[] arguments)
{
var lexicalEnviroment = Scope.NewDeclarativeEnviroment();
var variableEnviroment = Scope.NewDeclarativeEnviroment();
var thisBinding = thisObject ?? Engine.GlobalEnviroment.GlobalObject;
var newContext = new ExecutionContext(Engine, lexicalEnviroment, variableEnviroment, thisBinding);
Engine.EnterContext(newContext);
var result = Function.Value(newContext, arguments);
Engine.LeaveContext();
return result;
}

最佳答案

我不敢相信开始工作是多么容易。基本上在我的编译器中,我检查函数是否返回调用自身的结果。如果是这样,我改为返回正在传递的参数。然后我只需获取任何引用值并重新调用支持 lambda。有了这个,我就能够进行数百万次递归调用。

我要感谢 DrJokepu 启发了这个解决方案。

public object Call(object thisObject, object[] arguments)
{
var lexicalEnviroment = Scope.NewDeclarativeEnviroment();
var variableEnviroment = Scope.NewDeclarativeEnviroment();
var thisBinding = thisObject ?? Engine.GlobalEnviroment.GlobalObject;
var newContext = new ExecutionContext(Engine, lexicalEnviroment, variableEnviroment, thisBinding);
var result = default(object);
var callArgs = default(object[]);

Engine.EnterContext(newContext);
while (true)
{
result = Function.Value(newContext, arguments);
callArgs = result as object[];
if (callArgs == null)
{
break;
}
for (int i = 0; i < callArgs.Length; i++)
{
callArgs[i] = Reference.GetValue(callArgs[i]);
}
arguments = callArgs;
}
Engine.LeaveContext();

return result;
}

关于c# - 如何提高我的 ECMAScript 实现的递归能力?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2893358/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com