diff --git a/packages/mondo/mondo.mjs b/packages/mondo/mondo.mjs index 0e8dc857..89236a3b 100644 --- a/packages/mondo/mondo.mjs +++ b/packages/mondo/mondo.mjs @@ -175,10 +175,10 @@ export class MondoParser { return children; } get_lambda(args, children) { - // (.fast 2) = (lambda (_) (fast _ 2)) + // (.fast 2) = (fn (_) (fast _ 2)) children = this.desugar(children); const body = children.length === 1 ? children[0] : { type: 'list', children }; - return [{ type: 'plain', value: 'lambda' }, { type: 'list', children: args }, body]; + return [{ type: 'plain', value: 'fn' }, { type: 'list', children: args }, body]; } // returns location range of given ast (even if desugared) get_range(ast, range = [Infinity, 0]) { @@ -322,7 +322,7 @@ export class MondoRunner { console.log(printAst(ast)); return this.evaluate(ast); } - evaluate(ast, scope = []) { + evaluate(ast, scope = {}) { if (ast.type !== 'list') { // is leaf if (ast.type === 'number') { @@ -333,7 +333,20 @@ export class MondoRunner { return this.evaluator(ast, scope); } - if (ast.children[0]?.value === 'lambda') { + if (ast.children[0]?.value === 'def') { + if (ast.children.length !== 3) { + throw new Error(`expected "def" to have 3 children, but got ${ast.children.length}`); + } + // (def myfn (fn (_) (ply 2 _))) + // ^name ^body + const name = ast.children[1].value; + const body = this.evaluate(ast.children[2], scope); + scope[name] = body; + return this.evaluator(ast, scope); + } + if (ast.children[0]?.value === 'fn') { + // (fn (_) (ply 2 _) + // ^args ^ body const [_, args, body] = ast.children; const argNames = args.children.map((child) => child.value); return (x) => { diff --git a/packages/mondo/test/mondo.test.mjs b/packages/mondo/test/mondo.test.mjs index 338a1fec..47e0e165 100644 --- a/packages/mondo/test/mondo.test.mjs +++ b/packages/mondo/test/mondo.test.mjs @@ -119,10 +119,10 @@ describe('mondo sugar', () => { '(speed .8 (s (square bd (* 2 hh) (crush 4 cp) (angle mt ht lt))))', )); - it('should desugar (.)', () => expect(desguar('(.)')).toEqual('(lambda (_) _)')); - it('should desugar lambda', () => expect(desguar('(.fast 2)')).toEqual('(lambda (_) (fast 2 _))')); + it('should desugar (.)', () => expect(desguar('(.)')).toEqual('(fn (_) _)')); + it('should desugar lambda', () => expect(desguar('(.fast 2)')).toEqual('(fn (_) (fast 2 _))')); it('should desugar lambda with pipe', () => - expect(desguar('(.fast 2 .room 1)')).toEqual('(lambda (_) (room 1 (fast 2 _)))')); + expect(desguar('(.fast 2 .room 1)')).toEqual('(fn (_) (room 1 (fast 2 _)))')); /* const lambda = parser.parse('(lambda (_) (fast 2 _))'); const target = { type: 'plain', value: 'xyz' }; it('should desugar_lambda', () => diff --git a/packages/mondough/mondough.mjs b/packages/mondough/mondough.mjs index d84ceb0c..543dcfeb 100644 --- a/packages/mondough/mondough.mjs +++ b/packages/mondough/mondough.mjs @@ -49,15 +49,19 @@ function evaluator(node, scope) { if (type === 'list') { const { children } = node; const [name, ...args] = children; + if (name.value === 'def') { + return silence; + } // name is expected to be a pattern of functions! const first = name.firstCycle(true)[0]; - if (typeof first?.value !== 'function') { - throw new Error(`[mondough] "${first}" is not a function`); + const type = typeof first?.value; + if (type !== 'function') { + throw new Error(`[mondough] "${first}" is not a function, got ${type} ...`); } return name .fmap((fn) => { if (typeof fn !== 'function') { - throw new Error(`[mondough] "${fn}" is not a function`); + throw new Error(`[mondough] "${fn}" is not a function b`); } return fn(...args); }) @@ -80,7 +84,6 @@ function evaluator(node, scope) { if (node.loc) { pat = pat.withLoc(node.loc[0], node.loc[1]); } - pat.foo = true; return pat; }