-
Notifications
You must be signed in to change notification settings - Fork 4
/
pegsh.js
84 lines (73 loc) · 2.37 KB
/
pegsh.js
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
var peg = document.querySelector('#peg textarea'),
css = document.querySelector('#css textarea'),
inp = document.querySelector('#inp textarea'),
out = document.querySelector('#out pre'),
customCSS = document.querySelector('#custom');
var worker, queuedCommands;
killWorker();
updateCSS();
peg.addEventListener('change',delayedParse,false);
peg.addEventListener('input', delayedParse,false);
inp.addEventListener('change',delayedParse,false);
inp.addEventListener('input', delayedParse,false);
css.addEventListener('change',updateCSS, false);
css.addEventListener('input', updateCSS, false);
var userTypingTimer;
function delayedParse() {
clearTimeout(userTypingTimer);
userTypingTimer = setTimeout(parseInput,200);
}
var deathRowTimer;
function parseInput(){
queuedCommands++;
clearTimeout(deathRowTimer);
deathRowTimer = setTimeout(killWorker,2000);
worker.postMessage({ command:'parseInput', peg:peg.value, input:inp.value });
}
function killWorker() {
if (worker){
worker.terminate();
out.innerHTML = "…parser stalled processing the input; something is bad…"
}
worker = new Worker('parser.js');
worker.addEventListener('message',handleWorkerResponse,false);
queuedCommands = 0;
delayedParse(); // Try again?
}
function handleWorkerResponse(evt) {
if (!--queuedCommands) clearTimeout(deathRowTimer);
var data = evt.data;
if (data.error) logError(data.error,data.details);
else out.innerHTML = htmlFrom(data.parseTree);
}
function htmlFrom(node){
if (node instanceof Array){
return node.map(htmlFrom).join('');
}else if (node && node.n){
return '<span class="'+node.n+'">'+htmlFrom(node.v)+'</span>';
}else{
return node || "";
}
}
function updateCSS(){
customCSS.innerHTML = css.value;
}
function logError(label,e){
var messages = ["<div class='error'>"+label+"</div>"];
if (e){
if (e.summary) messages.push(e.summary);
if (e.line) messages.push(" line: "+e.line);
if (e.column) messages.push(" column: "+e.column);
if (e.offset) messages.push(" offset: "+e.offset);
// if (e.expected) messages.push("expected: "+e.expected.map(JSON.stringify).join("\n"));
// if (e.found) messages.push(" found: "+e.found);
// if (e.message) messages.push(" message: "+e.message);
}
out.innerHTML = messages.join('\n');
}
function bootstrap(){
if (validParser===undefined){
compileParser();
setTimeout(bootstrap,500);
}
}