Class: Rupture::Reader

Inherits:
Object show all
Defined in:
lib/rupture/reader.rb

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Reader

Returns a new instance of Reader.



5
6
7
8
# File 'lib/rupture/reader.rb', line 5

def initialize(input)
  @input  = input
  @buffer = []
end

Instance Method Details

#getcObject



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/rupture/reader.rb', line 16

def getc
  while c = (@buffer.shift || @input.getc.chr)
    if c =~ /[\s,;]/
      next if @space
      @space = true
      @input.gets if c == ';'
      return ' '
    else
      @space = false
      return c
    end
  end
end

#peekcObject



30
31
32
# File 'lib/rupture/reader.rb', line 30

def peekc
  unget(getc)
end

#readObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rupture/reader.rb', line 34

def read
  case c = getc
  when '('  then read_list
  when '['  then read_list(Array, ']')
  when '{'  then read_map
  when '"'  then read_string
  when ':'  then read_keyword
  when ' '  then read
  when /\d/ then ungetc(c); read_number
  when /\w/ then ungetc(c); read_symbol
  when '-'
    case c = getc
    when /\d/ then ungetc(c);     -read_number
    else           ungetc('-', c); read_symbol
    end
  when '#'
    case c = getc
    when '{' then read_list(Set, '}')
    end
  end
end

#read_keywordObject



96
97
98
# File 'lib/rupture/reader.rb', line 96

def read_keyword
  read_symbol('')
end

#read_list(klass = List, terminator = ')') ⇒ Object



56
57
58
59
60
61
62
63
# File 'lib/rupture/reader.rb', line 56

def read_list(klass = List, terminator = ')')
  list = klass.new
  while c = getc
    return list if c == terminator
    ungetc(c)
    list << read
  end
end

#read_mapObject



65
66
67
68
69
70
71
72
# File 'lib/rupture/reader.rb', line 65

def read_map
  map = {}
  while c = getc
    return map if c == '}'
    ungetc(c)
    list[read] = read
  end
end

#read_numberObject



100
101
102
103
104
105
106
107
108
# File 'lib/rupture/reader.rb', line 100

def read_number
  number = read_while(/[-\d]/)
  if (c = getc) == '.'
    read_while(/\d/, number << '.').to_f
  else
    ungetc(c)
    number.to_i
  end
end

#read_stringObject



74
75
76
77
78
79
80
# File 'lib/rupture/reader.rb', line 74

def read_string
  string = ''
  while c = getc
    return string if c == '"'
    string << c
  end
end

#read_symbol(prefix = '@') ⇒ Object



92
93
94
# File 'lib/rupture/reader.rb', line 92

def read_symbol(prefix = '@')
  read_while(/[^\s{}\[\]()]/, prefix).to_sym
end

#read_while(pattern, token = '') ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/rupture/reader.rb', line 82

def read_while(pattern, token = '')
  while c = getc
    if c !~ pattern
      ungetc(c)
      return token
    end
    token << c
  end
end

#ungetc(*chars) ⇒ Object



10
11
12
13
14
# File 'lib/rupture/reader.rb', line 10

def ungetc(*chars)
  @buffer.concat(chars)
  @space = false
  chars.last
end