UNPKG

@nat-lang/nat

Version:
145 lines (144 loc) 7.46 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } }; import { v4 } from 'uuid'; import initialize from "../lib/nat"; export const GEN_START = "__start_generation__"; const GEN_END = "__stop_generation__"; export const CORE_DIR = "core", SRC_DIR = "src"; export const abs = (path) => `/${SRC_DIR}/${path}`; export var InterpretationStatus; (function (InterpretationStatus) { InterpretationStatus[InterpretationStatus["OK"] = 0] = "OK"; InterpretationStatus[InterpretationStatus["COMPILATION_ERROR"] = 1] = "COMPILATION_ERROR"; InterpretationStatus[InterpretationStatus["RUNTIME_ERROR"] = 2] = "RUNTIME_ERROR"; })(InterpretationStatus || (InterpretationStatus = {})); class Runtime { constructor() { this.handleStdOut = (stdout) => Object.values(this.stdOutHandlers).forEach(handler => handler(stdout)); this.handleStdErr = (stderr) => Object.values(this.stdOutHandlers).forEach(handler => handler(stderr)); this.storeErr = (err) => this.errors.push(err); this.onStdout = (handler) => { let uid = v4(); this.stdOutHandlers[uid] = handler; return () => { delete this.stdOutHandlers[uid]; }; }; this.onStderr = (handler) => { let uid = v4(); this.stdErrHandlers[uid] = handler; return () => { delete this.stdErrHandlers[uid]; }; }; this.loadWasmModule = () => __awaiter(this, void 0, void 0, function* () { if (!this.wasmModule) this.wasmModule = yield initialize({ print: this.handleStdOut.bind(this), printErr: this.handleStdErr.bind(this) }); return this.wasmModule; }); this.readStrMem = (ptr) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); const buf = new Uint8Array(mod.wasmMemory.buffer); let str = ""; while (buf[ptr] !== 0) str += String.fromCharCode(buf[ptr++]); return str; }); this.interpret = (path) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); const fn = mod.cwrap('vmInterpretEntrypoint_wasm', 'number', ['string']); const retPtr = fn(path); const out = yield this.readStrMem(retPtr); return JSON.parse(out); }); this.free = () => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); const free = mod.cwrap('vmFree_wasm', null, []); free(); }); this.getCoreFiles = (...args_1) => __awaiter(this, [...args_1], void 0, function* (dir = CORE_DIR) { const mod = yield this.loadWasmModule(); const files = [{ path: dir, type: "tree", content: "" }]; mod.FS.readdir(abs(dir)).forEach((file) => __awaiter(this, void 0, void 0, function* () { if ([".", ".."].includes(file)) return; let path = `${dir}/${file}`; let stat = mod.FS.stat(abs(path)); if (mod.FS.isDir(stat.mode)) { files.push(...yield this.getCoreFiles(path)); } else { let content = mod.FS.readFile(abs(path), { encoding: "utf8" }); files.push({ path, type: "blob", content }); } })); return files; }); this.mkDir = (path) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); const pathStat = mod.FS.analyzePath(abs(path)); if (!pathStat.exists) mod.FS.mkdir(abs(path)); }); this.getFile = (path) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); const content = mod.FS.readFile(abs(path), { encoding: "utf8" }); return { path, content, type: "blob" }; }); this.setFile = (path, content) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); mod.FS.writeFile(abs(path), content, { flags: "w+" }); }); this.rmFile = (path) => __awaiter(this, void 0, void 0, function* () { const mod = yield this.loadWasmModule(); mod.FS.unlink(abs(path)); }); this.wasmModule = undefined; this.stdOutHandlers = { console: console.log }; this.stdErrHandlers = { console: console.error, store: this.storeErr }; this.errors = []; } generate(path) { return __asyncGenerator(this, arguments, function* generate_1() { var _a; const mod = yield __await(this.loadWasmModule()); const fn = mod.cwrap('vmGenerate_wasm', 'number', ['string']); const next = () => __awaiter(this, void 0, void 0, function* () { let out = yield this.readStrMem(fn(path)); let resp = JSON.parse(out); return resp; }); let resp = null; while (((_a = (resp = yield __await(next()))) === null || _a === void 0 ? void 0 : _a.out) != GEN_END) yield yield __await(resp); }); } } export default Runtime;