Skip to content

Commit 9d0e41b

Browse files
committed
Multiline interpreter + major refactor
Managed to make it work, but the code is a bit messy and its syntax is not very flexible;
1 parent 1b99aff commit 9d0e41b

File tree

2 files changed

+102
-20
lines changed

2 files changed

+102
-20
lines changed

src/dynrpg_easyrpg.cpp

+64-19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
// Headers
1919
#include <map>
20+
#include <numeric>
2021

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

101102
const std::string func = "easyrpg_raw";
102-
bool okay = false;
103+
103104
int codeArgIndex = 0;
104105
int stringArgIndex = 1;
106+
int indentArgIndex = -1;
107+
105108
bool endOfLine = false;
109+
bool okay = false;
106110

107111
lcf::rpg::EventCommand cmd;
112+
lcf::rpg::EventCommand _cmd;
108113
std::vector<int32_t> outputArgs;
109114
std::vector<lcf::rpg::EventCommand> cmdList;
110115

111116
for (size_t i = 0; i < args.size(); ++i) {
112-
if (i == args.size() - 1) {
113-
if (args[i].back() == ';') args[i] = args[i].substr(0, args[i].length() - 1);
114-
endOfLine = true;
117+
118+
bool valid = !args[i].empty();
119+
120+
if (valid && args[i].front() == '[') args[i] = args[i].substr(1);
121+
if (valid && args[i].back() == ']') {
122+
args[i] = args[i].substr(0, args[i].length() - 1);
123+
indentArgIndex = i + 1;
115124
}
116125

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

119-
if (i == codeArgIndex) {
120-
if (args[i].front() == '@') args[i] = constList.get("EventCode", args[i].substr(1));
121-
std::tie(cmd.code) = DynRpg::ParseArgs<int>(func, args, &okay);
122-
}
123-
else if (i == stringArgIndex) {
124-
auto [stringArg] = DynRpg::ParseArgs<std::string>(func, args.subspan(i), &okay);
125-
cmd.string = lcf::DBString(stringArg);
126-
}
127-
else {
128-
if (args[i].front() == '@') args[i] = constList.get("DestinyScript", args[i].substr(1));
129-
auto [intArg] = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);
130-
outputArgs.push_back(intArg);
128+
if (i == args.size() - 1) endOfLine = true;
129+
130+
131+
else if (args[i] == ";") {
132+
endOfLine = !args[i + 1].empty();
133+
valid = 0;
131134
}
132135

136+
if (valid) {
137+
if (i == codeArgIndex)
138+
{
139+
size_t start_pos = args[i].find_first_not_of(" \t\r\n");
140+
if (start_pos != std::string::npos)
141+
args[i] = args[i].substr(start_pos);
142+
143+
// Output::Debug("code ----> {}", args[i]);
144+
145+
if (args[i].front() == '$')
146+
args[i] = constList.get("EventCode", args[i].substr(1));
147+
std::tie(cmd.code) = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);
148+
}
149+
else if (i == stringArgIndex)
150+
{
151+
// Output::Debug("str ----> {}", args[i]);
152+
auto [stringArg] = DynRpg::ParseArgs<std::string>(func, args.subspan(i), &okay);
153+
cmd.string = lcf::DBString(stringArg);
154+
}
155+
else
156+
{
157+
if (args[i].front() == '$')
158+
args[i] = constList.get("DestinyScript", args[i].substr(1));
159+
auto [intArg] = DynRpg::ParseArgs<int>(func, args.subspan(i), &okay);
160+
161+
if (indentArgIndex == i) {
162+
// Output::Debug("idt ----> {}", args[i]);
163+
indentArgIndex = -1;
164+
cmd.indent = intArg;
165+
}
166+
else
167+
// Output::Debug("pls ----> {}", args[i]),
168+
outputArgs.push_back(intArg);
169+
}
170+
}
133171
if (endOfLine) {
134-
codeArgIndex = i + 1;
135-
stringArgIndex = i + 2;
172+
// Output::Debug("com ----> {}\n\n", cmd.code);
136173
cmd.parameters = lcf::DBArray<int32_t>(outputArgs.begin(), outputArgs.end());
137174
cmdList.push_back(cmd);
175+
outputArgs.clear();
176+
177+
cmd = _cmd;
178+
179+
codeArgIndex = i + 1;
180+
stringArgIndex = i + 2;
181+
182+
endOfLine = false;
138183
}
139184

140185
if (!okay) return true;

src/game_dynrpg.cpp

+38-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,44 @@ std::string DynRpg::ParseCommand(std::string command, std::vector<std::string>&
314314
token.str("");
315315
break;
316316
}
317-
} else {
317+
}
318+
else if (chr == ';') {
319+
switch (mode) {
320+
case ParseMode_Function:
321+
// End of function token
322+
function_name = Utils::LowerCase(token.str());
323+
if (function_name.empty()) {
324+
// empty function name
325+
Output::Warning("Empty DynRPG function name");
326+
return {};
327+
}
328+
token.str("");
329+
// Empty arg
330+
args.emplace_back("");
331+
mode = ParseMode_WaitForArg;
332+
break;
333+
case ParseMode_WaitForComma:
334+
mode = ParseMode_WaitForArg;
335+
break;
336+
case ParseMode_WaitForArg:
337+
338+
// Empty arg
339+
args.emplace_back("");
340+
break;
341+
case ParseMode_String:
342+
token << chr;
343+
break;
344+
case ParseMode_Token:
345+
tmp = ParseToken(token.str(), function_name);
346+
args.emplace_back(tmp);
347+
if (function_name == "easyrpg_raw") args.emplace_back(";");
348+
// already on a comma
349+
mode = ParseMode_WaitForArg;
350+
token.str("");
351+
break;
352+
}
353+
}
354+
else {
318355
// Anything else that isn't special purpose
319356
switch (mode) {
320357
case ParseMode_Function:

0 commit comments

Comments
 (0)