3

我正在为非编程用户编写现有的 .Net 应用程序脚本。我添加了 lua,它就像一个魅力。然后我通过 debug.sethook添加了调试功能(暂停/继续/步骤) 。它也像一个魅力。

现在我意识到我的应用程序需要像 Visual Studio 那样的编辑和继续功能。您暂停执行可以编辑代码,然后从当前状态继续应用更改。这个功能对我来说非常重要。我认为这对于脚本语言来说很容易做到。

我在任何地方读到脚本语言都可以做到这一点。但即使经过数小时的搜索,我还没有找到 Lua 实现。它不一定是 Lua,但 Lua 中的热交换代码将是我的首选。

如何为用户提供暂停和编辑脚本并在应用更改后继续执行的能力?

注意:不必是 Lua,每种脚本语言都可以

更新

@Schollii 这是一个例子:

function doOnX() 
   if getValue() == "200" then
      value = getCalculation()
      doSomething() -- many function calls, each can take about 2s
      doSomething()
      doSomething()
      print(value)
      doX(value)
   end
end

doOnX() 

谢谢你的建议。这就是它的工作方式:

  1. 我将使用https://github.com/frabert/NetLua它是一个非常酷、编写良好的 100% C# Lua 解释器。它首先生成一个 AST 树,然后直接执行它。
  2. 解析器需要修改。在 Parser.cspublic Ast.Block ParseString(string Chunk)中首先生成了一个 parseTree。parseTree.tokens[i].locations 包含每个标记的确切位置。然后Irony.Parsing.ParseTree再次解析并转换为a NetLua.Ast.Block,但丢失了位置信息。我需要改变它,所以稍后我会知道哪条语句在哪一行。
  3. 现在 AST 树中的每个 Statement 都直接通过 EvalBlock 执行。需要添加调试功能(就像我在 C Binding lua Interpreter DynamicLua via debug.setHook 中的那样)。这可以在 LuaInterpreter.cs internal static LuaArguments EvalBlock(`. Pause/continue/step 函数中完成。我现在也可以添加当前行突出显示,因为每个语句都包含位置行信息。
  4. 当执行暂停并且代码被编辑时,当前的 LuaContxct 被保存。它包含所有变量。最后一个执行行的最后一个语句也被保存。
  5. 现在,代码 String 再次被解析为新的 AST 树。它被执行。但是所有语句都被跳过,直到到达带有 line 语句的已保存语句。保存LuaContext的被恢复并且可以继续执行所有应用的更改。

新变量也可以在最后执行的行之后添加,因为一个新的NetLua.Ast.AssignmentStatement 可以只向当前的 LuaContext 添加一个新变量,一切都应该正常工作。

这行得通吗?

4

1 回答 1

2

我认为这是非常具有挑战性和棘手的事情。

可能唯一能做到这一点的方法就是完全重新编译代码块。在一个函数中,这意味着整个函数,无论编辑在哪里。然后再次调用该函数。显然,该函数必须是可重入的,否则它的副作用(例如增加全局或上值)将不得不撤消,这是不可能的。如果它不是可重入的,它仍然可以工作,只是不会给出预期的结果(例如,如果函数将全局变量增加 1,再次调用它将导致全局变量在函数最终返回时增加 2)。

但是,如果真正通用的解决方案,在脚本中找到 chunknstarts 和 end 的行将是棘手的。对于特定的解决方案,您必须发布要运行的脚本的特定示例和要编辑的行示例。如果整个用户脚本被重新编译并重新运行,那么这不是问题,但副作用仍然是一个问题,示例也可以提供帮助。

于 2014-10-04T22:39:51.890 回答