From abc7a1e48d3e8cfb301d39a711ddb59ffcf8ae38 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 26 Mar 2025 03:55:00 +0100 Subject: [PATCH] mondo: this is the way --- packages/mondo/mondo.mjs | 17 +++++++---------- packages/mondough/mondough.mjs | 5 +++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index 165e597bb..3ff781256 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -207,11 +207,6 @@ export class MondoParser { while (chunks.length > 1) { let [left, right, ...rest] = chunks; - if (right.length && right[0].type === 'list') { - // x.(y) => not allowed anymore for now.. - const snip = this.get_code_snippet(right[0]); - throw new Error(`${this.errorhead(right[0])} cannot apply list: expected "(${snip})" to be a word`); - } if (!left.length) { const arg = { type: 'plain', value: '_' }; return this.get_lambda([arg], [arg, ...children]); @@ -342,11 +337,13 @@ export class MondoRunner { // is list // the first element is expected to be the function name const first = ast.children[0]; - const name = first.value; - this.assert( - first?.type === 'plain', - `${this.parser.errorhead(first)} expected function name, got ${first.type}${name ? ` "${name}"` : ''}.`, - ); + let name; + if (first?.type !== 'list') { + name = first.value; // regular function call e.g. (fast 2 (s bd)) + } else { + // dynamic function name e.g. "( 2 (s bd))" + name = this.evaluate(first); + } if (name === 'lambda') { const [_, args, body] = ast.children; diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index f42f0ca76..081d054b9 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -11,6 +11,7 @@ import { chooseIn, degradeBy, silence, + isPattern, } from '@strudel/core'; import { registerLanguage } from '@strudel/transpiler'; import { MondoRunner } from '../mondo/mondo.mjs'; @@ -42,6 +43,10 @@ lib['or'] = (...children) => chooseIn(...children); // always has structure but let runner = new MondoRunner({ call(name, args, scope) { + if (isPattern(name)) { + // patterned function name, e.g. "s bd . 2" + return name.fmap((fn) => fn(...args)).innerJoin(); + } const fn = lib[name] || strudelScope[name]; if (!fn) { throw new Error(`[moundough]: unknown function "${name}"`);