123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- module Chervil
- RSpec.describe Parser do
- def parse(source)
- lexer = Lexer.new(source)
- parser = Parser.new(lexer)
- parser.parse
- end
-
- it 'parses a number' do
- expect(parse('1').first).to eq(AST::Number.new(1.0))
- end
-
- it 'parses a string' do
- expect(parse('"hello world"').first).to eq(AST::String.new('hello world'))
- end
-
- it 'parses an identifier' do
- expect(parse('+').first).to eq(AST::Identifier.new('+'))
- end
-
- it 'parses booleans' do
- expect(parse('#t #f')).to eq(
- [AST::Boolean.new(true), AST::Boolean.new(false)]
- )
- end
-
- it 'parses an application' do
- expect(parse('(+ 1 2)').first).to eq(
- AST::List.new(
- [AST::Identifier.new('+'), AST::Number.new(1.0), AST::Number.new(2.0)]
- )
- )
- end
-
- it 'parses a definition' do
- expect(parse('(define x 5)').first).to eq(
- AST::Definition.new(AST::Identifier.new('x'), AST::Number.new(5.0))
- )
- end
-
- it 'parses a nested expression' do
- expect(parse('(+ (+ 1 2) (- 3 4))').first).to eq(
- AST::List.new(
- [
- AST::Identifier.new('+'),
- AST::List.new(
- [
- AST::Identifier.new('+'),
- AST::Number.new(1.0),
- AST::Number.new(2.0)
- ]
- ),
- AST::List.new(
- [
- AST::Identifier.new('-'),
- AST::Number.new(3.0),
- AST::Number.new(4.0)
- ]
- )
- ]
- )
- )
- end
-
- it 'parses a function definition' do
- expect(parse('(define (square x) (* x x))').first).to eq(
- AST::Definition.new(
- AST::Identifier.new('square'),
- AST::Function.new(
- AST::Identifier.new('square'),
- [AST::Identifier.new('x')],
- [
- AST::List.new(
- [
- AST::Identifier.new('*'),
- AST::Identifier.new('x'),
- AST::Identifier.new('x')
- ]
- )
- ]
- )
- )
- )
- end
-
- it 'returns a syntax error object instead of raising' do
- expect(parse('(+ 1')).to eq(Error.new('Expected rparen but got eof'))
- expect(parse('1)')).to eq(Error.new('Unexpected token rparen: )'))
- end
-
- it 'parses a conditional' do
- expect(parse('(if #t 1 0)').first).to eq(
- AST::Conditional.new(
- AST::Boolean.new(true),
- AST::Number.new(1.0),
- AST::Number.new(0.0)
- )
- )
- end
- end
- end
|