class Cauldron::Solution::Composite
Attributes
operators[R]
Public Class Methods
new(children)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 7 def initialize(children) raise StandardError.new('inital value should be an array') unless children.kind_of?(Array) @operators = children end
Public Instance Methods
add_first_statement(statement)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 168 def add_first_statement(statement) [:stmts_add, [:stmts_new], statement] end
add_statement(statement, inner)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 172 def add_statement(statement, inner) [:stmts_add, inner, statement] end
add_statement_at(statement, point)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 35 def add_statement_at(statement, point) if point.length == 2 container = self.operators[0] #return self if container.length > 1 # TODO: Quick hack to get it working container << Tree::TreeNode.new('SASA', statement) elsif point.length == 1 operators << Tree::TreeNode.new('SASA', statement) else raise StandardError.new('Have not written code: '+point.inspect) end self end
clone_solution()
click to toggle source
# File lib/cauldron/solution/composite.rb, line 27 def clone_solution #self.clone tree_operators = operators.collect do |node| Tree::TreeNode.new('x', node.content.clone_statement) end Composite.new(tree_operators) end
end_points()
click to toggle source
# File lib/cauldron/solution/composite.rb, line 17 def end_points results = [] operators.each do |x| if x.content.branch? results << [0,x.children.length] end end results << [operators.length] end
insert_tracking(params)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 48 def insert_tracking(params) scope = Cauldron::Scope.new(params.clone) # TODO Might be useful # trace = TracePoint.new(:call) do |tp| # p [tp.lineno, tp.event, tp.raised_exception] # end # NEW: Implementation m = %Q{ def function(#{params.join(',')}) #{to_ruby(Cauldron::Scope.new(params.clone))} end } sexp = Ripper::SexpBuilder.new(m).parse rendered_code = Sorcerer.source(sexp, indent: true) caret = Cauldron::Caret.new rendered_code = Sorcerer.source(sexp, indent: true).gsub(/end/,"\nend").split("\n").reject(&:empty?).join("\n") # Generate tracking code with pending substitutions tracked_code = [] rendered_code.each_line do |line| #if line.match /end\s+/ if line.match /end/ tracked_code << Sorcerer.source(Ripper::SexpBuilder.new(Cauldron::Tracer.substitue_tracking).parse) #Sorcerer.source(Cauldron::Tracer.substitue_tracking) end tracked_code << line end sexp = Ripper::SexpBuilder.new(tracked_code.join("\n")).parse code_tracking = Sorcerer.source(sexp, indent: true) code_tracking.split("\n") current_line = -1 total_lines = 0 new_tracked_code = [] last_line = nil relative_line = 0 placeholder = nil point = [0,0] current_depth = 0 caret = Cauldron::Caret.new points = end_points code_tracking.split("\n").each do |line| if line.match /record/ depth = (line.match(/^(\s+)/)[0].length / 2) -1 if depth > current_depth relative_line = 0 end current_depth = depth new_tracked_code << last_line new_tracked_code << Sorcerer.source( Cauldron::Tracer.tracking(relative_line, depth, total_lines, points.shift) ) new_tracked_code << placeholder else total_lines += 1 unless line['='] placeholder = "#{'placeholder_'+rand(10000000000).to_s}" last_line = "#{placeholder} = "+line end if last_line if !last_line.match(/\s+end/).nil? || !last_line.match(/function/).nil? # || last_line.match /function/ last_line = nil placeholder = nil end end if line.match /end$/ unless line.strip == 'end' line = line.gsub(/end$/,'') end end new_tracked_code << line current_line += 1 end #total_lines += 1 end # NOTE: Keep this to debug before conversion of S-EXP sexp = Ripper::SexpBuilder.new(new_tracked_code.join("\n")).parse Cauldron::Tracer.new(sexp) end
record(example)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 12 def record(example) # TODO params passed twice - and example not used at all insert_tracking(example.params).process(example) end
reset_and_track(caret)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 143 def reset_and_track(caret) caret.return_depth(0) Cauldron::Tracer.tracking(caret.line, caret.current_depth, caret.total_lines) end
solution?(problems)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 176 def solution?(problems) o = Object.new m = %Q{ def function(#{problems.variables.join(',')}) #{to_ruby(problems.scope)} end } o.instance_eval(m) #o.function *problems.examples.first.arguments problems.all? do |example| o.function(*example.arguments) == example.response end # TODO: Remove this resque - it is just a temp rescue NoMethodError => e return false rescue NameError => e return false rescue TypeError => e return false end
successful?(problem)
click to toggle source
TODO Drop this method
# File lib/cauldron/solution/composite.rb, line 200 def successful?(problem) # # TODO track the parameters of the operator # operators.trace(problem) # # TODO For now just evalute the code # return true if problem[:arguments].first == problem[:response] # false pt = PryTester.new args = problem.arguments variables = problem.params #(0...args.length).collect {|x| 'var'+x.to_s} a = [ 'def function('+variables.join(',')+');'+self.to_ruby(variables)+"; end", 'function('+problem.arguments.collect {|x| to_programme(x) }.join(',')+')' ] res = pt.eval( ['def function('+variables.join(',')+');'+self.to_ruby(variables)+"; end", 'function('+problem.arguments.collect {|x| to_programme(x) }.join(',')+')'] ) problem.response == res end
to_programme(value)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 225 def to_programme(value) if value.kind_of?(String) return %Q{'#{value}'} end value.to_s end
to_ruby(scope)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 163 def to_ruby(scope) return '' if operators.empty? Sorcerer.source(to_sexp(scope)) end
to_sexp(scope=Cauldron::Scope.new)
click to toggle source
# File lib/cauldron/solution/composite.rb, line 148 def to_sexp(scope=Cauldron::Scope.new) res = operators.collect do |operator| #begin operator.content.to_ruby(scope, operator.children) # rescue NoMethodError => e # binding.pry # end end.join("\n") sexp = Ripper::SexpBuilder.new(res).parse return sexp end