@nat-lang/nat
Version:
wasm compiler for nat
110 lines (109 loc) • 5.24 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());
});
};
import { v4 } from 'uuid';
import initialize from "../lib/nat";
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.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 = (pointer) => __awaiter(this, void 0, void 0, function* () {
const mod = yield this.loadWasmModule();
const memBuff = new Uint8Array(mod.wasmMemory.buffer);
let str = "";
while (memBuff[pointer] !== 0)
str += String.fromCharCode(memBuff[pointer++]);
return str;
});
this.typeset = (path) => __awaiter(this, void 0, void 0, function* () {
const mod = yield this.loadWasmModule();
const interpret = mod.cwrap('vmTypesetModule_wasm', 'number', ['string']);
const free = mod.cwrap('vmFree_wasm', null, []);
const respPtr = interpret(path);
const resp = yield this.readStrMem(respPtr);
free();
return {
success: true,
tex: resp,
errors: [],
};
});
this.interpret = (path) => __awaiter(this, void 0, void 0, function* () {
const mod = yield this.loadWasmModule();
const fn = mod.cwrap('vmInterpretEntrypoint_wasm', 'number', ['string']);
return fn(path);
});
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.wasmModule = undefined;
this.stdOutHandlers = { console: console.log };
this.stdErrHandlers = { console: console.error, store: this.storeErr };
this.errors = [];
}
}
export default Runtime;