Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Evaluator for Little Schemer chapter 1
class Atom
attr_reader :symbol
def initialize(symbol)
@symbol = symbol
end
def ==(other)
self.symbol == other.symbol
end
end
class Evaluator
def initialize(program)
@program = program
end
def evaluate(env={})
function, argument = @program.car, @program.cdr.car
operation = function.symbol
case argument
when Atom
env[argument.symbol].send(operation)
when List
self.class.new(argument).evaluate(env).send(operation)
else
raise
end
end
end
require 'minitest/autorun'
require_relative 'atom'
require_relative 'list'
require_relative 'evaluator'
class EvaluatorTest < Minitest::Test
def test_car
assert_equal Atom.new(:a), evaluate(
List.new(Atom.new(:car), Atom.new(:l)),
l: List.new(Atom.new(:a), Atom.new(:b), Atom.new(:c))
)
end
def test_car_car
assert_equal Atom.new(:hotdogs), evaluate(
List.new(Atom.new(:car), List.new(Atom.new(:car), Atom.new(:l))),
l: List.new(List.new(Atom.new(:hotdogs), Atom.new(:and)))
)
end
def test_cdr
assert_equal List.new(Atom.new(:b), Atom.new(:c)), evaluate(
List.new(Atom.new(:cdr), Atom.new(:l)),
l: List.new(Atom.new(:a), Atom.new(:b), Atom.new(:c))
)
end
private
def evaluate(program, env={})
Evaluator.new(program).evaluate(env)
end
end
class List
def initialize(*array)
@array = array
end
def car
@array.first
end
def cdr
self.class.new(*@array[1..-1])
end
def ==(other)
self.array == other.array
end
protected
attr_reader :array
end
@tomstuart

This comment has been minimized.

Copy link

commented Jan 22, 2014

Great!

The book hasn’t yet told us how to provide a literal (i.e. unevaluated) list argument to car and cdr, so IMO only the *_with_environment_lookup tests make sense.

@tomstuart

This comment has been minimized.

Copy link

commented Jan 22, 2014

I guess what I mean is: the book doesn’t say “(car (a b c)) is a” or “(cdr (a b c)) is (b c)”, but the tests do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.