@nat-lang/nat
Version:
wasm compiler for nat
145 lines (144 loc) • 7.46 kB
JavaScript
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;