mondo: let expressions
This commit is contained in:
parent
60d09adb44
commit
989bd0990e
2 changed files with 59 additions and 0 deletions
|
|
@ -331,6 +331,19 @@ export class MondoRunner {
|
||||||
//console.log(printAst(ast));
|
//console.log(printAst(ast));
|
||||||
return this.evaluate(ast, scope);
|
return this.evaluate(ast, scope);
|
||||||
}
|
}
|
||||||
|
evaluate_let(ast, scope) {
|
||||||
|
// (let ((x 3) (y 4)) ...body)
|
||||||
|
// = ((fn (x y) ...body) 3 4)
|
||||||
|
const defs = ast.children[1].children;
|
||||||
|
const args = defs.map((pair) => pair.children[0]);
|
||||||
|
const vals = defs.map((pair) => pair.children[1]);
|
||||||
|
const body = ast.children.slice(2);
|
||||||
|
const lambda = {
|
||||||
|
type: 'list',
|
||||||
|
children: [{ type: 'plain', value: 'fn' }, { type: 'list', children: args }, ...body],
|
||||||
|
};
|
||||||
|
return this.evaluate({ type: 'list', children: [lambda, ...vals] }, scope);
|
||||||
|
}
|
||||||
evaluate_def(ast, scope) {
|
evaluate_def(ast, scope) {
|
||||||
// function definition special form?
|
// function definition special form?
|
||||||
if (ast.children[1].type === 'list') {
|
if (ast.children[1].type === 'list') {
|
||||||
|
|
@ -441,6 +454,9 @@ export class MondoRunner {
|
||||||
if (name === 'if') {
|
if (name === 'if') {
|
||||||
return this.evaluate_if(ast, scope);
|
return this.evaluate_if(ast, scope);
|
||||||
}
|
}
|
||||||
|
if (name === 'let') {
|
||||||
|
return this.evaluate_let(ast, scope);
|
||||||
|
}
|
||||||
if (name === 'def') {
|
if (name === 'def') {
|
||||||
this.evaluate_def(ast, scope);
|
this.evaluate_def(ast, scope);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -610,4 +610,47 @@ describe('mondo arithmetic', () => {
|
||||||
),
|
),
|
||||||
).toEqual(0.24998750000000042));
|
).toEqual(0.24998750000000042));
|
||||||
it('sicp 84.1', () => expect(evaluate(`((fn (x y z) (+ x y (square z))) 1 2 3)`, scope)).toEqual(12));
|
it('sicp 84.1', () => expect(evaluate(`((fn (x y z) (+ x y (square z))) 1 2 3)`, scope)).toEqual(12));
|
||||||
|
|
||||||
|
// let expressions
|
||||||
|
it('sicp 87.1', () =>
|
||||||
|
expect(
|
||||||
|
evaluate(
|
||||||
|
`
|
||||||
|
(+ (let ((x 3))
|
||||||
|
(+ x (* x 10))) x)
|
||||||
|
`,
|
||||||
|
{ x: 5 },
|
||||||
|
),
|
||||||
|
).toEqual(38));
|
||||||
|
it('sicp 87.2', () =>
|
||||||
|
expect(
|
||||||
|
evaluate(
|
||||||
|
`
|
||||||
|
(let ((x 3)
|
||||||
|
(y (+ x 2)))
|
||||||
|
(* x y))
|
||||||
|
`,
|
||||||
|
{ x: 2 },
|
||||||
|
),
|
||||||
|
).toEqual(12));
|
||||||
|
it('sicp 88.1', () =>
|
||||||
|
expect(
|
||||||
|
evaluate(
|
||||||
|
`
|
||||||
|
(def (f g) (g 2))
|
||||||
|
(f square)
|
||||||
|
`,
|
||||||
|
scope,
|
||||||
|
),
|
||||||
|
).toEqual(4));
|
||||||
|
it('sicp 88.2', () =>
|
||||||
|
expect(
|
||||||
|
evaluate(
|
||||||
|
`
|
||||||
|
(def (f g) (g 2))
|
||||||
|
(f (fn (z) (* z (+ z 1))))
|
||||||
|
`,
|
||||||
|
scope,
|
||||||
|
),
|
||||||
|
).toEqual(6));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue