edn_turbo 0.5.7 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 846fd6b6a142bea1696ae918087fc9ae2c89264b
4
- data.tar.gz: 0a6c9520a17d1cd2967c1f0e61efba2bfbb40fde
2
+ SHA256:
3
+ metadata.gz: 59342940a3cb92e4792239598d5a858376a2ed18ef78872ea2d6a00a4421e18b
4
+ data.tar.gz: 04e6d9ab8648b13a7e850ac0ea84d85464ac8e3474cde3642e83c9f9ac2a44c8
5
5
  SHA512:
6
- metadata.gz: 4c4a5d4d8357b9bcf773cc3cfdb66d191f0248326c8772ef15c2ff31904740d3b4df1bea8db54edf5a0817b0bb55446bd064b1bf25ad721cd46ee5df2f7171cb
7
- data.tar.gz: a4dc313919664ffd6881e9be561ec9453b77c78569ddb5726a7c8ef6e4c34ccaddab25385920cbcbd7ff811865cc8ae081fe58f880bae9fed179edce6f291c78
6
+ metadata.gz: 208f82034dec3313c9bc6eaacc46debb746d39379e385195ee727afce4a3e5cf26cb5f06336a137428409a2914caa3e6531138a8c36b2223620bb9920a82f024
7
+ data.tar.gz: ab5e07ba292a835729b5174973280253040ea9fdf78742ff46bd7afd271f1e9884173a4571cffd4a766f21eca9a2232edddee7b3e7c969472e888069fe60ea02
data/.dir-locals.el ADDED
@@ -0,0 +1,3 @@
1
+ ((c++-mode
2
+ (flycheck-clang-language-standard . "c++11")
3
+ (flycheck-gcc-language-standard . "c++11")))
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
3
+
4
+ ## 0.7.1 - 2021-02-07
5
+ ### Changed
6
+ - Set minimum ruby version to 2.5
7
+
8
+ ### Fixed
9
+ - Compilation error when building against ruby versions > 2
10
+
11
+ ## 0.7.0 - 2020-02-07
12
+ ### Added
13
+ - big_decimal_edn_turbo method to replace calling edn-ruby's
14
+ big_decimal as it breaks things in ruby 2.7 and up
15
+
16
+ ### Changed
17
+ - Removed compiler warning due to scalar wrapped in braces
18
+ - Updated docker configs to use latest 2.4 and 2.6 ruby
19
+ versions. Added 2.5 and 2.7 too.
20
+
21
+ ## 0.6.2 - 2019-05-21
22
+ ### Fixed
23
+ - Handling of ##Inf, ##Nan, et al.
24
+
25
+ ## 0.6.1 - 2019-05-20
26
+ ### Added
27
+ - Implement parsing of Ratio literals, represented as a ruby Rational.
28
+
29
+ ### Fixed
30
+ - Parsing of exact precision types.
31
+
32
+ ### Changed
33
+ - Build lists using EDN::list method that was previously broken.
34
+
35
+
36
+ ## 0.6.0 - 2019-05-13
37
+ ### Changed
38
+ - switched from MiniTest to RSpec.
39
+ - replaced `NULL` with `nullptr`.
40
+ - replaced old-style casts.
41
+ - prohibit Parser copy and move ops.
42
+ - assigning a source that does not respond to `read` now throws
43
+ `ArgumentError` instead of `RuntimeError`.
44
+
45
+ ### Added
46
+ - initial version of docker configs for testing on Ubuntu.
47
+
48
+ [Unreleased]: https://github.com/edporras/edn_turbo/-/compare/0.7.1...main
49
+ [0.7.1]: https://github.com/edporras/edn_turbo/-/compare/0.7.0...0.7.1
50
+ [0.7.0]: https://github.com/edporras/edn_turbo/-/compare/0.6.2...0.7.0
51
+ [0.6.2]: https://github.com/edporras/edn_turbo/-/compare/0.6.1...0.6.2
52
+ [0.6.1]: https://github.com/edporras/edn_turbo/-/compare/0.6.0...0.6.1
53
+ [0.6.0]: https://github.com/edporras/edn_turbo/-/compare/0.5.7...0.6.0
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) <year> <copyright holders>
3
+ Copyright (c) 2015-2019 Ed Porras
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,14 +1,13 @@
1
- edn_turbo 0.5.7
1
+ edn_turbo 0.7.1
2
2
  ===============
3
3
 
