transpiler (for future reference)

This commit is contained in:
Felix Roos 2024-05-17 23:09:43 +02:00
parent 2499c4057c
commit 3b4ae44fb3
2 changed files with 58 additions and 4 deletions

View File

@ -52,6 +52,9 @@ function curry(patterns, body, scope, ops) {
export function run(node, scope, ops = {}) {
let runInScope = (node, scp = scope) => run(node, scp, ops);
//console.log("node", node.type, node.text);
if (ops[node.type]) {
return ops[node.type](node);
}
switch (node.type) {
case 'ERROR':
throw new Error(`invalid syntax: "${node.text}"`);

View File

@ -1,6 +1,5 @@
import { reify } from '@strudel/core';
import { miniAllStrings } from '@strudel/mini';
import { evaluate, loadParser } from 'hs2js';
import { loadParser, run, parse } from 'hs2js';
function getInfixOperators() {
let operators = {
@ -29,12 +28,15 @@ function getInfixOperators() {
ops['~>'] = (l, r) => reify(l).late(reify(r));
ops['<~'] = (l, r) => reify(l).early(reify(r));
ops['<$>'] = (l, r) => reify(r).fmap(l).outerJoin(); // is this right?
ops['string'] = (node) => {
const str = node.text.slice(1, -1);
return m(str, 1);
};
return ops;
}
const ops = getInfixOperators();
export async function initTidal() {
miniAllStrings(); // TODO: get rid of this and implement custom string parser in hs2js
// TODO: implement this in regular land
window.d1 = (pat) => pat.p('d1');
window.d2 = (pat) => pat.p('d2');
@ -45,6 +47,10 @@ export async function initTidal() {
window.d7 = (pat) => pat.p('d7');
window.d8 = (pat) => pat.p('d8');
window.d9 = (pat) => pat.p('d9');
window.minicurry = (str) => (loc) => {
console.log('minicurry', str, loc);
return m(str, loc);
};
return loadParser();
}
@ -52,5 +58,50 @@ export function tidal(code) {
if (Array.isArray(code)) {
code = code.join('');
}
return evaluate(code, window, ops);
let ast = parse(code).rootNode;
// ast = transpile(ast);
console.log('ast', ast);
return run(ast, window, ops);
}
function edit(ast, options) {
if (!ast || ast.skip) {
return ast;
}
const { enter, leave } = options;
ast = enter?.(ast);
if (!ast.skip && ast.children) {
const children = ast.children.map((child) => edit(child, options));
ast = { type: ast.type, text: ast.text, children };
}
leave?.(ast);
return ast;
}
function transpile(ast) {
return edit(ast, {
enter: (node) => {
if (node.type === 'literal' && node.children[0].type === 'string') {
return miniWithLocation(node.text, 1);
}
return node;
},
});
}
function miniWithLocation(string, loc) {
return {
type: 'apply',
children: [
{
type: 'apply',
skip: true,
children: [
{ type: 'variable', text: 'minicurry', children: [] },
{ type: 'string', text: string, children: [] },
],
},
{ type: 'float', text: loc + '', children: [] },
],
};
}