Skip to content

Commit

Permalink
Multiline interpreter + major refactor
Browse files Browse the repository at this point in the history
Managed to make it work, but the code is a bit messy and its syntax is not very flexible;
  • Loading branch information
jetrotal committed Nov 12, 2023
1 parent 1b99aff commit 9d0e41b
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 20 deletions.
83 changes: 64 additions & 19 deletions src/dynrpg_easyrpg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

// Headers
#include <map>
#include <numeric>

#include "dynrpg_easyrpg.h"
#include "string_view.h"
Expand Down Expand Up @@ -99,42 +100,86 @@ bool DynRpg::EasyRpgPlugin::EasyRaw(dyn_arg_list args, Game_Interpreter* interpr
Constants constList;

const std::string func = "easyrpg_raw";
bool okay = false;

int codeArgIndex = 0;
int stringArgIndex = 1;
int indentArgIndex = -1;

bool endOfLine = false;
bool okay = false;

lcf::rpg::EventCommand cmd;
lcf::rpg::EventCommand _cmd;
std::vector<int32_t> outputArgs;
std::vector<lcf::rpg::EventCommand> cmdList;

for (size_t i = 0; i < args.size(); ++i) {
if (i == args.size() - 1) {
if (args[i].back() == ';') args[i] = args[i].substr(0, args[i].length() - 1);
endOfLine = true;

bool valid = !args[i].empty();

if (valid && args[i].front() == '[') args[i] = args[i].substr(1);
if (valid && args[i].back() == ']') {
args[i] = args[i].substr(0, args[i].length() - 1);
indentArgIndex = i + 1;
}

// TODO: Implement multi-line command interpretation split by ';'.
valid = !args[i].empty();

if (i == codeArgIndex) {
if (args[i].front() == '@') args[i] = constList.get("EventCode", args[i].substr(1));
std::tie(cmd.code) = DynRpg::ParseArgs<int>(func, args, &okay);
}
else if (i == stringArgIndex) {
auto [stringArg] = DynRpg::ParseArgs<std::string>(func, args.subspan(i), &okay);
cmd.string = lcf::DBString(stringArg);
}
else {
if (args[i].front() == '@') args[i] = constList.get("DestinyScript", args[i].substr(1));
auto [intArg] = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);
outputArgs.push_back(intArg);
if (i == args.size() - 1) endOfLine = true;


else if (args[i] == ";") {
endOfLine = !args[i + 1].empty();
valid = 0;
}

if (valid) {
if (i == codeArgIndex)
{
size_t start_pos = args[i].find_first_not_of(" \t\r\n");
if (start_pos != std::string::npos)
args[i] = args[i].substr(start_pos);

// Output::Debug("code ----> {}", args[i]);

if (args[i].front() == '$')
args[i] = constList.get("EventCode", args[i].substr(1));
std::tie(cmd.code) = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);
}
else if (i == stringArgIndex)
{
// Output::Debug("str ----> {}", args[i]);
auto [stringArg] = DynRpg::ParseArgs<std::string>(func, args.subspan(i), &okay);
cmd.string = lcf::DBString(stringArg);
}
else
{
if (args[i].front() == '$')
args[i] = constList.get("DestinyScript", args[i].substr(1));
auto [intArg] = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);

if (indentArgIndex == i) {
// Output::Debug("idt ----> {}", args[i]);
indentArgIndex = -1;
cmd.indent = intArg;
}
else
// Output::Debug("pls ----> {}", args[i]),
outputArgs.push_back(intArg);
}
}
if (endOfLine) {
codeArgIndex = i + 1;
stringArgIndex = i + 2;
// Output::Debug("com ----> {}\n\n", cmd.code);
cmd.parameters = lcf::DBArray<int32_t>(outputArgs.begin(), outputArgs.end());
cmdList.push_back(cmd);
outputArgs.clear();

cmd = _cmd;

codeArgIndex = i + 1;
stringArgIndex = i + 2;

endOfLine = false;
}

if (!okay) return true;
Expand Down
39 changes: 38 additions & 1 deletion src/game_dynrpg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,44 @@ std::string DynRpg::ParseCommand(std::string command, std::vector<std::string>&
token.str("");
break;
}
} else {
}
else if (chr == ';') {
switch (mode) {
case ParseMode_Function:
// End of function token
function_name = Utils::LowerCase(token.str());
if (function_name.empty()) {
// empty function name
Output::Warning("Empty DynRPG function name");
return {};
}
token.str("");
// Empty arg
args.emplace_back("");
mode = ParseMode_WaitForArg;
break;
case ParseMode_WaitForComma:
mode = ParseMode_WaitForArg;
break;
case ParseMode_WaitForArg:

// Empty arg
args.emplace_back("");
break;
case ParseMode_String:
token << chr;
break;
case ParseMode_Token:
tmp = ParseToken(token.str(), function_name);
args.emplace_back(tmp);
if (function_name == "easyrpg_raw") args.emplace_back(";");
// already on a comma
mode = ParseMode_WaitForArg;
token.str("");
break;
}
}
else {
// Anything else that isn't special purpose
switch (mode) {
case ParseMode_Function:
Expand Down

0 comments on commit 9d0e41b

Please sign in to comment.