Add transpilation of strings to lua-compatible ones, and fix a comment

This commit is contained in:
Username404-59 2021-08-24 17:23:31 +02:00
parent 5d4be1039d
commit 1992e1d42b
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
4 changed files with 60 additions and 37 deletions

View File

@ -20,7 +20,6 @@ struct ParseComponent {
}; };
namespace StandardComponents { namespace StandardComponents {
struct [[deprecated]] Expression: ParseComponent {};
struct NamedIdentifier: public ParseComponent { struct NamedIdentifier: public ParseComponent {
const string name; const string name;
explicit NamedIdentifier(string_view nameText): name(nameText) {} explicit NamedIdentifier(string_view nameText): name(nameText) {}
@ -41,7 +40,7 @@ namespace StandardComponents {
}; };
namespace types { namespace types {
struct String: ParseComponent { struct String: ParseComponent {
const char* content; const string content;
explicit String(const char* string): content(string) {} explicit String(const char* string): content(string) {}
}; };
} }

View File

@ -15,46 +15,44 @@ namespace Parser {
ParseTree parseTree; ParseTree parseTree;
using namespace StandardComponents; using namespace StandardComponents;
using enum tok::type; using enum tok::type;
if (lexed.size() > 1) { unsigned int i = 0;
unsigned int i = 0; const auto nextAre = [&i, &lexed](convertible_to<unsigned int> auto nextValues,...) {
const auto nextAre = [&i, &lexed](convertible_to<unsigned int> auto nextValues,...) { va_list argumentsList;
va_list argumentsList; va_start(argumentsList, nextValues);
va_start(argumentsList, nextValues); for (decltype(nextValues) j = 1; j <= nextValues; ++j) {
for (decltype(nextValues) j = 1; j <= nextValues; ++j) { if (!cmp_greater(lexed.size() - i, nextValues) || lexed[i + j].toktype != va_arg(argumentsList, decltype(nextValues))) {
if (!cmp_greater(lexed.size() - i, nextValues) || lexed[i + j].toktype != va_arg(argumentsList, decltype(nextValues))) { va_end(argumentsList);
va_end(argumentsList); return false;
return false;
}
} }
va_end(argumentsList); }
return true; va_end(argumentsList);
}; return true;
for (;i < lexed.size() - 1; ++i) { };
const auto& current = lexed[i], next = lexed[i + 1]; for (;i < lexed.size(); ++i) {
const tok& current = lexed[i], next = (i != lexed.size() - 1) ? lexed[i + 1] : tok(UNEXPECTED, string(), current.line);
switch (current.toktype) { switch (current.toktype) {
case STRING: parseTree << types::String(current.toktext.data()); break; case STRING: parseTree << types::String(current.toktext.data()); break;
case IDENTIFIER: { case IDENTIFIER: {
if (current.toktext == "class") { if (current.toktext == "class") {
if (next.toktype == IDENTIFIER) { if (next.toktype == IDENTIFIER) {
parseTree << Class(next.toktext); ++i; parseTree << Class(next.toktext); ++i;
} else throw ParsingException('"' + next.toktext + "\" is not a valid class identifier"); } else throw ParsingException('"' + next.toktext + "\" is not a valid class identifier");
} else { } else {
if ((lexed.size() - i) > 2) { if ((lexed.size() - i) > 2) {
bool isFinalDefine = nextAre(2, TAG, DEFINE); bool isFinalDefine = nextAre(2, TAG, DEFINE);
if (isFinalDefine || next.toktype == DEFINE) { if (isFinalDefine || next.toktype == DEFINE) {
parseTree << Define(isFinalDefine, current.toktext); parseTree << Define(isFinalDefine, current.toktext);
i += isFinalDefine ? 2 : 1; i += isFinalDefine ? 2 : 1;
} else { } else {
parseTree << Reference(current.toktext); parseTree << Reference(current.toktext);
}
} }
} }
} }
default: break;
} }
default: break;
} }
} else throw ParsingException("At least 2 tokens must be provided"); }
return parseTree; return parseTree;
} }
} }

View File

@ -5,9 +5,35 @@ struct LuaTarget: Target {
void on(const StandardComponents::Define &parseComponent) override { void on(const StandardComponents::Define &parseComponent) override {
if (parseComponent.final) output << "local "; if (parseComponent.final) output << "local ";
output << parseComponent.name; output << parseComponent.name;
if (parseComponent.final) output << " <const>"; // TODO Find an alternative to <const> for lua >5.4 if (parseComponent.final) output << " <const>"; // TODO Find an alternative to <const> for lua <5.4
output << " = "; output << " = ";
} }
void on(const StandardComponents::types::String &parseComponent) override {
const string_view view (parseComponent.content);
vector<size_t> interpolationVector;
const string interpolationString = "${";
unsigned long occurence_position = view.find(interpolationString);
while (occurence_position != string_view::npos) {
interpolationVector.push_back(occurence_position);
occurence_position = view.find(interpolationString, occurence_position + interpolationString.size());
}
const bool multiline = view.find('\n') != string_view::npos;
const char* openCharacters = multiline ? "[[" : "\"";
decltype(openCharacters) closeCharacters = multiline ? "]]" : "\"";
if (not interpolationVector.empty()) {
unsigned long closingBrace = 0;
for (unsigned long i = 0; cmp_less(i, interpolationVector.size()); ++i) {
const auto& occurence = interpolationVector[i];
if (i > 0) output << "..";
output << openCharacters << view.substr((i > 0) ? closingBrace + 1 : 0, occurence - (closingBrace + 1)) << closeCharacters;
closingBrace = view.find_first_of('}', occurence);
if (closingBrace == string_view::npos) {
throw Yerbacon::Exception("Closing brace missing in a string");
}
output << ".." << view.substr(occurence + interpolationString.size(), (closingBrace - occurence) - interpolationString.size());
}
} else output << openCharacters << view << closeCharacters << '\n';
}
}; };
#endif #endif

View File

@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg); else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg);
} }
const auto compile = [&target](string_view name) { const auto compile = [&target](string_view name) {
const string transpiledString = transpile(parseString(getFileContent(name.data())), target); string transpiledString = transpile(parseString(getFileContent(name.data())), target);
name.remove_suffix(6); name.remove_suffix(6);
string outputFile; string outputFile;
(outputFile = name).append(target); (outputFile = name).append(target);