class Sparse

Public Instance Methods

parse(text) click to toggle source
# File lib/sparse/sparse.rb, line 2
def parse(text)
  @scanner = StringScanner.new(text)
  @line = 1
  @column = 1

  result = []
  until @scanner.eos?
    case
      when whitespace || comment
        # do nothing
      when open_parenthesis
        result << strip
      when quote
        result << :quote
        unless open_parenthesis
          blowup 'Expected list'
        end
        @scanner.unscan
      when syntax_quote
        result << :syntax_quote
        unless open_parenthesis
          blowup 'Expected list'
        end
        @scanner.unscan

      else
        blowup
    end

  end

  result

end

Private Instance Methods

blowup(message = "Unexpected token click to toggle source
# File lib/sparse/sparse.rb, line 38
def blowup(message = "Unexpected token #{@scanner.rest}")
  raise SyntaxError.new "#{message} in position #{@scanner.pos + 1}, line #{@line}, column #{@scanner.pos - @column + 1}"
end
close_parenthesis() click to toggle source
# File lib/sparse/sparse.rb, line 95
def close_parenthesis
  @scanner.scan(/[)]/)
end
comment() click to toggle source
# File lib/sparse/sparse.rb, line 129
def comment
  @scanner.scan(/^;.*$/)
end
fn() click to toggle source
# File lib/sparse/sparse.rb, line 117
def fn
  @scanner.scan(/[#]/)
end
number() click to toggle source
# File lib/sparse/sparse.rb, line 125
def number
  @scanner.scan(/[-]?[0-9]+([.][0-9]+)?/)
end
open_parenthesis() click to toggle source

singular: parenthesis plural : parentheses

# File lib/sparse/sparse.rb, line 91
def open_parenthesis
  @scanner.scan(/[(]/)
end
quote() click to toggle source
# File lib/sparse/sparse.rb, line 109
def quote
  @scanner.scan(/[']/)
end
string() click to toggle source
# File lib/sparse/sparse.rb, line 133
def string
  @scanner.scan(/"[^"]*"/)
end
strip() click to toggle source
# File lib/sparse/sparse.rb, line 42
def strip
  current = []
  until close_parenthesis
    start_rest = @scanner.rest

    case
      when whitespace || comment
        # do nothing
      when open_parenthesis
        current << strip
      when quote
        current << :quote
        unless open_parenthesis || symbol || number
          blowup 'Expected a list, symbol or number'
        end
        @scanner.unscan
      when syntax_quote
        current << :syntax_quote
        unless open_parenthesis
          blowup 'Expected a list'
        end
        @scanner.unscan
      when fn
        current << :fn
        unless open_parenthesis
          blowup 'Expected a list'
        end
        @scanner.unscan
      when symbol
        sym = @scanner.matched
        current << (sym == '- ' ? '-' : sym).to_sym
      when string
        current << eval(@scanner.matched)
      when number
        current << eval(@scanner.matched)
    end

    if start_rest == @scanner.rest
      blowup 'Unbalanced brackets'

    end

  end

  current
end
symbol() click to toggle source
# File lib/sparse/sparse.rb, line 121
def symbol
  @scanner.scan(/([-][^0-9]|[&+*\/:\[\]]|[a-zA-Z\$][a-zA-Z0-9\-\$]*[?]?)/)
end
syntax_quote() click to toggle source
# File lib/sparse/sparse.rb, line 113
def syntax_quote
  @scanner.scan(/[`]/)
end
whitespace() click to toggle source
# File lib/sparse/sparse.rb, line 99
def whitespace
  ret = @scanner.scan(/[ \t\n\r]/)
  if ret == "\n"
    @line += 1
    @column = @scanner.pos
  end

  ret
end