yoga 0.3.2 → 0.4.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
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