tickly 0.0.6 → 0.0.7

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.
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.3
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
- gem "bychar", "~> 1.0.1"
6
+ gem "bychar", "~> 1.1"
7
7
 
8
8
  # Add dependencies to develop your gem here.
9
9
  # Include everything needed to run rake, tests, features, etc.
data/lib/tickly/parser.rb CHANGED
@@ -4,22 +4,6 @@ require 'bychar'
4
4
  module Tickly
5
5
 
6
6
 
7
- # Since you parse char by char, you will likely call
8
- # eof? on each iteration. Instead. allow it to raise and do not check.
9
- # This takes the profile time down from 36 seconds to 30 seconds
10
- # for a large file.
11
- class EOFError < RuntimeError #:nodoc: all
12
- end
13
-
14
- class W < Bychar::Reader #:nodoc: all
15
- def read_one_byte
16
- cache if @buf.eos?
17
- raise EOFError if @buf.eos?
18
-
19
- @buf.getch
20
- end
21
- end
22
-
23
7
  # Simplistic, incomplete and most likely incorrect TCL parser
24
8
  class Parser
25
9
 
@@ -30,7 +14,7 @@ module Tickly
30
14
  def parse(io_or_str)
31
15
  bare_io = io_or_str.respond_to?(:read) ? io_or_str : StringIO.new(io_or_str)
32
16
  # Wrap the IO in a Bychar buffer to read faster
33
- reader = W.new(bare_io)
17
+ reader = Bychar::Reader.new(bare_io)
34
18
  sub_parse(reader)
35
19
  end
36
20
 
@@ -45,112 +29,87 @@ module Tickly
45
29
  TERMINATORS = ["\n", ";"]
46
30
  ESC = 92.chr # Backslash (\)
47
31
 
32
+ # Package the expressions, stack and buffer.
33
+ # We use a special flag to tell us whether we need multuple expressions
34
+ # or not, if not we just discard them
35
+ def wrap_up(expressions, stack, buf, stack_depth, multiple_expressions)
36
+ stack << buf if (buf.length > 0)
37
+ return stack unless multiple_expressions
38
+
39
+ expressions << stack if stack.any?
40
+ expressions.each { |expr| expand_subexpr!(expr, stack_depth + 1) }
41
+
42
+ return expressions
43
+ end
44
+
48
45
  # Parse from a passed IO object either until an unescaped stop_char is reached
49
46
  # or until the IO is exhausted. The last argument is the class used to
50
47
  # compose the subexpression being parsed. The subparser is reentrant and not
51
48
  # destructive for the object containing it.
52
49
  def sub_parse(io, stop_char = nil, stack_depth = 0)
53
50
  # A standard stack is an expression that does not evaluate to a string
51
+ expressions = []
54
52
  stack = []
55
53
  buf = ''
56
54
  last_char_was_linebreak = false
55
+ multiple_expressions = false
57
56
 
58
57
  no_eof do
59
- char = io.read_one_byte
60
-
61
- if buf[LAST_CHAR] != ESC
62
- if char == stop_char # Bail out of a subexpr
63
- stack << buf if (buf.length > 0)
64
- # Chip away the tailing linebreak if it's there
65
- chomp!(stack)
66
- return stack
67
- elsif char == " " || char == "\n" # Space
68
- if buf.length > 0
69
- stack << buf
70
- buf = ''
71
- end
72
- if TERMINATORS.include?(char) # Introduce a stack separator! This is a new line
73
- if stack.any? && !last_char_was_linebreak
74
- last_char_was_linebreak = true
75
- stack = handle_expr_terminator(stack, stack_depth)
76
- end
77
- end
78
- elsif char == '[' # Opens a new string expression
79
- stack << buf if (buf.length > 0)
80
- last_char_was_linebreak = false
81
- stack << [:b] + sub_parse(io, ']', stack_depth + 1)
82
- elsif char == '{' # Opens a new literal expression
83
- stack << buf if (buf.length > 0)
84
- last_char_was_linebreak = false
85
- stack << [:c] + sub_parse(io, '}', stack_depth + 1)
86
- elsif char == '"'
87
- stack << buf if (buf.length > 0)
88
- last_char_was_linebreak = false
89
- stack << parse_str(io, '"')
90
- elsif char == "'"
91
- stack << buf if (buf.length > 0)
92
- last_char_was_linebreak = false
93
- stack << parse_str(io, "'")
58
+ char = io.read_one_byte!
59
+
60
+ if char == stop_char # Bail out of a subexpr
61
+ # Handle any remaining subexpressions
62
+ return wrap_up(expressions, stack, buf, stack_depth, multiple_expressions)
63
+ elsif char == " " || char == "\n" # Space
64
+ if buf.length > 0
65
+ stack << buf
66
+ buf = ''
67
+ end
68
+ if TERMINATORS.include?(char) && stack.any? && !last_char_was_linebreak # Introduce a stack separator! This is a new line
69
+ stack << buf if buf.length > 0
70
+ expressions << stack
71
+ stack = []
72
+ last_char_was_linebreak = true
73
+ multiple_expressions = true
74
+ #puts "Next expression! #{expressions.inspect} #{stack.inspect} #{buf.inspect}"
94
75
  else
