Class: CappRuby::RubyBuilder::CappIseq

Inherits:
Object
  • Object
show all
Defined in:
lib/cappruby/ruby_builder.rb

Instance Method Summary collapse

Constructor Details

#initialize(type) ⇒ CappIseq

Returns a new instance of CappIseq.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/cappruby/ruby_builder.rb', line 37

def initialize(type)
  # iseq type
  @type = type
  # names => minimixed names (i.e. letters)
  @local_names = { }
  # same, for args
  @arg_names = { }
  # has a value, other than nil, of the str used to set the block param
  # e.g. def method(&adam)' end ... this will be "adam", incase we 
  # reference it. The block always points to _$, whether we name it or not
  @block_name = nil
  # current to use for minimized. 'a' is always self, so we start there
  # and increment one time for every new local in context.
  @local_current = 'a'
  # Also, if type is a method, then we need room for a selector aswell:
  if type == RubyBuilder::ISEQ_TYPE_METHOD
    @local_current = @local_current.next
  end
  
  
  # to store code strings
  @code = []
end

Instance Method Details

#finalizeObject

finalizes, as described above



93
94
95
96
97
# File 'lib/cappruby/ruby_builder.rb', line 93

def finalize
  if @type == RubyBuilder::ISEQ_TYPE_BLOCK
    @parent_iseq.local_current =  @local_current
  end
end

#local_currentObject



65
66
67
# File 'lib/cappruby/ruby_builder.rb', line 65

def local_current
  @local_current
end

#local_current=(s) ⇒ Object



69
70
71
# File 'lib/cappruby/ruby_builder.rb', line 69

def local_current=(s)
  @local_current = s
end

#lookup_local(str) ⇒ Object

looks u; the local name “str”. This checks method arguments as well as local variables defined. If we have the local, then the string version of the minimized name is returned (e.g. _a, _b.…. etc), or if we do not have it, then nil is returned.

Also of note, this also checks if the str is the name of the block that was declared (if a method). A block &block is not an arg or a local, but can be referecenced if declared as a method “argument”. These are stored as the local var _$, if present.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/cappruby/ruby_builder.rb', line 108

def lookup_local(str)
  if @local_names.has_key? str
    @local_names[str]
  elsif @arg_names.has_key? str
    @arg_names[str]
  elsif @block_name
    "_$"
  else
    if @type == RubyBuilder::ISEQ_TYPE_BLOCK
      return @parent_iseq.lookup_local(str)
    end
    # if we are a block, check parent...
    nil
  end
end

#parent_iseq=(other) ⇒ Object

When we set this, if we are a blcok, then we need to set our parents to be what ours finishes at. This avoids clashing local var names.

Doing it this way avoids us including these vars, declared in the block as vars in the method. they are vas just for the block.



84
85
86
87
88
89
90
# File 'lib/cappruby/ruby_builder.rb', line 84

def parent_iseq=(other)
  @parent_iseq = other
  
  if @type == RubyBuilder::ISEQ_TYPE_BLOCK
    @local_current = other.local_current
  end
end

#push_arg_name(str) ⇒ Object

push arg name, and returns the “minimized version”



125
126
127
128
129
# File 'lib/cappruby/ruby_builder.rb', line 125

def push_arg_name(str)
  @local_current = @local_current.next
  @arg_names[str] = "_#{@local_current}"
  "_#{@local_current}"
end

#push_block_name(str) ⇒ Object

set the block name, if present



139
140
141
142
# File 'lib/cappruby/ruby_builder.rb', line 139

def push_block_name(str)
  @block_name = str
  "_$"
end

#push_local_name(str) ⇒ Object

push local name, and returns the “minimized version”



132
133
134
135
136
# File 'lib/cappruby/ruby_builder.rb', line 132

def push_local_name(str)
  @local_current = @local_current.next
  @local_names[str] = "_#{@local_current}"
  "_#{@local_current}"
end

#to_sObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/cappruby/ruby_builder.rb', line 144

def to_s
  r = ""
  # function should accept self. if a method type, then accept "sel" for
  # selector, if block, dont add self, just args. top and class also 
  # accept just "self" - self is always _a
  # puts @code
  case @type
  when RubyBuilder::ISEQ_TYPE_TOP
    # _a is self (top self)
    r << "function(_a"
  when RubyBuilder::ISEQ_TYPE_METHOD
    # _a is self, _b is the selector
    r << "function(_a,_b"
    @arg_names.each_value { |v| r << ",#{v}" }
  when RubyBuilder::ISEQ_TYPE_CLASS
    # _a is self (the class just created/modified)
    r << "function(_a"
  when RubyBuilder::ISEQ_TYPE_BLOCK
    # no self, just args etc..
    r << "function("
    r << @arg_names.each_value.to_a.join(",")
  else
    abort "erm, unknwon iseq type"
  end
  
  r << "){"
  # locals
  if @local_names.length > 0
    r << "var #{@local_names.each_value.to_a.join(", ")};"
  end
  
  r << "#{@code.join("")}}"
  
  r
end

#typeObject



61
62
63
# File 'lib/cappruby/ruby_builder.rb', line 61

def type
  @type
end

#write(str) ⇒ Object



73
74
75
# File 'lib/cappruby/ruby_builder.rb', line 73

def write(str)
  @code << str
end