Add experimental string transpilation with interpolation
This commit is contained in:
parent
871ebabb11
commit
2dba7fbda6
|
@ -57,7 +57,7 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
|
|||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_GNU})
|
||||
message(FATAL_ERROR "G++ ${MINIMAL_GNU} or higher is required.")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts -s")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -foptimize-strlen -fsched-pressure -flive-range-shrinkage -fpredictive-commoning -ftree-partial-pre -fira-loop-pressure -ftree-loop-distribution -floop-interchange -fsplit-paths -fgcse-las -fgcse-sm -fipa-pta -fstdarg-opt -fivopts -s")
|
||||
set(CMAKE_CXX_FLAGS "-fno-use-linker-plugin -fwhole-program ${CMAKE_CXX_FLAGS}")
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${MINIMAL_CLANG})
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<img align="left" src="/Username404-59/Yerbacon/raw/branch/stable/resources/Yerbacon.png" alt="Yerbacon logo" width="192" height="192">
|
||||
Aka Yer Bacon,
|
||||
|
||||
- #### A language that transpiles into lua, javascript or python code.
|
||||
- #### A language that transpiles into lua, javascript (ES6) or python code.
|
||||
```
|
||||
main #=> {
|
||||
println "Hello, World!"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "../parsing/ParseComponents.hpp"
|
||||
|
||||
|
@ -14,7 +15,49 @@ class Target {
|
|||
protected:
|
||||
std::stringstream output;
|
||||
INCLUDECOMPONENT(StandardComponents::Define);
|
||||
INCLUDECOMPONENT(StandardComponents::types::String)
|
||||
INCLUDECOMPONENT(StandardComponents::types::String);
|
||||
void stringInterpolation(string view, const char* openMultiline = "", const char* closeMultiline = "", const char* concatenationCharacters = "+") {
|
||||
vector<size_t> interpolationVector;
|
||||
const string interpolationString = "${";
|
||||
unsigned long occurence_position = view.find(interpolationString);
|
||||
while (occurence_position != string::npos) {
|
||||
interpolationVector.push_back(occurence_position);
|
||||
occurence_position = view.find(interpolationString, occurence_position + interpolationString.size());
|
||||
}
|
||||
const bool noMultiline = not (strcmp(openMultiline, "") != 0 && strcmp(closeMultiline, openMultiline) != 0);
|
||||
const bool multiline = view.find('\n') != string::npos && not noMultiline;
|
||||
if (noMultiline) {
|
||||
unsigned long newLine = view.find('\n');
|
||||
while (newLine != string::npos) {
|
||||
view.erase(newLine, 1);
|
||||
view.insert(newLine, "\\n");
|
||||
newLine = view.find('\n', newLine);
|
||||
}
|
||||
}
|
||||
const char* const openCharacters = multiline ? openMultiline : "\"";
|
||||
decltype(openCharacters) closeCharacters = multiline ? closeMultiline : openCharacters;
|
||||
if (not interpolationVector.empty()) {
|
||||
unsigned long closingBrace = 0;
|
||||
for (unsigned long i = 0; i < interpolationVector.size(); ++i) {
|
||||
const auto& occurence = interpolationVector[i];
|
||||
const bool hasNext = (i + 1) < interpolationVector.size();
|
||||
const bool oldClosingBraceIsFar = closingBrace >= occurence;
|
||||
if (i > 0) output << concatenationCharacters;
|
||||
output << openCharacters << view.substr(closingBrace + (i > 0), (occurence - closingBrace) - (i > 0));
|
||||
closingBrace = view.find_first_of('}', occurence);
|
||||
const bool closingBraceIsNPOS = closingBrace == string::npos;
|
||||
const bool wrongClosingBrace = !closingBraceIsNPOS && ((hasNext && closingBrace > interpolationVector[i + 1]));
|
||||
if (closingBraceIsNPOS || wrongClosingBrace) {
|
||||
output << view.substr(occurence - 1, (hasNext ? interpolationVector[i + 1] - (occurence - 1) : 0));
|
||||
}
|
||||
output << closeCharacters;
|
||||
if (not closingBraceIsNPOS && not wrongClosingBrace) {
|
||||
output << concatenationCharacters;
|
||||
output << view.substr(occurence + interpolationString.size(), (closingBrace - occurence) - interpolationString.size());
|
||||
}
|
||||
}
|
||||
} else output << openCharacters << view << closeCharacters << '\n';
|
||||
}
|
||||
INCLUDECOMPONENT(StandardComponents::Reference);
|
||||
INCLUDECOMPONENT(StandardComponents::Class);
|
||||
public:
|
||||
|
|
|
@ -5,6 +5,9 @@ struct JsTarget: Target {
|
|||
void on(const StandardComponents::Define &parseComponent) override {
|
||||
output << (parseComponent.final ? "const " : "let ") << parseComponent.name << " = ";
|
||||
}
|
||||
void on(const StandardComponents::types::String &parseComponent) override {
|
||||
stringInterpolation(parseComponent.content);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,30 +9,7 @@ struct LuaTarget: Target {
|
|||
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';
|
||||
stringInterpolation(parseComponent.content, "[[", "]]", "..");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ struct PyTarget: Target {
|
|||
void on(const StandardComponents::Define &parseComponent) override {
|
||||
output << parseComponent.name << " = ";
|
||||
}
|
||||
void on(const StandardComponents::types::String &parseComponent) override {
|
||||
stringInterpolation(parseComponent.content, "\"\"\"", "\"\"\"");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue