main.jsannotatedmain.jssource83 lines · 2.2 KB · raw
1import { run, parse, loadParser } from 'hs2js';
2import { initStrudel, reify, late, samples, stack } from '@strudel/web';
3
4initStrudel({
5  prebake: () => samples('github:tidalcycles/dirt-samples'),
6});
7
8const ready = loadParser();
9
10const textarea = document.getElementById('code');
11if (window.location.hash) {
12  textarea.value = atob(window.location.hash.slice(1));
13} else {
14  textarea.value = 'd1 $ s "jvbass(3,8)"';
15}
16textarea.addEventListener('input', (e) => {
17  window.location.hash = btoa(e.target.value);
18  update();
19});
20update();
21
22function getInfixOperators() {
23  let operators = {
24    '>': 'set',
25    '#': 'set',
26    '+': 'add',
27    '-': 'sub',
28    '*': 'mul',
29    '/': 'div',
30  };
31  let alignments = {
32    in: (s) => '|' + s,
33    out: (s) => s + '|',
34    mix: (s) => '|' + s + '|',
35  };
36  let ops = {};
37  Object.entries(operators).forEach(([o, name]) => {
38    // operator without alignment
39    ops[o] = (l, r) => reify(l)[name](reify(r));
40    Object.entries(alignments).forEach(([a, getSymbol]) => {
41      // get symbol with alignment
42      let symbol = getSymbol(o);
43      ops[symbol] = (l, r) => reify(l)[name][a](reify(r));
44    });
45  });
46  ops['~>'] = (l, r) => reify(l).late(reify(r));
47  ops['<~'] = (l, r) => reify(l).early(reify(r));
48  ops['<$>'] = (l, r) => reify(r).fmap(l).outerJoin(); // is this right?
49  return ops;
50}
51const ops = getInfixOperators();
52
53async function update() {
54  let result, tree;
55  await ready;
56  try {
57    tree = parse(textarea.value);
58  } catch (err) {
59    console.warn('parse error');
60    console.error(err);
61  }
62  console.log('parsed tree');
63  console.log(tree.rootNode.toString());
64  try {
65    let patterns = {};
66    window.p = (name, pattern) => {
67      patterns[name] = pattern;
68    };
69    window.d1 = (pat) => window.p(1, pat);
70    window.d2 = (pat) => window.p(2, pat);
71    window.d3 = (pat) => window.p(3, pat);
72    window.rot = late;
73    result = run(tree.rootNode, window, ops);
74    if (Object.values(patterns).length) {
75      stack(...Object.values(patterns)).play();
76    }
77  } catch (err) {
78    console.warn('eval error');
79    console.error(err);
80    result = 'ERROR: ' + err.message;
81  }
82  document.getElementById('result').innerHTML = 'Result: ' + result;
83}