1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
import CodeFlask from "https://cdn.jsdelivr.net/npm/codeflask@1.4.1/+esm";
const output = document.querySelector("#output");
const initialCode = document.querySelector("#code").innerHTML;
const prismGrammar = {
comment: {
pattern: /\/\/.*/,
greedy: true,
},
function: /([a-z_][a-z0-9_]+)(?=\()/,
keyword:
/\b(use|case|if|@external|@deprecated|fn|import|let|assert|try|pub|type|opaque|const|panic|todo|as)\b/,
symbol: {
pattern: /([A-Z][A-Za-z0-9_]+)/,
greedy: true,
},
operator: {
pattern:
/(<<|>>|<-|->|\|>|<>|\.\.|<=\.?|>=\.?|==\.?|!=\.?|<\.?|>\.?|&&|\|\||\+\.?|-\.?|\/\.?|\*\.?|%\.?|=)/,
greedy: true,
},
string: {
pattern: /"((?:[^"\\]|\\.)*)"/,
greedy: true,
},
module: {
pattern: /([a-z][a-z0-9_]*)\./,
inside: {
punctuation: /\./,
},
alias: "keyword",
},
punctuation: /[.\\:,{}()]/,
number:
/\b(?:0b[0-1]+|0o[0-7]+|[[:digit:]][[:digit:]_]*(\\.[[:digit:]]*)?|0x[[:xdigit:]]+)\b/,
};
function clearOutput() {
while (output.firstChild) {
output.removeChild(output.firstChild);
}
}
function appendOutput(content, className) {
if (!content) return;
const element = document.createElement("pre");
element.textContent = content;
element.className = className;
output.appendChild(element);
}
const editor = new CodeFlask("#editor-target", {
language: "gleam",
});
editor.addLanguage("gleam", prismGrammar);
editor.updateCode(initialCode);
function debounce(fn, delay) {
let timer = null;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
let workerWorking = false;
let queuedWork = undefined;
const worker = new Worker("/worker.js", { type: "module" });
function sendToWorker(code) {
if (workerWorking) {
queuedWork = code;
return;
}
worker.postMessage(code);
}
worker.onmessage = (event) => {
// Handle the result of the compilation and execution
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");
}
// Deal with any queued work
workerWorking = false;
if (queuedWork) sendToWorker(queuedWork);
queuedWork = undefined;
};
editor.onUpdate(debounce((code) => worker.postMessage(code), 200));
worker.postMessage(initialCode);
|