diff --git a/wasm/in.civet b/wasm/in.civet index 09f85b0..5f70937 100644 --- a/wasm/in.civet +++ b/wasm/in.civet @@ -33,17 +33,17 @@ colors := new Colors // This is a clever little hack: elements.fooBar is the element with id="foo-bar". It uses document.getElementById on // first access, but then saves it for fast access later. elements := new Proxy>> {}, get: (target, p) -> - if p '-' + s.toLowerCase() + target[p] = document.getElementById p.replace /[A-Z]/g, (s) => '-' + s.toLowerCase() // @ts-expect-error If it's a symbol then so what. target[p] -clearOutput := :void -> +clearOutput := :void => elements.stdout.innerHTML = '' elements.stderr.innerHTML = '' -generateContracted := -> +generateContracted := => programText .= (elements.program as! HTMLTextAreaElement).value.replace /\n| /gu, '' // programText.length is wrong when there's high Unicode characters programLength := [programText...].length @@ -55,11 +55,11 @@ generateContracted := -> programText = programText.replace new RegExp(`\\.{0,${programLength - minLength}}$`), '' programText.replace /^#!/u, '#\n!' -contractInput := :void -> +contractInput := :void => clearOutput() elements.program.value = generateContracted() -generateURL := :void -> +generateURL := :void => baseURL := location.href.split(/[?#]/u).0 fragment := '#' + encodeURIComponent generateContracted() query := @@ -74,24 +74,24 @@ generateURL := :void -> elements.urlButton.textContent = 'Copy URL' elements.urlButton.onclick = copyURL -copyURL := :void -> +copyURL := :void => url := elements.urlOut.textContent! (elements.urlOut.setSelectionRange as (undefined | HTMLInputElement['setSelectionRange']))? 0, url.length navigator.clipboard.writeText url elements.copyAlert.className = '' - setTimeout -> elements.copyAlert.className = 'hide-slow' + setTimeout :void -> elements.copyAlert.className = 'hide-slow' -wasmCancel := :void -> +wasmCancel := :void => worker?.terminate() worker = null resolve() -isBufferFull := (buf: ArrayLike) -> +isBufferFull := (buf: ArrayLike) => buf.length is 4 or (((buf.0 + 256) & 0xf0) is 0xe0 and buf.length is 3) or (((buf.0 + 256) & 0xe0) is 0xc0 and buf.length is 2) -stdout := (char: number | null): void -> +stdout := (char: number | null): void => return unless char? if char < 0 stdoutBuffer.push char @@ -101,7 +101,7 @@ stdout := (char: number | null): void -> else elements.stdout.textContent += String.fromCharCode char -stderr := (char: number | null): void -> +stderr := (char: number | null): void => return unless char? appendText := (text: string) -> if elements.stderr.lastChild instanceof Text @@ -119,7 +119,7 @@ stderr := (char: number | null): void -> else appendText String.fromCharCode char -createWorker := (name: string) -> -> +createWorker := (name: string) => => threadCount .= -1 clearOutput() @@ -133,10 +133,10 @@ createWorker := (name: string) -> -> elements.stdin.oninput = null worker ?= new Worker window.WORKER_URL - step = -> worker!.postMessage ['step'] + step = => worker!.postMessage ['step'] promise := new Promise (r): void -> resolve = r - .then :void -> + .then :void => elements.stdin.oninput = :void -> worker = null @oninput = null @@ -161,7 +161,7 @@ createWorker := (name: string) -> -> [3, [threadNum, thread]] threads[threadNum] = thread try - if threadCount is threads.reduce (x) -> x + 1, 0 + if threadCount is threads.reduce (x) => x + 1, 0 renderThreads() else step() @@ -186,12 +186,12 @@ disassembleProgram := createWorker 'disassembleProgram' expandBase := createWorker 'expandInput' debugBase := createWorker 'debugProgram' -expandInput := :Promise -> +expandInput := :Promise => await expandBase() elements.program.value = elements.stdout.innerText elements.stdout.innerText = '' -pause := :void -> +pause := :void => clearInterval interval interval = -1 elements.playPause.textContent = window.PLAY_TEXT @@ -203,7 +203,7 @@ pause := :void -> minDelay := 4 // Not really a useful upper limit but one that keeps setInterval from breaking maxDelay := 1 << 30 -play := :void -> +play := :void => elements.playPause.textContent = window.PAUSE_TEXT elements.slower.disabled = delay >= maxDelay elements.faster.disabled = delay <= minDelay @@ -212,24 +212,24 @@ play := :void -> Object.defineProperty window, 'isPaused', get: -> interval is -1 -playPause := :void -> +playPause := :void => if window.isPaused then play() else pause() -faster := :void -> +faster := :void => clearInterval interval delay /= 2 interval = setInterval step, delay elements.slower.disabled = false elements.faster.disabled = delay <= minDelay -slower := :void -> +slower := :void => clearInterval interval delay *= 2 interval = setInterval step, delay elements.faster.disabled = false elements.slower.disabled = delay >= maxDelay -debugProgram := :Promise -> +debugProgram := :Promise => await expandBase() elements.debugProgram.hidden = false @@ -239,7 +239,7 @@ debugProgram := :Promise -> elements.colorPicker.hidden = true elements.stdout.innerText.trimEnd().split '\n' - .forEach (textRow, i): void -> + .forEach (textRow, i): void => el := document.createElement 'div' el.id = `row-${i}` matchLength := (/^ */u.exec textRow)?.0.length ?? 0 @@ -255,7 +255,7 @@ debugProgram := :Promise -> elements.debugInfo.hidden = false if not elements.playPause.style?.width elements.playPause.textContent = window.PAUSE_TEXT - setTimeout :void -> + setTimeout :void => elements.playPause.style.width = `${elements.playPause.offsetWidth}px` pause() @@ -268,9 +268,9 @@ debugProgram := :Promise -> elements.program.hidden = false pause() -renderThreads := :void -> +renderThreads := :void => elements.threads.innerHTML = '' - threads.forEach (thread, idx): void -> + threads.forEach (thread, idx): void => row := document.createElement 'tr' highlightDiv := colors.getHighlightDiv(idx) ?? throw new TypeError( "You haven't selected enough colors for that many threads!" @@ -286,7 +286,7 @@ renderThreads := :void -> row.appendChild threadContentsEl elements.threads.appendChild row -changeHighlightColor := (before: string | number, after: string) -> +changeHighlightColor := (before: string | number, after: string) => threadNum := colors.replaceColor before, after return true unless threadNum? return false if threadNum < 0 @@ -301,29 +301,29 @@ changeHighlightColor := (before: string | number, after: string) -> true // Given y,x, find the horizontal offset necessary to highlight that position -getColumn := (y: number, x: number) -> +getColumn := (y: number, x: number) => row := document.getElementById(`row-${y}`) if row? +row.dataset.offset! + 2 * x else -1 -highlightIndex := (x: number, y: number, div: HTMLDivElement): void -> +highlightIndex := (x: number, y: number, div: HTMLDivElement): void => col := getColumn y, x div.style.left = `${col}ch` elements.debugProgram.insertBefore div, document.getElementById `row-${y}` -hideUrl := :void -> +hideUrl := :void => elements.urlOutBox.className = 'content-hidden' elements.urlButton.textContent = 'Generate URL' elements.urlButton.onclick = generateURL elements.program.addEventListener 'input', hideUrl, { +passive } elements.includeInput.addEventListener 'change', hideUrl, { +passive } -elements.stdin.addEventListener 'change', :void -> +elements.stdin.addEventListener 'change', :void => hideUrl() if elements.includeInput.checked , { +passive } -toHex := (rgba: string) -> +toHex := (rgba: string) => return rgba if /^#[0-9a-d]{6}$/i.test rgba // Adapted from https://stackoverflow.com/a/3627747/6253337 '#' + rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/)![1...] @@ -334,7 +334,7 @@ toHex := (rgba: string) -> .replace 'NaN', '' .join '' -createColorDiv := (color: string, i: number) -> +createColorDiv := (color: string, i: number) => input := document.createElement 'input' input.type = 'color' input.value = toHex color @@ -351,7 +351,7 @@ createColorDiv := (color: string, i: number) -> removeButton.type = 'button' removeButton.title = 'remove color' - removeButton.addEventListener 'click', :void -> + removeButton.addEventListener 'click', :void => if colors.removeColor i updateColorPicker() renderThreads() @@ -359,9 +359,9 @@ createColorDiv := (color: string, i: number) -> removeButton.appendChild document.createTextNode 'x' div -updateColorPicker := -> +updateColorPicker := :void => elements.colorPicker.innerHTML = '' - colors.allColors().forEach (color, i): void -> + colors.allColors().forEach (color, i): void => div := createColorDiv color, i elements.colorPicker.appendChild div @@ -385,7 +385,7 @@ updateColorPicker := -> elements.addColorButton = button elements.colorPicker.appendChild elements.addColorButton -toggleColorPicker := :void -> +toggleColorPicker := :void => if elements.colorPicker.hidden updateColorPicker() elements.colorPicker.hidden = false @@ -393,7 +393,7 @@ toggleColorPicker := :void -> elements.colorPicker.hidden = true // Allow the header itself, or noninteractable children (e.g. the select icon) -isHeader := (target: EventTarget | null) -> +isHeader := (target: EventTarget | null) => target? and (target is elements.debugHeader or ((target as Element).tagName isnt 'BUTTON' and elements.debugHeader.contains(target as Node)) @@ -402,7 +402,7 @@ isHeader := (target: EventTarget | null) -> // Adapted from https://www.w3schools.com/howto/howto_js_draggable.asp pos3 .= 0 pos4 .= 0 -elements.debugHeader.addEventListener 'mousedown', (e): void -> +elements.debugHeader.addEventListener 'mousedown', (e): void => if not isHeader e.target return e.preventDefault() @@ -419,7 +419,7 @@ elements.debugHeader.addEventListener 'mousedown', (e): void -> document.onmouseup = :void -> @onmousemove = null @onmouseup = null -elements.debugHeader.addEventListener 'touchstart', (e): void -> +elements.debugHeader.addEventListener 'touchstart', (e): void=> if not isHeader e.target return e.preventDefault() @@ -438,18 +438,20 @@ elements.debugHeader.addEventListener 'touchstart', (e): void -> @ontouchcancel = null @ontouchend = null -width := elements.runStop.offsetWidth -remSize := parseFloat getComputedStyle(document.body).fontSize -elements.runStop.textContent = 'Run!' -setTimeout :void -> elements.runStop.style.width = `${(0.49 + Math.max width, elements.runStop.offsetWidth) / remSize}rem` -elements.runStop.onclick = interpretProgram -elements.urlButton.onclick = generateURL - -if location.hash.length > 1 - elements.program.value = decodeURIComponent location.hash.slice 1 - -params := new URLSearchParams location.search -inputParam := params.get 'i' -if inputParam? - elements.stdin.value = inputParam - elements.includeInput.checked = true +do + width := elements.runStop.offsetWidth + remSize := parseFloat getComputedStyle(document.body).fontSize + elements.runStop.textContent = 'Run!' + setTimeout :void => + elements.runStop.style.width = `${(0.49 + Math.max width, elements.runStop.offsetWidth) / remSize}rem` + elements.runStop.onclick = interpretProgram + elements.urlButton.onclick = generateURL + + if location.hash.length > 1 + elements.program.value = decodeURIComponent location.hash.slice 1 + + params := new URLSearchParams location.search + inputParam := params.get 'i' + if inputParam? + elements.stdin.value = inputParam + elements.includeInput.checked = true diff --git a/wasm/package-lock.json b/wasm/package-lock.json index 10c6893..a45114c 100644 --- a/wasm/package-lock.json +++ b/wasm/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "dependencies": { - "@danielx/civet": "~0.6.65", + "@danielx/civet": "~0.6.68", "sass": "^1.64.1", "terser": "^5.19.2" }, @@ -174,9 +174,9 @@ } }, "node_modules/@danielx/civet": { - "version": "0.6.65", - "resolved": "https://registry.npmjs.org/@danielx/civet/-/civet-0.6.65.tgz", - "integrity": "sha512-TSgzTe7FYvEcSOfascIyw08/4OwqzkBwbCPMP9lVL7vyPm1d4RVTiOszIONKpfAEnl4rorQPWKZMBXYzeF4bBg==", + "version": "0.6.68", + "resolved": "https://registry.npmjs.org/@danielx/civet/-/civet-0.6.68.tgz", + "integrity": "sha512-CiP0mhqX0G+S+lg6butqs0SOHhJNrjWPtfuJPVHC4vvFIn3jGDgb0b5qaFopvFvLFTSnjnMyAlTzFq46Tb+G8g==", "dependencies": { "@cspotcode/source-map-support": "^0.8.1", "@typescript/vfs": "^1.5.0", @@ -4299,9 +4299,9 @@ "requires": {} }, "@danielx/civet": { - "version": "0.6.65", - "resolved": "https://registry.npmjs.org/@danielx/civet/-/civet-0.6.65.tgz", - "integrity": "sha512-TSgzTe7FYvEcSOfascIyw08/4OwqzkBwbCPMP9lVL7vyPm1d4RVTiOszIONKpfAEnl4rorQPWKZMBXYzeF4bBg==", + "version": "0.6.68", + "resolved": "https://registry.npmjs.org/@danielx/civet/-/civet-0.6.68.tgz", + "integrity": "sha512-CiP0mhqX0G+S+lg6butqs0SOHhJNrjWPtfuJPVHC4vvFIn3jGDgb0b5qaFopvFvLFTSnjnMyAlTzFq46Tb+G8g==", "requires": { "@cspotcode/source-map-support": "^0.8.1", "@typescript/vfs": "^1.5.0", diff --git a/wasm/package.json b/wasm/package.json index ff3a3e6..4f44178 100644 --- a/wasm/package.json +++ b/wasm/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "@danielx/civet": "~0.6.65", + "@danielx/civet": "~0.6.68", "sass": "^1.64.1", "terser": "^5.19.2" }, diff --git a/wasm/worker.civet b/wasm/worker.civet index 19963e3..c62e71b 100644 --- a/wasm/worker.civet +++ b/wasm/worker.civet @@ -25,7 +25,7 @@ let funcName: string | undefined encoder := new TextEncoder signals := new Map void> -halfReady := (arg?: string): void -> +halfReady := (arg?: string): void => funcName = arg ?? funcName unless ready ready = true @@ -38,14 +38,14 @@ halfReady := (arg?: string): void -> postMessage [0, null] Module['preInit'] = -> - stdin := -> if inputIndex >= stdinBuffer.length then null else stdinBuffer.at(inputIndex++)! - stdout := (char: number | null) -> postMessage [1, char] - stderr := (char: number | null) -> postMessage [2, char] + stdin := => if inputIndex >= stdinBuffer.length then null else stdinBuffer.at(inputIndex++)! + stdout := (char: number | null) => postMessage [1, char] + stderr := (char: number | null) => postMessage [2, char] FS.init stdin, stdout, stderr Module['onRuntimeInitialized'] = halfReady Module['noExitRuntime'] = true -callInterpreter := (warnings: 0 | 1, disassemble: 0 | 1, expand: 0 | 1) -> :Promise -> +callInterpreter := (warnings: 0 | 1, disassemble: 0 | 1, expand: 0 | 1) => :Promise => inputIndex = 0 try await Module['ccall'] 'wasm_entrypoint',