mondo: def node
This commit is contained in:
parent
b4027fd92a
commit
a0fb8fb37f
3 changed files with 27 additions and 11 deletions
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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', () =>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue