Skip to content

Commit

Permalink
cleanup stack/ruby_builder
Browse files Browse the repository at this point in the history
  • Loading branch information
Sven Fuchs committed Jun 28, 2009
1 parent fa88763 commit 88727e6
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 84 deletions.
5 changes: 5 additions & 0 deletions lib/core_ext/hash/delete_at.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Hash
def delete_at(*keys)
keys.map { |key| delete(key) }
end
end
72 changes: 18 additions & 54 deletions lib/ripper/ruby_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ def build(src, filename = nil)

NEWLINE = [:@nl, :@ignored_nl]
WHITESPACE = [:@sp, :@comment] + NEWLINE
OPENERS = [:@lparen, :@lbracket, :@lbrace, :@class, :@module, :@def, :@begin, :@while, :@until,
OPENERS = [:@lparen, :@lbracket, :@lbrace, :@class, :@module, :@def, :@begin, :@while, :@until,
:@for, :@if, :@elsif, :@else, :@unless, :@case, :@when, :@embexpr_beg, :@do, :@rescue,
:'@=', :'@::']
KEYWORDS = [:@alias, :@and, :@BEGIN, :@begin, :@break, :@case, :@class, :@def, :@defined,
:@do, :@else, :@elsif, :@END, :@end, :@ensure, :@false, :@for, :@if, :@in,
:@module, :@next, :@nil, :@not, :@or, :@redo, :@rescue, :@retry, :@return,
:@self, :@super, :@then, :@true, :@undef, :@unless, :@until, :@when, :@while,
KEYWORDS = [:@alias, :@and, :@BEGIN, :@begin, :@break, :@case, :@class, :@def, :@defined,
:@do, :@else, :@elsif, :@END, :@end, :@ensure, :@false, :@for, :@if, :@in,
:@module, :@next, :@nil, :@not, :@or, :@redo, :@rescue, :@retry, :@return,
:@self, :@super, :@then, :@true, :@undef, :@unless, :@until, :@when, :@while,
:@yield]

SEPARATORS = [:@semicolon, :@comma]

UNARY_OPERATORS = [:'@+', :'@-', :'@!', :'@~', :@not]
BINARY_OPERATORS = [:'@**', :'@*', :'@/', :'@%', :'@+', :'@-', :'@<<', :'@>>', :'@&', :'@|', :'@^',
:'@>', :'@>=', :'@<', :'@<=', :'@<=>', :'@==', :'@===', :'@!=', :'@=~', :'@!~',
BINARY_OPERATORS = [:'@**', :'@*', :'@/', :'@%', :'@+', :'@-', :'@<<', :'@>>', :'@&', :'@|', :'@^',
:'@>', :'@>=', :'@<', :'@<=', :'@<=>', :'@==', :'@===', :'@!=', :'@=~', :'@!~',
:'@&&', :'@||', :@and, :@or]
TERNARY_OPERATORS = [:'@?', :'@:']
ASSIGN_OPERATORS = [:'@=', :'@+=', :'@-=', :'@*=', :'@**=', :'@%=', :'@/=', :'@|=', :'@&=', :'@^=',
ASSIGN_OPERATORS = [:'@=', :'@+=', :'@-=', :'@*=', :'@**=', :'@%=', :'@/=', :'@|=', :'@&=', :'@^=',
:'@[]=', :'@||=', :'@&&=', :'@<<=', :'@>>=']
ACCESS_OPERATORS = [:'@[]']

Expand All @@ -62,65 +62,37 @@ def initialize(src, filename = nil, lineno = nil)
protected

def position
Ruby::Node::Position.new(lineno - 1, column)
Ruby::Node::Position.new(lineno.to_i - 1, column)
end

def push(sexp = nil)
token = Token.new(*sexp) if sexp
token = Token.new(sexp[0], sexp[1], position) if sexp
stack.push(token) unless extra_heredoc_chars(token)
token
end

def pop(*args)
options = args.last.is_a?(::Hash) ? args.pop : {}
if types = options[:ignore]
stack_ignore(types) { stack.pop(*args << options) }
else
stack.pop(*args << options)
end
end

def shift(*args)
stack.reverse!
result = pop(*args)
stack.reverse!
result
end

def pop_one(*types)
options = types.last.is_a?(::Hash) ? types.pop : {}
options[:max] = 1
pop(*types << options).first
stack.pop(*args)
end

def pop_token(*types)
options = types.last.is_a?(::Hash) ? types.pop : {}
options[:max] = 1
pop_tokens(*types << options).first
end

def shift_token(*types)
options = types.last.is_a?(::Hash) ? types.pop : {}
options[:max] = 1
shift_tokens(*types << options).first
end

def pop_tokens(*types)
pop(*types).map { |token| build_token(token) }.flatten.compact
end

def shift_tokens(*types)
shift(*types).map { |token| build_token(token) }.flatten.compact
end

def pop_identifier(type, options = {})
pop_token(type, options).to_identifier
end

def pop_operator(options = {})
pop_token(*OPERATORS, options)
end

def pop_unary_operator(options = {})
pop_token(*UNARY_OPERATORS, options)
end
Expand All @@ -129,10 +101,6 @@ def pop_binary_operator(options = {})
pop_token(*BINARY_OPERATORS, options)
end

def pop_ternary_operators(options = {})
pop_tokens(*TERNARY_OPERATORS, options)
end

def pop_ternary_operator(options = {})
pop_token(*TERNARY_OPERATORS, options)
end
Expand All @@ -145,18 +113,14 @@ def pop_context
stack.context.get
end

def stack_ignore(*types, &block)
stack.ignore_types(*types, &block)
end

def build_token(token)
Ruby::Token.new(token.token, token.position, token.context) if token
end

def build_keyword(token)
klass = Ruby.const_get(token.token[0].upcase + token.token[1..-1])
klass.new(token, token.position, token.context)
rescue NameError
rescue NameError
Ruby::Keyword.new(token, token.position, token.context)
end

Expand Down
4 changes: 2 additions & 2 deletions lib/ripper/ruby_builder/events/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ def on_words_end(rdelim = nil)
def on_aref(target, args)
args ||= Ruby::ArgsList.new
args.ldelim ||= pop_token(:@lbracket, :left => target)
args.rdelim ||= shift_token(:@rbracket, :pass => true, :left => args.ldelim)
args.rdelim ||= pop_token(:@rbracket, :reverse => true, :pass => true, :left => args.ldelim)
Ruby::Call.new(target, nil, nil, args)
end

def on_aref_field(target, args)
args ||= Ruby::ArgsList.new
args.ldelim ||= pop_token(:@lbracket, :left => target)
args.rdelim ||= shift_token(:@rbracket, :pass => true, :left => args.ldelim)
args.rdelim ||= pop_token(:@rbracket, :reverse => true, :pass => true, :left => args.ldelim)
Ruby::Call.new(target, nil, nil, args)
end

Expand Down
32 changes: 7 additions & 25 deletions lib/ripper/ruby_builder/stack.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'core_ext/hash/delete_at'
require 'ripper/ruby_builder/queue'
require 'ripper/ruby_builder/context'

Expand All @@ -22,45 +23,26 @@ def push(token)
alias :_pop :pop
def pop(*types)
options = types.last.is_a?(::Hash) ? types.pop : {}
max, pass = options.delete(:max), options.delete(:pass)
@ignored, tokens = [], []
max, pass, revert = options.delete_at(:max, :pass, :reverse)
ignored, tokens = [], []
reverse! if revert

while !empty? && !(max && tokens.length >= max)
if types.include?(last.type) && matches?(options)
tokens << _pop()
elsif ignore?(last.type)
ignore!
elsif last.opener? && !pass
break
else
ignore!
ignored.unshift(_pop())
end
end

replace(self + @ignored)
replace(self + ignored)
reverse! if revert
tokens
end

def ignore?(type)
ignore_stack.flatten.include?(type)
end

def ignore!
@ignored.unshift(_pop())
end

def ignore_types(*types)
ignore_stack.push(types)
result = yield
ignore_stack.pop
result
end

protected

def ignore_stack
@ignore_stack ||= []
end

def matches?(conditions)
conditions.inject(true) do |result, (type, value)|
Expand Down
6 changes: 3 additions & 3 deletions lib/ripper/ruby_builder/token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class Token
attr_accessor :type, :token, :position, :context

def initialize(type = nil, token = nil, position = nil)
@type = normalize_type(type, token)
@type = token_type(type, token)
@token = token
@position = Ruby::Node::Position.new(position[0] - 1, position[1]) if position
@position = position if position
end

def newline?
Expand Down Expand Up @@ -63,7 +63,7 @@ def <=>(other)

protected

def normalize_type(type, token)
def token_type(type, token)
case type
when :@kw
:"@#{token.gsub(/\W/, '')}"
Expand Down

0 comments on commit 88727e6

Please sign in to comment.