Add transpilation of strings to lua-compatible ones, and fix a comment
This commit is contained in:
parent
5d4be1039d
commit
1992e1d42b
@ -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) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user