Class: Class::DecisionTable
- Inherits:
-
Array
- Object
- Array
- Class::DecisionTable
- Defined in:
- lib/redparse/decisiontree.rb
Overview
attr_accessor :member_range
def member_num; member_range.first end
Instance Method Summary collapse
- #c_ref_to(obj) ⇒ Object
- #compile ⇒ Object
- #compile_to_c ⇒ Object
- #compile_to_ruby ⇒ Object
- #decide(klass, member_ranges) ⇒ Object
- #decide_from_classid(x) ⇒ Object
-
#initialize(fh, class2result) ⇒ DecisionTable
constructor
A new instance of DecisionTable.
- #inspect ⇒ Object
- #pretty_print(q) ⇒ Object
- #ref_to(obj) ⇒ Object
- #to_c(low = 0, high = self.size-1) ⇒ Object
-
#to_ruby(low = 0, high = results.size-1) ⇒ Object
def self.overlapping_class_range_list(classes,member_ranges) classes=sort_by_inheiritance(*classes) return classes,classes.map{|k| member_ranges } end.
Constructor Details
#initialize(fh, class2result) ⇒ DecisionTable
Returns a new instance of DecisionTable.
158 159 160 161 162 163 164 |
# File 'lib/redparse/decisiontree.rb', line 158 def initialize(fh,class2result) @hierarchy=fh classes,ranges=fh.nonoverlapping_results_range_list(class2result) newme=[] classes.each_with_index{|k,i| newme.push k,ranges[i]} replace newme end |
Instance Method Details
#c_ref_to(obj) ⇒ Object
301 302 303 304 305 306 |
# File 'lib/redparse/decisiontree.rb', line 301 def c_ref_to(obj) @dont_delete_yet||=[] @dont_delete_yet << obj #keep a real ref around so that weak ref in inline c code #keeps pointing to the right object. return "(VALUE)0x#{obj.object_id.to_s(16)}L" end |
#compile ⇒ Object
331 332 333 334 335 336 337 |
# File 'lib/redparse/decisiontree.rb', line 331 def compile begin compile_to_c rescue Exception compile_to_ruby end end |
#compile_to_c ⇒ Object
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/redparse/decisiontree.rb', line 312 def compile_to_c huh "this prolly won't work cause inline c code has to be in an actual class" huh 'so,, need to rewrite as temporary class (module?) for the method to live in... then delegate to that' begin require 'rubygems' rescue Exception end require 'inline' class << self inline{|write| write.c %{ static VALUE decide_from_classid(unsigned x){ #{to_c} } } } end end |
#compile_to_ruby ⇒ Object
308 309 310 |
# File 'lib/redparse/decisiontree.rb', line 308 def compile_to_ruby eval " def self.decide_from_classid(x)\n#{to_ruby}\n end" end |
#decide(klass, member_ranges) ⇒ Object
176 177 178 |
# File 'lib/redparse/decisiontree.rb', line 176 def decide(klass,member_ranges) decide_from_classid(member_ranges[klass]) end |
#decide_from_classid(x) ⇒ Object
179 180 181 182 183 184 185 186 187 188 |
# File 'lib/redparse/decisiontree.rb', line 179 def decide_from_classid(x) huh broken if x.send op, val use=iftrue else use=iffalse end return use.decide_from_classid(x) if DecisionTree===use return use end |
#inspect ⇒ Object
167 168 169 |
# File 'lib/redparse/decisiontree.rb', line 167 def inspect "Class::DecisionTable"+super end |
#pretty_print(q) ⇒ Object
170 171 172 173 174 |
# File 'lib/redparse/decisiontree.rb', line 170 def pretty_print(q) q.group(1, 'Class::DecisionTable[', ']') { q.seplist(self) {|v| q.pp v } } end |
#ref_to(obj) ⇒ Object
294 295 296 297 298 299 |
# File 'lib/redparse/decisiontree.rb', line 294 def ref_to obj @ruby_refs= defined?(@ruby_refs) ? @ruby_refs+1 : 1 result="@ruby_ref_#{@ruby_refs}" instance_variable_set result, obj return result end |
#to_c(low = 0, high = self.size-1) ⇒ Object
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/redparse/decisiontree.rb', line 278 def to_c(low=0,high=self.size-1) #if downto a list of just 1 possibility #then return the corresponding result return "return "+c_ref_to(self[1+2*low]) if high==low low<high or fail mid=((high+low+0.5)/2).to_i #midpoint of remaining list mid_class_id=self[2*mid].first " if (x<#{mid_class_id}) #{to_c(low,mid-1)}; else #{to_c(mid,high)}; " end |
#to_ruby(low = 0, high = results.size-1) ⇒ Object
def self.overlapping_class_range_list(classes,member_ranges)
classes=sort_by_inheiritance(*classes)
return classes,classes.map{|k| member_ranges[k] }
end
def self.nonoverlapping_class_range_list(classes,member_ranges)
classes,ranges=overlapping_class_range_list(classes,member_ranges)
myclasses=[];myranges=[]
classes_index_stack=[]
classes.each_with_index{|k,i|
x=ranges[i].first
if i>0 and ranges[i-1]===x #if overlaps previous range
classes_index_stack.push i-1 #add to the stack of saved-up ranges
else
#pop off old superclasses that no longer apply to k,
#adding regions for their last fragment as we go along
until classes_index_stack.empty?
current_range=ranges[classes_index_stack.last]
break if current_range===x
ending=classes_index_stack.pop
done_thru=myranges.last.last
current_end=current_range.last
unless done_thru==current_end
myranges<<(done_thru+1..current_end)
myclasses<<classes[ending]
end
end
end
#if a gap between (sub-?)classes, emit a fragment for the appropriate super (or default to nil)
next_expected=myranges.last.last+1
if next_expected!=x #was: (ranges[i].huh)
myclasses<< (classes[classes_index_stack.last] unless classes_index_stack.empty?)
myranges<<(next_expected..x-1)
end
#emit initial fragment for current class
myclasses<<k
myranges<<(x..[ranges[i+1].first-1,ranges[i].last].min)
}
return myclasses, myranges
end
def self.nonoverlapping_results_range_list(class2results,member_ranges)
classes=class2results.keys
classes,ranges=nonoverlapping_class_range_list(classes,member_ranges)
return classes.map{|k| class2results[k] }, ranges
end
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/redparse/decisiontree.rb', line 261 def to_ruby(low=0,high=results.size-1) #if downto a list of just 1 possibility #then return the corresponding result return ref_to self[1+2*low] if high==low low<high or fail mid=((high+low+0.5)/2).to_i #midpoint of remaining list mid_class_id=self[2*mid].first " if (x<#{mid_class_id}) #{to_ruby(low,mid-1)}; else #{to_ruby(mid,high)}; end " end |