test html
This commit is contained in:
commit
378cb98859
4 changed files with 179 additions and 0 deletions
46
index.html
Normal file
46
index.html
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>CALC</title>
|
||||||
|
<style>
|
||||||
|
tr, td { border-collapse: collapse; }
|
||||||
|
table { width:100%; border-collapse: collapse; text-align: center; }
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
textarea.emscripten { font-family: monospace; font-size: 16px; width: 100%; overflow-x: scroll; white-space: pre; background: black; color: rgb(0,255,0);}
|
||||||
|
.frame1 { width: 96%; margin: 0; padding: 10px; background-color: #FFFFC0; border: 10px solid #F0C0F0; }
|
||||||
|
.canvas { width: 100%; height: 65vh; background-color: black; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="module" src="index.js"></script>
|
||||||
|
<div class="frame1"><canvas id="canvas" class="canvas"></canvas></div>
|
||||||
|
<div class="frame1"><input id="buttonTest" type="button" value="Submit"></div>
|
||||||
|
<div class="frame1">
|
||||||
|
<table><tr>
|
||||||
|
<td width="40%"><textarea class="emscripten" id="input" rows="10" spellcheck="false"></textarea></td>
|
||||||
|
<td><textarea readonly class="emscripten" id="stdout" rows="10" spellcheck="false"></textarea></td>
|
||||||
|
</tr></table>
|
||||||
|
</div>
|
||||||
|
<div class="frame1">
|
||||||
|
<h2>Kalkulátor s grafickým výstupem.</h2>
|
||||||
|
<p>Když jsem přepisoval z nudy syntax highlighter pro C++ z pythonu do C++, zjistil jsem, že regulární výrazy
|
||||||
|
jsou kupodivu v tom pythonu efektivnější. V tomto ohledu je STL knihovna asi dost naprd. Ale vzpomněl jsem si
|
||||||
|
na prastarý pár flex a bison, který umí nejen regulární výrazy, ale jde s tím parsovat dost jednoduše gramatika.
|
||||||
|
Mělo by to jít i v C++, ale příklady na webu byly dost zamotané a bylo nutné použít STL, kterou jsem pro tento
|
||||||
|
účel neměl k dispozici. Vyřešilo se to jednoduše - vygenerovaný C-čkový kód se přeloží jako C++, přičemž je
|
||||||
|
nutné povypínat něktetré warningy.
|
||||||
|
</p>
|
||||||
|
<p>Je to tedy jednoduchý kalkulátor, jde napsat výraz s normální notací (+-*/^), obsahující čísla (i desetinná),
|
||||||
|
který to normálně vyhodnotí. Postupně přibyly proměnné (jen písmenkové řetězce), které mohou mít i rozsah ve
|
||||||
|
kterém se pak výraz zobrazí jako funkce. Komentáře jsou ve složených závorkách. Vložené matematické funkce
|
||||||
|
jsou sin(), cos(), exp(), log() (přirozené).<b>Na konci výrazu musí být ENTER.</b>
|
||||||
|
</p>
|
||||||
|
<p>Jsou v tom chyby, celé je to vlasně hloupost, celé by to šlo napsat v javascriptu mnohem jednodušeji,
|
||||||
|
ale v podstatě to funguje a jde si podle toho udělat představu, jak daná funkce vypadá. Zdrojáky v licenci
|
||||||
|
MIT <a href="flex.zip">přikládám</a>. Pro kompilaci je použit jen clang a jím kompilovaná C-čková knihovna
|
||||||
|
<a href="https://sourceware.org/newlib/" target="_blank">newlib</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
126
index.js
Normal file
126
index.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
var gWASM; // globální proměnná + elementy stránky
|
||||||
|
const Outs = document.getElementById('stdout');
|
||||||
|
const Btnt = document.getElementById('buttonTest');
|
||||||
|
const Canvas = document.getElementById('canvas');
|
||||||
|
// async/await z příkladu na webu
|
||||||
|
window.onload = async function() {
|
||||||
|
Btnt.disabled = true;
|
||||||
|
Outs.value = 'Compiling ...¨\n'; // presets
|
||||||
|
// Build WebAssembly instance - WebAssembly.instantiateStreaming problem
|
||||||
|
const memory = new WebAssembly.Memory({ initial: 4 });
|
||||||
|
const importObject = {
|
||||||
|
env: { memory }, // nutné pro práci a pamětí
|
||||||
|
imports: { // importované funkce do wasm
|
||||||
|
printout : (ptr, len) => {
|
||||||
|
// pohled do paměti - ptr je vlastně číslo
|
||||||
|
const view = new Uint8Array (memory.buffer, ptr, len);
|
||||||
|
const utf8decoder = new TextDecoder();
|
||||||
|
Outs.value += utf8decoder.decode(view); // to String
|
||||||
|
},
|
||||||
|
memoryGrow : (len) => {
|
||||||
|
console.log ('Growing the memory by ' + len.toString() + '. 64K blocks');
|
||||||
|
memory.grow (len); // patrně to jde volat přímo z C/C++ kódu, ale tohle funguje
|
||||||
|
},
|
||||||
|
drawPoints : (px, py, len, pj, jl) => {
|
||||||
|
const xview = new Float32Array (memory.buffer, px, len);
|
||||||
|
const yview = new Float32Array (memory.buffer, py, len);
|
||||||
|
const view = new Uint8Array (memory.buffer, pj, jl);
|
||||||
|
const utf8decoder = new TextDecoder();
|
||||||
|
const obj = JSON.parse (utf8decoder.decode(view));
|
||||||
|
// console.log (obj);
|
||||||
|
if (!obj) obj = '{"name":"nothing"}';
|
||||||
|
polyLine (xview, yview, len, obj);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const response = await fetch('./module.wasm');
|
||||||
|
const bytes = await response.arrayBuffer();
|
||||||
|
const module = await WebAssembly.instantiate(bytes, importObject);
|
||||||
|
gWASM = {
|
||||||
|
asm : module.instance.exports,
|
||||||
|
mem : memory,
|
||||||
|
};
|
||||||
|
gWASM.asm.init(memory.buffer.byteLength);
|
||||||
|
Btnt.onclick = () => {
|
||||||
|
Outs.value = '';
|
||||||
|
const expression = document.getElementById('input').value;
|
||||||
|
// console.log(expression);
|
||||||
|
stringToModule (expression, gWASM.asm.compute);
|
||||||
|
};
|
||||||
|
Outs.value = 'Module compiled - [insert formula and] press button Submit\n';
|
||||||
|
Btnt.disabled = false;
|
||||||
|
// console.log (gWASM);
|
||||||
|
window.addEventListener('resize', resizeCanvas, false);
|
||||||
|
resizeCanvas();
|
||||||
|
getFile ('test.txt');
|
||||||
|
Splash ();
|
||||||
|
};
|
||||||
|
function stringToModule (str, mfunc) {
|
||||||
|
const utf8EncodeText = new TextEncoder();
|
||||||
|
const bytes = utf8EncodeText.encode(str);
|
||||||
|
// alokovat pamet v modulu je nutne, aby bylo kam kopirovat
|
||||||
|
const cArrayPointer = gWASM.asm.cAlloc(bytes.length);
|
||||||
|
if (!cArrayPointer) return;
|
||||||
|
const cArray = new Uint8Array(gWASM.mem.buffer, cArrayPointer, bytes.length);
|
||||||
|
cArray.set(bytes); // naplnit dekodovanym stringem
|
||||||
|
mfunc (cArrayPointer, cArray.length);
|
||||||
|
}
|
||||||
|
function resizeCanvas () {
|
||||||
|
const width = canvas.clientWidth;
|
||||||
|
const height = canvas.clientHeight;
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
// console.log (width, height);
|
||||||
|
gWASM.asm.resizeCanvas (width, height);
|
||||||
|
}
|
||||||
|
function drawLine (ctx, line, x, y) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(line.b[0], line.b[1]);
|
||||||
|
ctx.lineTo(line.e[0], line.e[1]);
|
||||||
|
ctx.lineWidth = line.w;
|
||||||
|
ctx.strokeStyle = line.color;
|
||||||
|
if (line.lbl) {
|
||||||
|
//console.log (line.lbl);
|
||||||
|
ctx.fillStyle = line.color;
|
||||||
|
ctx.fillText (line.lbl, line.b[0] + x, line.b[1] - y);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
function polyLine (ax, ay, len, obj) {
|
||||||
|
// console.log (ax, ay);
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.font = '16px serif';
|
||||||
|
ctx.textAlign = 'left';
|
||||||
|
if (obj.name === "axes") {
|
||||||
|
drawLine (ctx, obj.x, 0, 0);
|
||||||
|
drawLine (ctx, obj.y, 0, 0);
|
||||||
|
const ndotsx = obj.xdots.length;
|
||||||
|
for (let n=0; n<ndotsx; n++) { drawLine (ctx, obj.xdots[n], 0, 5); }
|
||||||
|
const ndotsy = obj.ydots.length;
|
||||||
|
for (let n=0; n<ndotsy; n++) { drawLine (ctx, obj.ydots[n], 10, 0); }
|
||||||
|
}
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(ax[0], ay[0]);
|
||||||
|
for (let n=1; n<len; n++) {
|
||||||
|
ctx.lineTo(ax[n], ay[n]);
|
||||||
|
}
|
||||||
|
ctx.lineWidth = 3;
|
||||||
|
ctx.strokeStyle = "#00ff00";
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
async function getFile (name) {
|
||||||
|
const response = await fetch (name);
|
||||||
|
if (!response.ok) return;
|
||||||
|
const bytes = await response.arrayBuffer();
|
||||||
|
const array = new Uint8Array(bytes);
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
document.getElementById('input').value = decoder.decode(bytes);
|
||||||
|
}
|
||||||
|
function Splash () {
|
||||||
|
const content = Canvas.getContext('2d');
|
||||||
|
content.font = '96px serif';
|
||||||
|
content.fillStyle = '#00FF00';
|
||||||
|
content.textAlign = 'center';
|
||||||
|
content.fillText ('Graphic calculator', Canvas.width / 2, Canvas.height / 2);
|
||||||
|
}
|
BIN
module.wasm
Executable file
BIN
module.wasm
Executable file
Binary file not shown.
7
test.txt
Normal file
7
test.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{vlnový balík}
|
||||||
|
max=10
|
||||||
|
x=-max,max,1000
|
||||||
|
a=1/4
|
||||||
|
omega=2*pi
|
||||||
|
phi=omega/4
|
||||||
|
1.e-8 * sin (omega*x - phi) * exp (-(x*a)^2)
|
Loading…
Reference in a new issue