summaryrefslogtreecommitdiff
path: root/src/toys/godel/js/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/toys/godel/js/ui.js')
-rw-r--r--src/toys/godel/js/ui.js224
1 files changed, 0 insertions, 224 deletions
diff --git a/src/toys/godel/js/ui.js b/src/toys/godel/js/ui.js
deleted file mode 100644
index 97e5209..0000000
--- a/src/toys/godel/js/ui.js
+++ /dev/null
@@ -1,224 +0,0 @@
-import parser from "./parser.js";
-import { compileProgram } from "./compiler.js";
-
-const SAMPLE_PROGRAM = `// THIS PROGRAM COMPUTES X1 + X2
-
-// Y <- X1
-[ A1 ] IF X1 != 0 GOTO A2
- GOTO B1
-[ A2 ] X1 <- X1 - 1
- Y <- Y + 1
- GOTO A1
-
-// Z1 <- X2
-[ B1 ] IF X2 != 0 GOTO B2
- GOTO C1
-[ B2 ] X2 <- X2 - 1
- Z1 <- Z1 + 1
- GOTO B1
-
-// Y <- Y + Z1
-[ C1 ] IF Z1 != 0 GOTO C2
- GOTO E1
-[ C2 ] Z1 <- Z1 - 1
- Y <- Y + 1
- GOTO C1`;
-
-const STATUS_VARIANTS = {
- success: "text-success",
- error: "text-error",
- info: "muted"
-};
-
-export class GodelPlayground {
- constructor() {
- this.elements = {
- compileBtn: document.getElementById("compile-btn"),
- copyBtn: document.getElementById("copy-btn"),
- evalBtn: document.getElementById("eval-btn"),
- computeNumberBtn: document.getElementById("compute-godel-btn"),
- compileStatus: document.getElementById("compile-status"),
- evalStatus: document.getElementById("eval-status"),
- godelSequence: document.getElementById("godel-sequence"),
- godelNumber: document.getElementById("godel-number")
- };
-
- this.sourceEditor = null;
- this.compiledEditor = null;
- this.worker = null;
- this.latestSequence = [];
-
- this.init();
- }
-
- init() {
- this.setupEditors();
- this.bindEvents();
- this.hydrateFromParams();
- if (!this.getSource().trim()) {
- this.setSource(SAMPLE_PROGRAM);
- }
- this.compileSource();
- }
-
- setupEditors() {
- this.sourceEditor = adelieEditor.init("#source-editor", {
- language: "javascript"
- });
- this.compiledEditor = adelieEditor.init("#compiled-editor", {
- language: "javascript"
- });
- this.setSource(SAMPLE_PROGRAM);
- }
-
- bindEvents() {
- this.elements.compileBtn.addEventListener("click", () => this.compileSource());
- this.elements.evalBtn.addEventListener("click", () => this.evaluateCompiled());
- this.elements.copyBtn.addEventListener("click", () => this.copyShareLink());
- this.elements.computeNumberBtn.addEventListener("click", () => this.computeGodelNumber());
-
- document.addEventListener("keydown", (event) => {
- if (event.ctrlKey && event.key === "Enter") {
- event.preventDefault();
- this.compileSource();
- }
- });
- }
-
- hydrateFromParams() {
- const params = new URLSearchParams(window.location.search);
- const encoded = params.get("instructions");
- if (encoded) {
- try {
- const decoded = atob(encoded);
- this.setSource(decoded);
- } catch (error) {
- console.warn("Failed to decode instructions from URL", error);
- }
- }
- }
-
- getSource() {
- return this.sourceEditor.state.doc.toString();
- }
-
- setSource(content) {
- const docLength = this.sourceEditor.state.doc.toString().length;
- this.sourceEditor.dispatch({
- changes: { from: 0, to: docLength, insert: content }
- });
- }
-
- getCompiled() {
- return this.compiledEditor.state.doc.toString();
- }
-
- setCompiled(content) {
- const docLength = this.compiledEditor.state.doc.toString().length;
- this.compiledEditor.dispatch({
- changes: { from: 0, to: docLength, insert: content }
- });
- }
-
- prepareSource(source) {
- return source.replace(/\/\/.*$/gm, "").trim();
- }
-
- compileSource() {
- const raw = this.getSource();
- const prepared = this.prepareSource(raw);
-
- if (!prepared) {
- this.setStatus("compile", "Provide some source to compile", "error");
- return;
- }
-
- try {
- const ast = parser.parse(prepared);
- const { js, godelSequence } = compileProgram(ast);
- this.latestSequence = godelSequence;
- this.setCompiled(js);
- this.renderSequence(godelSequence);
- this.setStatus("compile", "Successful compilation", "success");
- this.elements.computeNumberBtn.disabled = godelSequence.length === 0;
- } catch (error) {
- this.latestSequence = [];
- this.renderSequence([]);
- this.elements.computeNumberBtn.disabled = true;
- this.setStatus("compile", error.message || "Error compiling", "error");
- }
- }
-
- evaluateCompiled() {
- const js = this.getCompiled();
- if (!js.trim()) {
- this.setStatus("eval", "Compile a program first", "error");
- return;
- }
-
- try {
- const result = (0, eval)(js);
- this.setStatus(
- "eval",
- `Result: ${typeof result === "undefined" ? "(no return)" : result}`,
- "success"
- );
- } catch (error) {
- this.setStatus("eval", error.message || "Failed to evaluate program", "error");
- }
- }
-
- renderSequence(sequence) {
- if (!sequence.length) {
- this.elements.godelSequence.textContent = "Compile to view the Gödel sequence.";
- this.elements.godelNumber.textContent = "";
- return;
- }
- this.elements.godelSequence.textContent = `[${sequence.join(", ")}]`;
- this.elements.godelNumber.textContent = "";
- }
-
- copyShareLink() {
- const data = btoa(this.getSource());
- const url = `${window.location.href.split("?")[0]}?instructions=${data}`;
-
- navigator.clipboard.writeText(url)
- .then(() => alert("Shareable link copied to clipboard"))
- .catch(() => alert("Failed to copy link"));
- }
-
- computeGodelNumber() {
- if (!this.latestSequence.length) {
- this.setStatus("compile", "Compile a program to produce its Gödel sequence", "error");
- return;
- }
-
- this.elements.godelNumber.textContent = "Working...";
- this.elements.computeNumberBtn.disabled = true;
-
- const worker = this.getWorker();
- worker.onmessage = (event) => {
- this.elements.godelNumber.textContent = event.data;
- this.elements.computeNumberBtn.disabled = false;
- };
- worker.onerror = () => {
- this.elements.godelNumber.textContent = "Failed to compute Gödel number";
- this.elements.computeNumberBtn.disabled = false;
- };
- worker.postMessage(this.latestSequence);
- }
-
- getWorker() {
- if (!this.worker) {
- const workerUrl = new URL("./godel-worker.js", import.meta.url);
- this.worker = new Worker(workerUrl, { type: "module" });
- }
- return this.worker;
- }
-
- setStatus(kind, message, variant = "info") {
- const element = kind === "compile" ? this.elements.compileStatus : this.elements.evalStatus;
- element.textContent = message;
- element.className = `status-text ${STATUS_VARIANTS[variant] || ""}`;
- }
-}