class SXP::Reader::CommonLisp

A Common Lisp S-expressions parser.

@see www.cs.cmu.edu/Groups/AI/html/cltl/clm/node14.html

Constants

CHARACTERS

Escape characters, used in the form `#Backspace`. Case is treated insensitively @see www.cs.cmu.edu/Groups/AI/html/cltl/clm/node22.html

DECIMAL
INTEGER_BASE_10
INTEGER_BASE_16
INTEGER_BASE_2
INTEGER_BASE_8
OPTIONS
RATIONAL

Public Class Methods

new(input, **options, &block) click to toggle source

Initializes the reader.

@param [IO, StringIO, String] input @param [Hash{Symbol => Object}] options @option options [Object] :nil (nil) @option options [Object] :t (true) @option options [Object] :quote (:quote) @option options [Object] :function (:function)

Calls superclass method SXP::Reader::new
# File lib/sxp/reader/common_lisp.rb, line 39
def initialize(input, **options, &block)
  super(input, **OPTIONS.merge(options), &block)
end

Public Instance Methods

read_character() click to toggle source

Read characters sequences like `#backspace`. Otherwise, reads a single character. Requires the ability to put eroneously read characters back in the input stream

@return [String] @see www.cs.cmu.edu/Groups/AI/html/cltl/clm/node22.html

# File lib/sxp/reader/common_lisp.rb, line 117
def read_character
  lit = read_literal

  return " " if lit.empty? && peek_char == " "
  CHARACTERS.fetch(lit.downcase) do |string|
    # Return just the first character
    unread(string[1..-1])
    string[0,1]
  end
end
read_function() click to toggle source

Reads `#'mapcar` forms.

@return [Array]

# File lib/sxp/reader/common_lisp.rb, line 106
def read_function
  [options[:function] || :function, read]
end
read_quote() click to toggle source

Reads `'foobar` forms.

@return [Array]

# File lib/sxp/reader/common_lisp.rb, line 97
def read_quote
  skip_char # "'"
  [options[:quote] || :quote, read]
end
read_sharp() click to toggle source

@return [Object]

# File lib/sxp/reader/common_lisp.rb, line 56
def read_sharp
  skip_char # '#'
  case char = read_char
    when ?b, ?B  then read_integer(2)
    when ?o, ?O  then read_integer(8)
    when ?x, ?X  then read_integer(16)
    when ?\\     then read_character
    when ?(      then read_vector
    when ?'      then read_function
    else raise Error, "invalid sharp-sign read syntax: ##{char.chr}"
  end
end
read_symbol(delimiter = nil) click to toggle source

@return [Symbol]

# File lib/sxp/reader/common_lisp.rb, line 71
def read_symbol(delimiter = nil)
  buffer = String.new
  skip_char # '|'
  until delimiter === peek_char
    buffer <<
      case char = read_char
        when ?\\ then read_character
        else char
      end
  end
  skip_char # '|'
  buffer.to_sym
end
read_token() click to toggle source

@return [Object]

Calls superclass method SXP::Reader::Basic#read_token
# File lib/sxp/reader/common_lisp.rb, line 45
def read_token
  case peek_char
    when ?#  then [:atom, read_sharp]
    when ?|  then [:atom, read_symbol(?|)]
    when ?'  then [:atom, read_quote]
    else super
  end
end
read_vector() click to toggle source

Reads `#(1 2 3)` forms.

@return [Array]

# File lib/sxp/reader/common_lisp.rb, line 89
def read_vector
  raise NotImplementedError, "#{self.class}#read_vector" # TODO
end
skip_comments() click to toggle source

@return [void]

# File lib/sxp/reader/common_lisp.rb, line 130
def skip_comments
  until eof?
    case (char = peek_char).chr
      when /\s+/ then skip_char
      when /;/   then skip_line
      else break
    end
  end
end