1import { reify } from '@strudel/core'; 2import { m } from '@strudel/mini'; 3import { loadParser, evaluate } from 'hs2js'; 4 5function getInfixOperators() { 6 let operators = { 7 '>': 'set', 8 '#': 'set', 9 '+': 'add', 10 '-': 'sub', 11 '*': 'mul', 12 '/': 'div', 13 }; 14 let alignments = { 15 in: (s) => '|' + s, 16 out: (s) => s + '|', 17 mix: (s) => '|' + s + '|', 18 }; 19 let ops = {}; 20 Object.entries(operators).forEach(([o, name]) => { 21 // operator without alignment 22 ops[o] = (l, r) => reify(l)[name](reify(r)); 23 Object.entries(alignments).forEach(([a, getSymbol]) => { 24 // get symbol with alignment 25 let symbol = getSymbol(o); 26 ops[symbol] = (l, r) => reify(l)[name][a](reify(r)); 27 }); 28 }); 29 ops['~>'] = (l, r) => reify(l).late(reify(r)); 30 ops['<~'] = (l, r) => reify(l).early(reify(r)); 31 ops['<$>'] = (l, r) => reify(r).fmap(l).outerJoin(); // is this right? 32 return ops; 33} 34const ops = getInfixOperators(); 35 36export async function initTidal() { 37 // TODO: implement this in regular land 38 window.d1 = (pat) => pat.p('d1'); 39 window.d2 = (pat) => pat.p('d2'); 40 window.d3 = (pat) => pat.p('d3'); 41 window.d4 = (pat) => pat.p('d4'); 42 window.d5 = (pat) => pat.p('d5'); 43 window.d6 = (pat) => pat.p('d6'); 44 window.d7 = (pat) => pat.p('d7'); 45 window.d8 = (pat) => pat.p('d8'); 46 window.d9 = (pat) => pat.p('d9'); 47 return loadParser(); 48} 49 50// offset is expected to be passed in from transpiler 51/* 521. acorn parses JS to find location of tidal call 532. haskell-tree-sitter calls "string" function with node (including location) 543. m function sets locations for individual mini notation atom 55 56so the location for a mini notation atom is: 57 58js offset + hs offset + atom offset 59*/ 60export function tidal(code, offset = 0) { 61 if (Array.isArray(code)) { 62 code = code.join(''); 63 } 64 return evaluate(code, window, { 65 ...ops, 66 string: (node) => { 67 // parses strings as mini notation and passes location 68 const str = node.text.slice(1, -1); 69 const col = node.startIndex + offset; 70 return m(str, col); 71 }, 72 }); 73}