#!/usr/bin/env node function m() { main_func = ""; decl = "const"; all_code = ""; VERBOSE_DEBUG = this.global && process.env["DEBUG"] == "true"; function get_all_declarations() { return ((this.global && process.env["DECLS"]) || "").split(/,,/); } g = 0; const javascript = process["mode"] === "js"; const cpp = process["mode"] === "cpp"; javascript || cpp || alert("Error, no mode selected"); if (cpp) { decl = "const"; decl_int = "size_t"; array_decl = "Array_sub "; precode = ` #define function static inline void* #define var auto #define let auto #define const const auto `; } else { array_decl = decl = decl_int = ""; precode = ` function set_globals() { nesting=0;VERBOSE_DEBUG=${VERBOSE_DEBUG};function puts() { eval("return con" + "sole" + ".warn"); } } ; set_globals(); `; } /* if (javascript)*/ if (cpp) { len = "array.size()"; } else { len = "array.length"; } const m = (func, array, cond, one, i = [0, len]) => { func = func.split(".").join("_"); c = ""; if (cpp) { c += `#ifndef ${func}_macro #define ${func}_macro #undef ${func} #undef ${func}_otherwise #ifndef nop_func_macro #define nop_func_macro static double* nop_func(...) { return nullptr; } #endif #define ${func}_otherwise nop_func`; } var new_one = []; one = one.split(/\s*;\s*/); for (const i of one) { if (i.length) { new_one.push(i + ";"); } } one = new_one; c += precode + `function ${func}(${array_decl} array, ${decl_int} i) {`; c += `${cpp ? "double * " : "var"} rvalue`; // }}`; c += ` ${ this.global && get_all_declarations().map((i) => { if (!i.trim()) return ""; return "/* DECL */ const " + i; }) } ${VERBOSE_DEBUG ? ++nesting : ""}; const max = ${i[1]}; while (i < max) { BasicObject element = array[i]; `; if (javascript) { c += `const style = element.style`; } c += ` ${ VERBOSE_DEBUG ? 'puts(" ".repeat((nesting - 1) * 4) + `....Iteration ${i} i=` + [i, "/", max, " (", Math.round(i/max*100, 2), "%", ") +", 1.0/max*100, "%", " of loop completed"].join(""))' : "" } const condition = ${cond}; if (condition) { using namespace std; ${one.slice(0, one.length - 1).join("\n\t\t\t\t")} //{one.slice(one.length - 1) rvalue = ${ cpp ? "*(double**)(size_t)(size_t*)&(" : "" }${(last = one[one.length - 1]).substr( 0, last.length - 1 )}${cpp ? ")" : ""}; } else {`; if (javascript) { c += "try { "; } c += ` rvalue = ${func}_otherwise(${cpp ? "&(" : "["}element${ cpp ? ")" : "]" }, 0); `; if (javascript) c += ` } catch (e) {}`; c; c += ` } ++i; } `; if (VERBOSE_DEBUG && javascript) c += ` puts("Loop comp"); --nesting;`; c += ` return rvalue; } `; if (cpp) { c += `#endif` + "\n"; } { } function remove_sides(a, first, last) { if (a.startsWith(first)) a = a.slice(first.length, a.length); if (a.endsWith(last)) { a = a.slice(0, a.length - last.length); } return a; } /* String.prototype.gsub = function*/ if (!func.endsWith("otherwise")) { d = main_func; if (cpp) { try { array = mod(JSON.parse(array)); } catch (e) { console.warn(e); process.exit(); } d += "return \n"; d += `${func}(\n${array},\n${i[0]}\n);`; } main_func = d; } function to_s(e) { return e; } }; args = ""; try { args = process.argv.slice(2).join(",,"); } catch (_) { args = [...arguments].join(",,"); } if (!args) { puts("Added m function and env function"); return; } args = args.split(",,"); for (var i = 0; i < args.length; ) { s = args.slice(i, i + 4); if (s[0].match(/otherwise$/)) { s = [s[0], [true], true, s[1]]; i += 2; } else { i += 4; } m(...s); foo(s[0], c); all_code += c; } all_code += ` function ${(prog_name = "e" + Date.now())}_main() { ${main_func} }`; if (cpp) all_code = cpp_pre_code() + all_code + `\n\n\nint main(int argc, char ** argv , char ** envp) { main_( argc, argv, envp); }`; else all_code += "\n" + prog_name + "_main();"; foo("all_code", all_code); if (javascript) { try { eval(all_code); } catch (e) { console.warn(e); } } function foo(func, code) { const out = `${func}.${process.mode}`; try { require("fs").writeFileSync(out, code); } catch (_) { console.log(_); var saveData = (function () { var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; return function (data, fileName) { var json = data, blob = new Blob([json], { type: "octet/stream" }), url = window.URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); }; })(); saveData(code, out); } } return true; } env("mode", "js", 1) && m() && env("mode", "cpp", 1) && m(); function env(a, b, mode) { var n = this.global || window; n.process = n.process || { env: { DEBUG: "true", DECLS: "" } }; if (!mode) { process.env.DECLS += `${a}=${b},,`; } else { process[a] = b; } return true; } function help() { console.table(`m() (Browser console and node) -> generates a list of all arguments (or strings separted by double commas) Functions are run sequentially. Otherwise functions are not run. All functions loop over something All functions have a conditional. func_name iterable (such as a list or a DOMElement) condition expression The resultant function returns the last expression in the function This isn't a DSL, it's extremely broad. Any algorithm can be expressed this way. This makes writing algorithms much, much easier. It works in Node.js and in the browser. After generating all functions, the resultant code gets downloaded. `); } //functin cpp function cpp_code() { return (cpp_code = ` #include #include #include #include #include #include //namespace { enum { INT, DOUBLE, STRING, VECTOR, MAP, NEEDS_FREEING, NEEDS_DELETING, NEEDS_DELETING_ARRAY }; class BasicObject { public: operator const std::string() const; const BasicObject& print() const; bool operator < (BasicObject a) const { return (const std::string)(*this) < (const std::string)(a); }; public: double type; double value; }; class Object_That_Destructs : public BasicObject { public: ~Object_That_Destructs() { union A { char* c; double d; }; A a; a.d =value; switch ((size_t)type) { case NEEDS_FREEING: // std::cout << "Freeing " << (std::string)(*this) << "\\n"; free(a.c); break; case NEEDS_DELETING_ARRAY: delete a.c; break; case NEEDS_DELETING: delete [] a.c; break; } }; }; typedef Object_That_Destructs Object; template class Array_sub : public std::vector { public: Array_sub(std::initializer_list a) : std::vector{a} {} inline void push(const BasicObject value) { std::vector::emplace_back( *(A*)(&value) ); } inline Array_sub& operator<< (BasicObject v) { push(v); return *this; } inline Array_sub& operator<< (Object v) { push(v); return *this; } inline const auto surround(const char* first, const char* second) const { Array_sub b{}; //std::cout << "Start of loops\\n"; for (size_t i = 0; i < this->size(); ++i) { std::string s{first}; s+= (std::string)((*this)[i]); s += second; b.emplace_back(construct_needs_freeing(strdup(s.c_str()))); // std::cout << "Loop number " << i << std::endl; } // std::cout << "End of loops\\n"; return b; } inline auto js() { return surround(""); } inline const auto construct_needs_freeing(const char* const a) const { union { const char* c; double d; } u; u.c = a; return *new BasicObject{NEEDS_FREEING, u.d}; } operator const std::string() const { return to_s(); } inline auto append(const char* arg1) const { return surround(nullptr, arg1); } inline auto prepend(const char* arg1) const { return surround(nullptr, arg1); } inline auto quote() const { return surround("'", "'"); } inline auto join(const char* delim) const { std::string result; const auto length=this->size(); for (size_t i = 0; i < length; ++i) { result += (*this)[i]; if (i==length-1) { } else { result += delim; } } return result; } inline auto html(const char* title) const { std::string site_content; site_content += "Content-type: text/html\\r\\n\\r\\n"; site_content += title; site_content += ""; site_content += ""; //this->surround("

