edn_turbo 0.5.7 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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
  /*