2023-11-16 21:06:35 -05:00
|
|
|
const MESSAGES = {
|
|
|
|
COMPILE: "COMPILE",
|
|
|
|
COMPILE_RESULT: "COMPILE_RESULT",
|
|
|
|
EVAL: "EVAL",
|
|
|
|
EVAL_STATUS: "EVAL_RESULT",
|
|
|
|
};
|
2023-11-16 16:56:56 -05:00
|
|
|
|
2023-11-16 21:06:35 -05:00
|
|
|
// -- the "real" code --
|
2023-11-16 16:56:56 -05:00
|
|
|
|
|
|
|
const state = new Observable();
|
2023-11-16 21:06:35 -05:00
|
|
|
|
|
|
|
const prepareSource = (text) => text.replaceAll(/\/\/.*/g, "").trim();
|
|
|
|
|
|
|
|
const main = () => {
|
|
|
|
let program;
|
|
|
|
|
|
|
|
state.subscribe((msg) => {
|
|
|
|
if (msg.type == MESSAGES.COMPILE) {
|
|
|
|
const { value } = msg;
|
|
|
|
const source = prepareSource(value);
|
2023-11-17 14:09:44 -05:00
|
|
|
|
2023-11-16 21:06:35 -05:00
|
|
|
try {
|
|
|
|
const ast = parser.parse(source);
|
2023-11-17 14:09:44 -05:00
|
|
|
const { js, godelSequence } = compile(ast);
|
2023-11-16 21:06:35 -05:00
|
|
|
|
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.COMPILE_RESULT,
|
2023-11-17 14:09:44 -05:00
|
|
|
success: true,
|
|
|
|
js,
|
|
|
|
godelSequence,
|
2023-11-16 21:06:35 -05:00
|
|
|
});
|
|
|
|
} catch (e) {
|
2023-11-17 14:09:44 -05:00
|
|
|
console.error(e);
|
2023-11-16 21:06:35 -05:00
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.COMPILE_RESULT,
|
|
|
|
error: e.toString(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (msg.type == MESSAGES.EVAL) {
|
|
|
|
const source = compiledEditorEl.getValue();
|
|
|
|
try {
|
|
|
|
const result = eval(source);
|
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.EVAL_RESULT,
|
2023-11-17 14:09:44 -05:00
|
|
|
success: true,
|
2023-11-16 21:06:35 -05:00
|
|
|
value: result,
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.EVAL_RESULT,
|
|
|
|
error: e.toString(),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
main();
|
|
|
|
|
|
|
|
// -- a bit of some hacky ui code --
|
|
|
|
|
2023-11-17 14:09:44 -05:00
|
|
|
const codeMirrorConfig = {
|
2023-11-16 21:06:35 -05:00
|
|
|
lineNumbers: true,
|
2023-11-17 14:09:44 -05:00
|
|
|
};
|
|
|
|
const instructionsEl = document.getElementById("instructions");
|
|
|
|
const instructionsEditorEl = CodeMirror.fromTextArea(
|
|
|
|
instructionsEl,
|
|
|
|
codeMirrorConfig
|
|
|
|
);
|
2023-11-16 21:06:35 -05:00
|
|
|
|
|
|
|
const compileButton = document.getElementById("compile");
|
|
|
|
const evalButton = document.getElementById("eval");
|
|
|
|
const evalStatusEl = document.getElementById("eval_status");
|
|
|
|
const compileStatusEl = document.getElementById("compile_status");
|
|
|
|
const compiledEl = document.getElementById("compiled");
|
2023-11-17 14:09:44 -05:00
|
|
|
const compiledEditorEl = CodeMirror.fromTextArea(compiledEl, codeMirrorConfig);
|
|
|
|
const godelSequenceEl = document.getElementById("godel_sequence");
|
|
|
|
const godelNumberEl = document.getElementById("godel_number");
|
|
|
|
const godelNumberComputeBtn = document.getElementById("godel_number_comp");
|
2023-11-17 14:12:57 -05:00
|
|
|
const copyStateButton = document.getElementById("copy");
|
|
|
|
|
|
|
|
// hackily copy the program state and put it in the clipboard
|
|
|
|
copyStateButton.addEventListener("click", () => {
|
|
|
|
const instructions = btoa(instructionsEditorEl.getValue());
|
|
|
|
|
|
|
|
navigator.clipboard
|
|
|
|
.writeText(
|
|
|
|
window.location.href.split("?")[0] + `?instructions=${instructions}`
|
|
|
|
)
|
|
|
|
.then(() => alert("copied to clipboard"));
|
|
|
|
});
|
2023-11-17 14:09:44 -05:00
|
|
|
|
2023-11-16 21:06:35 -05:00
|
|
|
state.subscribe((msg) => {
|
|
|
|
if (msg.type == MESSAGES.COMPILE_RESULT) {
|
|
|
|
evalStatusEl.classList.remove("error");
|
|
|
|
evalStatusEl.classList.remove("success");
|
|
|
|
evalStatusEl.innerHTML = "";
|
|
|
|
|
2023-11-17 14:09:44 -05:00
|
|
|
if (msg.success) {
|
|
|
|
const { js, godelSequence } = msg;
|
|
|
|
compiledEditorEl.setValue(js);
|
|
|
|
|
|
|
|
godelSequenceEl.innerHTML = `[${godelSequence.join(", ")}]`;
|
|
|
|
godelNumberComputeBtn.style.display = "inline";
|
2023-11-16 21:06:35 -05:00
|
|
|
|
|
|
|
compileStatusEl.classList.add("success");
|
|
|
|
compileStatusEl.classList.remove("error");
|
|
|
|
compileStatusEl.innerHTML = `Successful compile at ${new Date().toLocaleString()}!`;
|
|
|
|
} else if (msg.error) {
|
|
|
|
compiledEditorEl.setValue("");
|
2023-11-17 14:09:44 -05:00
|
|
|
godelSequenceEl.innerHTML = "";
|
|
|
|
godelNumberEl.innerHTML = "";
|
|
|
|
godelNumberComputeBtn.style.display = "none";
|
2023-11-16 21:06:35 -05:00
|
|
|
|
|
|
|
compileStatusEl.classList.remove("success");
|
|
|
|
compileStatusEl.classList.add("error");
|
|
|
|
compileStatusEl.innerHTML = msg.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2023-11-17 14:09:44 -05:00
|
|
|
|
|
|
|
state.subscribe((msg) => {
|
|
|
|
if (msg.type == MESSAGES.COMPILE_RESULT) {
|
|
|
|
if (msg.success) {
|
|
|
|
const { godelSequence } = msg;
|
|
|
|
|
|
|
|
godelNumberComputeBtn.onclick = () => {
|
|
|
|
godelNumberEl.innerHTML = "working...";
|
|
|
|
|
|
|
|
const worker = new Worker("js/godelWorker.js");
|
|
|
|
|
|
|
|
worker.addEventListener("message", (e) => {
|
|
|
|
const godelNumber = e.data;
|
|
|
|
godelNumberEl.innerHTML = godelNumber.toString();
|
|
|
|
});
|
|
|
|
|
|
|
|
worker.postMessage(godelSequence);
|
|
|
|
};
|
|
|
|
} else if (msg.error) {
|
|
|
|
godelNumberComputeBtn.onclick = () => {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-11-16 21:06:35 -05:00
|
|
|
state.subscribe((msg) => {
|
|
|
|
if (msg.type == MESSAGES.EVAL_RESULT) {
|
2023-11-17 14:09:44 -05:00
|
|
|
if (msg.success) {
|
2023-11-16 21:06:35 -05:00
|
|
|
evalStatusEl.classList.add("success");
|
|
|
|
evalStatusEl.classList.remove("error");
|
|
|
|
evalStatusEl.innerHTML = `Result: ${msg.value}`;
|
|
|
|
} else if (msg.error) {
|
|
|
|
evalStatusEl.classList.remove("success");
|
|
|
|
evalStatusEl.classList.add("error");
|
|
|
|
evalStatusEl.innerHTML = msg.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
if (urlParams.get("instructions")) {
|
2023-11-17 14:12:57 -05:00
|
|
|
instructionsEditorEl.setValue(atob(urlParams.get("instructions")));
|
2023-11-16 21:06:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
compileButton.addEventListener("click", () => {
|
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.COMPILE,
|
|
|
|
value: instructionsEditorEl.getValue(),
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
evalButton.addEventListener("click", () => {
|
|
|
|
state.notify({
|
|
|
|
type: MESSAGES.EVAL,
|
|
|
|
});
|
|
|
|
});
|