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