-
-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
81 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
import CodeFlask from "https://cdn.jsdelivr.net/npm/[email protected]/+esm"; | ||
import initGleamCompiler from "./compiler.js"; | ||
import stdlib from "./stdlib.js"; | ||
|
||
const output = document.querySelector("#output"); | ||
const initialCode = document.querySelector("#code").innerHTML; | ||
|
@@ -38,63 +36,12 @@ const prismGrammar = { | |
/\b(?:0b[0-1]+|0o[0-7]+|[[:digit:]][[:digit:]_]*(\\.[[:digit:]]*)?|0x[[:xdigit:]]+)\b/, | ||
}; | ||
|
||
// Monkey patch console.log to keep a copy of the output | ||
let logged = ""; | ||
const log = console.log; | ||
console.log = (...args) => { | ||
log(...args); | ||
logged += args.map((e) => `${e}`).join(" ") + "\n"; | ||
}; | ||
|
||
function resetLogCapture() { | ||
logged = ""; | ||
} | ||
|
||
async function compileEval(project, code) { | ||
try { | ||
project.writeModule("main", code); | ||
project.compilePackage("javascript"); | ||
const js = project.readCompiledJavaScript("main"); | ||
const main = await loadProgram(js); | ||
resetLogCapture(); | ||
if (main) main(); | ||
replaceOutput(logged, "log"); | ||
} catch (error) { | ||
console.error(error); | ||
replaceOutput(logged, "log"); | ||
appendOutput(error.toString(), "error"); | ||
} | ||
for (const warning of project.takeWarnings()) { | ||
appendOutput(warning, "warning"); | ||
} | ||
} | ||
|
||
async function loadProgram(js) { | ||
const url = new URL(import.meta.url); | ||
url.pathname = ""; | ||
url.hash = ""; | ||
url.search = ""; | ||
const href = url.toString(); | ||
const js1 = js.replaceAll( | ||
/from\s+"\.\/(.+)"/g, | ||
`from "${href}precompiled/$1"`, | ||
); | ||
const js2 = btoa(unescape(encodeURIComponent(js1))); | ||
const module = await import("data:text/javascript;base64," + js2); | ||
return module.main; | ||
} | ||
|
||
function clearOutput() { | ||
while (output.firstChild) { | ||
output.removeChild(output.firstChild); | ||
} | ||
} | ||
|
||
function replaceOutput(content, className) { | ||
clearOutput(); | ||
appendOutput(content, className); | ||
} | ||
|
||
function appendOutput(content, className) { | ||
if (!content) return; | ||
const element = document.createElement("pre"); | ||
|
@@ -109,12 +56,6 @@ const editor = new CodeFlask("#editor-target", { | |
editor.addLanguage("gleam", prismGrammar); | ||
editor.updateCode(initialCode); | ||
|
||
const compiler = await initGleamCompiler(); | ||
const project = compiler.newProject(); | ||
for (const [name, code] of Object.entries(stdlib)) { | ||
project.writeModule(name, code); | ||
} | ||
|
||
function debounce(fn, delay) { | ||
let timer = null; | ||
return (...args) => { | ||
|
@@ -123,5 +64,17 @@ function debounce(fn, delay) { | |
}; | ||
} | ||
|
||
editor.onUpdate(debounce((code) => compileEval(project, code), 200)); | ||
compileEval(project, initialCode); | ||
const worker = new Worker("worker.js", { type: "module" }); | ||
|
||
worker.onmessage = (event) => { | ||
const result = event.data; | ||
clearOutput(); | ||
if (result.log) appendOutput(result.log, "log"); | ||
if (result.error) appendOutput(result.error, "error"); | ||
for (const warning of result.warnings) { | ||
appendOutput(warning, "warning"); | ||
} | ||
}; | ||
|
||
editor.onUpdate(debounce((code) => worker.postMessage(code), 200)); | ||
worker.postMessage(initialCode); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import initGleamCompiler from "./compiler.js"; | ||
import stdlib from "./stdlib.js"; | ||
|
||
const compiler = await initGleamCompiler(); | ||
const project = compiler.newProject(); | ||
|
||
for (const [name, code] of Object.entries(stdlib)) { | ||
project.writeModule(name, code); | ||
} | ||
|
||
// Monkey patch console.log to keep a copy of the output | ||
let logged = ""; | ||
const log = console.log; | ||
console.log = (...args) => { | ||
log(...args); | ||
logged += args.map((e) => `${e}`).join(" ") + "\n"; | ||
}; | ||
|
||
function resetLogCapture() { | ||
logged = ""; | ||
} | ||
|
||
async function loadProgram(js) { | ||
const url = new URL(import.meta.url); | ||
url.pathname = ""; | ||
url.hash = ""; | ||
url.search = ""; | ||
const href = url.toString(); | ||
const js1 = js.replaceAll( | ||
/from\s+"\.\/(.+)"/g, | ||
`from "${href}precompiled/$1"`, | ||
); | ||
const js2 = btoa(unescape(encodeURIComponent(js1))); | ||
const module = await import("data:text/javascript;base64," + js2); | ||
return module.main; | ||
} | ||
|
||
async function compileEval(code) { | ||
const result = { | ||
log: null, | ||
error: null, | ||
warnings: [], | ||
}; | ||
|
||
try { | ||
project.writeModule("main", code); | ||
project.compilePackage("javascript"); | ||
const js = project.readCompiledJavaScript("main"); | ||
const main = await loadProgram(js); | ||
resetLogCapture(); | ||
if (main) main(); | ||
} catch (error) { | ||
console.error(error); | ||
result.error = error.toString(); | ||
} | ||
for (const warning of project.takeWarnings()) { | ||
result.warnings.push(warning); | ||
} | ||
result.log = logged; | ||
|
||
return result; | ||
} | ||
|
||
self.onmessage = async (event) => { | ||
const result = compileEval(event.data); | ||
postMessage(await result); | ||
}; |