", "

"); site_content += this->surround("

", "

"); site_content += ""; return site_content; } inline auto p() const { return surround("

", "

"); } inline auto div() const { return surround("
", "
"); } inline auto nls() const { return surround(nullptr, "\\n"); } const std::string to_s() const { std::ostringstream str; str << '['; for (size_t i = 0; i < this->size(); ++i) { str << (std::string)((*this)[i]); if (i == this->size() - 1) { } else { str << ", "; } } str << ']'; return str.str(); } }; //typedef Array_sub Array; union Object_v { double d; const void* v; long long int long_long; const std::map* map; //const char* string; const Array_sub* array; /*/const ch const cha*/ const char* string; }; BasicObject::operator const std::string() const { Object_v val_; val_.d = this->value; switch ((size_t)this->type) { case STRING: return val_.string; case NEEDS_DELETING: return "[needs_deleting]"; case NEEDS_FREEING:return val_.string; // return std::string(val_.string) + "; case NEEDS_DELETING_ARRAY: return "[needs_deleting_array]"; case INT: return std::to_string((long long int)val_.long_long ); case DOUBLE: return std::to_string(val_.d); case VECTOR: return val_.array->to_s(); case MAP: std::string map_str = "{"; // std::mapmap; for (const auto& i : *val_.map) { map_str += (std::string)(i.first); map_str += ": "; map_str += (std::string)(i.second); map_str += ", "; } // map_str[map_str.size() = if (map_str.size () ) { map_str[map_str.size() - 2] = '}'; map_str.resize(map_str.size() - 1); } // std::cout << map_str; return map_str; } return "Error string"; }; const BasicObject& BasicObject::print() const { std::cout << (std::string)(*this) << "
"; return *this; } auto construct(const long long int a) { union Object_v un; un.long_long = a; return BasicObject {0, un.d};} auto construct(const std::map && a) {Object_v un; un.map = &a; return BasicObject{4, un.d}; } auto construct(Array_sub && a ) {Object_v q; q.array = &a; return BasicObject{3, q.d}; } auto operator ""_c(unsigned long long a) { return construct(a); } auto construct(const double a) { return BasicObject{1, a}; } auto construct(const char* a) { union { double d; const void* v; } b; b.v = a; return BasicObject{2, b.d}; } ` + additional_cpp_code()); //moremore+more_cpp_code(); } function nums(a) { if (typeof a != "number") return mod(a); //while (1) console.log(a) if (a.toString().includes(".")) { return surround(a); } else { return surround(a + "ll"); } } function cpp_pre_code() { return cpp_code(); } function set_kv(kv) { for (var i_ of [0, 1]) kv[i_] = nums(kv[i_]); //} //} } function surround(a) { return "construct(" + a + ")"; } function mod(array, a = 0) { if (typeof array == "string") { return surround(JSON.stringify(array)); } a = a + 1; if (a == 1) { var str = " Array_sub {"; } else var str = ""; var element = false; try { // let str = ""; if (typeof array == "object" && array.length === undefined) { str = "construct(" + "\n" + "\t".repeat(a) + " std::map< BasicObject, BasicObject >{"; // var element var a = 0; console.log(array); // fs.writeFileSync("args/" + const s = JSON.stringify; for (var i in array) { var kv = [i, array[i]]; element = true; set_kv(kv); const t = " BasicObject "; const pair = "std::pair<" + t + "," + t + ">"; str += pair + "(" + kv.join(",") + ")"; str += ", "; } str = str.replace(/, $/, "}" + ") , /* end of map */"); //"; } else if (array.length === undefined) { array = ["", array]; set_kv(array); return array[1]; } else for (var i of array) { // if (a == if (typeof i != "number") { if (typeof i == "object" && i.join === undefined) { str += mod(i, a); } else if (typeof i == "string") { const SEPARATOR = ","; str += "construct(" + JSON.stringify(i) + ") /* string literal */" + SEPARATOR; } else { str += "\t".repeat(a) + "construct(" + "Array_sub" + "{" + "\n" + "\t".repeat(a) + mod(i, a) + "\t".repeat(a - 1) + "}" + ")" + ",\n"; } } else { const value = ["", i]; set_kv(value); str += value[1] + ", "; } } if (a == 1) str += "}"; //str = str.slice(0, s return str.replace(/, $/, ""); } catch (e) { console.warn(e); process.exit(1); } } //#include function additional_cpp_code() { return ` #include \"fcgio.h\" using namespace std; #define endl "
" static inline void* ${prog_name}_main (); static int mmain(); int main_ ( int argc, char** argv, char** envp) { (void)envp; Array_sub args{}; for (int i = 0; i < argc; ++i) args << construct(argv[i]); //auto content = (string)args.html("Title"); //cout << c auto content=std::string{}; //cout << Array_sub{(Object)construct(1ll)}.html("Hello"); //cout << content; const auto server=0; if (server) { // Backup the stdio streambufs streambuf * cin_streambuf = cin.rdbuf(); streambuf * cout_streambuf = cout.rdbuf(); streambuf * cerr_streambuf = cerr.rdbuf(); FCGX_Request request; FCGX_Init(); /* * * * * The above function seems to memory leak 1 block of 768 bytes. It never deletes it at exit. * * * */ FCGX_InitRequest(&request, 0, 0); while (FCGX_Accept_r(&request) == 0) { fcgi_streambuf cin_fcgi_streambuf(request.in); fcgi_streambuf cout_fcgi_streambuf(request.out); fcgi_streambuf cerr_fcgi_streambuf(request.err); cin.rdbuf(&cin_fcgi_streambuf); cout.rdbuf(&cout_fcgi_streambuf); cerr.rdbuf(&cerr_fcgi_streambuf); cout << content; // system(\"echo 5 > /root/six\"); mmain(); cout << "Where?"; // system(\"echo 6\"); // Note: the fcgi_streambuf destructor will auto flush } // restore stdio streambufs cin.rdbuf(cin_streambuf); cout.rdbuf(cout_streambuf); cerr.rdbuf(cerr_streambuf); } ${prog_name}_main(); return 0; } static int mmain() { std::string command(\"ls * 2>&1\"); char buffer[4096]; std::string result; // std::cout << "Opening reading pipe" FILE* pipe = popen(command.c_str(), \"r\"); if (!pipe) { std::cerr << \"Couldn't start command.\" << endl; return 0; } while (fgets(buffer, sizeof(buffer), pipe) != NULL) { //std::cout << \"Reading...\" << std::endl; result += buffer; } auto returnCode = pclose(pipe); std::cout << result << endl; std::cout << returnCode << endl; // ${prog_name}_main(); ${prog_name}_main (); return 0; } `; }