yoga 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e30bbc7d17d9d4847b096576cc5efb39c71eec4e
4
- data.tar.gz: 5813baee5ef2e6704fa2db41a3f77316e478ec3f
3
+ metadata.gz: 03845e88ffb4574489a6881d994554233bffe779
4
+ data.tar.gz: 1217f182ff6402b7df6f5997f7f24dca773e39d2
5
5
  SHA512:
6
- metadata.gz: 0d6a878a6eaaf68427d1c4b873c465d82d82a61bef900f5f53cd173dc2e12b83e17e0bca277511edf3bfde66b009755a2272e75a9c6f6232a45cad8e253d0458
7
- data.tar.gz: 642ddf68de1ce8acd8d69d198eaa4f7af87abd45c1deaba76e230b738f3abcb8aedad2dfec061bb4f01b1816f4d5527be5c8b9f59e0f755b057b50491ec2d277
6
+ metadata.gz: 14e9209587fc857be6637316ae9e3cdfe08022b61d5326987b2d7f7a3e2ba18b2c20e2bc8277097f7f35dfa38742813378b2acb02114c7afb9780afdea4e3343
7
+ data.tar.gz: 84892e0eca95a1d0b56f64ccab0bb1b6c532f3775185e31b89b54f21386c0803873e872361abf66d6d425c8383d6423eacfa4790618b4e576e71859c2c1f5643
@@ -13,6 +13,7 @@ module Yoga
13
13
  # @param tokens [::Enumerable<Yoga::Token>]
14
14
  def initialize(tokens)
15
15
  @tokens = tokens
16
+ @buffer = []
16
17
  end
17
18
 
18
19
  # Performs the parsing.
@@ -112,25 +112,39 @@ module Yoga
112
112
  #
113
113
  # @return [Yoga::Token]
114
114
  def peek
115
- if next?
116
- @_last = @tokens.peek
117
- else
118
- @_last
119
- end
115
+ @_last = (@buffer.any? ? @buffer.first : @tokens.peek)
116
+ rescue ::StopIteration
117
+ @_last
120
118
  end
121
119
 
122
- # Checks if the next token exists. It does this by checking for a
123
- # `StopIteration` error. This is actually really slow, but there's
124
- # not much else I can do.
120
+ # Peeks out to a given token. If peeking would cause a `StopIteration`
121
+ # error, it instead returns the last value that was peeked. This is
122
+ # an expensive operation, and should be used sparingly. All other
123
+ # methods work as normal, even after this.
125
124
  #
126
- # @return [::Boolean]
127
- def next?
128
- @tokens.peek
129
- true
130
- rescue StopIteration
131
- false
125
+ # @param to [::Numeric] The distance to peek to.
126
+ # @return [Yoga::Token]
127
+ def peek_out(to)
128
+ return @buffer[to] if to <= @buffer.size
129
+ (to - @buffer.size + 1).times { @buffer << @tokens.next }
130
+ @buffer.last
131
+ rescue ::StopIteration
132
+ @buffer.last
133
+ end
134
+
135
+ # Pushes back tokens onto the buffer. These, in reverse order, are
136
+ # the tokens that are pulled out by `peek/1`, `peek_to/1`, `expect/1`,
137
+ # and `shift/1`.
138
+ #
139
+ # @param tokens [<Yoga::Token>]
140
+ # @return [self]
141
+ def push(*tokens)
142
+ tokens.each { |t| @buffer.push(t) }
143
+ self
132
144
  end
133
145
 
146
+ alias_method :<<, :push
147
+
134
148
  # Switches the function executed based on the given nodes. If the
135
149
  # peeked node matches one of the mappings, it calls the resulting
136
150
  # block or method.
@@ -140,10 +154,10 @@ module Yoga
140
154
  # @see ClassMethods#switch
141
155
  # @param name [::Symbol] The name of the switch to use.
142
156
  # @return [::Object] The result of calling the block.
143
- def switch(name, *param)
157
+ def switch(name, *param, token: peek)
144
158
  switch = self.class.switch(name)
145
159
  block = switch
146
- .fetch(peek.kind) { switch.fetch(:$else) { error(switch.keys) } }
160
+ .fetch(token.kind) { switch.fetch(:$else) { error(switch.keys) } }
147
161
  instance_exec(*param, &block)
148
162
  end
149
163
 
@@ -165,10 +179,13 @@ module Yoga
165
179
  return [] if (ending && peek?(ending)) || (!ending && !join)
166
180
 
167
181
  children << yield
168
- while (join && expect(join)) && !(ending && peek?(ending))
169
- children << yield
182
+
183
+ cond = proc do
184
+ (join ? peek?(join) && expect(join) : true) &&
185
+ !(ending && peek?(ending))
170
186
  end
171
187
 
188
+ (children << yield) while cond.call
172
189
  children
173
190
  end
174
191
 
@@ -184,11 +201,24 @@ module Yoga
184
201
  tokens.include?(peek.kind)
185
202
  end
186
203
 
204
+ # Peeks out to a specific point in the future to match. This is an
205
+ # expensive operation.
206
+ #
207
+ # @see #peek?
208
+ # @see peek_out
209
+ # @param to [::Numeric] The distance to peek to.
210
+ # @param tokens [<::Symbol>] The kinds of tokens to check for.
211
+ # @return [::Boolean]
212
+ def peek_out?(to, tokens)
213
+ tokens = Utils.flatten_into_set([tokens])
214
+ tokens.include?(peek_out(to).kind)
215
+ end
216
+
187
217
  # Shifts to the next token, and returns the old token.
188
218
  #
189
219
  # @return [Yoga::Token]
190
220
  def shift
191
- @tokens.next
221
+ @buffer.any? ? @buffer.shift : @tokens.next
192
222
  rescue ::StopIteration
193
223
  fail InvalidShiftError, location: peek.location
194
224
  end
@@ -5,5 +5,5 @@ module Yoga
5
5
  # The version of the module.
6
6
  #
7
7
  # @return [::String]
8
- VERSION = "0.3.2"
8
+ VERSION = "0.4.1"
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yoga
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-10 00:00:00.000000000 Z
11
+ date: 2017-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixture