94 lines
4.6 KiB
C++
94 lines
4.6 KiB
C++
#include <iostream>
|
|
#include <map>
|
|
#include "headers/Yerbacon.hpp"
|
|
#include <future>
|
|
#include <filesystem>
|
|
using namespace std;
|
|
|
|
#include "headers/misc.hpp"
|
|
#include "headers/arguments.hpp"
|
|
#include "headers/transpiler/Target.hpp"
|
|
|
|
int main(int argc, char* argv[]) {
|
|
setlocale(LC_ALL, "");
|
|
string target = "lua";
|
|
bool printResult = false,
|
|
parallel = false,
|
|
newLines = true,
|
|
text_provided = false;
|
|
using unit_result = pair<string, optional<Yerbacon::Exception>>;
|
|
using unit = future<unit_result>;
|
|
map<string_view, unit> Units;
|
|
for (signed int i = 1; i < argc; ++i)
|
|
{
|
|
const string_view currentArgument (argv[i]);
|
|
if (currentArgument == ArgumentShort("printresult")) printResult = true;
|
|
else if (currentArgument == ArgumentAssignable("target")) {
|
|
const string_view value = ArgumentAssignable::getValueFor(currentArgument);
|
|
if (not value.empty()) target = value;
|
|
else Yerbacon::fail("No target was provided.");
|
|
}
|
|
else if (currentArgument == Argument("parallel")) parallel = true;
|
|
else if (currentArgument == ArgumentAssignable("newlines")) {
|
|
const string_view enabled = ArgumentAssignable::getValueFor(currentArgument);
|
|
if (enabled == "off") {
|
|
newLines = false;
|
|
} else if (enabled == "on") {
|
|
newLines = true;
|
|
} else goto invalid_argument;
|
|
}
|
|
else if (currentArgument == ArgumentShort("text")) { text_provided = true; printResult = true; }
|
|
else if (text_provided || currentArgument.ends_with(".ybcon"))
|
|
Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [currentArgument, &text_provided, &target, &newLines]() {
|
|
unit_result resultingPair;
|
|
try {
|
|
resultingPair.first = Target::forName(target, newLines)->transpileWithTree(
|
|
parseString(text_provided ? currentArgument : getFileContent(currentArgument.data()))
|
|
);
|
|
if (not text_provided) outputFileContent(string(currentArgument.substr(0, currentArgument.size() - 6)) + '.' + target, resultingPair.first);
|
|
} catch (const Yerbacon::Exception& error) {
|
|
size_t lastSlash = 0;
|
|
const size_t position1 = currentArgument.find_last_of('/');
|
|
if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1;
|
|
if constexpr(filesystem::path::preferred_separator != '/') {
|
|
const size_t position2 = currentArgument.find_last_of(filesystem::path::preferred_separator);
|
|
if (cmp_not_equal(position2, string_view::npos)) {
|
|
lastSlash = max(lastSlash, position2);
|
|
}
|
|
}
|
|
resultingPair.first = currentArgument.substr(lastSlash + 1);
|
|
resultingPair.second.emplace(error);
|
|
}
|
|
return resultingPair;
|
|
}));
|
|
else {
|
|
if (argc == 2) {
|
|
if (currentArgument == Argument("version")) {
|
|
cout << Yerbacon::getVersion();
|
|
} else if (currentArgument == Argument("buildInfo")) {
|
|
cout << Yerbacon::getBuildInfo();
|
|
} else goto invalid_argument;
|
|
cout << '\n'; exit(EXIT_SUCCESS);
|
|
} else invalid_argument: Yerbacon::fail({"\"", currentArgument.data(), "\" is not a valid argument."});
|
|
}
|
|
}
|
|
if (!Units.empty()) {
|
|
if (printResult) cout << "~~~~[Yerbacon compilation result]~~~~\n\n";
|
|
for (auto entry_iterator = Units.rbegin(); entry_iterator != Units.rend(); ++entry_iterator) {
|
|
const pair result = entry_iterator->second.get();
|
|
const bool is_exception = result.second.has_value();
|
|
if (not is_exception) {
|
|
if (printResult && !(result.first.empty() || all_of(result.first.begin(), result.first.end(), [](const char& character){
|
|
return isspace(character);
|
|
}))) {
|
|
cout << result.first << '\n';
|
|
}
|
|
} else {
|
|
cout << "Compilation"; if (not text_provided) cout << " of " << result.first; cout << " has failed with the following error:" << endl;
|
|
cerr << result.second.value().what() << '\n';
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
} else cout << (!text_provided ? "No valid file provided" : "No text was provided") << ".\n";
|
|
return EXIT_SUCCESS;
|
|
} |