tidy tidal package
- move tidal repl to examples - make hs2js synchronous
This commit is contained in:
parent
d108de40d0
commit
fd950d4476
12 changed files with 171 additions and 154 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
|
|
|
|||
27
packages/tidal/.gitignore
vendored
27
packages/tidal/.gitignore
vendored
|
|
@ -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
|
||||
|
|
@ -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
|
||||
```
|
||||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
# public
|
||||
|
||||
this file is just here to make sure the public folder exists
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue