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

View File

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

View File

@ -5,9 +5,35 @@ struct LuaTarget: Target {
void on(const StandardComponents::Define &parseComponent) override {
if (parseComponent.final) output << "local ";
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 << " = ";
}
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

View File

@ -31,7 +31,7 @@ int main(int argc, char* argv[]) {
else if (currentArg.ends_with(".ybcon")) files.push_back(currentArg);
}
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);
string outputFile;
(outputFile = name).append(target);