Class: SXP::Reader::CommonLisp
- Inherits:
-
Basic
- Object
- SXP::Reader
- Basic
- SXP::Reader::CommonLisp
- Defined in:
- lib/sxp/reader/common_lisp.rb
Overview
A Common Lisp S-expressions parser.
Constant Summary collapse
- OPTIONS =
{nil: false, t: true, quote: :quote, function: :function}
- DECIMAL =
/^[+-]?(\d*)?\.\d*$/
- INTEGER_BASE_2 =
/^[+-]?[01]+$/
- INTEGER_BASE_8 =
/^[+-]?[0-7]+$/
- INTEGER_BASE_10 =
/^[+-]?\d+$/
- INTEGER_BASE_16 =
/^[+-]?[\da-z]+$/i
- RATIONAL =
/^([+-]?\d+)\/(\d+)$/
- CHARACTERS =
Escape characters, used in the form ‘#Backspace`. Case is treated insensitively
{ 'newline' => "\n", 'space' => " ", 'backspace' => "\b", # \010 BS 'tab' => "\t", # \011 HT 'linefeed' => "\n", # \012 LF 'page' => "\f", # \014 FF 'return' => "\r", # \015 CR 'rubout' => "\x7F", # \177 DEL }
Constants inherited from Basic
Basic::ATOM, Basic::INTEGER, Basic::LPARENS, Basic::RPARENS
Instance Attribute Summary
Attributes inherited from SXP::Reader
Instance Method Summary collapse
-
#initialize(input, **options, &block) ⇒ CommonLisp
constructor
Initializes the reader.
-
#read_atom ⇒ Object
Based on Basic#read_atom, but adds ‘t’ and ‘nil’ atoms.
-
#read_character ⇒ String
Read characters sequences like ‘#backspace`.
-
#read_function ⇒ Array
Reads ‘#’mapcar` forms.
-
#read_quote ⇒ Array
Reads ‘’foobar` forms.
- #read_sharp ⇒ Object
- #read_symbol(delimiter = nil) ⇒ Symbol
- #read_token ⇒ Object
-
#read_vector ⇒ Array
Reads ‘#(1 2 3)` forms.
- #skip_comments ⇒ void
Methods inherited from Basic
Methods inherited from SXP::Reader
#each, read, #read, read_all, #read_all, read_file, #read_files, #read_integer, #read_list, #read_literal, #read_string, read_url
Constructor Details
#initialize(input, **options, &block) ⇒ CommonLisp
Initializes the reader.
42 43 44 |
# File 'lib/sxp/reader/common_lisp.rb', line 42 def initialize(input, **, &block) super(input, **OPTIONS.merge(), &block) end |
Instance Method Details
#read_atom ⇒ Object
Based on Basic#read_atom, but adds ‘t’ and ‘nil’ atoms.
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/sxp/reader/common_lisp.rb', line 75 def read_atom case buffer = read_literal when '.' then buffer.to_sym when RATIONAL then Rational($1.to_i, $2.to_i) when DECIMAL then Float(buffer) # FIXME? when INTEGER then Integer(buffer) when /^t$/i then true when /^nil$/i then nil else buffer.to_sym end end |
#read_character ⇒ String
Read characters sequences like ‘#backspace`. Otherwise, reads a single character. Requires the ability to put eroneously read characters back in the input stream
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/sxp/reader/common_lisp.rb', line 136 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 ⇒ Array
Reads ‘#’mapcar` forms.
125 126 127 |
# File 'lib/sxp/reader/common_lisp.rb', line 125 def read_function [[:function] || :function, read] end |
#read_quote ⇒ Array
Reads ‘’foobar` forms.
116 117 118 119 |
# File 'lib/sxp/reader/common_lisp.rb', line 116 def read_quote skip_char # "'" [[:quote] || :quote, read.tap {|s| s.quote_style = :squote if s.is_a?(String)}] end |
#read_sharp ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/sxp/reader/common_lisp.rb', line 59 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) ⇒ Symbol
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/sxp/reader/common_lisp.rb', line 89 def read_symbol(delimiter = nil) buffer = "" skip_char # '|' until delimiter === peek_char buffer << case char = read_char when ?\\ then read_char else char end end skip_char # '|' buffer.to_sym end |
#read_token ⇒ Object
48 49 50 51 52 53 54 55 |
# File 'lib/sxp/reader/common_lisp.rb', line 48 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 ⇒ Array
Reads ‘#(1 2 3)` forms.
107 108 109 110 |
# File 'lib/sxp/reader/common_lisp.rb', line 107 def read_vector list = read_list(')') Vector.[](*list) end |
#skip_comments ⇒ void
This method returns an undefined value.
149 150 151 152 153 154 155 156 157 |
# File 'lib/sxp/reader/common_lisp.rb', line 149 def skip_comments until eof? case (char = peek_char).chr when /\s+/ then skip_char when /;/ then skip_line else break end end end |