Chervil is a toy Lisp interpreter written in Ruby
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

interpreter_spec.rb 1.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. module Chervil
  2. RSpec.describe Interpreter do
  3. def interpret(source, env)
  4. lexer = Lexer.new(source)
  5. tree = Parser.new(lexer).parse
  6. Interpreter.new(tree, env).interpret
  7. end
  8. it 'interprets a definition and variable usage' do
  9. env = Env.new
  10. interpret('(define x 5)', env)
  11. expect(env.get('x')).to eq(AST::Number.new(5.0))
  12. expect(interpret('x', env).first).to eq(5.0)
  13. end
  14. it 'interprets a recursive function' do
  15. env = Env.new
  16. interpret('(define (fact x) (if (= x 0) 1 (* x (fact (- x 1)))))', env)
  17. expect(interpret('(fact 5)', env).first).to eq(120.0)
  18. end
  19. it 'supports closures' do
  20. env = Env.new
  21. interpret('(define one 1)', env)
  22. interpret('(define (plus-one x) (+ x one))', env)
  23. expect(interpret('(plus-one 2)', env).first).to eq(3.0)
  24. end
  25. it "doesn't leave variables bound after function execution" do
  26. env = Env.new
  27. interpret('(define (plus-one x) (+ 1 x))', env)
  28. interpret('(plus-one 5)', env)
  29. expect(env.get('x')).to eq(nil)
  30. end
  31. it 'returns a type error for invalid operation' do
  32. expect(interpret('(+ 1 "hello")', Env.new).first).to eq(
  33. Error.new('Expected an argument of type number but got string')
  34. )
  35. end
  36. end
  37. end