Skip to content

Commit

Permalink
Added another example program + some documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
amitayh committed Aug 21, 2015
1 parent b67eb84 commit 29a70dc
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,23 @@ var map = [
['map', 'inc', 'coll']
];
console.log(lisp.run(map)); // Prints [2, 3, 4]

// Contains (checks if element exists in collection)
var contains = [
// Define contains function
['define', 'contains',
['lambda', ['el', 'coll'],
['if', ['empty', 'coll'],
false,
['or',
['=', 'el', ['car', 'coll']],
['contains', 'el', ['cdr', 'coll']]]]]],

// Define some collection
['define', 'coll', ['quote', [1, 2, 3]]],

// Check if collection contains 2
['contains', 2, 'coll']
];
console.log(lisp.run(contains)); // Prints true
```
24 changes: 20 additions & 4 deletions specs/lisp-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ describe('lispjs', function () {

describe('programs tests', function () {
it('should calculate fibonacci recursively', function () {
var prog =
var fib =
['define', 'fib',
['lambda', ['n'],
['if', ['<', 'n', 2],
Expand All @@ -152,7 +152,7 @@ describe('lispjs', function () {
['fib', ['-', 'n', 1]],
['fib', ['-', 'n', 2]]]]]];

var fibEnv = lisp.evaluate(prog, lisp.defaultEnv)[1];
var fibEnv = lisp.evaluate(fib, lisp.defaultEnv)[1];

var tests = [
{input: 0, output: 1},
Expand All @@ -168,14 +168,14 @@ describe('lispjs', function () {
});

it('should calculate factorial recursively', function () {
var prog =
var fact =
['define', 'fact',
['lambda', ['n'],
['if', ['<', 'n', 2],
1,
['*', 'n', ['fact', ['-', 'n', 1]]]]]];

var factEnv = lisp.evaluate(prog, lisp.defaultEnv)[1];
var factEnv = lisp.evaluate(fact, lisp.defaultEnv)[1];

var tests = [
{input: 0, output: 1},
Expand Down Expand Up @@ -215,6 +215,22 @@ describe('lispjs', function () {

assert.deepEqual(lisp.run(prog), [2, 3, 4]);
});

it('should search for element in collection', function () {
var contains =
['define', 'contains',
['lambda', ['el', 'coll'],
['if', ['empty', 'coll'],
false,
['or',
['=', 'el', ['car', 'coll']],
['contains', 'el', ['cdr', 'coll']]]]]];

var containsEnv = lisp.evaluate(contains, lisp.defaultEnv)[1];

assert.equal(lisp.getResult(['contains', 0, ['quote', [1, 2, 3]]], containsEnv), false);
assert.equal(lisp.getResult(['contains', 2, ['quote', [1, 2, 3]]], containsEnv), true);
});
});

});
18 changes: 17 additions & 1 deletion src/lisp.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Evaluate an expression with given environment.
* Returns a tuple [result, env] - with evaluation result and new environment
*/
function evaluate(expr, env) {
if (isBound(expr, env)) {
return [env[expr], env];
Expand All @@ -14,10 +18,19 @@ function evaluate(expr, env) {
return [expr, env];
}

/**
* Evaluate an expression with given environment.
* Returns just the evaluation result
*/
function getResult(expr, env) {
return evaluate(expr, env)[0];
}

/**
* Run a program in with default environment.
* A program is a list of expressions.
* Returns the evaluation result of the last expression
*/
function run(prog) {
var result = [null, defaultEnv];
prog.forEach(function (expr) {
Expand Down Expand Up @@ -76,6 +89,9 @@ var defaultEnv = {
'-': function (a, b) { return a - b; },
'*': function (a, b) { return a * b; },
'/': function (a, b) { return a / b; },
and: function (a, b) { return a && b; },
or: function (a, b) { return a || b; },
not: function (expr) { return !expr; },
car: function (xs) { return xs[0]; },
cdr: function (xs) { return xs.slice(1); },
cons: function (x, xs) { return [x].concat(xs); },
Expand All @@ -87,4 +103,4 @@ module.exports = {
evaluate: evaluate,
getResult: getResult,
run: run
};
};

0 comments on commit 29a70dc

Please sign in to comment.