Improve Lua REPL handling of statements

Stop printing syntax error messages when executing variable assignments etc.
This commit is contained in:
kalimag 2024-09-07 03:32:21 +02:00
parent ab7f379e74
commit 06bc2efe2b
3 changed files with 37 additions and 14 deletions

View File

@ -51,7 +51,7 @@ namespace BizHawk.Client.Common
void SpawnAndSetFileThread(string pathToLoad, LuaFile lf);
void ExecuteString(string command);
object[] ExecuteString(string command);
(bool WaitForFrame, bool Terminated) ResumeScript(LuaFile lf);
}

View File

@ -1388,18 +1388,14 @@ namespace BizHawk.Client.EmuHawk
LuaSandbox.Sandbox(null, () =>
{
LuaImp.ExecuteString($"console.log({rawCommand})");
}, () =>
{
LuaSandbox.Sandbox(null, () =>
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 [ ] and not [ null ] || OutputBox.Text == consoleBeforeCall)
{
LuaImp.ExecuteString(rawCommand);
if (OutputBox.Text == consoleBeforeCall)
{
WriteLine("Command successfully executed");
}
});
LuaLibraries.Print(results);
}
});
_messageCount = 0;

View File

@ -323,8 +323,35 @@ namespace BizHawk.Client.EmuHawk
public void SpawnAndSetFileThread(string pathToLoad, LuaFile lf)
=> lf.Thread = SpawnCoroutine(pathToLoad);
public void ExecuteString(string command)
=> _lua.DoString(command);
/// <summary>
/// Executes Lua code. Automatically prepends <see langword="return"/> statement if possible.
/// </summary>
/// <returns>
/// Values returned by the Lua script, if any.
/// </returns>
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)
{