支持“编辑和继续”或“热切换”的脚本语言?(也许在Lua中可能实现?)
2017-5-23 10:28:45
收藏:0
阅读:68
评论:1
我正在使我的现有 .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()
感谢您提供建议。以下是它可能的工作方式:
- 我将使用 https://github.com/frabert/NetLua 这是一个非常酷,编写得很好的 100% C# Lua 解释器。它首先生成 AST 树,然后直接执行它。
- 需要修改解析器。在 Parser.cs 中的
public Ast.Block ParseString(string Chunk)中,首先生成 parseTree。 parseTree.tokens[i].locations 包含每个标记的确切位置。Irony.Parsing.ParseTree然后再次解析,并转换为NetLua.Ast.Block,但是遗漏了位置信息。我需要更改它,以便稍后我将知道哪个语句在哪一行。 - 现在,AST 树中的每个语句都会直接通过 EvalBlock 执行。需要添加调试功能(就像在我的 C 绑定 lua 解释器 DynamicLua 中一样,通过 debug.setHook)。在 LuaInterpreter.cs 的
internal static LuaArguments EvalBlock()中可以完成。暂停/继续/按步骤函数应该没有问题。现在,每个语句都包含位置行信息,因此我也可以添加当前行突出显示。 - 当执行被暂停并且代码已被编辑时,当前的 LuaContext 会被保存。它包含所有变量。还保存了最后执行行的最后一条语句。
- 现在,将代码字符串再次解析为新的 AST 树。它被执行。但是在达到保存的包含执行线的最后一个语句之前,所有语句都将被跳过。保存的
LuaContext被恢复,可以使用所有更改继续执行。
新变量也可以添加到最后一行执行之后,因为新的 NetLua.Ast.Assignment 语句只需将新变量添加到当前 LuaContext 中,一切都应该正常工作。
这样能行吗?
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
我觉得这个做起来非常具有挑战性和棘手。
可能实现它的唯一方式是重新编译完整的代码块。在一个函数中,这意味着整个函数,无论编辑在函数中的哪个位置。然后再次调用该函数。显然,该函数必须是可重入的,否则它的副作用(比如全局或者upvalue的增加)将无法被撤销。如果它不是可重入的,它仍然可以工作,但是不能给出预期的结果(例如,如果该函数将全局变量增加1,则再次调用它将导致全局变量增加了2,直到函数最终返回)。
但是,如果想要实现一种真正通用的解决方案,找到脚本中块的起始和结束行将是棘手的。对于特定的解决方案,您必须发布您想要运行的脚本的具体示例和您想要编辑的行的示例。如果整个用户脚本被重新编译和重新运行,则这不是问题,但副作用仍然是一个问题,例子也可以帮助解决这个问题。