123456789101112131415161718192021222324252627282930313233343536373839404142 |
- module Chervil
- RSpec.describe Interpreter do
- def interpret(source, env)
- lexer = Lexer.new(source)
- tree = Parser.new(lexer).parse
- Interpreter.new(tree, env).interpret
- end
-
- it 'interprets a definition and variable usage' do
- env = Env.new
- interpret('(define x 5)', env)
- expect(env.get('x')).to eq(AST::Number.new(5.0))
- expect(interpret('x', env).first).to eq(5.0)
- end
-
- it 'interprets a recursive function' do
- env = Env.new
- interpret('(define (fact x) (if (= x 0) 1 (* x (fact (- x 1)))))', env)
- expect(interpret('(fact 5)', env).first).to eq(120.0)
- end
-
- it 'supports closures' do
- env = Env.new
- interpret('(define one 1)', env)
- interpret('(define (plus-one x) (+ x one))', env)
- expect(interpret('(plus-one 2)', env).first).to eq(3.0)
- end
-
- it "doesn't leave variables bound after function execution" do
- env = Env.new
- interpret('(define (plus-one x) (+ 1 x))', env)
- interpret('(plus-one 5)', env)
- expect(env.get('x')).to eq(nil)
- end
-
- it 'returns a type error for invalid operation' do
- expect(interpret('(+ 1 "hello")', Env.new).first).to eq(
- Error.new('Expected an argument of type number but got string')
- )
- end
- end
- end
|