lib/sxp/reader/scheme.rb in sxp-0.1.0 vs lib/sxp/reader/scheme.rb in sxp-0.1.2

- old
+ new

@@ -9,10 +9,18 @@ INTEGER_BASE_8 = /^[+-]?[0-7]+$/ INTEGER_BASE_10 = /^[+-]?\d+$/ INTEGER_BASE_16 = /^[+-]?[\da-z]+$/i RATIONAL = /^([+-]?\d+)\/(\d+)$/ + # Escape characters, used in the form `#\newline`. Case is treated + # insensitively + # @see http://people.csail.mit.edu/jaffer/r4rs_9.html#SEC65 + CHARACTERS = { + 'newline' => "\n", + 'space' => " ", + } + ## # Initializes the reader. # # @param [IO, StringIO, String] input # @param [Hash{Symbol => Object}] options @@ -56,9 +64,27 @@ when ?x, ?X then read_integer(16) when ?\\ then read_character when ?; then skip; read when ?! then skip_line; read # shebang else raise Error, "invalid sharp-sign read syntax: ##{char.chr}" + end + end + + ## + # Read characters sequences like `#\space`. Otherwise, + # reads a single character. Requires the ability to put + # eroneously read characters back in the input stream + # + # @return [String] + # @see http://people.csail.mit.edu/jaffer/r4rs_9.html#SEC65 + def read_character + lit = read_literal + + return " " if lit.empty? && peek_char == " " + CHARACTERS.fetch(lit.downcase) do + # Return just the first character + unread(lit[1..-1]) + lit[0,1] end end end # Scheme end; end # SXP::Reader