Improve Lua REPL handling of statements (squashed PR #4026)

* Improve Lua REPL handling of statements

Stop printing syntax error messages when executing variable assignments etc.

* Move doc comments to interface

* Simplify pattern matching expression

* Use reference equality to test for console output

* Revert "Use reference equality to test for console output"

This reverts commit 875bc3c41e.

* Use `_messageCount` to test for console output
This commit is contained in:
kalimag 2024-11-23 12:41:31 +01:00 committed by GitHub
parent 7e9e2d553c
commit 2bd2aed4aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 15 deletions

View File

@ -51,7 +51,13 @@ namespace BizHawk.Client.Common
void SpawnAndSetFileThread(string pathToLoad, LuaFile lf);
void ExecuteString(string command);
/// <summary>
/// Executes Lua code. Automatically prepends <see langword="return"/> statement if possible.
/// </summary>
/// <returns>
/// Values returned by the Lua script, if any.
/// </returns>
object[] ExecuteString(string command);
(bool WaitForFrame, bool Terminated) ResumeScript(LuaFile lf);
}

View File

@ -1373,7 +1373,6 @@ namespace BizHawk.Client.EmuHawk
{
if (e.KeyCode == Keys.Enter)
{
string consoleBeforeCall = OutputBox.Text;
var rawCommand = InputBox.Text;
InputBox.Clear();
InputBox.Refresh(); // if the command is something like `client.seekframe`, the Lua Console (and MainForm) will freeze until it finishes, so at least make it obvious that the Enter press was received
@ -1388,18 +1387,15 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.Sandbox(null, () =>
{
LuaImp.ExecuteString($"console.log({rawCommand})");
}, () =>
{
LuaSandbox.Sandbox(null, () =>
var prevMessageCount = _messageCount;
var results = LuaImp.ExecuteString(rawCommand);
// empty array if the command was e.g. a variable assignment or a loop without return statement
// "void" functions return a single null
// if output didn't change, Print will take care of writing out "(no return)"
if (results is not ([ ] or [ null ]) || _messageCount == prevMessageCount)
{
LuaImp.ExecuteString(rawCommand);
if (OutputBox.Text == consoleBeforeCall)
{
WriteLine("Command successfully executed");
}
});
LuaLibraries.Print(results);
}
});
_messageCount = 0;

View File

@ -323,8 +323,29 @@ namespace BizHawk.Client.EmuHawk
public void SpawnAndSetFileThread(string pathToLoad, LuaFile lf)
=> lf.Thread = SpawnCoroutine(pathToLoad);
public void ExecuteString(string command)
=> _lua.DoString(command);
public object[] ExecuteString(string command)
{
const string ChunkName = "input"; // shows up in error messages
// Use LoadString to separate parsing and execution, to tell syntax errors and runtime errors apart
LuaFunction func;
try
{
// Adding a return is necessary to get out return values of functions and turn expressions ("1+1" etc.) into valid statements
func = _lua.LoadString($"return {command}", ChunkName);
}
catch (Exception)
{
// command may be a valid statement without the added "return"
// if previous attempt couldn't be parsed, run the raw command
return _lua.DoString(command, ChunkName);
}
using (func)
{
return func.Call();
}
}
public (bool WaitForFrame, bool Terminated) ResumeScript(LuaFile lf)
{