cplusplus2x.Examples/C++20/scanner/ETL/export.cpp
Source: cplusplus2x.Examples/C++20/scanner/ETL/export.cpp
#define VERSION_INFO "1.0"
#include "ir.hpp"
#include "ir_opt.hpp"
#include "parser.hpp"
#include <emscripten.h>
#include <emscripten/bind.h>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>
extern void outputDebugInfo(std::ostream &file, symbol::SymbolTable &table, const ir::IRCode &code);
std::string test_parse(const std::string &data) {
std::ostringstream stream;
scan::TString p(data);
std::ostringstream code;
bool in_string = false;
bool escaped = false;
while (1) {
auto c = p.getch();
if (c.has_value()) {
if (escaped) {
code << *c;
escaped = false;
} else if (*c == '\\') {
escaped = true;
code << *c;
} else if (*c == '"') {
in_string = !in_string;
code << *c;
} else if (*c == '#' && !in_string) {
do {
c = p.getch();
} while (c.has_value() && *c != '\n');
} else {
code << *c;
}
} else
break;
}
try {
if (data.length() > 0) {
parse::Parser parser(new scan::Scanner(scan::TString(code.str())));
if (parser.parse()) {
auto rootAST = parser.getAST();
if (rootAST) {
parse::IRGenerator irGen;
auto irContext = irGen.generateIR(rootAST);
ir::IROptimizer opt;
irContext.instructions = std::move(opt.optimize(irContext.instructions));
outputDebugInfo(stream, irContext.table, irContext.instructions);
return stream.str();
}
} else {
stream << "<b>ETL: Parsing failed...</b>\n";
return stream.str();
}
} else {
stream << "<b>ETL: Zero bytes to read..</b>\n";
return stream.str();
}
} catch (ir::IRException &e) {
stream << "<b>ETL: IR Exception: " << e.why() << "</b>\n";
return stream.str();
} catch (parse::ParseException &e) {
stream << "<b>ETL: Parse Exception: " << e.why() << "</b>\n";
return stream.str();
} catch (...) {
stream << "<b>ETL: Unknown Exception</b>\n";
return stream.str();
}
return stream.str();
}
class ETL_Export {
public:
ETL_Export() {
}
std::string scan(std::string input_line) {
return test_parse(input_line);
}
};
using namespace emscripten;
EMSCRIPTEN_BINDINGS(my_ETL) {
class_<ETL_Export>("ETL")
.constructor()
.function("scan", &ETL_Export::scan);
}