feat: add mondough package to run strudel via mondo
This commit is contained in:
parent
11196fb1e6
commit
fae59a6bcd
8 changed files with 221 additions and 5 deletions
|
|
@ -19,8 +19,11 @@ export class MondoParser {
|
|||
pipe: /^\./,
|
||||
stack: /^,/,
|
||||
op: /^[*/]/,
|
||||
plain: /^[a-zA-Z0-9-]+/,
|
||||
plain: /^[a-zA-Z0-9-_]+/,
|
||||
};
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
}
|
||||
// matches next token
|
||||
next_token(code) {
|
||||
for (let type in this.token_types) {
|
||||
|
|
@ -29,7 +32,7 @@ export class MondoParser {
|
|||
return { type, value: match[0] };
|
||||
}
|
||||
}
|
||||
throw new Error(`zilp: could not match '${code}'`);
|
||||
throw new Error(`mondo: could not match '${code}'`);
|
||||
}
|
||||
// takes code string, returns list of matched tokens (if valid)
|
||||
tokenize(code) {
|
||||
|
|
@ -182,7 +185,7 @@ export class MondoParser {
|
|||
const [callee, ...rest] = right.children;
|
||||
const leftSide = children.slice(0, pipeIndex - 1);
|
||||
const left = children[pipeIndex - 1];
|
||||
const args = [callee, left, ...rest];
|
||||
let args = [callee, left, ...rest];
|
||||
const call = { type: 'list', children: args };
|
||||
children = [...leftSide, call, ...rightSide];
|
||||
} else {
|
||||
|
|
@ -200,6 +203,10 @@ export class MondoParser {
|
|||
}
|
||||
return children;
|
||||
}
|
||||
flip_call(children) {
|
||||
let [name, first, ...rest] = children;
|
||||
return [name, ...rest, first];
|
||||
}
|
||||
parse_pair(open_type, close_type) {
|
||||
this.consume(open_type);
|
||||
const children = [];
|
||||
|
|
@ -252,9 +259,10 @@ export function printAst(ast, compact = false, lvl = 0) {
|
|||
|
||||
// lisp runner
|
||||
export class MondoRunner {
|
||||
constructor(lib) {
|
||||
this.parser = new MondoParser();
|
||||
constructor(lib, config = {}) {
|
||||
this.parser = new MondoParser(config);
|
||||
this.lib = lib;
|
||||
this.config = config;
|
||||
}
|
||||
// a helper to check conditions and throw if they are not met
|
||||
assert(condition, error) {
|
||||
|
|
@ -264,6 +272,7 @@ export class MondoRunner {
|
|||
}
|
||||
run(code) {
|
||||
const ast = this.parser.parse(code);
|
||||
console.log(printAst(ast));
|
||||
return this.call(ast);
|
||||
}
|
||||
call(ast) {
|
||||
|
|
@ -298,6 +307,9 @@ export class MondoRunner {
|
|||
// look up function in lib
|
||||
const fn = this.lib[name];
|
||||
this.assert(fn, `function call: unknown function name "${name}"`);
|
||||
if (this.lib.call) {
|
||||
return this.lib.call(fn, args, name);
|
||||
}
|
||||
return fn(...args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
packages/mondough/README.md
Normal file
3
packages/mondough/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# @strudel/mondough
|
||||
|
||||
connects mondo to strudel.
|
||||
35
packages/mondough/mondough.mjs
Normal file
35
packages/mondough/mondough.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { strudelScope, reify, fast, slow, isControlName } from '@strudel/core';
|
||||
import { MondoRunner } from '../mondo/mondo.mjs';
|
||||
|
||||
let runner = new MondoRunner(strudelScope, { pipepost: true });
|
||||
|
||||
//strudelScope.plain = reify;
|
||||
strudelScope.plain = (v) => {
|
||||
// console.log('plain', v);
|
||||
return reify(v);
|
||||
// return v;
|
||||
};
|
||||
// strudelScope.number = (n) => n;
|
||||
strudelScope.number = reify;
|
||||
|
||||
strudelScope.call = (fn, args, name) => {
|
||||
const [pat, ...rest] = args;
|
||||
if (!['seq', 'cat', 'stack'].includes(name)) {
|
||||
args = [...rest, pat];
|
||||
}
|
||||
|
||||
// console.log('call', name, ...flipped);
|
||||
|
||||
return fn(...args);
|
||||
};
|
||||
|
||||
strudelScope['*'] = fast;
|
||||
strudelScope['/'] = slow;
|
||||
|
||||
export function mondo(code, offset = 0) {
|
||||
if (Array.isArray(code)) {
|
||||
code = code.join('');
|
||||
}
|
||||
const pat = runner.run(code, { pipepost: true });
|
||||
return pat;
|
||||
}
|
||||
42
packages/mondough/package.json
Normal file
42
packages/mondough/package.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "@strudel/mondough",
|
||||
"version": "1.1.0",
|
||||
"description": "mondo notation for strudel",
|
||||
"main": "mondough.mjs",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"main": "dist/mondough.mjs"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"bench": "vitest bench",
|
||||
"build:parser": "peggy -o krill-parser.js --format es ./krill.pegjs",
|
||||
"build": "vite build",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tidalcycles/strudel.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tidalcycles",
|
||||
"strudel",
|
||||
"pattern",
|
||||
"livecoding",
|
||||
"algorave"
|
||||
],
|
||||
"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",
|
||||
"dependencies": {
|
||||
"@strudel/core": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mondo": "*",
|
||||
"vite": "^6.0.11",
|
||||
"vitest": "^3.0.4"
|
||||
}
|
||||
}
|
||||
19
packages/mondough/vite.config.js
Normal file
19
packages/mondough/vite.config.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { defineConfig } from 'vite';
|
||||
//import { dependencies } from './package.json';
|
||||
import { resolve } from 'path';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [],
|
||||
build: {
|
||||
lib: {
|
||||
entry: resolve(__dirname, 'mondough.mjs'),
|
||||
formats: ['es'],
|
||||
fileName: (ext) => ({ es: 'mondough.mjs' })[ext],
|
||||
},
|
||||
rollupOptions: {
|
||||
// external: [...Object.keys(dependencies)],
|
||||
},
|
||||
target: 'esnext',
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue