← index
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);
}