summaryrefslogtreecommitdiffstats
path: root/site/robo.mjs
blob: e6db244f544a820bae022e0b369074be18bd48e4 (plain)
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
import init, { make_vm } from './wasm/automathon.js';

let vm;

function vmData(vm) {
    const wordlist = vm.wordlist().map(bc => {
        let res = [];
        for (let i = 0; i < bc.len(); i++) {
            res.push(bc.at(i))
        }
        return res;
    });
    const callstack = vm.callstack().map(e => { return { word: e.word, offset: e.offset }; });
    const vars = Object.fromEntries(['out', 'heading', 'speed', 'doppler'].map(name => [name, vm[name]()]));
    const ip = {word: vm.ip().word, offset: vm.ip().offset};
    const annos = vm.annotations().map(word_annos => {
        let res = [];
        for (let i = 0; i < word_annos.len(); i++) {
            const anno = word_annos.at(i);
            res.push({ start: anno.start, end: anno.end })
        }
        return res;
    });
    return {
        wordlist,
        stack: vm.stack(),
        callstack,
        vars,
        ip,
        annos,
    }
}

function compile(text) {
    const start = performance.now();
    const res = vm.compile(text);
    const end = performance.now();
    console.info(`compile took ${end-start} ms`);
    postMessage({ kind: 'compile', res, vm: vmData(vm) });
}

function tick() {
    if (!vm.tick()) {
        vm.reset_ip();
    }
    postMessage({ kind: 'tick', vm: vmData(vm) });
}

let mod;
async function messageHandler(e) {
    if (mod === undefined) {
        console.debug('worker running init');
        mod = await init();
        console.debug('worker init done');
        vm = make_vm();
        console.debug('worker vm made');
    }
    const { kind } = e.data;
    switch (kind) {
    case 'compile':
        compile(e.data.text);
        break;
    case 'tick':
        tick();
        break;
    default:
        console.error('invalid message to robo worker', e.data);
        postMessage({ kind: 'error', error: 'badmsg' });
    }
}

console.debug('loading robo worker');
addEventListener('message', messageHandler);