class Class::DecisionTable
attr_accessor :member_range def member_num; member_range.first end
Public Class Methods
new(fh,class2result)
click to toggle source
# 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
Also aliased as: []
Public Instance Methods
c_ref_to(obj)
click to toggle source
# 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()
click to toggle source
# File lib/redparse/decisiontree.rb, line 331 def compile begin compile_to_c rescue Exception compile_to_ruby end end
compile_to_c()
click to toggle source
# 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()
click to toggle source
# 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)
click to toggle source
# File lib/redparse/decisiontree.rb, line 176 def decide(klass,member_ranges) decide_from_classid(member_ranges[klass]) end
decide_from_classid(x)
click to toggle source
# 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()
click to toggle source
Calls superclass method
# File lib/redparse/decisiontree.rb, line 167 def inspect "Class::DecisionTable"+super end
pretty_print(q)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
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
# 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