Class: Clojure::Reader
- Inherits:
-
Object
- Object
- Clojure::Reader
- Defined in:
- lib/clojure/reader.rb
Overview
read Clojure as Ruby’s data-structures
Instance Attribute Summary collapse
-
#ast ⇒ Object
readonly
Returns the value of attribute ast.
Instance Method Summary collapse
- #cursor ⇒ Object
- #eof? ⇒ Boolean
-
#initialize(source) ⇒ Reader
constructor
A new instance of Reader.
- #inspect ⇒ Object
- #next_char ⇒ Object
- #read_form(till: ")", into: []) ⇒ Object
- #read_keyword ⇒ Object
- #read_next ⇒ Object
- #read_number ⇒ Object
- #read_quote ⇒ Object
- #read_sexp_comment ⇒ Object
- #read_special ⇒ Object
- #read_string ⇒ Object
- #read_symbol ⇒ Object
- #skip_char ⇒ Object
- #skip_comment ⇒ Object
Constructor Details
#initialize(source) ⇒ Reader
Returns a new instance of Reader.
4 5 6 7 8 9 10 11 12 13 14 |
# 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 |
Instance Attribute Details
#ast ⇒ Object (readonly)
Returns the value of attribute ast.
20 21 22 |
# File 'lib/clojure/reader.rb', line 20 def ast @ast end |
Instance Method Details
#cursor ⇒ Object
22 23 24 |
# File 'lib/clojure/reader.rb', line 22 def cursor @cursor || next_char end |
#eof? ⇒ Boolean
26 27 28 |
# File 'lib/clojure/reader.rb', line 26 def eof? @cursor == :eof end |
#inspect ⇒ Object
16 17 18 |
# File 'lib/clojure/reader.rb', line 16 def inspect @ast end |
#next_char ⇒ Object
30 31 32 |
# File 'lib/clojure/reader.rb', line 30 def next_char @cursor = @io.getc || :eof end |
#read_form(till: ")", into: []) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 |
# 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 ⇒ Object
98 99 100 101 102 103 104 105 |
# 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 ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 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 ⇒ Object
90 91 92 93 94 95 96 |
# 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 ⇒ Object
107 108 109 110 |
# File 'lib/clojure/reader.rb', line 107 def read_quote skip_char # ' ["quote", read_next] end |
#read_sexp_comment ⇒ Object
61 62 63 64 65 |
# File 'lib/clojure/reader.rb', line 61 def read_sexp_comment next_char read_next nil end |
#read_special ⇒ Object
54 55 56 57 58 59 |
# 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 ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# 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 ⇒ Object
135 136 137 138 139 140 141 |
# File 'lib/clojure/reader.rb', line 135 def read_symbol symbol = cursor while next_char.match(/\w|-|\.|\?|\+|\//) symbol << cursor end symbol end |
#skip_char ⇒ Object
67 68 69 70 |
# File 'lib/clojure/reader.rb', line 67 def skip_char next_char nil end |
#skip_comment ⇒ Object
72 73 74 75 |
# File 'lib/clojure/reader.rb', line 72 def skip_comment next_char until cursor == "\n" || eof? nil end |