tidy tidal package

- move tidal repl to examples
- make hs2js synchronous
This commit is contained in:
Felix Roos 2024-05-17 20:36:41 +02:00
parent d108de40d0
commit fd950d4476
12 changed files with 171 additions and 154 deletions

View file

@ -2,8 +2,12 @@
"name": "hs2js",
"version": "0.0.7",
"description": "Experimental Haskell in JavaScript interpreter",
"main": "dist/index.js",
"module": "dist/index.mjs",
"main": "src/index.mjs",
"type": "module",
"publishConfig": {
"main": "dist/index.js",
"module": "dist/index.mjs"
},
"scripts": {
"build-wasm": "tree-sitter build-wasm node_modules/tree-sitter-haskell && mv tree-sitter-haskell.wasm ./dist/ && cp node_modules/web-tree-sitter/tree-sitter.wasm ./dist/",
"build": "vite build && npm run build-wasm",

View file

@ -127,7 +127,7 @@ export function run(node, scope, ops = {}) {
}
}
export async function evaluate(haskellCode, scope = globalThis, ops) {
const ast = await parse(haskellCode);
export function evaluate(haskellCode, scope = globalThis, ops) {
const ast = parse(haskellCode);
return run(ast.rootNode, scope, ops);
}

View file

@ -5,15 +5,18 @@ export function setBase(path) {
base = path;
}
let isReady = false,
parser;
async function _loadParser() {
await Parser.init({
locateFile(scriptName, scriptDirectory) {
return `${base}${scriptName}`;
},
});
const parser = new Parser();
parser = new Parser();
const Lang = await Parser.Language.load(`${base}tree-sitter-haskell.wasm`);
parser.setLanguage(Lang);
isReady = true;
return parser;
}
@ -25,8 +28,10 @@ export function loadParser() {
return parserLoaded;
}
export async function parse(code) {
const parser = await loadParser();
export function parse(code) {
if (!isReady) {
throw new Error('hs2js not ready. await loadParser before calling evaluate or parse functions');
}
// for some reason, the parser doesn't like new lines..
return parser.parse(code.replaceAll('\n\n', '~~~~').replaceAll('\n', '').replaceAll('~~~~', '\n'));
}

View file

@ -1,27 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
public/tree-sitter.wasm
public/tree-sitter-haskell.wasm

View file

@ -1,10 +0,0 @@
# @strudel/tidal
This is an experiment in implementing tree-sitter for parsing haskell.
```sh
pnpm i
cd haskell
pnpm copy-wasm
pnpm dev
```

View file

@ -1,28 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tree sitter test</title>
<style>
body {
background-color: #121213;
color: white;
}
textarea {
padding: 10px;
color: white;
background-color: transparent;
outline: none;
}
a {
color: white;
}
</style>
</head>
<body style="margin: 0; padding: 0">
<textarea id="code" style="width: 100%; height: 200px"></textarea>
<pre id="result"></pre>
<script type="module" src="/tidal.mjs"></script>
</body>
</html>

View file

@ -1,36 +1,26 @@
{
"name": "@strudel/tidal",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"build": "pnpm copy-wasm && vite build",
"preview": "vite preview",
"copy-wasm": "cp node_modules/hs2js/dist/tree-sitter.wasm public && cp node_modules/hs2js/dist/tree-sitter-haskell.wasm public"
},
"version": "0.0.7",
"description": "Experimental Tidal Code interpreter",
"module": "tidal.mjs",
"repository": {
"type": "git",
"url": "git+https://github.com/tidalcycles/strudel.git"
"url": "git+https://github.com/felixroos/hs2js.git"
},
"keywords": [
"titdalcycles",
"strudel",
"pattern",
"livecoding",
"algorave"
"haskell",
"javascript"
],
"author": "Felix Roos <flix91@gmail.com>",
"license": "AGPL-3.0-or-later",
"bugs": {
"url": "https://github.com/tidalcycles/strudel/issues"
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"homepage": "https://github.com/tidalcycles/strudel/tree/main/packages/hs2js",
"dependencies": {
"@strudel/web": "workspace:*",
"hs2js": "workspace:*"
},
"devDependencies": {
"vite": "^5.0.8"
"vite": "^5.0.10"
}
}

View file

@ -1,3 +0,0 @@
# public
this file is just here to make sure the public folder exists

View file

@ -1,20 +1,4 @@
import { run, parse } from 'hs2js';
import { initStrudel, reify, late, samples, stack } from '@strudel/web';
initStrudel({
prebake: () => samples('github:tidalcycles/dirt-samples'),
});
const textarea = document.getElementById('code');
if (window.location.hash) {
textarea.value = atob(window.location.hash.slice(1));
} else {
textarea.value = 'd1 $ s "jvbass(3,8)"';
}
textarea.addEventListener('input', (e) => {
window.location.hash = btoa(e.target.value);
update();
});
update();
import { evaluate, loadParser } from 'hs2js';
function getInfixOperators() {
let operators = {
@ -47,33 +31,10 @@ function getInfixOperators() {
}
const ops = getInfixOperators();
async function update() {
let result, tree;
try {
tree = await parse(textarea.value);
} catch (err) {
console.warn('parse error');
console.error(err);
}
console.log('parsed tree');
console.log(tree.rootNode.toString());
try {
let patterns = {};
window.p = (name, pattern) => {
patterns[name] = pattern;
};
window.d1 = (pat) => window.p(1, pat);
window.d2 = (pat) => window.p(2, pat);
window.d3 = (pat) => window.p(3, pat);
window.rot = late;
result = run(tree.rootNode, window, ops);
if (Object.values(patterns).length) {
stack(...Object.values(patterns)).play();
}
} catch (err) {
console.warn('eval error');
console.error(err);
result = 'ERROR: ' + err.message;
}
document.getElementById('result').innerHTML = 'Result: ' + result;
export async function initTidal() {
return loadParser();
}
export function tidal(code) {
return evaluate(code, window, ops);
}