Class: DSL

Inherits:
Object show all
Defined in:
ext/ripper/tools/dsl.rb

Constant Summary collapse

TAG_PATTERN =
/(?><[a-zA-Z0-9_]+>)/.source
NAME_PATTERN =
/(?>\$|\d+|[a-zA-Z_][a-zA-Z0-9_]*|\[[a-zA-Z_.][-a-zA-Z0-9_.]*\])(?>(?:\.|->)[a-zA-Z_][a-zA-Z0-9_]*)*/.source
NOT_REF_PATTERN =
/(?>\#.*|[^\"$@]*|"(?>\\.|[^\"])*")/.source

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, options) ⇒ DSL

Returns a new instance of DSL.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'ext/ripper/tools/dsl.rb', line 21

def initialize(code, options)
  @events = {}
  @error = options.include?("error")
  @brace = options.include?("brace")
  if options.include?("final")
    @final = "p->result"
  else
    @final = (options.grep(/\A\$#{NAME_PATTERN}\z/o)[0] || "$$")
  end
  @vars = 0

  # struct parser_params *p
  p = p = "p"

  @code = ""
  code = code.gsub(%r[\G#{NOT_REF_PATTERN}\K[$@]#{TAG_PATTERN}?#{NAME_PATTERN}]o, '"\&"')
  @last_value = eval(code)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(event, *args) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'ext/ripper/tools/dsl.rb', line 77

def method_missing(event, *args)
  if event.to_s =~ /!\z/
    add_event(event, args)
  elsif args.empty? and /\Aid[A-Z_]/ =~ event.to_s
    event
  else
    "#{ event }(#{ args.join(", ") })"
  end
end

Instance Attribute Details

#eventsObject (readonly)

Returns the value of attribute events.



40
41
42
# File 'ext/ripper/tools/dsl.rb', line 40

def events
  @events
end

Class Method Details

.const_missing(name) ⇒ Object



87
88
89
# File 'ext/ripper/tools/dsl.rb', line 87

def self.const_missing(name)
  name
end

Instance Method Details

#add_event(event, args, qundef_check = false) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'ext/ripper/tools/dsl.rb', line 62

def add_event(event, args, qundef_check = false)
  event = event.to_s.sub(/!\z/, "")
  @events[event] = args.size
  vars = []
  args.each do |arg|
    vars << v = new_var
    @code << "#{ v }=#{ arg };"
  end
  v = new_var
  d = "dispatch#{ args.size }(#{ [event, *vars].join(",") })"
  d = "#{ vars.last }==Qundef ? #{ vars.first } : #{ d }" if qundef_check
  @code << "#{ v }=#{ d };"
  v
end

#generateObject



46
47
48
49
50
51
52
# File 'ext/ripper/tools/dsl.rb', line 46

def generate
  s = "#@code#@final=#@last_value;"
  s = "{VALUE #{ (1..@vars).map {|v| "v#{ v }" }.join(",") };#{ s }}" if @vars > 0
  s << "ripper_error(p);" if @error
  s = "{#{ s }}" if @brace
  "\t\t\t#{s}"
end

#new_varObject



54
55
56
# File 'ext/ripper/tools/dsl.rb', line 54

def new_var
  "v#{ @vars += 1 }"
end

#opt_event(event, default, addend) ⇒ Object



58
59
60
# File 'ext/ripper/tools/dsl.rb', line 58

def opt_event(event, default, addend)
  add_event(event, [default, addend], true)
end