import { tokenize, Parser, Environment } from "./tabloid.js"; import { SAMPLE_PROGRAMS } from "./samples.js"; class TabloidRunner { run(code) { const stdout = []; const stderr = []; if (!code) { stderr.push("No code to execute."); return { stdout, stderr }; } try { const tokens = tokenize(code); const nodes = new Parser(tokens).parse(); const env = new Environment({ print: (msg) => stdout.push(String(msg)), input: (promptText) => window.prompt(promptText) ?? "" }); env.run(nodes); } catch (error) { stderr.push(error.message || error.toString()); } return { stdout, stderr }; } } export class TabloidPlayground { constructor() { this.runner = new TabloidRunner(); this.programLookup = new Map(SAMPLE_PROGRAMS.map((program) => [program.id, program])); this.activeProgramId = this.defaultProgramId = SAMPLE_PROGRAMS[0].id; this.stdoutElement = document.getElementById("stdout-content"); this.errorElement = document.getElementById("error-content"); this.programSelect = document.getElementById("program-select"); this.runButton = document.getElementById("run-button"); this.clearButton = document.getElementById("clear-button"); this.editor = adelieEditor.init("#code-editor", { language: "tabloid" }); this.init(); } init() { this.populateProgramSelect(); this.registerEvents(); this.loadProgram(this.activeProgramId); } populateProgramSelect() { if (!this.programSelect) { return; } this.programSelect.innerHTML = ""; SAMPLE_PROGRAMS.forEach((program) => { const option = document.createElement("option"); option.value = program.id; option.textContent = program.label; this.programSelect.appendChild(option); }); this.programSelect.value = this.activeProgramId; } registerEvents() { this.runButton.addEventListener("click", () => this.runCode()); this.clearButton.addEventListener("click", () => this.resetOutput()); this.programSelect.addEventListener("change", () => { this.loadProgram(this.programSelect.value); }); document.addEventListener("keydown", (event) => { if (event.ctrlKey && event.key === "Enter") { event.preventDefault(); this.runCode(); } }); } setEditorContent(content) { const length = this.editor.state.doc.toString().length; this.editor.dispatch({ changes: { from: 0, to: length, insert: content } }); } loadProgram(programId = this.defaultProgramId) { const selectedProgram = this.programLookup.get(programId); if (!selectedProgram) { return; } this.activeProgramId = selectedProgram.id; this.setEditorContent(selectedProgram.code); this.resetOutput(); if (this.programSelect) { this.programSelect.value = this.activeProgramId; } } resetOutput() { this.stdoutElement.textContent = ""; this.errorElement.textContent = ""; } runCode() { const code = this.editor.state.doc.toString(); const result = this.runner.run(code); this.stdoutElement.textContent = result.stdout.join("\n"); this.errorElement.textContent = result.stderr.join("\n"); } }