diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8899969..5bf32ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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})
diff --git a/README.md b/README.md
index 1a0772a..5dfe333 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
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!"
diff --git a/src/headers/transpiler/Target.hpp b/src/headers/transpiler/Target.hpp
index 39a753a..138ecc2 100644
--- a/src/headers/transpiler/Target.hpp
+++ b/src/headers/transpiler/Target.hpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#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 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:
diff --git a/src/headers/transpiler/implementations/Js.hpp b/src/headers/transpiler/implementations/Js.hpp
index f850a20..4ad2054 100644
--- a/src/headers/transpiler/implementations/Js.hpp
+++ b/src/headers/transpiler/implementations/Js.hpp
@@ -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
\ No newline at end of file
diff --git a/src/headers/transpiler/implementations/Lua.hpp b/src/headers/transpiler/implementations/Lua.hpp
index dba5e4b..66d68cd 100644
--- a/src/headers/transpiler/implementations/Lua.hpp
+++ b/src/headers/transpiler/implementations/Lua.hpp
@@ -9,30 +9,7 @@ struct LuaTarget: Target {
output << " = ";
}
void on(const StandardComponents::types::String &parseComponent) override {
- const string_view view (parseComponent.content);
- vector 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, "[[", "]]", "..");
}
};
diff --git a/src/headers/transpiler/implementations/Py.hpp b/src/headers/transpiler/implementations/Py.hpp
index 5e81c71..2bbdb4c 100644
--- a/src/headers/transpiler/implementations/Py.hpp
+++ b/src/headers/transpiler/implementations/Py.hpp
@@ -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
\ No newline at end of file