diff --git a/Gemfile b/Gemfile index 06eb956..6046b0c 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gemspec -gem "rdf", git: "git://github.com/ruby-rdf/rdf.git", branch: "develop" +gem "rdf", git: "https://github.com/ruby-rdf/rdf", branch: "develop" group :debug do gem "byebug", platform: :mri diff --git a/lib/sxp/reader/common_lisp.rb b/lib/sxp/reader/common_lisp.rb index 44b6203..7ca59e9 100644 --- a/lib/sxp/reader/common_lisp.rb +++ b/lib/sxp/reader/common_lisp.rb @@ -7,7 +7,7 @@ module SXP; class Reader # # @see https:/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node14.html class CommonLisp < Basic - OPTIONS = {nil: nil, t: true, quote: :quote, function: :function} + OPTIONS = {nil: false, t: true, quote: :quote, function: :function} DECIMAL = /^[+-]?(\d*)?\.\d*$/ INTEGER_BASE_2 = /^[+-]?[01]+$/ @@ -35,7 +35,7 @@ class CommonLisp < Basic # # @param [IO, StringIO, String] input # @param [Hash{Symbol => Object}] options - # @option options [Object] :nil (nil) + # @option options [Object] :nil (false) # @option options [Object] :t (true) # @option options [Object] :quote (:quote) # @option options [Object] :function (:function) @@ -69,6 +69,21 @@ def read_sharp end end + ## + # Based on Basic#read_atom, but adds 't' and 'nil' atoms. + # @return [Object] + def read_atom + case buffer = read_literal + when '.' then buffer.to_sym + when RATIONAL then Rational($1.to_i, $2.to_i) + when DECIMAL then Float(buffer) # FIXME? + when INTEGER then Integer(buffer) + when /^t$/i then true + when /^nil$/i then nil + else buffer.to_sym + end + end + ## # @return [Symbol] def read_symbol(delimiter = nil) diff --git a/spec/common_lisp_spec.rb b/spec/common_lisp_spec.rb index b9526c1..4413ad2 100644 --- a/spec/common_lisp_spec.rb +++ b/spec/common_lisp_spec.rb @@ -76,6 +76,22 @@ end end + context "when reading atoms" do + { + 't' => true, + 'T' => true, + 'nil' => nil, + 'NIL' => nil, + '1/2' => Rational(1, 2), + '1.0' => Float(1.0), + "10" => Integer(10), + }.each_pair do |input, output| + it "reads #{input} as an atom" do + expect(read(input)).to eq output + end + end + end + context "when reading lists" do it "reads `()` as an empty list" do expect(read(%q(()))).to eq [] # FIXME