class Clojure::Reader
read Clojure
as Ruby’s data-structures
Attributes
ast[R]
Public Class Methods
new(source)
click to toggle source
# File lib/clojure/reader.rb, line 4 def initialize(source) @source = source @io = StringIO.new source @ast = [] loop do break if eof? r = read_next @ast << r if r end true end
Public Instance Methods
cursor()
click to toggle source
# File lib/clojure/reader.rb, line 22 def cursor @cursor || next_char end
eof?()
click to toggle source
# File lib/clojure/reader.rb, line 26 def eof? @cursor == :eof end
inspect()
click to toggle source
# File lib/clojure/reader.rb, line 16 def inspect @ast end
next_char()
click to toggle source
# File lib/clojure/reader.rb, line 30 def next_char @cursor = @io.getc || :eof end
read_form(till: ")", into: [])
click to toggle source
# File lib/clojure/reader.rb, line 77 def read_form(till: ")", into: []) opening = cursor skip_char # opening parenthesis ast = into until cursor == till raise Exception, "Unbalanced #{opening}#{till}" if eof? r = read_next ast << r if r end skip_char # closing parenthesis ast end
read_keyword()
click to toggle source
# File lib/clojure/reader.rb, line 98 def read_keyword next_char k = cursor while next_char.match /\w|\.|#|-|_/ k << cursor end k.to_sym end
read_next()
click to toggle source
# File lib/clojure/reader.rb, line 34 def read_next # puts "reading next" # puts "-> #{cursor}" case cursor when :eof then return when /\s/ then skip_char when /\,/ then skip_char when /\;/ then skip_comment when /\d/ then read_number when /\(/ then read_form when /\[/ then read_form till: "]", into: ["vector"] when /\{/ then read_form till: "}", into: ["hash-map"] when /\:/ then read_keyword when /\"/ then read_string when /\'/ then read_quote when /\#/ then read_special when /\S/ then read_symbol end end
read_number()
click to toggle source
# File lib/clojure/reader.rb, line 90 def read_number n = cursor while next_char.match /[\d|.]/ n << cursor end Integer(n) rescue Float(n) end
read_quote()
click to toggle source
# File lib/clojure/reader.rb, line 107 def read_quote skip_char # ' ["quote", read_next] end
read_sexp_comment()
click to toggle source
# File lib/clojure/reader.rb, line 61 def read_sexp_comment next_char read_next nil end
read_special()
click to toggle source
# File lib/clojure/reader.rb, line 54 def read_special case next_char when /\_/ then read_sexp_comment else raise Exception, "Unknown token: ##{cur}" end end
read_string()
click to toggle source
# File lib/clojure/reader.rb, line 112 def read_string next_char if cursor == '"' next_char return ['str', ['quote', '']] end s = cursor.dup prev = cursor until (next_char == '"' && prev != "\\") if cursor == "\\" elsif cursor == "\"" s << cursor elsif prev == "\\" s << "\\#{cursor}" else s << cursor end prev = cursor end next_char ['str', ['quote', s]] end
read_symbol()
click to toggle source
# File lib/clojure/reader.rb, line 135 def read_symbol symbol = cursor while next_char.match(/\w|-|\.|\?|\+|\//) symbol << cursor end symbol end
skip_char()
click to toggle source
# File lib/clojure/reader.rb, line 67 def skip_char next_char nil end
skip_comment()
click to toggle source
# File lib/clojure/reader.rb, line 72 def skip_comment next_char until cursor == "\n" || eof? nil end