<!DOCTYPE html>
<html style="display: block; width: 100%; height: 100%; box-sizing: border-box;">
<head>
<style type="text/css">
body {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
box-sizing: border-box;
align-items: stretch;
justify-items: stretch;
margin: 0px;
}
#editor {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
box-sizing: border-box;
align-items: stretch;
justify-items: stretch;
margin: 0px;
}
textarea {
margin: 5px;
font-family: monospace;
}
div#output td {
height: 6px;
width: 6px;
}
div#output tr, div#output td, div#output table {
margin: 0px;
padding: 0px;
border-collapse: collapse;
}
</style>
</head>
<body>
<div id="editor">
<textarea id="source" onkeyup="run()" style="flex-grow: 1;">
tail = 9;
loop {
for(n = get_length) {
set_pixel(n-1, 0, 0, 0);
};
t = get_precise_time;
for(i = tail) {
set_pixel((t + i) % get_length, 255 - (i * (255 / tail)), 0 ,0);
};
for(i=tail) {
set_pixel((t - i) % get_length, 255 - (i * (255 / tail)), 0 ,0);
};
set_pixel(t % get_length, 255, 100, 50);
blit;
yield;
}
</textarea>
<textarea readonly id="binary" style="flex-grow: 1;"></textarea>
<textarea readonly id="assembly" style="flex-grow: 1;"></textarea>
<div id="output" style="flex-grow: 1;"></div>
</div>
<button onclick="benchmark()">Benchmark</button>
</body>
</html>
<script type="module">
import init, { compile, assemble, run as runProgram } from './pkg/pwlp.js';
let initialized = false;
if(window.localStorage.getItem("source")) {
document.getElementById("source").value = window.localStorage.getItem("source");
}
document.getElementById('source').addEventListener('keydown', function(e) {
if (e.key == 'Tab') {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
this.value = this.value.substring(0, start) +
"\t" + this.value.substring(end);
this.selectionStart =
this.selectionEnd = start + 1;
}
});
window.benchmark = function() {
const source = document.getElementById("source").value;
for(let x = 0; x<100; x++) {
compile(source);
}
const start = performance.now();
const iterations = 100000;
let a = 0;
for(;a<iterations; a++) {
compile(source);
if(a % 1000 === 0) {
if((performance.now() - start) > 10000) {
break;
}
}
}
const elapsed = performance.now() - start;
alert("Time elapsed: " + elapsed + "ms, " + (elapsed / a).toFixed(2) + "ms/iteration, " + (a / elapsed * 1000).toFixed(0)+ " iterations/sec");
};
window.run = async function() {
if(window.event) {
window.event.preventDefault();
window.event.stopPropagation();
}
if(!initialized) {
initialized = true;
await init();
}
const source = document.getElementById("source").value;
window.localStorage.setItem("source", source);
let res = "";
try {
const outputDiv = document.getElementById("output");
outputDiv.innerHTML = "";
const res = compile(source);
console.log({res});
document.getElementById("binary").value = [...res].map(x => x.toString(16).toUpperCase()).join(" ");
const ass = assemble(source);
document.getElementById("assembly").value = ass;
const out = runProgram(res, 25, 10000);
const colors = out.split("\n").slice(0, 50).map(x => x.split(" "));
const table = document.createElement("TABLE");
colors.forEach(row => {
const tr = document.createElement("TR");
row.forEach(color => {
if(color !== "") {
const td = document.createElement("TD");
td.style = "background-color: #" + color;
td.title = color;
tr.appendChild(td);
}
});
table.appendChild(tr);
});
outputDiv.appendChild(table);
}
catch(e) {
console.error(e);
document.getElementById("output").innerHTML = "";
document.getElementById("assembly").value = "";
}
};
window.run();
</script>