4
- Fast Ragel-based EDN parser for Ruby.
4
+ Fast [Ragel](http://www.colm.net/open-source/ragel/)-based EDN parser for Ruby.
5
5
 
6
- `edn_turbo` is a parser plugin for
6
+ `edn_turbo` can be used as a parser plugin for
7
7
  [edn](https://github.com/relevance/edn-ruby). With a few exceptions
8
8
  `edn_turbo` provides the same functionality as the edn gem, but since
9
- the `edn_turbo` parser is implemented in C, it is an order of
10
- magintude faster.
11
-
9
+ the `edn_turbo` parser is implemented in C++, it is an order of
10
+ magnitude faster.
12
11
 
13
12
  Some quick sample runs comparing time output of file reads using `edn`
14
13
  and `edn_turbo` (see [issue 12](https://github.com/relevance/edn-ruby/issues/12)):
@@ -32,27 +31,24 @@ irb(main):008:0> Benchmark.realtime { 100000.times { EDN::read(s) } }
32
31
  => 2.866411
33
32
  ```
34
33
 
35
-
36
34
  Dependencies
37
35
  ============
38
36
 
37
+ Ruby 2.6 or greater.
38
+
39
39
  - ruby gems:
40
40
  - [rake](http://rake.rubyforge.org)
41
41
  - [rake-compiler 1.0](http://rake-compiler.rubyforge.org)
42
42
  - [edn 1.1](https://github.com/relevance/edn-ruby)
43
+ - a C++-11 capable compiler.
43
44
  - [icu4c](http://icu-project.org/apiref/icu4c/)
44
45
 
45
-
46
46
  Notes:
47
47
  ------
48
48
 
49
49
  - `edn_turbo` uses a ragel-based parser but the generated .cc file is
50
50
  bundled so ragel should not need to be installed.
51
51
 
52
- - If the gem fails to install due to a compilation error, make sure you
53
- have `icu4c` installed. The reported gem install error doesn't make
54
- it clear this is the issue.
55
-
56
52
  Usage
57
53
  =====
58
54
 
@@ -70,10 +66,10 @@ the API is the same as the edn gem.
70
66
  # also accepts a string
71
67
  pp EDN.read("[ 1 2 3 abc ]")
72
68
 
73
- # metadata
74
- e = EDN.read('^String ^:foo ^{:foo false :tag Boolean :bar 2} [1 2]')
75
- pp e # -> [1, 2]
76
- pp e.metadata # -> {:foo=>true, :tag=>#<EDN::Type::Symbol:0x007fdbea8a29b0 @symbol=:String>, :bar=>2}
69
+ # metadata
70
+ e = EDN.read('^String ^:foo ^{:foo false :tag Boolean :bar 2} [1 2]')
71
+ pp e # -> [1, 2]
72
+ pp e.metadata # -> {:foo=>true, :tag=>#<EDN::Type::Symbol:0x007fdbea8a29b0 @symbol=:String>, :bar=>2}
77
73
 
78
74
  ```
79
75
 
@@ -107,16 +103,14 @@ Or instantiate and reuse an instance of a parser:
107
103
 
108
104
  Differences with edn gem
109
105
  ========================
110
- `edn_turbo` reads `String` and core IO types using C-api calls.
106
+ - `edn_turbo` reads `String` and core IO types using C-api calls.
111
107
  However, data from `StringIO` sources is extracted using `read()`
112
108
  calls into the ruby side.
113
109
 
114
- Known problems
115
- ==============
110
+ - As of v0.6.1, `edn_turbo` supports EDN ratio literals, returning a
111
+ ruby Rational representation for them. See https://github.com/edn-format/edn/issues/64.
116
112
 
117
- v0.3.2:
113
+ - As of v0.6.2, `edn_turbo` supports representation of `##Inf` as
114
+ `Float::INFINITY` and `##NaN` as `Float::NAN`.
118
115
 
119
- - Some unhandled corner cases with operators and spacing
120
- remain. `edn_turbo` handles things like `1 / 12` and `1/ 12` but
121
- parse errors occur with `1/12` and `1 /12` because it treats `/12`
122
- as an invalid symbol.
116
+ - As of v0.7.1, `edn_turbo` requires ruby 2.5 or greater.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/testtask'
2
4
  require 'rake/extensiontask'
3
5
  require 'rake/clean'
@@ -8,57 +10,50 @@ LIB_DIR = "lib/#{NAME}"
8
10
  EXT_BUNDLE = "#{LIB_DIR}/#{NAME}.#{RbConfig::CONFIG['DLEXT']}"
9
11
 
10
12
  EXT_PATH = "ext/#{NAME}"
11
- RAGEL_PARSER_SRC = "edn_parser.rl"
13
+ RAGEL_PARSER_SRC = 'edn_parser.rl'
12
14
  RAGEL_PARSER_SRC_PATH = "#{EXT_PATH}/#{RAGEL_PARSER_SRC}"
13
- GEN_CC_PARSER_SRC = "edn_parser.cc"
15
+ GEN_CC_PARSER_SRC = 'edn_parser.cc'
14
16
  GEN_CC_PARSER_SRC_PATH = "#{EXT_PATH}/#{GEN_CC_PARSER_SRC}"
15
17
 
16
18
  task :irb do
17
- sh "irb -I lib -r edn_turbo"
18
- sh "reset"
19
+ sh 'irb -I lib -r edn_turbo'
20
+ sh 'reset'
19
21
  end
20
22
 
21
- task :runthru => [:clean, :default, :test]
23
+ task runthru: %i[clean default test]
22
24
 
23
- Rake::ExtensionTask.new("#{NAME}") do |extension|
25
+ Rake::ExtensionTask.new(NAME) do |extension|
24
26
  extension.lib_dir = LIB_DIR
25
- extension.source_pattern = "*.{cc,h}"
27
+ extension.source_pattern = '*.{cc,h}'
26
28
  end
27
29
 
28
30
  task :chmod do
29
- File.chmod(0775, EXT_BUNDLE)
31
+ File.chmod(0o0775, EXT_BUNDLE)
30
32
  end
31
33
 
32
- CLEAN.include(["*.png", "*.gem"])
34
+ CLEAN.include(['*.png', '*.gem'])
33
35
 
34
36
  # ragel cc source generation
35
- task :ragel => GEN_CC_PARSER_SRC_PATH
37
+ task ragel: GEN_CC_PARSER_SRC_PATH
36
38
  file GEN_CC_PARSER_SRC_PATH => RAGEL_PARSER_SRC_PATH do
37
- cd EXT_PATH do
39
+ Dir.chdir(EXT_PATH) do
38
40
  sh "ragel -G2 -o #{GEN_CC_PARSER_SRC} #{RAGEL_PARSER_SRC}"
39
41
  src = File.read(GEN_CC_PARSER_SRC).gsub(/[ \t]+$/, '')
40
- File.open(GEN_CC_PARSER_SRC, "w") {|f| f.print src}
42
+ File.open(GEN_CC_PARSER_SRC, 'w') { |f| f.print src }
41
43
  end
42
44
  end
43
45
 
44
46
  # graph generation for testing machine output
45
- task :graph, [:machine] do |t, args|
46
- args.with_defaults(:machine => 'EDN_value')
47
- TMPFILE='/tmp/ragel_edn'
48
- MACHINE=args[:machine]
47
+ task :graph, %i[machine] do |_t, args|
48
+ args.with_defaults(machine: 'EDN_value')
49
+ tmpfile = '/tmp/ragel_edn'
50
+ machine = args[:machine]
49
51
 
50
52
  # assumes graphviz is installed
51
- sh "ragel -Vp -S #{MACHINE} -o #{TMPFILE} #{EXT_PATH}/#{RAGEL_PARSER_SRC} && dot -Tpng #{TMPFILE} -o #{MACHINE}.png"
53
+ sh "ragel -Vp -S #{machine} -o #{tmpfile} #{EXT_PATH}/#{RAGEL_PARSER_SRC} && "\
54
+ "dot -Tpng #{tmpfile} -o #{machine}.png"
52
55
  end
53
56
 
54
- task :build => [:clean, :ragel, :compile, :chmod]
55
-
56
- # add dependency to test task
57
- task :test => EXT_BUNDLE
58
-
59
- Rake::TestTask.new do |t|
60
- t.libs << 'test'
61
- t.test_files = FileList['test/test_output_diff.rb']
62
- end
57
+ task build: %i[clean ragel compile chmod]
63
58
 
64
- task :default => :compile
59
+ task default: :compile
data/docker/Dockerfile ADDED
@@ -0,0 +1,40 @@
1
+ FROM buildpack-deps:stretch
2
+ MAINTAINER github@digressed.net
3
+ ARG ruby_version
4
+
5
+ ENV LC_ALL C.UTF-8
6
+
7
+ USER root
8
+ RUN groupadd -r ned -g 1000 && \
9
+ useradd -u 1000 -r -g ned -m -s /sbin/nologin -c "Docker image user" ned && \
10
+ mkdir /home/ned/bin && \
11
+ mkdir /home/ned/src && \
12
+ chown -R ned:ned /home/ned
13
+
14
+ WORKDIR /home/ned/src
15
+
16
+ # Update Ubuntu Software repository && update deps
17
+ RUN apt-get update && \
18
+ apt-get install -y \
19
+ libicu-dev \
20
+ libreadline-dev \
21
+ ragel && \
22
+ rm -rf /var/lib/apt/lists/*
23
+
24
+ USER ned
25
+
26
+ ENV PATH "/home/ned/.rbenv/bin:/home/ned/.rbenv/shims:$PATH"
27
+
28
+ # install rbenv
29
+ RUN \curl -sL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash - && \
30
+ eval "$(rbenv init -)"
31
+
32
+ RUN rm -f .ruby-version
33
+
34
+ # the specified ruby version
35
+ RUN rbenv install $ruby_version && \
36
+ rbenv global $ruby_version
37
+
38
+ COPY --chown=ned:ned . /home/ned/src
39
+
40
+ ENTRYPOINT ["docker/entrypoint"]
data/docker/build ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ . docker/common.sh
4
+
5
+ set -e
6
+
7
+ set_ruby_ver $@
8
+
9
+ docker build --build-arg ruby_version=$RUBY_VERSION -f docker/Dockerfile -t digressed/test:edn_turbo-rb-$RUBY_VERSION .
10
+ docker tag "digressed/test:edn_turbo-rb-$RUBY_VERSION" "edn_turbo-rb-$RUBY_VERSION"
11
+ docker push "digressed/test:edn_turbo-rb-$RUBY_VERSION"
data/docker/common.sh ADDED
@@ -0,0 +1,28 @@
1
+ #!/bin/sh
2
+
3
+ RUBY_MAJOR_VER=3.0
4
+
5
+ function update_ruby_build()
6
+ {
7
+ if [ -e "~/.rbenv/plugins/" ]; then
8
+ echo "Updating ruby-build definitions"
9
+
10
+ pushd ~/.rbenv/plugins/ruby-build/ >> /dev/null
11
+ git pull
12
+ popd >> /dev/null
13
+ fi
14
+ }
15
+
16
+ function set_ruby_ver()
17
+ {
18
+ local args=("$@")
19
+
20
+ if [ ${#args[@]} -eq 0 ]; then
21
+ update_ruby_build
22
+ RUBY_VERSION=`ruby-build --definitions | grep "^$RUBY_MAJOR_VER" | tail -1`
23
+ else
24
+ RUBY_VERSION=$1
25
+ fi
26
+
27
+ echo "Using ruby $RUBY_VERSION"
28
+ }
data/docker/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ if [ $# -eq 0 ]; then
4
+ RUBY_VERSION=3.0.0
5
+ else
6
+ RUBY_VERSION=$1
7
+ fi
8
+
9
+ echo "running on ruby ${RUBY_VERSION}"
10
+
11
+ docker-compose -f docker/docker-compose.yml run rb-$RUBY_VERSION /bin/bash
@@ -0,0 +1,22 @@
1
+ version: "3"
2
+ services:
3
+
4
+ rb-3.0.0:
5
+ image: digressed/test:edn_turbo-rb-3.0.0
6
+ stdin_open: true
7
+ tty: true
8
+
9
+ rb-2.7.2:
10
+ image: digressed/test:edn_turbo-rb-2.7.2
11
+ stdin_open: true
12
+ tty: true
13
+
14
+ rb-2.6.6:
15
+ image: digressed/test:edn_turbo-rb-2.6.6
16
+ stdin_open: true
17
+ tty: true
18
+
19
+ rb-2.5.8:
20
+ image: digressed/test:edn_turbo-rb-2.5.8
21
+ stdin_open: true
22
+ tty: true
data/docker/entrypoint ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ exec "$@"
data/docker/make-check ADDED
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ set -x -e
4
+
5
+ gem install bundler &&
6
+ bundle && \
7
+ rake compile && \
8
+ bundle exec rspec
data/docker/run ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ . docker/common.sh
4
+
5
+ set -e
6
+
7
+ set_ruby_ver $@
8
+
9
+ docker-compose -f docker/docker-compose.yml run rb-$RUBY_VERSION docker/make-check
@@ -1,5 +1,27 @@
1
1
 
2
2
  #line 1 "edn_parser.rl"
3
+ // The MIT License (MIT)
4
+
5
+ // Copyright (c) 2015-2021 Ed Porras
6
+
7
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ // of this software and associated documentation files (the "Software"), to deal
9
+ // in the Software without restriction, including without limitation the rights
10
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ // copies of the Software, and to permit persons to whom the Software is
12
+ // furnished to do so, subject to the following conditions:
13
+
14
+ // The above copyright notice and this permission notice shall be included in
15
+ // all copies or substantial portions of the Software.
16
+
17
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ // THE SOFTWARE.
24
+
3
25
  #include <iostream>
4
26
  #include <string>
5
27
  #include <sstream>
@@ -21,7 +43,7 @@
21
43
  //
22
44
 
23
45
 
24
- #line 59 "edn_parser.rl"
46
+ #line 81 "edn_parser.rl"
25
47
 
26
48
 
27
49
  // ============================================================
@@ -29,7 +51,7 @@
29
51
  //
30
52
 
31
53
 
32
- #line 33 "edn_parser.cc"
54
+ #line 55 "edn_parser.cc"
33
55
  static const int EDN_value_start = 1;
34
56
  static const int EDN_value_first_final = 2;
35
57
  static const int EDN_value_error = 0;
@@ -37,24 +59,24 @@ static const int EDN_value_error = 0;
37
59
  static const int EDN_value_en_main = 1;
38
60
 
39
61
 
40
- #line 175 "edn_parser.rl"
62
+ #line 202 "edn_parser.rl"
41
63
 
42
64
 
43
65
 
44
66
  const char *edn::Parser::parse_value(const char *p, const char *pe, VALUE& v)
45
67
  {
46
- // std::cerr << __FUNCTION__ << "() p: \"" << p << "\"" << std::endl;
47
- int cs;
68
+ // std::cerr << __FUNCTION__ << "() p: \"" << p << "\"" << std::endl;
69
+ int cs;
48
70
 
49
71
 
50
- #line 51 "edn_parser.cc"
72
+ #line 73 "edn_parser.cc"
51
73
  {
52
74
  cs = EDN_value_start;
53
75
  }
54
76
 
55
- #line 184 "edn_parser.rl"
77
+ #line 211 "edn_parser.rl"
56
78
 
57
- #line 58 "edn_parser.cc"
79
+ #line 80 "edn_parser.cc"
58
80
  {
59
81
  if ( p == pe )
60
82
  goto _test_eof;
@@ -97,124 +119,129 @@ st0:
97
119
  cs = 0;
98
120
  goto _out;
99
121
  tr0:
100
- #line 103 "edn_parser.rl"
122
+ #line 130 "edn_parser.rl"
101
123
  {
102
- // stand-alone operators *, +, -, etc.
103
- const char *np = parse_operator(p, pe, v);
104
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
105
- }
124
+ // stand-alone operators *, +, -, etc.
125
+ const char *np = parse_operator(p, pe, v);
126
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
127
+ }
106
128
  goto st2;
107
129
  tr2:
108
- #line 71 "edn_parser.rl"
130
+ #line 93 "edn_parser.rl"
109
131
  {
110
- // string types within double-quotes
111
- const char *np = parse_string(p, pe, v);
112
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
113
- }
132
+ // string types within double-quotes
133
+ const char *np = parse_string(p, pe, v);
134
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
135
+ }
114
136
  goto st2;
115
137
  tr3:
116
- #line 155 "edn_parser.rl"
138
+ #line 182 "edn_parser.rl"
117
139
  {
118
- // handles tokens w/ leading # ("#_", "#{", and tagged elems)
119
- const char *np = parse_dispatch(p + 1, pe, v);
120
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
121
- }
140
+ // handles tokens w/ leading # ("#_", "#{", and tagged elems)
141
+ const char *np = parse_dispatch(p + 1, pe, v);
142
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
143
+ }
122
144
  goto st2;
123
145
  tr4:
124
- #line 137 "edn_parser.rl"
146
+ #line 164 "edn_parser.rl"
125
147
  {
126
- // (
127
- const char *np = parse_list(p, pe, v);
128
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
129
- }
148
+ // (
149
+ const char *np = parse_list(p, pe, v);
150
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
151
+ }
130
152
  goto st2;
131
153
  tr5:
132
- #line 83 "edn_parser.rl"
154
+ #line 105 "edn_parser.rl"
133
155
  {
134
- // tokens w/ leading digits: non-negative integers & decimals.
135
- // try to parse a decimal first
136
- const char *np = parse_decimal(p, pe, v);
137
- if (np == NULL) {
138
- // if we can't, try to parse it as an int
156
+ // tokens w/ leading digits: non-negative integers & decimals.
157
+ // try to parse a decimal first
158
+ const char *np = parse_decimal(p, pe, v);
159
+ if (np == nullptr) {
160
+ // if we can't, try to parse it as a ratio
161
+ np = parse_ratio(p, pe, v);
162
+
163
+ // otherwise, an int
164
+ if (np == nullptr) {
139
165
  np = parse_integer(p, pe, v);
140
- }
141
-
142
- if (np) {
143
- {p = (( np))-1;}
144
- p--;
145
- {p++; cs = 2; goto _out;}
146
- }
147
- else {
148
- error(__FUNCTION__, "number format error", *p);
149
- {p = (( pe))-1;}
150
- }
151
- }
166
+ }
167
+ }
168
+
169
+ if (np) {
170
+ {p = (( np))-1;}
171
+ p--;
172
+ {p++; cs = 2; goto _out;}
173
+ }
174
+ else {
175
+ error(__FUNCTION__, "number format error", *p);
176
+ {p = (( pe))-1;}
177
+ }
178
+ }
152
179
  goto st2;
153
180
  tr6:
154
- #line 77 "edn_parser.rl"
181
+ #line 99 "edn_parser.rl"
155
182
  {
156
- // tokens with a leading ':'
157
- const char *np = parse_keyword(p, pe, v);
158
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
159
- }
183
+ // tokens with a leading ':'
184
+ const char *np = parse_keyword(p, pe, v);
185
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
186
+ }
160
187
  goto st2;
161
188
  tr7:
162
- #line 115 "edn_parser.rl"
163
- {
164
- // user identifiers and reserved keywords (true, false, nil)
165
- VALUE sym = Qnil;
166
- const char *np = parse_symbol(p, pe, sym);
167
- if (np == NULL) { {p = (( pe))-1;} } else {
168
- // parse_symbol will make 'sym' a ruby string
169
- if (std::strcmp(RSTRING_PTR(sym), "true") == 0) { v = Qtrue; }
170
- else if (std::strcmp(RSTRING_PTR(sym), "false") == 0) { v = Qfalse; }
171
- else if (std::strcmp(RSTRING_PTR(sym), "nil") == 0) { v = Qnil; }
172
- else {
173
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
174
- }
175
- {p = (( np))-1;}
176
- }
177
- }
189
+ #line 142 "edn_parser.rl"
190
+ {
191
+ // user identifiers and reserved keywords (true, false, nil)
192
+ VALUE sym = Qnil;
193
+ const char *np = parse_symbol(p, pe, sym);
194
+ if (np == nullptr) { {p = (( pe))-1;} } else {
195
+ // parse_symbol will make 'sym' a ruby string
196
+ if (std::strcmp(RSTRING_PTR(sym), "true") == 0) { v = Qtrue; }
197
+ else if (std::strcmp(RSTRING_PTR(sym), "false") == 0) { v = Qfalse; }
198
+ else if (std::strcmp(RSTRING_PTR(sym), "nil") == 0) { v = Qnil; }
199
+ else {
200
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
201
+ }
202
+ {p = (( np))-1;}
203
+ }
204
+ }
178
205
  goto st2;
179
206
  tr8:
180
- #line 131 "edn_parser.rl"
207
+ #line 158 "edn_parser.rl"
181
208
  {
182
- // [
183
- const char *np = parse_vector(p, pe, v);
184
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
185
- }
209
+ // [
210
+ const char *np = parse_vector(p, pe, v);
211
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
212
+ }
186
213
  goto st2;
187
214
  tr9:
188
- #line 109 "edn_parser.rl"
215
+ #line 136 "edn_parser.rl"
189
216
  {
190
- // tokens w/ leading \ (escaped characters \newline, \c, etc.)
191
- const char *np = parse_esc_char(p, pe, v);
192
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
193
- }
217
+ // tokens w/ leading \ (escaped characters \newline, \c, etc.)
218
+ const char *np = parse_esc_char(p, pe, v);
219
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
220
+ }
194
221
  goto st2;
195
222
  tr10:
196
- #line 149 "edn_parser.rl"
223
+ #line 176 "edn_parser.rl"
197
224
  {
198
- // ^
199
- const char *np = parse_meta(p, pe);
200
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
201
- }
225
+ // ^
226
+ const char *np = parse_meta(p, pe);
227
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
228
+ }
202
229
  goto st2;
203
230
  tr11:
204
- #line 143 "edn_parser.rl"
231
+ #line 170 "edn_parser.rl"
205
232
  {
206
- // {
207
- const char *np = parse_map(p, pe, v);
208
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
209
- }
233
+ // {
234
+ const char *np = parse_map(p, pe, v);
235
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
236
+ }
210
237
  goto st2;
211
238
  st2:
212
239
  if ( ++p == pe )
213
240
  goto _test_eof2;
214
241
  case 2:
215
- #line 58 "edn_parser.rl"
242
+ #line 80 "edn_parser.rl"
216
243
  { p--; {p++; cs = 2; goto _out;} }
217
- #line 218 "edn_parser.cc"
244
+ #line 245 "edn_parser.cc"
218
245
  goto st0;
219
246
  }
220
247
  _test_eof2: cs = 2; goto _test_eof;
@@ -223,17 +250,17 @@ case 2:
223
250
  _out: {}
224
251
  }
225
252
 
226
- #line 185 "edn_parser.rl"
227
-
228
- if (cs >= EDN_value_first_final) {
229
- return p;
230
- }
231
- else if (cs == EDN_value_error) {
232
- error(__FUNCTION__, "token error", *p);
233
- return pe;
234
- }
235
- else if (cs == EDN_value_en_main) {} // silence ragel warning
236
- return NULL;
253
+ #line 212 "edn_parser.rl"
254
+
255
+ if (cs >= EDN_value_first_final) {
256
+ return p;
257
+ }
258
+ else if (cs == EDN_value_error) {
259
+ error(__FUNCTION__, "token error", *p);
260
+ return pe;
261
+ }
262
+ else if (cs == EDN_value_en_main) {} // silence ragel warning
263
+ return nullptr;
237
264
  }
238
265
 
239
266
 
@@ -245,7 +272,7 @@ case 2:
245
272
  // ascii range is found.
246
273
  //
247
274
 
248
- #line 249 "edn_parser.cc"
275
+ #line 276 "edn_parser.cc"
249
276
  static const int EDN_string_start = 1;
250
277
  static const int EDN_string_first_final = 8;
251
278
  static const int EDN_string_error = 0;
@@ -253,26 +280,26 @@ static const int EDN_string_error = 0;
253
280
  static const int EDN_string_en_main = 1;
254
281
 
255
282
 
256
- #line 230 "edn_parser.rl"
283
+ #line 257 "edn_parser.rl"
257
284
 
258
285
 
259
286
 
260
287
  const char* edn::Parser::parse_string(const char *p, const char *pe, VALUE& v)
261
288
  {
262
- static const char* EDN_TYPE = "string";
263
- int cs;
264
- bool encode = false;
289
+ static const char* EDN_TYPE = "string";
290
+ int cs;
291
+ bool encode = false;
265
292
 
266
293
 
267
- #line 268 "edn_parser.cc"
294
+ #line 295 "edn_parser.cc"
268
295
  {
269
296
  cs = EDN_string_start;
270
297
  }
271
298
 
272
- #line 240 "edn_parser.rl"
273
- const char* p_save = p;
299
+ #line 267 "edn_parser.rl"
300
+ const char* p_save = p;
274
301
 
275
- #line 276 "edn_parser.cc"
302
+ #line 303 "edn_parser.cc"
276
303
  {
277
304
  if ( p == pe )
278
305
  goto _test_eof;
@@ -286,16 +313,16 @@ st0:
286
313
  cs = 0;
287
314
  goto _out;
288
315
  tr2:
289
- #line 219 "edn_parser.rl"
316
+ #line 246 "edn_parser.rl"
290
317
  {
291
- encode = true;
292
- }
318
+ encode = true;
319
+ }
293
320
  goto st2;
294
321
  st2:
295
322
  if ( ++p == pe )
296
323
  goto _test_eof2;
297
324
  case 2:
298
- #line 299 "edn_parser.cc"
325
+ #line 326 "edn_parser.cc"
299
326
  switch( (*p) ) {
300
327
  case 34: goto tr3;
301
328
  case 92: goto tr4;
@@ -304,34 +331,34 @@ case 2:
304
331
  goto tr2;
305
332
  goto st2;
306
333
  tr3:
307
- #line 211 "edn_parser.rl"
334
+ #line 238 "edn_parser.rl"
308
335
  {
309
- if (edn::util::parse_byte_stream(p_save + 1, p, v, encode)) {
310
- {p = (( p + 1))-1;}
311
- } else {
312
- p--; {p++; cs = 8; goto _out;}
313
- }
314
- }
315
- #line 58 "edn_parser.rl"
336
+ if (edn::util::parse_byte_stream(p_save + 1, p, v, encode)) {
337
+ {p = (( p + 1))-1;}
338
+ } else {
339
+ p--; {p++; cs = 8; goto _out;}
340
+ }
341
+ }
342
+ #line 80 "edn_parser.rl"
316
343
  { p--; {p++; cs = 8; goto _out;} }
317
344
  goto st8;
318
345
  st8:
319
346
  if ( ++p == pe )
320
347
  goto _test_eof8;
321
348
  case 8:
322
- #line 323 "edn_parser.cc"
349
+ #line 350 "edn_parser.cc"
323
350
  goto st0;
324
351
  tr4:
325
- #line 219 "edn_parser.rl"
352
+ #line 246 "edn_parser.rl"
326
353
  {
327
- encode = true;
328
- }
354
+ encode = true;
355
+ }
329
356
  goto st3;
330
357
  st3:
331
358
  if ( ++p == pe )
332
359
  goto _test_eof3;
333
360
  case 3:
334
- #line 335 "edn_parser.cc"
361
+ #line 362 "edn_parser.cc"
335
362
  switch( (*p) ) {
336
363
  case 34: goto tr2;
337
364
  case 47: goto tr2;
@@ -345,16 +372,16 @@ case 3:
345
372
  }
346
373
  goto st2;
347
374
  tr5:
348
- #line 219 "edn_parser.rl"
375
+ #line 246 "edn_parser.rl"
349
376
  {
350
- encode = true;
351
- }
377
+ encode = true;
378
+ }
352
379
  goto st4;
353
380
  st4:
354
381
  if ( ++p == pe )
355
382
  goto _test_eof4;
356
383
  case 4:
357
- #line 358 "edn_parser.cc"
384
+ #line 385 "edn_parser.cc"
358
385
  if ( (*p) < 65 ) {
359
386
  if ( 48 <= (*p) && (*p) <= 57 )
360
387
  goto tr6;
@@ -365,16 +392,16 @@ case 4:
365
392
  goto tr6;
366
393
  goto st0;
367
394
  tr6:
368
- #line 219 "edn_parser.rl"
395
+ #line 246 "edn_parser.rl"
369
396
  {
370
- encode = true;
371
- }
397
+ encode = true;
398
+ }
372
399
  goto st5;
373
400
  st5:
374
401
  if ( ++p == pe )
375
402
  goto _test_eof5;
376
403
  case 5:
377
- #line 378 "edn_parser.cc"
404
+ #line 405 "edn_parser.cc"
378
405
  if ( (*p) < 65 ) {
379
406
  if ( 48 <= (*p) && (*p) <= 57 )
380
407
  goto tr7;
@@ -385,16 +412,16 @@ case 5:
385
412
  goto tr7;
386
413
  goto st0;
387
414
  tr7:
388
- #line 219 "edn_parser.rl"
415
+ #line 246 "edn_parser.rl"
389
416
  {
390
- encode = true;
391
- }
417
+ encode = true;
418
+ }
392
419
  goto st6;
393
420
  st6:
394
421
  if ( ++p == pe )
395
422
  goto _test_eof6;
396
423
  case 6:
397
- #line 398 "edn_parser.cc"
424
+ #line 425 "edn_parser.cc"
398
425
  if ( (*p) < 65 ) {
399
426
  if ( 48 <= (*p) && (*p) <= 57 )
400
427
  goto tr8;
@@ -405,16 +432,16 @@ case 6:
405
432
  goto tr8;
406
433
  goto st0;
407
434
  tr8:
408
- #line 219 "edn_parser.rl"
435
+ #line 246 "edn_parser.rl"
409
436
  {
410
- encode = true;
411
- }
437
+ encode = true;
438
+ }
412
439
  goto st7;
413
440
  st7:
414
441
  if ( ++p == pe )
415
442
  goto _test_eof7;
416
443
  case 7:
417
- #line 418 "edn_parser.cc"
444
+ #line 445 "edn_parser.cc"
418
445
  if ( (*p) < 65 ) {
419
446
  if ( 48 <= (*p) && (*p) <= 57 )
420
447
  goto tr2;
@@ -438,31 +465,31 @@ case 7:
438
465
  {
439
466
  switch ( cs ) {
440
467
  case 2:
441
- #line 51 "edn_parser.rl"
468
+ #line 73 "edn_parser.rl"
442
469
  {
443
- std::stringstream s;
444
- s << "unterminated " << EDN_TYPE;
445
- error(__FUNCTION__, s.str());
446
- p--; {p++; cs = 0; goto _out;}
447
- }
470
+ std::stringstream s;
471
+ s << "unterminated " << EDN_TYPE;
472
+ error(__FUNCTION__, s.str());
473
+ p--; {p++; cs = 0; goto _out;}
474
+ }
448
475
  break;
449
- #line 450 "edn_parser.cc"
476
+ #line 477 "edn_parser.cc"
450
477
  }
451
478
  }
452
479
 
453
480
  _out: {}
454
481
  }
455
482
 
456
- #line 242 "edn_parser.rl"
483
+ #line 269 "edn_parser.rl"
457
484
 
458
- if (cs >= EDN_string_first_final) {
459
- return p + 1;
460
- }
461
- else if (cs == EDN_string_error) {
462
- return pe;
463
- }
464
- else if (cs == EDN_string_en_main) {} // silence ragel warning
465
- return NULL;
485
+ if (cs >= EDN_string_first_final) {
486
+ return p + 1;
487
+ }
488
+ else if (cs == EDN_string_error) {
489
+ return pe;
490
+ }
491
+ else if (cs == EDN_string_en_main) {} // silence ragel warning
492
+ return nullptr;
466
493
  }
467
494
 
468
495
 
@@ -471,7 +498,7 @@ case 7:
471
498
  // keyword parsing
472
499
  //
473
500
 
474
- #line 475 "edn_parser.cc"
501
+ #line 502 "edn_parser.cc"
475
502
  static const int EDN_keyword_start = 1;
476
503
  static const int EDN_keyword_first_final = 3;
477
504
  static const int EDN_keyword_error = 0;
@@ -479,24 +506,24 @@ static const int EDN_keyword_error = 0;
479
506
  static const int EDN_keyword_en_main = 1;
480
507
 
481
508
 
482
- #line 272 "edn_parser.rl"
509
+ #line 299 "edn_parser.rl"
483
510
 
484
511
 
485
512
 
486
513
  const char* edn::Parser::parse_keyword(const char *p, const char *pe, VALUE& v)
487
514
  {
488
- int cs;
515
+ int cs;
489
516
 
490
517
 
491
- #line 492 "edn_parser.cc"
518
+ #line 519 "edn_parser.cc"
492
519
  {
493
520
  cs = EDN_keyword_start;
494
521
  }
495
522
 
496
- #line 280 "edn_parser.rl"
497
- const char* p_save = p;
523
+ #line 307 "edn_parser.rl"
524
+ const char* p_save = p;
498
525
 
499
- #line 500 "edn_parser.cc"
526
+ #line 527 "edn_parser.cc"
500
527
  {
501
528
  if ( p == pe )
502
529
  goto _test_eof;
@@ -563,14 +590,14 @@ case 3:
563
590
  goto st3;
564
591
  goto tr3;
565
592
  tr3:
566
- #line 58 "edn_parser.rl"
593
+ #line 80 "edn_parser.rl"
567
594
  { p--; {p++; cs = 4; goto _out;} }
568
595
  goto st4;
569
596
  st4:
570
597
  if ( ++p == pe )
571
598
  goto _test_eof4;
572
599
  case 4:
573
- #line 574 "edn_parser.cc"
600
+ #line 601 "edn_parser.cc"
574
601
  goto st0;
575
602
  st5:
576
603
  if ( ++p == pe )
@@ -609,55 +636,54 @@ case 5:
609
636
  _out: {}
610
637
  }
611
638
 
612
- #line 282 "edn_parser.rl"
613
-
614
- if (cs >= EDN_keyword_first_final) {
615
- std::string buf;
616
- uintmax_t len = p - p_save;
617
- // don't include leading ':' because the ruby symbol will handle it
618
- buf.append(p_save + 1, len - 1);
619
- v = ID2SYM(rb_intern(buf.c_str()));
620
- return p;
621
- }
622
- else if (cs == EDN_keyword_error) {
623
- error(__FUNCTION__, "invalid keyword", *p);
624
- return pe;
625
- }
626
- else if (cs == EDN_keyword_en_main) {} // silence ragel warning
627
- return NULL;
639
+ #line 309 "edn_parser.rl"
640
+
641
+ if (cs >= EDN_keyword_first_final) {
642
+ std::string buf;
643
+ uintmax_t len = p - p_save;
644
+ // don't include leading ':' because the ruby symbol will handle it
645
+ buf.append(p_save + 1, len - 1);
646
+ v = ID2SYM(rb_intern(buf.c_str()));
647
+ return p;
648
+ }
649
+ else if (cs == EDN_keyword_error) {
650
+ error(__FUNCTION__, "invalid keyword", *p);
651
+ return pe;
652
+ }
653
+ else if (cs == EDN_keyword_en_main) {} // silence ragel warning
654
+ return nullptr;
628
655
  }
629
656
 
630
657
 
631
-
632
658
  // ============================================================
633
659
  // decimal parsing machine
634
660
  //
635
661
 
636
- #line 637 "edn_parser.cc"
662
+ #line 663 "edn_parser.cc"
637
663
  static const int EDN_decimal_start = 1;
638
664
  static const int EDN_decimal_first_final = 9;
639
665
 
640
666
  static const int EDN_decimal_en_main = 1;
641
667
 
642
668
 
643
- #line 315 "edn_parser.rl"
669
+ #line 341 "edn_parser.rl"
644
670
 
645
671
 
646
672
 
647
673
  const char* edn::Parser::parse_decimal(const char *p, const char *pe, VALUE& v)
648
674
  {
649
- int cs;
675
+ int cs;
650
676
 
651
677
 
652
- #line 653 "edn_parser.cc"
678
+ #line 679 "edn_parser.cc"
653
679
  {
654
680
  cs = EDN_decimal_start;
655
681
  }
656
682
 
657
- #line 323 "edn_parser.rl"
658
- const char* p_save = p;
683
+ #line 349 "edn_parser.rl"
684
+ const char* p_save = p;
659
685
 
660
- #line 661 "edn_parser.cc"
686
+ #line 687 "edn_parser.cc"
661
687
  {
662
688
  if ( p == pe )
663
689
  goto _test_eof;
@@ -711,14 +737,14 @@ case 9:
711
737
  goto st0;
712
738
  goto tr10;
713
739
  tr10:
714
- #line 58 "edn_parser.rl"
740
+ #line 80 "edn_parser.rl"
715
741
  { p--; {p++; cs = 10; goto _out;} }
716
742
  goto st10;
717
743
  st10:
718
744
  if ( ++p == pe )
719
745
  goto _test_eof10;
720
746
  case 10:
721
- #line 722 "edn_parser.cc"
747
+ #line 748 "edn_parser.cc"
722
748
  goto st0;
723
749
  st4:
724
750
  if ( ++p == pe )
@@ -834,14 +860,14 @@ case 8:
834
860
  _out: {}
835
861
  }
836
862
 
837
- #line 325 "edn_parser.rl"
863
+ #line 351 "edn_parser.rl"
838
864
 
839
- if (cs >= EDN_decimal_first_final) {
840
- v = edn::util::float_to_ruby(p_save, p - p_save);
841
- return p + 1;
842
- }
843
- else if (cs == EDN_decimal_en_main) {} // silence ragel warning
844
- return NULL;
865
+ if (cs >= EDN_decimal_first_final) {
866
+ v = edn::util::float_to_ruby(p_save, p - p_save);
867
+ return p + 1;
868
+ }
869
+ else if (cs == EDN_decimal_en_main) {} // silence ragel warning
870
+ return nullptr;
845
871
  }
846
872
 
847
873
 
@@ -849,30 +875,30 @@ case 8:
849
875
  // integer parsing machine - M suffix will return a BigNum
850
876
  //
851
877
 
852
- #line 853 "edn_parser.cc"
878
+ #line 879 "edn_parser.cc"
853
879
  static const int EDN_integer_start = 1;
854
880
  static const int EDN_integer_first_final = 3;
855
881
 
856
882
  static const int EDN_integer_en_main = 1;
857
883
 
858
884
 
859
- #line 348 "edn_parser.rl"
885
+ #line 374 "edn_parser.rl"
860
886
 
861
887
 
862
888
  const char* edn::Parser::parse_integer(const char *p, const char *pe, VALUE& v)
863
889
  {
864
- int cs;
890
+ int cs;
865
891
 
866
892
 
867
- #line 868 "edn_parser.cc"
893
+ #line 894 "edn_parser.cc"
868
894
  {
869
895
  cs = EDN_integer_start;
870
896
  }
871
897
 
872
- #line 355 "edn_parser.rl"
873
- const char* p_save = p;
898
+ #line 381 "edn_parser.rl"
899
+ const char* p_save = p;
874
900
 
875
- #line 876 "edn_parser.cc"
901
+ #line 902 "edn_parser.cc"
876
902
  {
877
903
  if ( p == pe )
878
904
  goto _test_eof;
@@ -914,14 +940,14 @@ case 3:
914
940
  goto st0;
915
941
  goto tr4;
916
942
  tr4:
917
- #line 58 "edn_parser.rl"
943
+ #line 80 "edn_parser.rl"
918
944
  { p--; {p++; cs = 4; goto _out;} }
919
945
  goto st4;
920
946
  st4:
921
947
  if ( ++p == pe )
922
948
  goto _test_eof4;
923
949
  case 4:
924
- #line 925 "edn_parser.cc"
950
+ #line 951 "edn_parser.cc"
925
951
  goto st0;
926
952
  st5:
927
953
  if ( ++p == pe )
@@ -962,17 +988,152 @@ case 6:
962
988
  _out: {}
963
989
  }
964
990
 
965
- #line 357 "edn_parser.rl"
991
+ #line 383 "edn_parser.rl"
966
992
 
967
- if (cs >= EDN_integer_first_final) {
968
- v = edn::util::integer_to_ruby(p_save, p - p_save);
969
- return p + 1;
970
- }
971
- else if (cs == EDN_integer_en_main) {} // silence ragel warning
972
- return NULL;
993
+ if (cs >= EDN_integer_first_final) {
994
+ v = edn::util::integer_to_ruby(p_save, p - p_save);
995
+ return p + 1;
996
+ }
997
+ else if (cs == EDN_integer_en_main) {} // silence ragel warning
998
+ return nullptr;
973
999
  }
974
1000
 
975
1001
 
1002
+ // ============================================================
1003
+ // ratio parsing machine
1004
+ //
1005
+
1006
+ #line 1007 "edn_parser.cc"
1007
+ static const int EDN_ratio_start = 1;
1008
+ static const int EDN_ratio_first_final = 6;
1009
+
1010
+ static const int EDN_ratio_en_main = 1;
1011
+
1012
+
1013
+ #line 406 "edn_parser.rl"
1014
+
1015
+
1016
+
1017
+ const char* edn::Parser::parse_ratio(const char *p, const char *pe, VALUE& v)
1018
+ {
1019
+ int cs;
1020
+
1021
+
1022
+ #line 1023 "edn_parser.cc"
1023
+ {
1024
+ cs = EDN_ratio_start;
1025
+ }
1026
+
1027
+ #line 414 "edn_parser.rl"
1028
+ const char* p_save = p;
1029
+
1030
+ #line 1031 "edn_parser.cc"
1031
+ {
1032
+ if ( p == pe )
1033
+ goto _test_eof;
1034
+ switch ( cs )
1035
+ {
1036
+ case 1:
1037
+ switch( (*p) ) {
1038
+ case 43: goto st2;
1039
+ case 45: goto st2;
1040
+ case 48: goto st3;
1041
+ }
1042
+ if ( 49 <= (*p) && (*p) <= 57 )
1043
+ goto st5;
1044
+ goto st0;
1045
+ st0:
1046
+ cs = 0;
1047
+ goto _out;
1048
+ st2:
1049
+ if ( ++p == pe )
1050
+ goto _test_eof2;
1051
+ case 2:
1052
+ if ( (*p) == 48 )
1053
+ goto st3;
1054
+ if ( 49 <= (*p) && (*p) <= 57 )
1055
+ goto st5;
1056
+ goto st0;
1057
+ st3:
1058
+ if ( ++p == pe )
1059
+ goto _test_eof3;
1060
+ case 3:
1061
+ if ( (*p) == 47 )
1062
+ goto st4;
1063
+ goto st0;
1064
+ st4:
1065
+ if ( ++p == pe )
1066
+ goto _test_eof4;
1067
+ case 4:
1068
+ if ( (*p) == 48 )
1069
+ goto st6;
1070
+ if ( 49 <= (*p) && (*p) <= 57 )
1071
+ goto st8;
1072
+ goto st0;
1073
+ st6:
1074
+ if ( ++p == pe )
1075
+ goto _test_eof6;
1076
+ case 6:
1077
+ switch( (*p) ) {
1078
+ case 43: goto st0;
1079
+ case 45: goto st0;
1080
+ }
1081
+ if ( 47 <= (*p) && (*p) <= 57 )
1082
+ goto st0;
1083
+ goto tr7;
1084
+ tr7:
1085
+ #line 80 "edn_parser.rl"
1086
+ { p--; {p++; cs = 7; goto _out;} }
1087
+ goto st7;
1088
+ st7:
1089
+ if ( ++p == pe )
1090
+ goto _test_eof7;
1091
+ case 7:
1092
+ #line 1093 "edn_parser.cc"
1093
+ goto st0;
1094
+ st8:
1095
+ if ( ++p == pe )
1096
+ goto _test_eof8;
1097
+ case 8:
1098
+ switch( (*p) ) {
1099
+ case 43: goto st0;
1100
+ case 45: goto st0;
1101
+ case 47: goto st0;
1102
+ }
1103
+ if ( 48 <= (*p) && (*p) <= 57 )
1104
+ goto st8;
1105
+ goto tr7;
1106
+ st5:
1107
+ if ( ++p == pe )
1108
+ goto _test_eof5;
1109
+ case 5:
1110
+ if ( (*p) == 47 )
1111
+ goto st4;
1112
+ if ( 48 <= (*p) && (*p) <= 57 )
1113
+ goto st5;
1114
+ goto st0;
1115
+ }
1116
+ _test_eof2: cs = 2; goto _test_eof;
1117
+ _test_eof3: cs = 3; goto _test_eof;
1118
+ _test_eof4: cs = 4; goto _test_eof;
1119
+ _test_eof6: cs = 6; goto _test_eof;
1120
+ _test_eof7: cs = 7; goto _test_eof;
1121
+ _test_eof8: cs = 8; goto _test_eof;
1122
+ _test_eof5: cs = 5; goto _test_eof;
1123
+
1124
+ _test_eof: {}
1125
+ _out: {}
1126
+ }
1127
+
1128
+ #line 416 "edn_parser.rl"
1129
+
1130
+ if (cs >= EDN_ratio_first_final) {
1131
+ v = edn::util::ratio_to_ruby(p_save, p - p_save);
1132
+ return p + 1;
1133
+ }
1134
+ else if (cs == EDN_ratio_en_main) {} // silence ragel warning
1135
+ return nullptr;
1136
+ }
976
1137
 
977
1138
  // ============================================================
978
1139
  // operator parsing - handles tokens w/ a leading operator:
@@ -982,7 +1143,7 @@ case 6:
982
1143
  // 3. stand-alone operators: +, -, /, *, etc.
983
1144
  //
984
1145
 
985
- #line 986 "edn_parser.cc"
1146
+ #line 1147 "edn_parser.cc"
986
1147
  static const int EDN_operator_start = 1;
987
1148
  static const int EDN_operator_first_final = 3;
988
1149
  static const int EDN_operator_error = 0;
@@ -990,24 +1151,24 @@ static const int EDN_operator_error = 0;
990
1151
  static const int EDN_operator_en_main = 1;
991
1152
 
992
1153
 
993
- #line 431 "edn_parser.rl"
1154
+ #line 493 "edn_parser.rl"
994
1155
 
995
1156
 
996
1157
 
997
1158
  const char* edn::Parser::parse_operator(const char *p, const char *pe, VALUE& v)
998
1159
  {
999
- int cs;
1160
+ int cs;
1000
1161
 
1001
1162
 
1002
- #line 1003 "edn_parser.cc"
1163
+ #line 1164 "edn_parser.cc"
1003
1164
  {
1004
1165
  cs = EDN_operator_start;
1005
1166
  }
1006
1167
 
1007
- #line 439 "edn_parser.rl"
1008
- const char* p_save = p;
1168
+ #line 501 "edn_parser.rl"
1169
+ const char* p_save = p;
1009
1170
 
1010
- #line 1011 "edn_parser.cc"
1171
+ #line 1172 "edn_parser.cc"
1011
1172
  {
1012
1173
  if ( p == pe )
1013
1174
  goto _test_eof;
@@ -1060,84 +1221,84 @@ case 3:
1060
1221
  goto tr9;
1061
1222
  goto tr6;
1062
1223
  tr6:
1063
- #line 415 "edn_parser.rl"
1064
- {
1065
- // stand-alone operators (-, +, /, ... etc)
1066
- char op[2] = { *p_save, 0 };
1067
- VALUE sym = rb_str_new2(op);
1068
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1069
- }
1070
- #line 58 "edn_parser.rl"
1224
+ #line 477 "edn_parser.rl"
1225
+ {
1226
+ // stand-alone operators (-, +, /, ... etc)
1227
+ char op[2] = { *p_save, 0 };
1228
+ VALUE sym = rb_str_new2(op);
1229
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1230
+ }
1231
+ #line 80 "edn_parser.rl"
1071
1232
  { p--; {p++; cs = 4; goto _out;} }
1072
1233
  goto st4;
1073
1234
  tr11:
1074
- #line 58 "edn_parser.rl"
1235
+ #line 80 "edn_parser.rl"
1075
1236
  { p--; {p++; cs = 4; goto _out;} }
1076
1237
  goto st4;
1077
1238
  tr17:
1078
- #line 381 "edn_parser.rl"
1239
+ #line 438 "edn_parser.rl"
1079
1240
  {
1080
- // parse a symbol including the leading operator (-, +, .)
1081
- VALUE sym = Qnil;
1082
- const char *np = parse_symbol(p_save, pe, sym);
1083
- if (np == NULL) { {p = (( pe))-1;} } else {
1084
- if (sym != Qnil)
1085
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1086
- {p = (( np))-1;}
1087
- }
1088
- }
1089
- #line 58 "edn_parser.rl"
1241
+ // parse a symbol including the leading operator (-, +, .)
1242
+ VALUE sym = Qnil;
1243
+ const char *np = parse_symbol(p_save, pe, sym);
1244
+ if (np == nullptr) { {p = (( pe))-1;} } else {
1245
+ if (sym != Qnil)
1246
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1247
+ {p = (( np))-1;}
1248
+ }
1249
+ }
1250
+ #line 80 "edn_parser.rl"
1090
1251
  { p--; {p++; cs = 4; goto _out;} }
1091
1252
  goto st4;
1092
1253
  st4:
1093
1254
  if ( ++p == pe )
1094
1255
  goto _test_eof4;
1095
1256
  case 4:
1096
- #line 1097 "edn_parser.cc"
1257
+ #line 1258 "edn_parser.cc"
1097
1258
  goto st0;
1098
1259
  tr5:
1099
- #line 25 "edn_parser.rl"
1260
+ #line 47 "edn_parser.rl"
1100
1261
  { line_number++; }
1101
1262
  goto st5;
1102
1263
  tr7:
1103
- #line 415 "edn_parser.rl"
1104
- {
1105
- // stand-alone operators (-, +, /, ... etc)
1106
- char op[2] = { *p_save, 0 };
1107
- VALUE sym = rb_str_new2(op);
1108
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1109
- }
1110
- #line 58 "edn_parser.rl"
1264
+ #line 477 "edn_parser.rl"
1265
+ {
1266
+ // stand-alone operators (-, +, /, ... etc)
1267
+ char op[2] = { *p_save, 0 };
1268
+ VALUE sym = rb_str_new2(op);
1269
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1270
+ }
1271
+ #line 80 "edn_parser.rl"
1111
1272
  { p--; {p++; cs = 5; goto _out;} }
1112
1273
  goto st5;
1113
1274
  tr8:
1114
- #line 415 "edn_parser.rl"
1115
- {
1116
- // stand-alone operators (-, +, /, ... etc)
1117
- char op[2] = { *p_save, 0 };
1118
- VALUE sym = rb_str_new2(op);
1119
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1120
- }
1121
- #line 25 "edn_parser.rl"
1275
+ #line 477 "edn_parser.rl"
1276
+ {
1277
+ // stand-alone operators (-, +, /, ... etc)
1278
+ char op[2] = { *p_save, 0 };
1279
+ VALUE sym = rb_str_new2(op);
1280
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1281
+ }
1282
+ #line 47 "edn_parser.rl"
1122
1283
  { line_number++; }
1123
- #line 58 "edn_parser.rl"
1284
+ #line 80 "edn_parser.rl"
1124
1285
  { p--; {p++; cs = 5; goto _out;} }
1125
1286
  goto st5;
1126
1287
  tr12:
1127
- #line 58 "edn_parser.rl"
1288
+ #line 80 "edn_parser.rl"
1128
1289
  { p--; {p++; cs = 5; goto _out;} }
1129
1290
  goto st5;
1130
1291
  tr13:
1131
- #line 25 "edn_parser.rl"
1292
+ #line 47 "edn_parser.rl"
1132
1293
  { line_number++; }
1133
- #line 58 "edn_parser.rl"
1294
+ #line 80 "edn_parser.rl"
1134
1295
  { p--; {p++; cs = 5; goto _out;} }
1135
1296
  goto st5;
1136
1297
  st5:
1137
1298
  if ( ++p == pe )
1138
1299
  goto _test_eof5;
1139
1300
  case 5:
1140
- #line 1141 "edn_parser.cc"
1301
+ #line 1302 "edn_parser.cc"
1141
1302
  switch( (*p) ) {
1142
1303
  case 10: goto tr13;
1143
1304
  case 32: goto tr12;
@@ -1162,25 +1323,25 @@ case 5:
1162
1323
  goto st0;
1163
1324
  goto tr11;
1164
1325
  tr10:
1165
- #line 415 "edn_parser.rl"
1166
- {
1167
- // stand-alone operators (-, +, /, ... etc)
1168
- char op[2] = { *p_save, 0 };
1169
- VALUE sym = rb_str_new2(op);
1170
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1171
- }
1172
- #line 58 "edn_parser.rl"
1326
+ #line 477 "edn_parser.rl"
1327
+ {
1328
+ // stand-alone operators (-, +, /, ... etc)
1329
+ char op[2] = { *p_save, 0 };
1330
+ VALUE sym = rb_str_new2(op);
1331
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1332
+ }
1333
+ #line 80 "edn_parser.rl"
1173
1334
  { p--; {p++; cs = 6; goto _out;} }
1174
1335
  goto st6;
1175
1336
  tr14:
1176
- #line 58 "edn_parser.rl"
1337
+ #line 80 "edn_parser.rl"
1177
1338
  { p--; {p++; cs = 6; goto _out;} }
1178
1339
  goto st6;
1179
1340
  st6:
1180
1341
  if ( ++p == pe )
1181
1342
  goto _test_eof6;
1182
1343
  case 6:
1183
- #line 1184 "edn_parser.cc"
1344
+ #line 1345 "edn_parser.cc"
1184
1345
  if ( (*p) == 10 )
1185
1346
  goto tr5;
1186
1347
  goto st2;
@@ -1192,48 +1353,53 @@ case 2:
1192
1353
  goto tr5;
1193
1354
  goto st2;
1194
1355
  tr9:
1195
- #line 381 "edn_parser.rl"
1356
+ #line 438 "edn_parser.rl"
1196
1357
  {
1197
- // parse a symbol including the leading operator (-, +, .)
1198
- VALUE sym = Qnil;
1199
- const char *np = parse_symbol(p_save, pe, sym);
1200
- if (np == NULL) { {p = (( pe))-1;} } else {
1201
- if (sym != Qnil)
1202
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1203
- {p = (( np))-1;}
1204
- }
1205
- }
1358
+ // parse a symbol including the leading operator (-, +, .)
1359
+ VALUE sym = Qnil;
1360
+ const char *np = parse_symbol(p_save, pe, sym);
1361
+ if (np == nullptr) { {p = (( pe))-1;} } else {
1362
+ if (sym != Qnil)
1363
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1364
+ {p = (( np))-1;}
1365
+ }
1366
+ }
1206
1367
  goto st7;
1207
1368
  tr16:
1208
- #line 392 "edn_parser.rl"
1209
- {
1210
- // parse a number with the leading symbol - this is slightly
1211
- // different than the one within EDN_value since it includes
1212
- // the leading - or +
1213
- //
1214
- // try to parse a decimal first
1215
- const char *np = parse_decimal(p_save, pe, v);
1216
- if (np == NULL) {
1217
- // if we can't, try to parse it as an int
1369
+ #line 449 "edn_parser.rl"
1370
+ {
1371
+ // parse a number with the leading symbol - this is slightly
1372
+ // different than the one within EDN_value since it includes
1373
+ // the leading - or +
1374
+ //
1375
+ // try to parse a decimal first
1376
+ const char *np = parse_decimal(p_save, pe, v);
1377
+ if (np == nullptr) {
1378
+ // if we can't, try to parse it as a ratio
1379
+ np = parse_ratio(p_save, pe, v);
1380
+
1381
+ if (np == nullptr) {
1382
+ // again, if we can't, try to parse it as an int
1218
1383
  np = parse_integer(p_save, pe, v);
1219
- }
1220
-
1221
- if (np) {
1222
- {p = (( np))-1;}
1223
- p--;
1224
- {p++; cs = 7; goto _out;}
1225
- }
1226
- else {
1227
- error(__FUNCTION__, "number format error", *p);
1228
- {p = (( pe))-1;}
1229
- }
1230
- }
1384
+ }
1385
+ }
1386
+
1387
+ if (np) {
1388
+ {p = (( np))-1;}
1389
+ p--;
1390
+ {p++; cs = 7; goto _out;}
1391
+ }
1392
+ else {
1393
+ error(__FUNCTION__, "number format error", *p);
1394
+ {p = (( pe))-1;}
1395
+ }
1396
+ }
1231
1397
  goto st7;
1232
1398
  st7:
1233
1399
  if ( ++p == pe )
1234
1400
  goto _test_eof7;
1235
1401
  case 7:
1236
- #line 1237 "edn_parser.cc"
1402
+ #line 1403 "edn_parser.cc"
1237
1403
  switch( (*p) ) {
1238
1404
  case 33: goto st0;
1239
1405
  case 95: goto st0;
@@ -1316,23 +1482,23 @@ case 9:
1316
1482
  goto tr18;
1317
1483
  goto tr17;
1318
1484
  tr18:
1319
- #line 381 "edn_parser.rl"
1485
+ #line 438 "edn_parser.rl"
1320
1486
  {
1321
- // parse a symbol including the leading operator (-, +, .)
1322
- VALUE sym = Qnil;
1323
- const char *np = parse_symbol(p_save, pe, sym);
1324
- if (np == NULL) { {p = (( pe))-1;} } else {
1325
- if (sym != Qnil)
1326
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1327
- {p = (( np))-1;}
1328
- }
1329
- }
1487
+ // parse a symbol including the leading operator (-, +, .)
1488
+ VALUE sym = Qnil;
1489
+ const char *np = parse_symbol(p_save, pe, sym);
1490
+ if (np == nullptr) { {p = (( pe))-1;} } else {
1491
+ if (sym != Qnil)
1492
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1493
+ {p = (( np))-1;}
1494
+ }
1495
+ }
1330
1496
  goto st10;
1331
1497
  st10:
1332
1498
  if ( ++p == pe )
1333
1499
  goto _test_eof10;
1334
1500
  case 10:
1335
- #line 1336 "edn_parser.cc"
1501
+ #line 1502 "edn_parser.cc"
1336
1502
  switch( (*p) ) {
1337
1503
  case 33: goto st10;
1338
1504
  case 95: goto st10;
@@ -1405,47 +1571,47 @@ case 11:
1405
1571
  {
1406
1572
  switch ( cs ) {
1407
1573
  case 9:
1408
- #line 381 "edn_parser.rl"
1574
+ #line 438 "edn_parser.rl"
1409
1575
  {
1410
- // parse a symbol including the leading operator (-, +, .)
1411
- VALUE sym = Qnil;
1412
- const char *np = parse_symbol(p_save, pe, sym);
1413
- if (np == NULL) { {p = (( pe))-1;} } else {
1414
- if (sym != Qnil)
1415
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1416
- {p = (( np))-1;}
1417
- }
1418
- }
1576
+ // parse a symbol including the leading operator (-, +, .)
1577
+ VALUE sym = Qnil;
1578
+ const char *np = parse_symbol(p_save, pe, sym);
1579
+ if (np == nullptr) { {p = (( pe))-1;} } else {
1580
+ if (sym != Qnil)
1581
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1582
+ {p = (( np))-1;}
1583
+ }
1584
+ }
1419
1585
  break;
1420
1586
  case 3:
1421
1587
  case 8:
1422
1588
  case 11:
1423
- #line 415 "edn_parser.rl"
1589
+ #line 477 "edn_parser.rl"
1424
1590
  {
1425
- // stand-alone operators (-, +, /, ... etc)
1426
- char op[2] = { *p_save, 0 };
1427
- VALUE sym = rb_str_new2(op);
1428
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1429
- }
1591
+ // stand-alone operators (-, +, /, ... etc)
1592
+ char op[2] = { *p_save, 0 };
1593
+ VALUE sym = rb_str_new2(op);
1594
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
1595
+ }
1430
1596
  break;
1431
- #line 1432 "edn_parser.cc"
1597
+ #line 1598 "edn_parser.cc"
1432
1598
  }
1433
1599
  }
1434
1600
 
1435
1601
  _out: {}
1436
1602
  }
1437
1603
 
1438
- #line 441 "edn_parser.rl"
1439
-
1440
- if (cs >= EDN_operator_first_final) {
1441
- return p;
1442
- }
1443
- else if (cs == EDN_operator_error) {
1444
- error(__FUNCTION__, "symbol syntax error", *p);
1445
- return pe;
1446
- }
1447
- else if (cs == EDN_operator_en_main) {} // silence ragel warning
1448
- return NULL;
1604
+ #line 503 "edn_parser.rl"
1605
+
1606
+ if (cs >= EDN_operator_first_final) {
1607
+ return p;
1608
+ }
1609
+ else if (cs == EDN_operator_error) {
1610
+ error(__FUNCTION__, "symbol syntax error", *p);
1611
+ return pe;
1612
+ }
1613
+ else if (cs == EDN_operator_en_main) {} // silence ragel warning
1614
+ return nullptr;
1449
1615
  }
1450
1616
 
1451
1617
 
@@ -1454,7 +1620,7 @@ case 11:
1454
1620
  // escaped char parsing - handles \c, \newline, \formfeed, etc.
1455
1621
  //
1456
1622
 
1457
- #line 1458 "edn_parser.cc"
1623
+ #line 1624 "edn_parser.cc"
1458
1624
  static const int EDN_escaped_char_start = 1;
1459
1625
  static const int EDN_escaped_char_first_final = 26;
1460
1626
  static const int EDN_escaped_char_error = 0;
@@ -1462,24 +1628,24 @@ static const int EDN_escaped_char_error = 0;
1462
1628
  static const int EDN_escaped_char_en_main = 1;
1463
1629
 
1464
1630
 
1465
- #line 471 "edn_parser.rl"
1631
+ #line 533 "edn_parser.rl"
1466
1632
 
1467
1633
 
1468
1634
 
1469
1635
  const char* edn::Parser::parse_esc_char(const char *p, const char *pe, VALUE& v)
1470
1636
  {
1471
- int cs;
1637
+ int cs;
1472
1638
 
1473
1639
 
1474
- #line 1475 "edn_parser.cc"
1640
+ #line 1641 "edn_parser.cc"
1475
1641
  {
1476
1642
  cs = EDN_escaped_char_start;
1477
1643
  }
1478
1644
 
1479
- #line 479 "edn_parser.rl"
1480
- const char* p_save = p;
1645
+ #line 541 "edn_parser.rl"
1646
+ const char* p_save = p;
1481
1647
 
1482
- #line 1483 "edn_parser.cc"
1648
+ #line 1649 "edn_parser.cc"
1483
1649
  {
1484
1650
  if ( p == pe )
1485
1651
  goto _test_eof;
@@ -1524,20 +1690,20 @@ case 26:
1524
1690
  goto tr28;
1525
1691
  goto st0;
1526
1692
  tr10:
1527
- #line 25 "edn_parser.rl"
1693
+ #line 47 "edn_parser.rl"
1528
1694
  { line_number++; }
1529
- #line 58 "edn_parser.rl"
1695
+ #line 80 "edn_parser.rl"
1530
1696
  { p--; {p++; cs = 27; goto _out;} }
1531
1697
  goto st27;
1532
1698
  tr28:
1533
- #line 58 "edn_parser.rl"
1699
+ #line 80 "edn_parser.rl"
1534
1700
  { p--; {p++; cs = 27; goto _out;} }
1535
1701
  goto st27;
1536
1702
  st27:
1537
1703
  if ( ++p == pe )
1538
1704
  goto _test_eof27;
1539
1705
  case 27:
1540
- #line 1541 "edn_parser.cc"
1706
+ #line 1707 "edn_parser.cc"
1541
1707
  switch( (*p) ) {
1542
1708
  case 10: goto tr10;
1543
1709
  case 32: goto tr28;
@@ -1555,14 +1721,14 @@ case 3:
1555
1721
  goto tr10;
1556
1722
  goto st3;
1557
1723
  tr29:
1558
- #line 58 "edn_parser.rl"
1724
+ #line 80 "edn_parser.rl"
1559
1725
  { p--; {p++; cs = 28; goto _out;} }
1560
1726
  goto st28;
1561
1727
  st28:
1562
1728
  if ( ++p == pe )
1563
1729
  goto _test_eof28;
1564
1730
  case 28:
1565
- #line 1566 "edn_parser.cc"
1731
+ #line 1732 "edn_parser.cc"
1566
1732
  goto st0;
1567
1733
  st29:
1568
1734
  if ( ++p == pe )
@@ -1871,26 +2037,25 @@ case 25:
1871
2037
  _out: {}
1872
2038
  }
1873
2039
 
1874
- #line 481 "edn_parser.rl"
1875
-
1876
- if (cs >= EDN_escaped_char_first_final) {
1877
- // convert the escaped value to a character
1878
- if (!edn::util::parse_escaped_char(p_save + 1, p, v)) {
1879
- return pe;
1880
- }
1881
- return p;
1882
- }
1883
- else if (cs == EDN_escaped_char_error) {
1884
- error(__FUNCTION__, "unexpected value", *p);
1885
- return pe;
1886
- }
1887
- else if (cs == EDN_escaped_char_en_main) {} // silence ragel warning
1888
- return NULL;
2040
+ #line 543 "edn_parser.rl"
2041
+
2042
+ if (cs >= EDN_escaped_char_first_final) {
2043
+ // convert the escaped value to a character
2044
+ if (!edn::util::parse_escaped_char(p_save + 1, p, v)) {
2045
+ return pe;
2046
+ }
2047
+ return p;
2048
+ }
2049
+ else if (cs == EDN_escaped_char_error) {
2050
+ error(__FUNCTION__, "unexpected value", *p);
2051
+ return pe;
2052
+ }
2053
+ else if (cs == EDN_escaped_char_en_main) {} // silence ragel warning
2054
+ return nullptr;
1889
2055
  }
1890
2056
 
1891
2057
 
1892
2058
 
1893
-
1894
2059
  // ============================================================
1895
2060
  // symbol parsing - handles identifiers that begin with an alpha
1896
2061
  // character and an optional leading operator (name, -today,
@@ -1898,7 +2063,7 @@ case 25:
1898
2063
  //
1899
2064
  //
1900
2065
 
1901
- #line 1902 "edn_parser.cc"
2066
+ #line 2067 "edn_parser.cc"
1902
2067
  static const int EDN_symbol_start = 1;
1903
2068
  static const int EDN_symbol_first_final = 4;
1904
2069
  static const int EDN_symbol_error = 0;
@@ -1906,24 +2071,24 @@ static const int EDN_symbol_error = 0;
1906
2071
  static const int EDN_symbol_en_main = 1;
1907
2072
 
1908
2073
 
1909
- #line 532 "edn_parser.rl"
2074
+ #line 593 "edn_parser.rl"
1910
2075
 
1911
2076
 
1912
2077
 
1913
2078
  const char* edn::Parser::parse_symbol(const char *p, const char *pe, VALUE& s)
1914
2079
  {
1915
- int cs;
2080
+ int cs;
1916
2081
 
1917
2082
 
1918
- #line 1919 "edn_parser.cc"
2083
+ #line 2084 "edn_parser.cc"
1919
2084
  {
1920
2085
  cs = EDN_symbol_start;
1921
2086
  }
1922
2087
 
1923
- #line 540 "edn_parser.rl"
1924
- const char* p_save = p;
2088
+ #line 601 "edn_parser.rl"
2089
+ const char* p_save = p;
1925
2090
 
1926
- #line 1927 "edn_parser.cc"
2091
+ #line 2092 "edn_parser.cc"
1927
2092
  {
1928
2093
  if ( p == pe )
1929
2094
  goto _test_eof;
@@ -1985,34 +2150,34 @@ case 4:
1985
2150
  goto st4;
1986
2151
  goto tr7;
1987
2152
  tr7:
1988
- #line 58 "edn_parser.rl"
2153
+ #line 80 "edn_parser.rl"
1989
2154
  { p--; {p++; cs = 5; goto _out;} }
1990
2155
  goto st5;
1991
2156
  st5:
1992
2157
  if ( ++p == pe )
1993
2158
  goto _test_eof5;
1994
2159
  case 5:
1995
- #line 1996 "edn_parser.cc"
2160
+ #line 2161 "edn_parser.cc"
1996
2161
  goto st0;
1997
2162
  tr4:
1998
- #line 25 "edn_parser.rl"
2163
+ #line 47 "edn_parser.rl"
1999
2164
  { line_number++; }
2000
2165
  goto st6;
2001
2166
  tr8:
2002
- #line 58 "edn_parser.rl"
2167
+ #line 80 "edn_parser.rl"
2003
2168
  { p--; {p++; cs = 6; goto _out;} }
2004
2169
  goto st6;
2005
2170
  tr9:
2006
- #line 25 "edn_parser.rl"
2171
+ #line 47 "edn_parser.rl"
2007
2172
  { line_number++; }
2008
- #line 58 "edn_parser.rl"
2173
+ #line 80 "edn_parser.rl"
2009
2174
  { p--; {p++; cs = 6; goto _out;} }
2010
2175
  goto st6;
2011
2176
  st6:
2012
2177
  if ( ++p == pe )
2013
2178
  goto _test_eof6;
2014
2179
  case 6:
2015
- #line 2016 "edn_parser.cc"
2180
+ #line 2181 "edn_parser.cc"
2016
2181
  switch( (*p) ) {
2017
2182
  case 10: goto tr9;
2018
2183
  case 32: goto tr8;
@@ -2037,14 +2202,14 @@ case 6:
2037
2202
  goto st0;
2038
2203
  goto tr7;
2039
2204
  tr11:
2040
- #line 58 "edn_parser.rl"
2205
+ #line 80 "edn_parser.rl"
2041
2206
  { p--; {p++; cs = 7; goto _out;} }
2042
2207
  goto st7;
2043
2208
  st7:
2044
2209
  if ( ++p == pe )
2045
2210
  goto _test_eof7;
2046
2211
  case 7:
2047
- #line 2048 "edn_parser.cc"
2212
+ #line 2213 "edn_parser.cc"
2048
2213
  if ( (*p) == 10 )
2049
2214
  goto tr4;
2050
2215
  goto st2;
@@ -2152,24 +2317,23 @@ case 9:
2152
2317
  _out: {}
2153
2318
  }
2154
2319
 
2155
- #line 542 "edn_parser.rl"
2156
-
2157
- if (cs >= EDN_symbol_first_final) {
2158
- // copy the symbol text
2159
- if (s == Qnil)
2160
- s = rb_str_new2("");
2161
- rb_str_cat(s, p_save, p - p_save);
2162
- return p;
2163
- }
2164
- else if (cs == EDN_symbol_error) {
2165
- error(__FUNCTION__, "invalid symbol sequence", *p);
2166
- }
2167
- else if (cs == EDN_symbol_en_main) {} // silence ragel warning
2168
- return NULL;
2320
+ #line 603 "edn_parser.rl"
2321
+
2322
+ if (cs >= EDN_symbol_first_final) {
2323
+ // copy the symbol text
2324
+ if (s == Qnil)
2325
+ s = rb_str_new2("");
2326
+ rb_str_cat(s, p_save, p - p_save);
2327
+ return p;
2328
+ }
2329
+ else if (cs == EDN_symbol_error) {
2330
+ error(__FUNCTION__, "invalid symbol sequence", *p);
2331
+ }
2332
+ else if (cs == EDN_symbol_en_main) {} // silence ragel warning
2333
+ return nullptr;
2169
2334
  }
2170
2335
 
2171
2336
 
2172
-
2173
2337
  // ============================================================
2174
2338
  // EDN_sequence_common is used to parse EDN containers - elements are
2175
2339
  // initially stored in an array and then the final corresponding
@@ -2177,13 +2341,13 @@ case 9:
2177
2341
  // sets the same array is used)
2178
2342
  //
2179
2343
 
2180
- #line 620 "edn_parser.rl"
2344
+ #line 680 "edn_parser.rl"
2181
2345
 
2182
2346
 
2183
2347
  //
2184
2348
  // vector-specific machine
2185
2349
 
2186
- #line 2187 "edn_parser.cc"
2350
+ #line 2351 "edn_parser.cc"
2187
2351
  static const int EDN_vector_start = 1;
2188
2352
  static const int EDN_vector_first_final = 4;
2189
2353
  static const int EDN_vector_error = 0;
@@ -2191,7 +2355,7 @@ static const int EDN_vector_error = 0;
2191
2355
  static const int EDN_vector_en_main = 1;
2192
2356
 
2193
2357
 
2194
- #line 635 "edn_parser.rl"
2358
+ #line 695 "edn_parser.rl"
2195
2359
 
2196
2360
 
2197
2361
 
@@ -2200,20 +2364,20 @@ static const int EDN_vector_en_main = 1;
2200
2364
  //
2201
2365
  const char* edn::Parser::parse_vector(const char *p, const char *pe, VALUE& v)
2202
2366
  {
2203
- static const char* EDN_TYPE = "vector";
2367
+ static const char* EDN_TYPE = "vector";
2204
2368
 
2205
- int cs;
2206
- VALUE elems; // will store the vector's elements - allocated in @open_seq
2369
+ int cs;
2370
+ VALUE elems; // will store the vector's elements - allocated in @open_seq
2207
2371
 
2208
2372
 
2209
- #line 2210 "edn_parser.cc"
2373
+ #line 2374 "edn_parser.cc"
2210
2374
  {
2211
2375
  cs = EDN_vector_start;
2212
2376
  }
2213
2377
 
2214
- #line 649 "edn_parser.rl"
2378
+ #line 709 "edn_parser.rl"
2215
2379
 
2216
- #line 2217 "edn_parser.cc"
2380
+ #line 2381 "edn_parser.cc"
2217
2381
  {
2218
2382
  if ( p == pe )
2219
2383
  goto _test_eof;
@@ -2224,74 +2388,74 @@ case 1:
2224
2388
  goto tr0;
2225
2389
  goto st0;
2226
2390
  tr2:
2227
- #line 51 "edn_parser.rl"
2391
+ #line 73 "edn_parser.rl"
2228
2392
  {
2229
- std::stringstream s;
2230
- s << "unterminated " << EDN_TYPE;
2231
- error(__FUNCTION__, s.str());
2232
- p--; {p++; cs = 0; goto _out;}
2233
- }
2393
+ std::stringstream s;
2394
+ s << "unterminated " << EDN_TYPE;
2395
+ error(__FUNCTION__, s.str());
2396
+ p--; {p++; cs = 0; goto _out;}
2397
+ }
2234
2398
  goto st0;
2235
- #line 2236 "edn_parser.cc"
2399
+ #line 2400 "edn_parser.cc"
2236
2400
  st0:
2237
2401
  cs = 0;
2238
2402
  goto _out;
2239
2403
  tr0:
2240
- #line 569 "edn_parser.rl"
2241
- {
2242
- // sequences store elements in an array, then process it to
2243
- // convert it to a list, set, or map as needed once the
2244
- // sequence end is reached
2245
- elems = rb_ary_new();
2246
- // additionally, metadata for elements in the sequence may be
2247
- // carried so we must push a new level in the metadata stack
2248
- new_meta_list();
2249
- }
2404
+ #line 629 "edn_parser.rl"
2405
+ {
2406
+ // sequences store elements in an array, then process it to
2407
+ // convert it to a list, set, or map as needed once the
2408
+ // sequence end is reached
2409
+ elems = rb_ary_new();
2410
+ // additionally, metadata for elements in the sequence may be
2411
+ // carried so we must push a new level in the metadata stack
2412
+ new_meta_list();
2413
+ }
2250
2414
  goto st2;
2251
2415
  tr4:
2252
- #line 25 "edn_parser.rl"
2416
+ #line 47 "edn_parser.rl"
2253
2417
  { line_number++; }
2254
2418
  goto st2;
2255
2419
  tr5:
2256
- #line 584 "edn_parser.rl"
2257
- {
2258
- // reads an item within a sequence (vector, list, map, or
2259
- // set). Regardless of the sequence type, an array of the
2260
- // items is built. Once done, the sequence parser will convert
2261
- // if needed
2262
- VALUE e;
2263
- std::size_t meta_sz = meta_size();
2264
- const char *np = parse_value(p, pe, e);
2265
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {
2266
- // if there's an entry in the discard list, the current
2267
- // object is not meant to be kept due to a #_ so don't
2268
- // push it into the list of elements
2269
- if (!discard.empty()) {
2270
- discard.pop_back();
2271
- }
2272
- else if (!meta_empty()) {
2273
- // check if parse_value added metadata
2274
- if (meta_size() == meta_sz) {
2275
- // there's metadata and it didn't increase so
2276
- // parse_value() read an element we care
2277
- // about. Bind the metadata to it and add it to
2278
- // the sequence
2279
- e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2280
- rb_ary_push(elems, e);
2281
- }
2282
- } else {
2283
- // no metadata.. just push it
2284
- rb_ary_push(elems, e);
2420
+ #line 644 "edn_parser.rl"
2421
+ {
2422
+ // reads an item within a sequence (vector, list, map, or
2423
+ // set). Regardless of the sequence type, an array of the
2424
+ // items is built. Once done, the sequence parser will convert
2425
+ // if needed
2426
+ VALUE e;
2427
+ std::size_t meta_sz = meta_size();
2428
+ const char *np = parse_value(p, pe, e);
2429
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
2430
+ // if there's an entry in the discard list, the current
2431
+ // object is not meant to be kept due to a #_ so don't
2432
+ // push it into the list of elements
2433
+ if (!discard.empty()) {
2434
+ discard.pop_back();
2435
+ }
2436
+ else if (!meta_empty()) {
2437
+ // check if parse_value added metadata
2438
+ if (meta_size() == meta_sz) {
2439
+ // there's metadata and it didn't increase so
2440
+ // parse_value() read an element we care
2441
+ // about. Bind the metadata to it and add it to
2442
+ // the sequence
2443
+ e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2444
+ rb_ary_push(elems, e);
2285
2445
  }
2286
- {p = (( np))-1;}
2287
- }
2288
- }
2446
+ } else {
2447
+ // no metadata.. just push it
2448
+ rb_ary_push(elems, e);
2449
+ }
2450
+ {p = (( np))-1;}
2451
+ }
2452
+ }
2289
2453
  goto st2;
2290
2454
  st2:
2291
2455
  if ( ++p == pe )
2292
2456
  goto _test_eof2;
2293
2457
  case 2:
2294
- #line 2295 "edn_parser.cc"
2458
+ #line 2459 "edn_parser.cc"
2295
2459
  switch( (*p) ) {
2296
2460
  case 10: goto tr4;
2297
2461
  case 32: goto st2;
@@ -2322,19 +2486,19 @@ case 3:
2322
2486
  goto tr4;
2323
2487
  goto st3;
2324
2488
  tr7:
2325
- #line 579 "edn_parser.rl"
2489
+ #line 639 "edn_parser.rl"
2326
2490
  {
2327
- // remove the current metadata level
2328
- del_top_meta_list();
2329
- }
2330
- #line 58 "edn_parser.rl"
2491
+ // remove the current metadata level
2492
+ del_top_meta_list();
2493
+ }
2494
+ #line 80 "edn_parser.rl"
2331
2495
  { p--; {p++; cs = 4; goto _out;} }
2332
2496
  goto st4;
2333
2497
  st4:
2334
2498
  if ( ++p == pe )
2335
2499
  goto _test_eof4;
2336
2500
  case 4:
2337
- #line 2338 "edn_parser.cc"
2501
+ #line 2502 "edn_parser.cc"
2338
2502
  goto st0;
2339
2503
  }
2340
2504
  _test_eof2: cs = 2; goto _test_eof;
@@ -2347,33 +2511,33 @@ case 4:
2347
2511
  switch ( cs ) {
2348
2512
  case 2:
2349
2513
  case 3:
2350
- #line 51 "edn_parser.rl"
2514
+ #line 73 "edn_parser.rl"
2351
2515
  {
2352
- std::stringstream s;
2353
- s << "unterminated " << EDN_TYPE;
2354
- error(__FUNCTION__, s.str());
2355
- p--; {p++; cs = 0; goto _out;}
2356
- }
2516
+ std::stringstream s;
2517
+ s << "unterminated " << EDN_TYPE;
2518
+ error(__FUNCTION__, s.str());
2519
+ p--; {p++; cs = 0; goto _out;}
2520
+ }
2357
2521
  break;
2358
- #line 2359 "edn_parser.cc"
2522
+ #line 2523 "edn_parser.cc"
2359
2523
  }
2360
2524
  }
2361
2525
 
2362
2526
  _out: {}
2363
2527
  }
2364
2528
 
2365
- #line 650 "edn_parser.rl"
2366
-
2367
- if (cs >= EDN_vector_first_final) {
2368
- v = elems;
2369
- return p + 1;
2370
- }
2371
- else if (cs == EDN_vector_error) {
2372
- error(__FUNCTION__, "vector format error", *p);
2373
- return pe;
2374
- }
2375
- else if (cs == EDN_vector_en_main) {} // silence ragel warning
2376
- return NULL;
2529
+ #line 710 "edn_parser.rl"
2530
+
2531
+ if (cs >= EDN_vector_first_final) {
2532
+ v = elems;
2533
+ return p + 1;
2534
+ }
2535
+ else if (cs == EDN_vector_error) {
2536
+ error(__FUNCTION__, "vector format error", *p);
2537
+ return pe;
2538
+ }
2539
+ else if (cs == EDN_vector_en_main) {} // silence ragel warning
2540
+ return nullptr;
2377
2541
  }
2378
2542
 
2379
2543
 
@@ -2382,7 +2546,7 @@ case 4:
2382
2546
  // list parsing machine
2383
2547
  //
2384
2548
 
2385
- #line 2386 "edn_parser.cc"
2549
+ #line 2550 "edn_parser.cc"
2386
2550
  static const int EDN_list_start = 1;
2387
2551
  static const int EDN_list_first_final = 4;
2388
2552
  static const int EDN_list_error = 0;
@@ -2390,7 +2554,7 @@ static const int EDN_list_error = 0;
2390
2554
  static const int EDN_list_en_main = 1;
2391
2555
 
2392
2556
 
2393
- #line 679 "edn_parser.rl"
2557
+ #line 739 "edn_parser.rl"
2394
2558
 
2395
2559
 
2396
2560
  //
@@ -2398,20 +2562,20 @@ static const int EDN_list_en_main = 1;
2398
2562
  //
2399
2563
  const char* edn::Parser::parse_list(const char *p, const char *pe, VALUE& v)
2400
2564
  {
2401
- static const char* EDN_TYPE = "list";
2565
+ static const char* EDN_TYPE = "list";
2402
2566
 
2403
- int cs;
2404
- VALUE elems; // stores the list's elements - allocated in @open_seq
2567
+ int cs;
2568
+ VALUE elems; // stores the list's elements - allocated in @open_seq
2405
2569
 
2406
2570
 
2407
- #line 2408 "edn_parser.cc"
2571
+ #line 2572 "edn_parser.cc"
2408
2572
  {
2409
2573
  cs = EDN_list_start;
2410
2574
  }
2411
2575
 
2412
- #line 692 "edn_parser.rl"
2576
+ #line 752 "edn_parser.rl"
2413
2577
 
2414
- #line 2415 "edn_parser.cc"
2578
+ #line 2579 "edn_parser.cc"
2415
2579
  {
2416
2580
  if ( p == pe )
2417
2581
  goto _test_eof;
@@ -2422,74 +2586,74 @@ case 1:
2422
2586
  goto tr0;
2423
2587
  goto st0;
2424
2588
  tr2:
2425
- #line 51 "edn_parser.rl"
2589
+ #line 73 "edn_parser.rl"
2426
2590
  {
2427
- std::stringstream s;
2428
- s << "unterminated " << EDN_TYPE;
2429
- error(__FUNCTION__, s.str());
2430
- p--; {p++; cs = 0; goto _out;}
2431
- }
2591
+ std::stringstream s;
2592
+ s << "unterminated " << EDN_TYPE;
2593
+ error(__FUNCTION__, s.str());
2594
+ p--; {p++; cs = 0; goto _out;}
2595
+ }
2432
2596
  goto st0;
2433
- #line 2434 "edn_parser.cc"
2597
+ #line 2598 "edn_parser.cc"
2434
2598
  st0:
2435
2599
  cs = 0;
2436
2600
  goto _out;
2437
2601
  tr0:
2438
- #line 569 "edn_parser.rl"
2439
- {
2440
- // sequences store elements in an array, then process it to
2441
- // convert it to a list, set, or map as needed once the
2442
- // sequence end is reached
2443
- elems = rb_ary_new();
2444
- // additionally, metadata for elements in the sequence may be
2445
- // carried so we must push a new level in the metadata stack
2446
- new_meta_list();
2447
- }
2602
+ #line 629 "edn_parser.rl"
2603
+ {
2604
+ // sequences store elements in an array, then process it to
2605
+ // convert it to a list, set, or map as needed once the
2606
+ // sequence end is reached
2607
+ elems = rb_ary_new();
2608
+ // additionally, metadata for elements in the sequence may be
2609
+ // carried so we must push a new level in the metadata stack
2610
+ new_meta_list();
2611
+ }
2448
2612
  goto st2;
2449
2613
  tr4:
2450
- #line 25 "edn_parser.rl"
2614
+ #line 47 "edn_parser.rl"
2451
2615
  { line_number++; }
2452
2616
  goto st2;
2453
2617
  tr5:
2454
- #line 584 "edn_parser.rl"
2455
- {
2456
- // reads an item within a sequence (vector, list, map, or
2457
- // set). Regardless of the sequence type, an array of the
2458
- // items is built. Once done, the sequence parser will convert
2459
- // if needed
2460
- VALUE e;
2461
- std::size_t meta_sz = meta_size();
2462
- const char *np = parse_value(p, pe, e);
2463
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {
2464
- // if there's an entry in the discard list, the current
2465
- // object is not meant to be kept due to a #_ so don't
2466
- // push it into the list of elements
2467
- if (!discard.empty()) {
2468
- discard.pop_back();
2469
- }
2470
- else if (!meta_empty()) {
2471
- // check if parse_value added metadata
2472
- if (meta_size() == meta_sz) {
2473
- // there's metadata and it didn't increase so
2474
- // parse_value() read an element we care
2475
- // about. Bind the metadata to it and add it to
2476
- // the sequence
2477
- e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2478
- rb_ary_push(elems, e);
2479
- }
2480
- } else {
2481
- // no metadata.. just push it
2482
- rb_ary_push(elems, e);
2618
+ #line 644 "edn_parser.rl"
2619
+ {
2620
+ // reads an item within a sequence (vector, list, map, or
2621
+ // set). Regardless of the sequence type, an array of the
2622
+ // items is built. Once done, the sequence parser will convert
2623
+ // if needed
2624
+ VALUE e;
2625
+ std::size_t meta_sz = meta_size();
2626
+ const char *np = parse_value(p, pe, e);
2627
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
2628
+ // if there's an entry in the discard list, the current
2629
+ // object is not meant to be kept due to a #_ so don't
2630
+ // push it into the list of elements
2631
+ if (!discard.empty()) {
2632
+ discard.pop_back();
2633
+ }
2634
+ else if (!meta_empty()) {
2635
+ // check if parse_value added metadata
2636
+ if (meta_size() == meta_sz) {
2637
+ // there's metadata and it didn't increase so
2638
+ // parse_value() read an element we care
2639
+ // about. Bind the metadata to it and add it to
2640
+ // the sequence
2641
+ e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2642
+ rb_ary_push(elems, e);
2483
2643
  }
2484
- {p = (( np))-1;}
2485
- }
2486
- }
2644
+ } else {
2645
+ // no metadata.. just push it
2646
+ rb_ary_push(elems, e);
2647
+ }
2648
+ {p = (( np))-1;}
2649
+ }
2650
+ }
2487
2651
  goto st2;
2488
2652
  st2:
2489
2653
  if ( ++p == pe )
2490
2654
  goto _test_eof2;
2491
2655
  case 2:
2492
- #line 2493 "edn_parser.cc"
2656
+ #line 2657 "edn_parser.cc"
2493
2657
  switch( (*p) ) {
2494
2658
  case 10: goto tr4;
2495
2659
  case 32: goto st2;
@@ -2513,19 +2677,19 @@ case 2:
2513
2677
  goto tr5;
2514
2678
  goto tr2;
2515
2679
  tr6:
2516
- #line 579 "edn_parser.rl"
2680
+ #line 639 "edn_parser.rl"
2517
2681
  {
2518
- // remove the current metadata level
2519
- del_top_meta_list();
2520
- }
2521
- #line 58 "edn_parser.rl"
2682
+ // remove the current metadata level
2683
+ del_top_meta_list();
2684
+ }
2685
+ #line 80 "edn_parser.rl"
2522
2686
  { p--; {p++; cs = 4; goto _out;} }
2523
2687
  goto st4;
2524
2688
  st4:
2525
2689
  if ( ++p == pe )
2526
2690
  goto _test_eof4;
2527
2691
  case 4:
2528
- #line 2529 "edn_parser.cc"
2692
+ #line 2693 "edn_parser.cc"
2529
2693
  goto st0;
2530
2694
  st3:
2531
2695
  if ( ++p == pe )
@@ -2545,35 +2709,33 @@ case 3:
2545
2709
  switch ( cs ) {
2546
2710
  case 2:
2547
2711
  case 3:
2548
- #line 51 "edn_parser.rl"
2712
+ #line 73 "edn_parser.rl"
2549
2713
  {
2550
- std::stringstream s;
2551
- s << "unterminated " << EDN_TYPE;
2552
- error(__FUNCTION__, s.str());
2553
- p--; {p++; cs = 0; goto _out;}
2554
- }
2714
+ std::stringstream s;
2715
+ s << "unterminated " << EDN_TYPE;
2716
+ error(__FUNCTION__, s.str());
2717
+ p--; {p++; cs = 0; goto _out;}
2718
+ }
2555
2719
  break;
2556
- #line 2557 "edn_parser.cc"
2720
+ #line 2721 "edn_parser.cc"
2557
2721
  }
2558
2722
  }
2559
2723
 
2560
2724
  _out: {}
2561
2725
  }
2562
2726
 
2563
- #line 693 "edn_parser.rl"
2564
-
2565
- if (cs >= EDN_list_first_final) {
2566
- v = elems;
2567
- // TODO: replace with this but first figure out why array is not unrolled by EDN::list()
2568
- // v = edn::util::call_module_fn(EDN_MAKE_LIST_METHOD, elems);
2569
- return p + 1;
2570
- }
2571
- else if (cs == EDN_list_error) {
2572
- error(__FUNCTION__, *p);
2573
- return pe;
2574
- }
2575
- else if (cs == EDN_list_en_main) {} // silence ragel warning
2576
- return NULL;
2727
+ #line 753 "edn_parser.rl"
2728
+
2729
+ if (cs >= EDN_list_first_final) {
2730
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_LIST_METHOD, elems);
2731
+ return p + 1;
2732
+ }
2733
+ else if (cs == EDN_list_error) {
2734
+ error(__FUNCTION__, *p);
2735
+ return pe;
2736
+ }
2737
+ else if (cs == EDN_list_en_main) {} // silence ragel warning
2738
+ return nullptr;
2577
2739
  }
2578
2740
 
2579
2741
 
@@ -2582,7 +2744,7 @@ case 3:
2582
2744
  // hash parsing
2583
2745
  //
2584
2746
 
2585
- #line 2586 "edn_parser.cc"
2747
+ #line 2748 "edn_parser.cc"
2586
2748
  static const int EDN_map_start = 1;
2587
2749
  static const int EDN_map_first_final = 4;
2588
2750
  static const int EDN_map_error = 0;
@@ -2590,28 +2752,28 @@ static const int EDN_map_error = 0;
2590
2752
  static const int EDN_map_en_main = 1;
2591
2753
 
2592
2754
 
2593
- #line 725 "edn_parser.rl"
2755
+ #line 783 "edn_parser.rl"
2594
2756
 
2595
2757
 
2596
2758
 
2597
2759
  const char* edn::Parser::parse_map(const char *p, const char *pe, VALUE& v)
2598
2760
  {
2599
- static const char* EDN_TYPE = "map";
2761
+ static const char* EDN_TYPE = "map";
2600
2762
 
2601
- int cs;
2602
- // since we don't know whether we're looking at a key or value,
2603
- // initially store all elements in an array (allocated in @open_seq)
2604
- VALUE elems;
2763
+ int cs;
2764
+ // since we don't know whether we're looking at a key or value,
2765
+ // initially store all elements in an array (allocated in @open_seq)
2766
+ VALUE elems;
2605
2767
 
2606
2768
 
2607
- #line 2608 "edn_parser.cc"
2769
+ #line 2770 "edn_parser.cc"
2608
2770
  {
2609
2771
  cs = EDN_map_start;
2610
2772
  }
2611
2773
 
2612
- #line 738 "edn_parser.rl"
2774
+ #line 796 "edn_parser.rl"
2613
2775
 
2614
- #line 2615 "edn_parser.cc"
2776
+ #line 2777 "edn_parser.cc"
2615
2777
  {
2616
2778
  if ( p == pe )
2617
2779
  goto _test_eof;
@@ -2622,74 +2784,74 @@ case 1:
2622
2784
  goto tr0;
2623
2785
  goto st0;
2624
2786
  tr2:
2625
- #line 51 "edn_parser.rl"
2787
+ #line 73 "edn_parser.rl"
2626
2788
  {
2627
- std::stringstream s;
2628
- s << "unterminated " << EDN_TYPE;
2629
- error(__FUNCTION__, s.str());
2630
- p--; {p++; cs = 0; goto _out;}
2631
- }
2789
+ std::stringstream s;
2790
+ s << "unterminated " << EDN_TYPE;
2791
+ error(__FUNCTION__, s.str());
2792
+ p--; {p++; cs = 0; goto _out;}
2793
+ }
2632
2794
  goto st0;
2633
- #line 2634 "edn_parser.cc"
2795
+ #line 2796 "edn_parser.cc"
2634
2796
  st0:
2635
2797
  cs = 0;
2636
2798
  goto _out;
2637
2799
  tr0:
2638
- #line 569 "edn_parser.rl"
2639
- {
2640
- // sequences store elements in an array, then process it to
2641
- // convert it to a list, set, or map as needed once the
2642
- // sequence end is reached
2643
- elems = rb_ary_new();
2644
- // additionally, metadata for elements in the sequence may be
2645
- // carried so we must push a new level in the metadata stack
2646
- new_meta_list();
2647
- }
2800
+ #line 629 "edn_parser.rl"
2801
+ {
2802
+ // sequences store elements in an array, then process it to
2803
+ // convert it to a list, set, or map as needed once the
2804
+ // sequence end is reached
2805
+ elems = rb_ary_new();
2806
+ // additionally, metadata for elements in the sequence may be
2807
+ // carried so we must push a new level in the metadata stack
2808
+ new_meta_list();
2809
+ }
2648
2810
  goto st2;
2649
2811
  tr4:
2650
- #line 25 "edn_parser.rl"
2812
+ #line 47 "edn_parser.rl"
2651
2813
  { line_number++; }
2652
2814
  goto st2;
2653
2815
  tr5:
2654
- #line 584 "edn_parser.rl"
2655
- {
2656
- // reads an item within a sequence (vector, list, map, or
2657
- // set). Regardless of the sequence type, an array of the
2658
- // items is built. Once done, the sequence parser will convert
2659
- // if needed
2660
- VALUE e;
2661
- std::size_t meta_sz = meta_size();
2662
- const char *np = parse_value(p, pe, e);
2663
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {
2664
- // if there's an entry in the discard list, the current
2665
- // object is not meant to be kept due to a #_ so don't
2666
- // push it into the list of elements
2667
- if (!discard.empty()) {
2668
- discard.pop_back();
2669
- }
2670
- else if (!meta_empty()) {
2671
- // check if parse_value added metadata
2672
- if (meta_size() == meta_sz) {
2673
- // there's metadata and it didn't increase so
2674
- // parse_value() read an element we care
2675
- // about. Bind the metadata to it and add it to
2676
- // the sequence
2677
- e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2678
- rb_ary_push(elems, e);
2679
- }
2680
- } else {
2681
- // no metadata.. just push it
2682
- rb_ary_push(elems, e);
2816
+ #line 644 "edn_parser.rl"
2817
+ {
2818
+ // reads an item within a sequence (vector, list, map, or
2819
+ // set). Regardless of the sequence type, an array of the
2820
+ // items is built. Once done, the sequence parser will convert
2821
+ // if needed
2822
+ VALUE e;
2823
+ std::size_t meta_sz = meta_size();
2824
+ const char *np = parse_value(p, pe, e);
2825
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
2826
+ // if there's an entry in the discard list, the current
2827
+ // object is not meant to be kept due to a #_ so don't
2828
+ // push it into the list of elements
2829
+ if (!discard.empty()) {
2830
+ discard.pop_back();
2831
+ }
2832
+ else if (!meta_empty()) {
2833
+ // check if parse_value added metadata
2834
+ if (meta_size() == meta_sz) {
2835
+ // there's metadata and it didn't increase so
2836
+ // parse_value() read an element we care
2837
+ // about. Bind the metadata to it and add it to
2838
+ // the sequence
2839
+ e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
2840
+ rb_ary_push(elems, e);
2683
2841
  }
2684
- {p = (( np))-1;}
2685
- }
2686
- }
2842
+ } else {
2843
+ // no metadata.. just push it
2844
+ rb_ary_push(elems, e);
2845
+ }
2846
+ {p = (( np))-1;}
2847
+ }
2848
+ }
2687
2849
  goto st2;
2688
2850
  st2:
2689
2851
  if ( ++p == pe )
2690
2852
  goto _test_eof2;
2691
2853
  case 2:
2692
- #line 2693 "edn_parser.cc"
2854
+ #line 2855 "edn_parser.cc"
2693
2855
  switch( (*p) ) {
2694
2856
  case 10: goto tr4;
2695
2857
  case 32: goto st2;
@@ -2723,19 +2885,19 @@ case 3:
2723
2885
  goto tr4;
2724
2886
  goto st3;
2725
2887
  tr7:
2726
- #line 579 "edn_parser.rl"
2888
+ #line 639 "edn_parser.rl"
2727
2889
  {
2728
- // remove the current metadata level
2729
- del_top_meta_list();
2730
- }
2731
- #line 58 "edn_parser.rl"
2890
+ // remove the current metadata level
2891
+ del_top_meta_list();
2892
+ }
2893
+ #line 80 "edn_parser.rl"
2732
2894
  { p--; {p++; cs = 4; goto _out;} }
2733
2895
  goto st4;
2734
2896
  st4:
2735
2897
  if ( ++p == pe )
2736
2898
  goto _test_eof4;
2737
2899
  case 4:
2738
- #line 2739 "edn_parser.cc"
2900
+ #line 2901 "edn_parser.cc"
2739
2901
  goto st0;
2740
2902
  }
2741
2903
  _test_eof2: cs = 2; goto _test_eof;
@@ -2748,47 +2910,46 @@ case 4:
2748
2910
  switch ( cs ) {
2749
2911
  case 2:
2750
2912
  case 3:
2751
- #line 51 "edn_parser.rl"
2913
+ #line 73 "edn_parser.rl"
2752
2914
  {
2753
- std::stringstream s;
2754
- s << "unterminated " << EDN_TYPE;
2755
- error(__FUNCTION__, s.str());
2756
- p--; {p++; cs = 0; goto _out;}
2757
- }
2915
+ std::stringstream s;
2916
+ s << "unterminated " << EDN_TYPE;
2917
+ error(__FUNCTION__, s.str());
2918
+ p--; {p++; cs = 0; goto _out;}
2919
+ }
2758
2920
  break;
2759
- #line 2760 "edn_parser.cc"
2921
+ #line 2922 "edn_parser.cc"
2760
2922
  }
2761
2923
  }
2762
2924
 
2763
2925
  _out: {}
2764
2926
  }
2765
2927
 
2766
- #line 739 "edn_parser.rl"
2767
-
2768
- if (cs >= EDN_map_first_final) {
2769
-
2770
- // hash parsing is done. Make sure we have an even count
2771
- if ((RARRAY_LEN(elems) % 2) != 0) {
2772
- error(__FUNCTION__, "odd number of elements in map");
2773
- return pe;
2774
- }
2775
-
2776
- // now convert the sequence to a hash
2777
- VALUE rslt = rb_hash_new();
2778
- while (RARRAY_LEN(elems) > 0)
2779
- {
2780
- VALUE k = rb_ary_shift(elems);
2781
- rb_hash_aset(rslt, k, rb_ary_shift(elems));
2782
- }
2783
-
2784
- v = rslt;
2785
- return p + 1;
2786
- }
2787
- else if (cs == EDN_map_error) {
2788
- return pe;
2789
- }
2790
- else if (cs == EDN_map_en_main) {} // silence ragel warning
2791
- return NULL;
2928
+ #line 797 "edn_parser.rl"
2929
+
2930
+ if (cs >= EDN_map_first_final) {
2931
+ // hash parsing is done. Make sure we have an even count
2932
+ if ((RARRAY_LEN(elems) % 2) != 0) {
2933
+ error(__FUNCTION__, "odd number of elements in map");
2934
+ return pe;
2935
+ }
2936
+
2937
+ // now convert the sequence to a hash
2938
+ VALUE rslt = rb_hash_new();
2939
+ while (RARRAY_LEN(elems) > 0)
2940
+ {
2941
+ VALUE k = rb_ary_shift(elems);
2942
+ rb_hash_aset(rslt, k, rb_ary_shift(elems));
2943
+ }
2944
+
2945
+ v = rslt;
2946
+ return p + 1;
2947
+ }
2948
+ else if (cs == EDN_map_error) {
2949
+ return pe;
2950
+ }
2951
+ else if (cs == EDN_map_en_main) {} // silence ragel warning
2952
+ return nullptr;
2792
2953
  }
2793
2954
 
2794
2955
 
@@ -2799,7 +2960,7 @@ case 4:
2799
2960
  // the remaining data to the correct parser
2800
2961
  //
2801
2962
 
2802
- #line 2803 "edn_parser.cc"
2963
+ #line 2964 "edn_parser.cc"
2803
2964
  static const int EDN_dispatch_start = 1;
2804
2965
  static const int EDN_dispatch_first_final = 2;
2805
2966
  static const int EDN_dispatch_error = 0;
@@ -2807,23 +2968,23 @@ static const int EDN_dispatch_error = 0;
2807
2968
  static const int EDN_dispatch_en_main = 1;
2808
2969
 
2809
2970
 
2810
- #line 803 "edn_parser.rl"
2971
+ #line 879 "edn_parser.rl"
2811
2972
 
2812
2973
 
2813
2974
 
2814
2975
  const char* edn::Parser::parse_dispatch(const char *p, const char *pe, VALUE& v)
2815
2976
  {
2816
- int cs;
2977
+ int cs;
2817
2978
 
2818
2979
 
2819
- #line 2820 "edn_parser.cc"
2980
+ #line 2981 "edn_parser.cc"
2820
2981
  {
2821
2982
  cs = EDN_dispatch_start;
2822
2983
  }
2823
2984
 
2824
- #line 811 "edn_parser.rl"
2985
+ #line 887 "edn_parser.rl"
2825
2986
 
2826
- #line 2827 "edn_parser.cc"
2987
+ #line 2988 "edn_parser.cc"
2827
2988
  {
2828
2989
  if ( p == pe )
2829
2990
  goto _test_eof;
@@ -2831,53 +2992,77 @@ const char* edn::Parser::parse_dispatch(const char *p, const char *pe, VALUE& v)
2831
2992
  {
2832
2993
  case 1:
2833
2994
  switch( (*p) ) {
2834
- case 95: goto tr2;
2835
- case 123: goto tr3;
2995
+ case 35: goto tr0;
2996
+ case 95: goto tr3;
2997
+ case 123: goto tr4;
2836
2998
  }
2837
2999
  if ( (*p) > 90 ) {
2838
3000
  if ( 97 <= (*p) && (*p) <= 122 )
2839
- goto tr0;
3001
+ goto tr2;
2840
3002
  } else if ( (*p) >= 65 )
2841
- goto tr0;
3003
+ goto tr2;
2842
3004
  goto st0;
2843
3005
  st0:
2844
3006
  cs = 0;
2845
3007
  goto _out;
2846
3008
  tr0:
2847
- #line 791 "edn_parser.rl"
3009
+ #line 854 "edn_parser.rl"
2848
3010
  {
2849
- // #inst, #uuid, or #user/tag
2850
- const char *np = parse_tagged(p, pe, v);
2851
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
2852
- }
2853
- #line 58 "edn_parser.rl"
3011
+ // ##Inf, ##NaN, etc.
3012
+ VALUE sym = Qnil;
3013
+ const char *np = parse_symbol(p+1, pe, sym);
3014
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
3015
+ if (std::strcmp(RSTRING_PTR(sym), "NaN") == 0) {
3016
+ v = RUBY_NAN_CONST;
3017
+ }
3018
+ else if (std::strcmp(RSTRING_PTR(sym), "Inf") == 0) {
3019
+ v = RUBY_INF_CONST;
3020
+ }
3021
+ else {
3022
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SYMBOL_METHOD, sym);
3023
+ }
3024
+
3025
+ {p = (( np))-1;}
3026
+ }
3027
+ }
3028
+ #line 80 "edn_parser.rl"
2854
3029
  { p--; {p++; cs = 2; goto _out;} }
2855
3030
  goto st2;
2856
3031
  tr2:
2857
- #line 785 "edn_parser.rl"
3032
+ #line 848 "edn_parser.rl"
2858
3033
  {
2859
- // discard token #_
2860
- const char *np = parse_discard(p, pe);
2861
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
2862
- }
2863
- #line 58 "edn_parser.rl"
3034
+ // #inst, #uuid, or #user/tag
3035
+ const char *np = parse_tagged(p, pe, v);
3036
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
3037
+ }
3038
+ #line 80 "edn_parser.rl"
2864
3039
  { p--; {p++; cs = 2; goto _out;} }
2865
3040
  goto st2;
2866
3041
  tr3:
2867
- #line 779 "edn_parser.rl"
3042
+ #line 842 "edn_parser.rl"
3043
+ {
3044
+ // discard token #_
3045
+ const char *np = parse_discard(p, pe);
3046
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
3047
+ }
3048
+ #line 80 "edn_parser.rl"
3049
+ { p--; {p++; cs = 2; goto _out;} }
3050
+ goto st2;
3051
+ tr4:
3052
+ #line 836 "edn_parser.rl"
2868
3053
  {
2869
- // #{ }
2870
- const char *np = parse_set(p, pe, v);
2871
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
2872
- }
2873
- #line 58 "edn_parser.rl"
3054
+ // #{ }
3055
+ const char *np = parse_set(p, pe, v);
3056
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {p = (( np))-1;}
3057
+ }
3058
+ #line 80 "edn_parser.rl"
2874
3059
  { p--; {p++; cs = 2; goto _out;} }
2875
3060
  goto st2;
2876
3061
  st2:
2877
3062
  if ( ++p == pe )
2878
3063
  goto _test_eof2;
2879
3064
  case 2:
2880
- #line 2881 "edn_parser.cc"
3065
+ #line 3066 "edn_parser.cc"
2881
3066
  goto st0;
2882
3067
  }
2883
3068
  _test_eof2: cs = 2; goto _test_eof;
@@ -2886,18 +3071,17 @@ case 2:
2886
3071
  _out: {}
2887
3072
  }
2888
3073
 
2889
- #line 812 "edn_parser.rl"
2890
-
2891
- if (cs >= EDN_dispatch_first_final) {
2892
- return p + 1;
2893
- }
2894
- else if (cs == EDN_dispatch_error) {
2895
- error(__FUNCTION__, "dispatch extend error", *p);
2896
- return pe;
2897
- }
2898
- else if (cs == EDN_dispatch_en_main) {} // silence ragel warning
2899
-
2900
- return NULL;
3074
+ #line 888 "edn_parser.rl"
3075
+
3076
+ if (cs >= EDN_dispatch_first_final) {
3077
+ return p + 1;
3078
+ }
3079
+ else if (cs == EDN_dispatch_error) {
3080
+ error(__FUNCTION__, "dispatch extend error", *p);
3081
+ return pe;
3082
+ }
3083
+ else if (cs == EDN_dispatch_en_main) {} // silence ragel warning
3084
+ return nullptr;
2901
3085
  }
2902
3086
 
2903
3087
 
@@ -2905,7 +3089,7 @@ case 2:
2905
3089
  // set parsing machine
2906
3090
  //
2907
3091
 
2908
- #line 2909 "edn_parser.cc"
3092
+ #line 3093 "edn_parser.cc"
2909
3093
  static const int EDN_set_start = 1;
2910
3094
  static const int EDN_set_first_final = 4;
2911
3095
  static const int EDN_set_error = 0;
@@ -2913,7 +3097,7 @@ static const int EDN_set_error = 0;
2913
3097
  static const int EDN_set_en_main = 1;
2914
3098
 
2915
3099
 
2916
- #line 841 "edn_parser.rl"
3100
+ #line 916 "edn_parser.rl"
2917
3101
 
2918
3102
 
2919
3103
  //
@@ -2921,20 +3105,20 @@ static const int EDN_set_en_main = 1;
2921
3105
  //
2922
3106
  const char* edn::Parser::parse_set(const char *p, const char *pe, VALUE& v)
2923
3107
  {
2924
- static const char* EDN_TYPE = "set";
3108
+ static const char* EDN_TYPE = "set";
2925
3109
 
2926
- int cs;
2927
- VALUE elems; // holds the set's elements as an array allocated in @open_seq
3110
+ int cs;
3111
+ VALUE elems; // holds the set's elements as an array allocated in @open_seq
2928
3112
 
2929
3113
 
2930
- #line 2931 "edn_parser.cc"
3114
+ #line 3115 "edn_parser.cc"
2931
3115
  {
2932
3116
  cs = EDN_set_start;
2933
3117
  }
2934
3118
 
2935
- #line 854 "edn_parser.rl"
3119
+ #line 929 "edn_parser.rl"
2936
3120
 
2937
- #line 2938 "edn_parser.cc"
3121
+ #line 3122 "edn_parser.cc"
2938
3122
  {
2939
3123
  if ( p == pe )
2940
3124
  goto _test_eof;
@@ -2945,74 +3129,74 @@ case 1:
2945
3129
  goto tr0;
2946
3130
  goto st0;
2947
3131
  tr2:
2948
- #line 51 "edn_parser.rl"
3132
+ #line 73 "edn_parser.rl"
2949
3133
  {
2950
- std::stringstream s;
2951
- s << "unterminated " << EDN_TYPE;
2952
- error(__FUNCTION__, s.str());
2953
- p--; {p++; cs = 0; goto _out;}
2954
- }
3134
+ std::stringstream s;
3135
+ s << "unterminated " << EDN_TYPE;
3136
+ error(__FUNCTION__, s.str());
3137
+ p--; {p++; cs = 0; goto _out;}
3138
+ }
2955
3139
  goto st0;
2956
- #line 2957 "edn_parser.cc"
3140
+ #line 3141 "edn_parser.cc"
2957
3141
  st0:
2958
3142
  cs = 0;
2959
3143
  goto _out;
2960
3144
  tr0:
2961
- #line 569 "edn_parser.rl"
2962
- {
2963
- // sequences store elements in an array, then process it to
2964
- // convert it to a list, set, or map as needed once the
2965
- // sequence end is reached
2966
- elems = rb_ary_new();
2967
- // additionally, metadata for elements in the sequence may be
2968
- // carried so we must push a new level in the metadata stack
2969
- new_meta_list();
2970
- }
3145
+ #line 629 "edn_parser.rl"
3146
+ {
3147
+ // sequences store elements in an array, then process it to
3148
+ // convert it to a list, set, or map as needed once the
3149
+ // sequence end is reached
3150
+ elems = rb_ary_new();
3151
+ // additionally, metadata for elements in the sequence may be
3152
+ // carried so we must push a new level in the metadata stack
3153
+ new_meta_list();
3154
+ }
2971
3155
  goto st2;
2972
3156
  tr4:
2973
- #line 25 "edn_parser.rl"
3157
+ #line 47 "edn_parser.rl"
2974
3158
  { line_number++; }
2975
3159
  goto st2;
2976
3160
  tr5:
2977
- #line 584 "edn_parser.rl"
2978
- {
2979
- // reads an item within a sequence (vector, list, map, or
2980
- // set). Regardless of the sequence type, an array of the
2981
- // items is built. Once done, the sequence parser will convert
2982
- // if needed
2983
- VALUE e;
2984
- std::size_t meta_sz = meta_size();
2985
- const char *np = parse_value(p, pe, e);
2986
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {
2987
- // if there's an entry in the discard list, the current
2988
- // object is not meant to be kept due to a #_ so don't
2989
- // push it into the list of elements
2990
- if (!discard.empty()) {
2991
- discard.pop_back();
2992
- }
2993
- else if (!meta_empty()) {
2994
- // check if parse_value added metadata
2995
- if (meta_size() == meta_sz) {
2996
- // there's metadata and it didn't increase so
2997
- // parse_value() read an element we care
2998
- // about. Bind the metadata to it and add it to
2999
- // the sequence
3000
- e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
3001
- rb_ary_push(elems, e);
3002
- }
3003
- } else {
3004
- // no metadata.. just push it
3005
- rb_ary_push(elems, e);
3161
+ #line 644 "edn_parser.rl"
3162
+ {
3163
+ // reads an item within a sequence (vector, list, map, or
3164
+ // set). Regardless of the sequence type, an array of the
3165
+ // items is built. Once done, the sequence parser will convert
3166
+ // if needed
3167
+ VALUE e;
3168
+ std::size_t meta_sz = meta_size();
3169
+ const char *np = parse_value(p, pe, e);
3170
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
3171
+ // if there's an entry in the discard list, the current
3172
+ // object is not meant to be kept due to a #_ so don't
3173
+ // push it into the list of elements
3174
+ if (!discard.empty()) {
3175
+ discard.pop_back();
3176
+ }
3177
+ else if (!meta_empty()) {
3178
+ // check if parse_value added metadata
3179
+ if (meta_size() == meta_sz) {
3180
+ // there's metadata and it didn't increase so
3181
+ // parse_value() read an element we care
3182
+ // about. Bind the metadata to it and add it to
3183
+ // the sequence
3184
+ e = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, e, ruby_meta());
3185
+ rb_ary_push(elems, e);
3006
3186
  }
3007
- {p = (( np))-1;}
3008
- }
3009
- }
3187
+ } else {
3188
+ // no metadata.. just push it
3189
+ rb_ary_push(elems, e);
3190
+ }
3191
+ {p = (( np))-1;}
3192
+ }
3193
+ }
3010
3194
  goto st2;
3011
3195
  st2:
3012
3196
  if ( ++p == pe )
3013
3197
  goto _test_eof2;
3014
3198
  case 2:
3015
- #line 3016 "edn_parser.cc"
3199
+ #line 3200 "edn_parser.cc"
3016
3200
  switch( (*p) ) {
3017
3201
  case 10: goto tr4;
3018
3202
  case 32: goto st2;
@@ -3046,19 +3230,19 @@ case 3:
3046
3230
  goto tr4;
3047
3231
  goto st3;
3048
3232
  tr7:
3049
- #line 579 "edn_parser.rl"
3233
+ #line 639 "edn_parser.rl"
3050
3234
  {
3051
- // remove the current metadata level
3052
- del_top_meta_list();
3053
- }
3054
- #line 58 "edn_parser.rl"
3235
+ // remove the current metadata level
3236
+ del_top_meta_list();
3237
+ }
3238
+ #line 80 "edn_parser.rl"
3055
3239
  { p--; {p++; cs = 4; goto _out;} }
3056
3240
  goto st4;
3057
3241
  st4:
3058
3242
  if ( ++p == pe )
3059
3243
  goto _test_eof4;
3060
3244
  case 4:
3061
- #line 3062 "edn_parser.cc"
3245
+ #line 3246 "edn_parser.cc"
3062
3246
  goto st0;
3063
3247
  }
3064
3248
  _test_eof2: cs = 2; goto _test_eof;
@@ -3071,34 +3255,34 @@ case 4:
3071
3255
  switch ( cs ) {
3072
3256
  case 2:
3073
3257
  case 3:
3074
- #line 51 "edn_parser.rl"
3258
+ #line 73 "edn_parser.rl"
3075
3259
  {
3076
- std::stringstream s;
3077
- s << "unterminated " << EDN_TYPE;
3078
- error(__FUNCTION__, s.str());
3079
- p--; {p++; cs = 0; goto _out;}
3080
- }
3260
+ std::stringstream s;
3261
+ s << "unterminated " << EDN_TYPE;
3262
+ error(__FUNCTION__, s.str());
3263
+ p--; {p++; cs = 0; goto _out;}
3264
+ }
3081
3265
  break;
3082
- #line 3083 "edn_parser.cc"
3266
+ #line 3267 "edn_parser.cc"
3083
3267
  }
3084
3268
  }
3085
3269
 
3086
3270
  _out: {}
3087
3271
  }
3088
3272
 
3089
- #line 855 "edn_parser.rl"
3090
-
3091
- if (cs >= EDN_set_first_final) {
3092
- // all elements collected; now convert to a set
3093
- v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SET_METHOD, elems);
3094
- return p + 1;
3095
- }
3096
- else if (cs == EDN_set_error) {
3097
- error(__FUNCTION__, *p);
3098
- return pe;
3099
- }
3100
- else if (cs == EDN_set_en_main) {} // silence ragel warning
3101
- return NULL;
3273
+ #line 930 "edn_parser.rl"
3274
+
3275
+ if (cs >= EDN_set_first_final) {
3276
+ // all elements collected; now convert to a set
3277
+ v = edn::util::call_module_fn(rb_mEDN, EDN_MAKE_SET_METHOD, elems);
3278
+ return p + 1;
3279
+ }
3280
+ else if (cs == EDN_set_error) {
3281
+ error(__FUNCTION__, *p);
3282
+ return pe;
3283
+ }
3284
+ else if (cs == EDN_set_en_main) {} // silence ragel warning
3285
+ return nullptr;
3102
3286
  }
3103
3287
 
3104
3288
 
@@ -3109,7 +3293,7 @@ case 4:
3109
3293
  // defining a machine to consume items within container delimiters
3110
3294
  //
3111
3295
 
3112
- #line 3113 "edn_parser.cc"
3296
+ #line 3297 "edn_parser.cc"
3113
3297
  static const int EDN_discard_start = 1;
3114
3298
  static const int EDN_discard_first_final = 4;
3115
3299
  static const int EDN_discard_error = 0;
@@ -3117,24 +3301,24 @@ static const int EDN_discard_error = 0;
3117
3301
  static const int EDN_discard_en_main = 1;
3118
3302
 
3119
3303
 
3120
- #line 905 "edn_parser.rl"
3304
+ #line 980 "edn_parser.rl"
3121
3305
 
3122
3306
 
3123
3307
 
3124
3308
  const char* edn::Parser::parse_discard(const char *p, const char *pe)
3125
3309
  {
3126
- int cs;
3127
- VALUE v;
3310
+ int cs;
3311
+ VALUE v;
3128
3312
 
3129
3313
 
3130
- #line 3131 "edn_parser.cc"
3314
+ #line 3315 "edn_parser.cc"
3131
3315
  {
3132
3316
  cs = EDN_discard_start;
3133
3317
  }
3134
3318
 
3135
- #line 914 "edn_parser.rl"
3319
+ #line 989 "edn_parser.rl"
3136
3320
 
3137
- #line 3138 "edn_parser.cc"
3321
+ #line 3322 "edn_parser.cc"
3138
3322
  {
3139
3323
  if ( p == pe )
3140
3324
  goto _test_eof;
@@ -3145,27 +3329,27 @@ case 1:
3145
3329
  goto st2;
3146
3330
  goto st0;
3147
3331
  tr2:
3148
- #line 895 "edn_parser.rl"
3332
+ #line 970 "edn_parser.rl"
3149
3333
  {
3150
- std::stringstream s;
3151
- s << "discard sequence without element to discard";
3152
- error(__FUNCTION__, s.str());
3153
- p--; {p++; cs = 0; goto _out;}
3154
- }
3334
+ std::stringstream s;
3335
+ s << "discard sequence without element to discard";
3336
+ error(__FUNCTION__, s.str());
3337
+ p--; {p++; cs = 0; goto _out;}
3338
+ }
3155
3339
  goto st0;
3156
- #line 3157 "edn_parser.cc"
3340
+ #line 3341 "edn_parser.cc"
3157
3341
  st0:
3158
3342
  cs = 0;
3159
3343
  goto _out;
3160
3344
  tr3:
3161
- #line 25 "edn_parser.rl"
3345
+ #line 47 "edn_parser.rl"
3162
3346
  { line_number++; }
3163
3347
  goto st2;
3164
3348
  st2:
3165
3349
  if ( ++p == pe )
3166
3350
  goto _test_eof2;
3167
3351
  case 2:
3168
- #line 3169 "edn_parser.cc"
3352
+ #line 3353 "edn_parser.cc"
3169
3353
  switch( (*p) ) {
3170
3354
  case 10: goto tr3;
3171
3355
  case 32: goto st2;
@@ -3191,25 +3375,25 @@ case 2:
3191
3375
  goto tr4;
3192
3376
  goto tr2;
3193
3377
  tr4:
3194
- #line 884 "edn_parser.rl"
3195
- {
3196
- const char *np = parse_value(p, pe, v);
3197
- if (np == NULL) { p--; {p++; cs = 4; goto _out;} } else {
3198
- // this token is to be discarded so store it in the
3199
- // discard stack - we really don't need to save it so this
3200
- // could be simplified
3201
- discard.push_back(v);
3202
- {p = (( np))-1;}
3203
- }
3204
- }
3205
- #line 58 "edn_parser.rl"
3378
+ #line 959 "edn_parser.rl"
3379
+ {
3380
+ const char *np = parse_value(p, pe, v);
3381
+ if (np == nullptr) { p--; {p++; cs = 4; goto _out;} } else {
3382
+ // this token is to be discarded so store it in the
3383
+ // discard stack - we really don't need to save it so this
3384
+ // could be simplified
3385
+ discard.push_back(v);
3386
+ {p = (( np))-1;}
3387
+ }
3388
+ }
3389
+ #line 80 "edn_parser.rl"
3206
3390
  { p--; {p++; cs = 4; goto _out;} }
3207
3391
  goto st4;
3208
3392
  st4:
3209
3393
  if ( ++p == pe )
3210
3394
  goto _test_eof4;
3211
3395
  case 4:
3212
- #line 3213 "edn_parser.cc"
3396
+ #line 3397 "edn_parser.cc"
3213
3397
  goto st0;
3214
3398
  st3:
3215
3399
  if ( ++p == pe )
@@ -3228,33 +3412,32 @@ case 3:
3228
3412
  {
3229
3413
  switch ( cs ) {
3230
3414
  case 2:
3231
- #line 895 "edn_parser.rl"
3415
+ #line 970 "edn_parser.rl"
3232
3416
  {
3233
- std::stringstream s;
3234
- s << "discard sequence without element to discard";
3235
- error(__FUNCTION__, s.str());
3236
- p--; {p++; cs = 0; goto _out;}
3237
- }
3417
+ std::stringstream s;
3418
+ s << "discard sequence without element to discard";
3419
+ error(__FUNCTION__, s.str());
3420
+ p--; {p++; cs = 0; goto _out;}
3421
+ }
3238
3422
  break;
3239
- #line 3240 "edn_parser.cc"
3423
+ #line 3424 "edn_parser.cc"
3240
3424
  }
3241
3425
  }
3242
3426
 
3243
3427
  _out: {}
3244
3428
  }
3245
3429
 
3246
- #line 915 "edn_parser.rl"
3247
-
3248
- if (cs >= EDN_discard_first_final) {
3249
- return p + 1;
3250
- }
3251
- else if (cs == EDN_discard_error) {
3252
- error(__FUNCTION__, *p);
3253
- return pe;
3254
- }
3255
- else if (cs == EDN_discard_en_main) {} // silence ragel warning
3256
-
3257
- return NULL;
3430
+ #line 990 "edn_parser.rl"
3431
+
3432
+ if (cs >= EDN_discard_first_final) {
3433
+ return p + 1;
3434
+ }
3435
+ else if (cs == EDN_discard_error) {
3436
+ error(__FUNCTION__, *p);
3437
+ return pe;
3438
+ }
3439
+ else if (cs == EDN_discard_en_main) {} // silence ragel warning
3440
+ return nullptr;
3258
3441
  }
3259
3442
 
3260
3443
 
@@ -3274,7 +3457,7 @@ case 3:
3274
3457
  // 2. add parse checks for uuid and inst for better error reporting
3275
3458
  //
3276
3459
 
3277
- #line 3278 "edn_parser.cc"
3460
+ #line 3461 "edn_parser.cc"
3278
3461
  static const int EDN_tagged_start = 1;
3279
3462
  static const int EDN_tagged_first_final = 7;
3280
3463
  static const int EDN_tagged_error = 0;
@@ -3282,28 +3465,28 @@ static const int EDN_tagged_error = 0;
3282
3465
  static const int EDN_tagged_en_main = 1;
3283
3466
 
3284
3467
 
3285
- #line 983 "edn_parser.rl"
3468
+ #line 1057 "edn_parser.rl"
3286
3469
 
3287
3470
 
3288
3471
 
3289
3472
  const char* edn::Parser::parse_tagged(const char *p, const char *pe, VALUE& v)
3290
3473
  {
3291
- VALUE sym_name = Qnil;
3292
- VALUE data = Qnil;
3293
- bool sym_ok = false;
3294
- bool data_ok = false;
3474
+ VALUE sym_name = Qnil;
3475
+ VALUE data = Qnil;
3476
+ bool sym_ok = false;
3477
+ bool data_ok = false;
3295
3478
 
3296
- int cs;
3479
+ int cs;
3297
3480
 
3298
3481
 
3299
- #line 3300 "edn_parser.cc"
3482
+ #line 3483 "edn_parser.cc"
3300
3483
  {
3301
3484
  cs = EDN_tagged_start;
3302
3485
  }
3303
3486
 
3304
- #line 996 "edn_parser.rl"
3487
+ #line 1070 "edn_parser.rl"
3305
3488
 
3306
- #line 3307 "edn_parser.cc"
3489
+ #line 3490 "edn_parser.cc"
3307
3490
  {
3308
3491
  if ( p == pe )
3309
3492
  goto _test_eof;
@@ -3320,21 +3503,21 @@ st0:
3320
3503
  cs = 0;
3321
3504
  goto _out;
3322
3505
  tr0:
3323
- #line 962 "edn_parser.rl"
3324
- {
3325
- // parses the symbol portion of the pair
3326
- const char *np = parse_symbol(p, pe, sym_name);
3327
- if (np == NULL) { p--; {p++; cs = 2; goto _out;} } else {
3328
- sym_ok = true;
3329
- {p = (( np))-1;}
3330
- }
3331
- }
3506
+ #line 1036 "edn_parser.rl"
3507
+ {
3508
+ // parses the symbol portion of the pair
3509
+ const char *np = parse_symbol(p, pe, sym_name);
3510
+ if (np == nullptr) { p--; {p++; cs = 2; goto _out;} } else {
3511
+ sym_ok = true;
3512
+ {p = (( np))-1;}
3513
+ }
3514
+ }
3332
3515
  goto st2;
3333
3516
  st2:
3334
3517
  if ( ++p == pe )
3335
3518
  goto _test_eof2;
3336
3519
  case 2:
3337
- #line 3338 "edn_parser.cc"
3520
+ #line 3521 "edn_parser.cc"
3338
3521
  switch( (*p) ) {
3339
3522
  case 10: goto tr3;
3340
3523
  case 32: goto st3;
@@ -3360,14 +3543,14 @@ case 2:
3360
3543
  goto st2;
3361
3544
  goto st0;
3362
3545
  tr3:
3363
- #line 25 "edn_parser.rl"
3546
+ #line 47 "edn_parser.rl"
3364
3547
  { line_number++; }
3365
3548
  goto st3;
3366
3549
  st3:
3367
3550
  if ( ++p == pe )
3368
3551
  goto _test_eof3;
3369
3552
  case 3:
3370
- #line 3371 "edn_parser.cc"
3553
+ #line 3554 "edn_parser.cc"
3371
3554
  switch( (*p) ) {
3372
3555
  case 10: goto tr3;
3373
3556
  case 32: goto st3;
@@ -3393,23 +3576,23 @@ case 3:
3393
3576
  goto tr7;
3394
3577
  goto st0;
3395
3578
  tr7:
3396
- #line 970 "edn_parser.rl"
3579
+ #line 1044 "edn_parser.rl"
3397
3580
  {
3398
- // parses the value portion
3399
- const char *np = parse_value(p, pe, data);
3400
- if (np == NULL) { p--; {p++; cs = 7; goto _out;} } else {
3401
- data_ok = true;
3402
- {p = (( np))-1;}
3403
- }
3404
- }
3405
- #line 58 "edn_parser.rl"
3581
+ // parses the value portion
3582
+ const char *np = parse_value(p, pe, data);
3583
+ if (np == nullptr) { p--; {p++; cs = 7; goto _out;} } else {
3584
+ data_ok = true;
3585
+ {p = (( np))-1;}
3586
+ }
3587
+ }
3588
+ #line 80 "edn_parser.rl"
3406
3589
  { p--; {p++; cs = 7; goto _out;} }
3407
3590
  goto st7;
3408
3591
  st7:
3409
3592
  if ( ++p == pe )
3410
3593
  goto _test_eof7;
3411
3594
  case 7:
3412
- #line 3413 "edn_parser.cc"
3595
+ #line 3596 "edn_parser.cc"
3413
3596
  goto st0;
3414
3597
  st4:
3415
3598
  if ( ++p == pe )
@@ -3487,45 +3670,43 @@ case 6:
3487
3670
  _out: {}
3488
3671
  }
3489
3672
 
3490
- #line 997 "edn_parser.rl"
3673
+ #line 1071 "edn_parser.rl"
3491
3674
 
3492
- if (cs >= EDN_tagged_first_final) {
3675
+ if (cs >= EDN_tagged_first_final) {
3493
3676
  //std::cerr << __FUNCTION__ << " parse symbol name as '" << sym_name << "', value is: " << data << std::endl;
3494
3677
 
3495
- if (!sym_ok || !data_ok) {
3496
- error(__FUNCTION__, "tagged element symbol error", *p);
3497
- v = EDN_EOF_CONST;
3498
- return NULL;
3499
- }
3500
-
3501
- try {
3502
- // tagged_element makes a call to ruby which may throw an
3503
- // exception when parsing the data
3504
- v = edn::util::call_module_fn(rb_mEDN, EDN_TAGGED_ELEM_METHOD, sym_name, data);
3505
- return p + 1;
3506
- } catch (std::exception& e) {
3507
- error(__FUNCTION__, e.what());
3508
- return pe;
3509
- }
3510
- }
3511
- else if (cs == EDN_tagged_error) {
3512
- error(__FUNCTION__, "tagged element symbol error", *p);
3513
- }
3514
- else if (cs == EDN_tagged_en_main) {} // silence ragel warning
3515
- v = EDN_EOF_CONST;
3516
- return NULL;
3678
+ if (!sym_ok || !data_ok) {
3679
+ error(__FUNCTION__, "tagged element symbol error", *p);
3680
+ v = EDN_EOF_CONST;
3681
+ return nullptr;
3682
+ }
3683
+
3684
+ try {
3685
+ // tagged_element makes a call to ruby which may throw an
3686
+ // exception when parsing the data
3687
+ v = edn::util::call_module_fn(rb_mEDN, EDN_TAGGED_ELEM_METHOD, sym_name, data);
3688
+ return p + 1;
3689
+ } catch (std::exception& e) {
3690
+ error(__FUNCTION__, e.what());
3691
+ return pe;
3692
+ }
3693
+ }
3694
+ else if (cs == EDN_tagged_error) {
3695
+ error(__FUNCTION__, "tagged element symbol error", *p);
3696
+ }
3697
+ else if (cs == EDN_tagged_en_main) {} // silence ragel warning
3698
+ v = EDN_EOF_CONST;
3699
+ return nullptr;
3517
3700
  }
3518
3701
 
3519
3702
 
3520
-
3521
-
3522
3703
  // ============================================================
3523
3704
  // metadata - looks like ruby just discards this but we'll track it
3524
3705
  // and provide a means to retrive after each parse op - might be
3525
3706
  // useful?
3526
3707
  //
3527
3708
 
3528
- #line 3529 "edn_parser.cc"
3709
+ #line 3710 "edn_parser.cc"
3529
3710
  static const int EDN_meta_start = 1;
3530
3711
  static const int EDN_meta_first_final = 3;
3531
3712
  static const int EDN_meta_error = 0;
@@ -3533,24 +3714,24 @@ static const int EDN_meta_error = 0;
3533
3714
  static const int EDN_meta_en_main = 1;
3534
3715
 
3535
3716
 
3536
- #line 1047 "edn_parser.rl"
3717
+ #line 1119 "edn_parser.rl"
3537
3718
 
3538
3719
 
3539
3720
 
3540
3721
  const char* edn::Parser::parse_meta(const char *p, const char *pe)
3541
3722
  {
3542
- int cs;
3543
- VALUE v;
3723
+ int cs;
3724
+ VALUE v;
3544
3725
 
3545
3726
 
3546
- #line 3547 "edn_parser.cc"
3727
+ #line 3728 "edn_parser.cc"
3547
3728
  {
3548
3729
  cs = EDN_meta_start;
3549
3730
  }
3550
3731
 
3551
- #line 1056 "edn_parser.rl"
3732
+ #line 1128 "edn_parser.rl"
3552
3733
 
3553
- #line 3554 "edn_parser.cc"
3734
+ #line 3735 "edn_parser.cc"
3554
3735
  {
3555
3736
  if ( p == pe )
3556
3737
  goto _test_eof;
@@ -3589,19 +3770,19 @@ case 2:
3589
3770
  goto tr2;
3590
3771
  goto st0;
3591
3772
  tr2:
3592
- #line 1039 "edn_parser.rl"
3773
+ #line 1111 "edn_parser.rl"
3593
3774
  {
3594
- const char *np = parse_value(p, pe, v);
3595
- if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else { {p = (( np))-1;} }
3596
- }
3597
- #line 58 "edn_parser.rl"
3775
+ const char *np = parse_value(p, pe, v);
3776
+ if (np == nullptr) { p--; {p++; cs = 3; goto _out;} } else { {p = (( np))-1;} }
3777
+ }
3778
+ #line 80 "edn_parser.rl"
3598
3779
  { p--; {p++; cs = 3; goto _out;} }
3599
3780
  goto st3;
3600
3781
  st3:
3601
3782
  if ( ++p == pe )
3602
3783
  goto _test_eof3;
3603
3784
  case 3:
3604
- #line 3605 "edn_parser.cc"
3785
+ #line 3786 "edn_parser.cc"
3605
3786
  goto st0;
3606
3787
  }
3607
3788
  _test_eof2: cs = 2; goto _test_eof;
@@ -3611,19 +3792,18 @@ case 3:
3611
3792
  _out: {}
3612
3793
  }
3613
3794
 
3614
- #line 1057 "edn_parser.rl"
3615
-
3616
- if (cs >= EDN_meta_first_final) {
3617
- append_to_meta(v);
3618
- return p + 1;
3619
- }
3620
- else if (cs == EDN_meta_error) {
3621
- error(__FUNCTION__, *p);
3622
- return pe;
3623
- }
3624
- else if (cs == EDN_meta_en_main) {} // silence ragel warning
3625
-
3626
- return NULL;
3795
+ #line 1129 "edn_parser.rl"
3796
+
3797
+ if (cs >= EDN_meta_first_final) {
3798
+ append_to_meta(v);
3799
+ return p + 1;
3800
+ }
3801
+ else if (cs == EDN_meta_error) {
3802
+ error(__FUNCTION__, *p);
3803
+ return pe;
3804
+ }
3805
+ else if (cs == EDN_meta_en_main) {} // silence ragel warning
3806
+ return nullptr;
3627
3807
  }
3628
3808
 
3629
3809
 
@@ -3633,7 +3813,7 @@ case 3:
3633
3813
  // top-level, therefore, does not tokenize source stream
3634
3814
  //
3635
3815
 
3636
- #line 3637 "edn_parser.cc"
3816
+ #line 3817 "edn_parser.cc"
3637
3817
  static const int EDN_parser_start = 2;
3638
3818
  static const int EDN_parser_first_final = 2;
3639
3819
  static const int EDN_parser_error = 0;
@@ -3641,59 +3821,59 @@ static const int EDN_parser_error = 0;
3641
3821
  static const int EDN_parser_en_main = 2;
3642
3822
 
3643
3823
 
3644
- #line 1106 "edn_parser.rl"
3824
+ #line 1177 "edn_parser.rl"
3645
3825
 
3646
3826
 
3647
3827
 
3648
3828
  VALUE edn::Parser::parse(const char* src, std::size_t len)
3649
3829
  {
3650
- int cs;
3651
- VALUE result = EDN_EOF_CONST;
3830
+ int cs;
3831
+ VALUE result = EDN_EOF_CONST;
3652
3832
 
3653
3833
 
3654
- #line 3655 "edn_parser.cc"
3834
+ #line 3835 "edn_parser.cc"
3655
3835
  {
3656
3836
  cs = EDN_parser_start;
3657
3837
  }
3658
3838
 
3659
- #line 1115 "edn_parser.rl"
3660
- set_source(src, len);
3839
+ #line 1186 "edn_parser.rl"
3840
+ set_source(src, len);
3661
3841
 
3662
- #line 3663 "edn_parser.cc"
3842
+ #line 3843 "edn_parser.cc"
3663
3843
  {
3664
3844
  if ( p == pe )
3665
3845
  goto _test_eof;
3666
3846
  switch ( cs )
3667
3847
  {
3668
3848
  tr1:
3669
- #line 25 "edn_parser.rl"
3849
+ #line 47 "edn_parser.rl"
3670
3850
  { line_number++; }
3671
3851
  goto st2;
3672
3852
  tr4:
3673
- #line 1083 "edn_parser.rl"
3674
- {
3675
- // save the count of metadata items before we parse this value
3676
- // so we can determine if we've read another metadata value or
3677
- // an actual data item
3678
- std::size_t meta_sz = meta_size();
3679
- const char* np = parse_value(p, pe, result);
3680
- if (np == NULL) { {p = (( pe))-1;} {p++; cs = 2; goto _out;} } else {
3681
- // if we have metadata saved and it matches the count we
3682
- // saved before we parsed a value, then we must bind the
3683
- // metadata sequence to it
3684
- if (!meta_empty() && meta_size() == meta_sz) {
3685
- // this will empty the metadata sequence too
3686
- result = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, result, ruby_meta());
3687
- }
3688
- {p = (( np))-1;}
3689
- }
3690
- }
3853
+ #line 1154 "edn_parser.rl"
3854
+ {
3855
+ // save the count of metadata items before we parse this value
3856
+ // so we can determine if we've read another metadata value or
3857
+ // an actual data item
3858
+ std::size_t meta_sz = meta_size();
3859
+ const char* np = parse_value(p, pe, result);
3860
+ if (np == nullptr) { {p = (( pe))-1;} {p++; cs = 2; goto _out;} } else {
3861
+ // if we have metadata saved and it matches the count we
3862
+ // saved before we parsed a value, then we must bind the
3863
+ // metadata sequence to it
3864
+ if (!meta_empty() && meta_size() == meta_sz) {
3865
+ // this will empty the metadata sequence too
3866
+ result = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, result, ruby_meta());
3867
+ }
3868
+ {p = (( np))-1;}
3869
+ }
3870
+ }
3691
3871
  goto st2;
3692
3872
  st2:
3693
3873
  if ( ++p == pe )
3694
3874
  goto _test_eof2;
3695
3875
  case 2:
3696
- #line 3697 "edn_parser.cc"
3876
+ #line 3877 "edn_parser.cc"
3697
3877
  switch( (*p) ) {
3698
3878
  case 10: goto tr1;
3699
3879
  case 32: goto st2;
@@ -3736,17 +3916,17 @@ case 1:
3736
3916
  _out: {}
3737
3917
  }
3738
3918
 
3739
- #line 1117 "edn_parser.rl"
3740
-
3741
- if (cs == EDN_parser_error) {
3742
- error(__FUNCTION__, *p);
3743
- return EDN_EOF_CONST;
3744
- }
3745
- else if (cs == EDN_parser_first_final) {
3746
- p = pe = eof = NULL;
3747
- }
3748
- else if (cs == EDN_parser_en_main) {} // silence ragel warning
3749
- return result;
3919
+ #line 1188 "edn_parser.rl"
3920
+
3921
+ if (cs == EDN_parser_error) {
3922
+ error(__FUNCTION__, *p);
3923
+ return EDN_EOF_CONST;
3924
+ }
3925
+ else if (cs == EDN_parser_first_final) {
3926
+ p = pe = eof = nullptr;
3927
+ }
3928
+ else if (cs == EDN_parser_en_main) {} // silence ragel warning
3929
+ return result;
3750
3930
  }
3751
3931
 
3752
3932
 
@@ -3754,13 +3934,13 @@ case 1:
3754
3934
  // token-by-token machine
3755
3935
  //
3756
3936
 
3757
- #line 3758 "edn_parser.cc"
3937
+ #line 3938 "edn_parser.cc"
3758
3938
  static const int EDN_tokens_start = 1;
3759
3939
 
3760
3940
  static const int EDN_tokens_en_main = 1;
3761
3941
 
3762
3942
 
3763
- #line 1171 "edn_parser.rl"
3943
+ #line 1242 "edn_parser.rl"
3764
3944
 
3765
3945
 
3766
3946
 
@@ -3768,39 +3948,39 @@ static const int EDN_tokens_en_main = 1;
3768
3948
  //
3769
3949
  edn::Parser::eTokenState edn::Parser::parse_next(VALUE& value)
3770
3950
  {
3771
- int cs;
3772
- eTokenState state = TOKEN_ERROR;
3773
- // need to track metadada read and bind it to the next value read
3774
- // - but must account for sequences of metadata values
3775
- std::size_t meta_sz;
3951
+ int cs;
3952
+ eTokenState state = TOKEN_ERROR;
3953
+ // need to track metadada read and bind it to the next value read
3954
+ // - but must account for sequences of metadata values
3955
+ std::size_t meta_sz;
3776
3956
 
3777
- // clear any previously saved discards; only track if read during
3778
- // this op
3779
- discard.clear();
3957
+ // clear any previously saved discards; only track if read during
3958
+ // this op
3959
+ discard.clear();
3780
3960
 
3781
3961
 
3782
- #line 3783 "edn_parser.cc"
3962
+ #line 3963 "edn_parser.cc"
3783
3963
  {
3784
3964
  cs = EDN_tokens_start;
3785
3965
  }
3786
3966
 
3787
- #line 1189 "edn_parser.rl"
3967
+ #line 1260 "edn_parser.rl"
3788
3968
 
3789
- #line 3790 "edn_parser.cc"
3969
+ #line 3970 "edn_parser.cc"
3790
3970
  {
3791
3971
  if ( p == pe )
3792
3972
  goto _test_eof;
3793
3973
  switch ( cs )
3794
3974
  {
3795
3975
  tr2:
3796
- #line 25 "edn_parser.rl"
3976
+ #line 47 "edn_parser.rl"
3797
3977
  { line_number++; }
3798
3978
  goto st1;
3799
3979
  st1:
3800
3980
  if ( ++p == pe )
3801
3981
  goto _test_eof1;
3802
3982
  case 1:
3803
- #line 3804 "edn_parser.cc"
3983
+ #line 3984 "edn_parser.cc"
3804
3984
  switch( (*p) ) {
3805
3985
  case 10: goto tr2;
3806
3986
  case 32: goto st1;
@@ -3829,47 +4009,47 @@ st0:
3829
4009
  cs = 0;
3830
4010
  goto _out;
3831
4011
  tr6:
3832
- #line 25 "edn_parser.rl"
4012
+ #line 47 "edn_parser.rl"
3833
4013
  { line_number++; }
3834
4014
  goto st4;
3835
4015
  tr3:
3836
- #line 1139 "edn_parser.rl"
3837
- {
3838
- // we won't know if we've parsed a discard or a metadata until
3839
- // after parse_value() is done. Save the current number of
3840
- // elements in the metadata sequence; then we can check if it
3841
- // grew or if the discard sequence grew
3842
- meta_sz = meta_size();
3843
-
3844
- const char* np = parse_value(p, pe, value);
3845
- if (np == NULL) { p--; {p++; cs = 4; goto _out;} } else {
3846
- if (!meta_empty()) {
3847
- // was an additional metadata entry read? if so, don't
3848
- // return a value
3849
- if (meta_size() > meta_sz) {
3850
- state = TOKEN_IS_META;
3851
- }
3852
- else {
3853
- // a value was read and there's a pending metadata
3854
- // sequence. Bind them.
3855
- value = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, value, ruby_meta());
3856
- state = TOKEN_OK;
3857
- }
3858
- } else if (!discard.empty()) {
3859
- // a discard read. Don't return a value
3860
- state = TOKEN_IS_DISCARD;
3861
- } else {
3862
- state = TOKEN_OK;
4016
+ #line 1210 "edn_parser.rl"
4017
+ {
4018
+ // we won't know if we've parsed a discard or a metadata until
4019
+ // after parse_value() is done. Save the current number of
4020
+ // elements in the metadata sequence; then we can check if it
4021
+ // grew or if the discard sequence grew
4022
+ meta_sz = meta_size();
4023
+
4024
+ const char* np = parse_value(p, pe, value);
4025
+ if (np == nullptr) { p--; {p++; cs = 4; goto _out;} } else {
4026
+ if (!meta_empty()) {
4027
+ // was an additional metadata entry read? if so, don't
4028
+ // return a value
4029
+ if (meta_size() > meta_sz) {
4030
+ state = TOKEN_IS_META;
4031
+ }
4032
+ else {
4033
+ // a value was read and there's a pending metadata
4034
+ // sequence. Bind them.
4035
+ value = edn::util::call_module_fn(rb_mEDNT, EDNT_EXTENDED_VALUE_METHOD, value, ruby_meta());
4036
+ state = TOKEN_OK;
3863
4037
  }
3864
- {p = (( np))-1;}
3865
- }
3866
- }
4038
+ } else if (!discard.empty()) {
4039
+ // a discard read. Don't return a value
4040
+ state = TOKEN_IS_DISCARD;
4041
+ } else {
4042
+ state = TOKEN_OK;
4043
+ }
4044
+ {p = (( np))-1;}
4045
+ }
4046
+ }
3867
4047
  goto st4;
3868
4048
  st4:
3869
4049
  if ( ++p == pe )
3870
4050
  goto _test_eof4;
3871
4051
  case 4:
3872
- #line 3873 "edn_parser.cc"
4052
+ #line 4053 "edn_parser.cc"
3873
4053
  switch( (*p) ) {
3874
4054
  case 10: goto tr6;
3875
4055
  case 32: goto st4;
@@ -3903,10 +4083,10 @@ case 3:
3903
4083
  _out: {}
3904
4084
  }
3905
4085
 
3906
- #line 1190 "edn_parser.rl"
4086
+ #line 1261 "edn_parser.rl"
3907
4087
 
3908
- if (cs == EDN_tokens_en_main) {} // silence ragel warning
3909
- return state;
4088
+ if (cs == EDN_tokens_en_main) {} // silence ragel warning
4089
+ return state;
3910
4090
  }
3911
4091
 
3912
4092
  /*