95
76
  last_char_was_linebreak = false
96
- buf << char
97
77
  end
78
+ elsif char == '[' # Opens a new string expression
79
+ stack << buf if (buf.length > 0)
80
+ stack << [:b] + sub_parse(io, ']', stack_depth + 1)
81
+ elsif char == '{' # Opens a new literal expression
82
+ stack << buf if (buf.length > 0)
83
+ stack << [:c] + sub_parse(io, '}', stack_depth + 1)
84
+ elsif char == '"'
85
+ stack << buf if (buf.length > 0)
86
+ stack << parse_str(io, '"')
87
+ elsif char == "'"
88
+ stack << buf if (buf.length > 0)
89
+ stack << parse_str(io, "'")
98
90
  else
99
- last_char_was_linebreak = false
100
91
  buf << char
101
92
  end
102
93
  end
103
-
104
- # Ramass any remaining buffer contents
105
- stack << buf if (buf.length > 0)
106
-
107
- # Handle any remaining subexpressions
108
- if stack.include?(nil)
109
- stack = handle_expr_terminator(stack, stack_depth)
110
- end
111
- # Chip awiy the trailing null
112
- chomp!(stack)
113
94
 
114
- return stack
95
+ return wrap_up(expressions, stack, buf, stack_depth, multiple_expressions)
115
96
  end
116
97
 
117
98
  def chomp!(stack)
118
99
  stack.delete_at(-1) if stack.any? && stack[-1].nil?
119
100
  end
120
101
 
121
- def handle_expr_terminator(stack, stack_depth)
122
- # Figure out whether there was a previous expr terminator
123
- previous_i = stack.index(nil)
124
- # If there were none, just get this over with. Wrap the stack contents
125
- # into a subexpression and carry on.
126
- unless previous_i
127
- subexpr = stack
128
- expand_subexpr!(subexpr, stack_depth + 1)
129
- return [subexpr] + [nil]
130
- end
131
-
132
- # Now, if there was one, we are the next subexpr in line that just terminated.
133
- # What we need to do is pick out all the elements from that terminator onwards
134
- # and wrap them.
135
- subexpr = stack[previous_i+1..-1]
136
-
137
- # Use expand_subexpr! to trim away any fat that we don't need
138
- expand_subexpr!(subexpr, stack_depth + 1)
139
-
140
- return stack[0...previous_i] + [subexpr] + [nil]
141
- end
142
-
143
102
  def no_eof(&blk)
144
103
  begin
145
104
  loop(&blk)
146
- rescue EOFError
105
+ rescue Bychar::EOFError
147
106
  end
148
107
  end
149
108
 
150
109
  def parse_str(io, stop_char)
151
110
  buf = ''
152
111
  no_eof do
153
- c = io.read_one_byte
112
+ c = io.read_one_byte!
154
113
  if c == stop_char && buf[LAST_CHAR] != ESC
155
114
  return buf
156
115
  elsif buf[LAST_CHAR] == ESC # Eat out the escape char
data/lib/tickly.rb CHANGED
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + "/tickly/evaluator"
4
4
  require 'forwardable'
5
5
 
6
6
  module Tickly
7
- VERSION = '0.0.6'
7
+ VERSION = '0.0.7'
8
8
 
9
9
  # Provides the methods for quickly emitting the expression arrays,
10
10
  # is used in tests
data/tickly.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "tickly"
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik Tarkhanov"]
@@ -54,14 +54,14 @@ Gem::Specification.new do |s|
54
54
  s.specification_version = 3
55
55
 
56
56
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
- s.add_runtime_dependency(%q<bychar>, ["~> 1.0.1"])
57
+ s.add_runtime_dependency(%q<bychar>, ["~> 1.1"])
58
58
  s.add_development_dependency(%q<shoulda>, [">= 0"])
59
59
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
60
60
  s.add_development_dependency(%q<bundler>, [">= 0"])
61
61
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
62
62
  s.add_development_dependency(%q<ruby-prof>, [">= 0"])
63
63
  else
64
- s.add_dependency(%q<bychar>, ["~> 1.0.1"])
64
+ s.add_dependency(%q<bychar>, ["~> 1.1"])
65
65
  s.add_dependency(%q<shoulda>, [">= 0"])
66
66
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
67
67
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -69,7 +69,7 @@ Gem::Specification.new do |s|
69
69
  s.add_dependency(%q<ruby-prof>, [">= 0"])
70
70
  end
71
71
  else
72
- s.add_dependency(%q<bychar>, ["~> 1.0.1"])
72
+ s.add_dependency(%q<bychar>, ["~> 1.1"])
73
73
  s.add_dependency(%q<shoulda>, [">= 0"])
74
74
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
75
75
  s.add_dependency(%q<bundler>, [">= 0"])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tickly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 1.0.1
21
+ version: '1.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 1.0.1
29
+ version: '1.1'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: shoulda
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -156,7 +156,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
156
  version: '0'
157
157
  segments:
158
158
  - 0
159
- hash: -2375266437877240498
159
+ hash: 1707085798664396026
160
160
  required_rubygems_version: !ruby/object:Gem::Requirement
161
161
  none: false
162
162
  requirements: