Решение на Бонус задача: ArnoldC+- от Исмаил Алиджиков

Обратно към всички решения

Към профила на Исмаил Алиджиков

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 23 успешни тест(а)
  • 6 неуспешни тест(а)

Код

module ArnoldCPM
def self.printer=(printer)
@printer = printer
end
def self.totally_recall(&block)
ArnoldCPMInterpreter.new(@printer).execute(&block) if block_given?
end
class ArnoldCPMInterpreter
def initialize(printer)
@printer = printer
@scopes = [{}]
@condition = true
end
def execute(&block)
self.instance_eval &block if block_given?
end
def its_showtime
# Start main
end
def you_have_been_terminated
# End main
end
def talk_to_the_hand(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
@printer.print var.value if @condition
end
def get_to_the_chopper(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@variable_name = var.name if @condition
end
def here_is_my_invitation(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable = var if @condition
end
def enough_talk
if @is_in_function
append_to_method_body(__method__)
return
end
if @condition
scope = @scopes.last
scope[@variable_name] = @current_variable.value
end
end
def get_up(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value += var.value if @condition
end
def get_down(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value -= var.value if @condition
end
def youre_fired(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value *= var.value if @condition
end
def he_had_to_split(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value /= var.value if @condition
end
def i_lied
0
end
def no_problemo
1
end
def consider_that_a_divorce(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value == 0
end
def knock_knock(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value != 0
end
def let_off_some_steam_bennet(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = @current_variable.value > var.value ? 1 : 0
end
def you_are_not_you_you_are_me(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
if var.value.is_a? String
@current_variable.value = @current_variable == arg ? 1 : 0
else
@current_variable.value = @current_variable.value == var.value ? 1 : 0
end
end
def because_im_going_to_say_please(condition)
var = wrap_to_variable(condition)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@condition = var.value != 0 ? true : false
@scopes.push({})
end
def bull_shit
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = !@condition
end
def you_have_no_respect_for_logic
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = true
@scopes.pop
end
def listen_to_me_very_carefully(var)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
@is_in_inner_method = true
return
end
@is_in_function = true
@function_name = var.name
@params = []
@method_source = ''
end
def i_need_your_clothes_your_boots_and_your_motorcycle(var)
if @is_in_inner_method
append_to_method_body(__method__, var.name || var.value)
return
end
@params.push(var)
end
def give_these_people_air
# Do nothing
end
def ill_be_back(arg = 0)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
if @condition
@return_value = var.value
@has_returned = true
end
end
def hasta_la_vista_baby
if @is_in_inner_method
append_to_method_body(__method__)
@is_in_inner_method = false
return
end
current_scope = @scopes.last
current_scope[@function_name] = @method_source
@is_in_function = false
end
def get_your_ass_to_mars(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@is_non_void = true
@return_variable_name = var.name
end
def do_it_now(var, *args)
return if @has_returned
args.map! { |arg| wrap_to_variable(arg) }
method_args = args.map { |arg| arg.name || arg.value }
if @is_in_function
append_to_method_body(__method__, [var.name] + method_args)
return
end
execute_function(var, args)
@scopes.last[@return_variable_name] = @return_value if @is_non_void
@has_returned = false
end
def method_missing(name)
@scopes.reverse_each do |scope|
return Variable.new(name, scope[name]) if scope.key? name
end
Variable.new(name, nil)
end
private
def wrap_to_variable(arg)
(arg.is_a? Integer) ? Variable.new(nil, arg) : arg
end
def append_to_method_body(method_name, *args)
@method_source += "#{method_name} #{args.join(', ')}\n"
end
def execute_function(var, args)
current_scope = {}
@scopes.push(current_scope)
(0...@params.length).each do |i|
current_scope[@params[i].name] = args[i].value
end
instance_eval(var.value)
@scopes.pop
end
end
class Variable
attr_accessor :name, :value
def initialize(name, value)
@name = name
@value = value
end
def ==(other)
@name == other.name && @value == other.value
end
end
end

Лог от изпълнението

......F...FF....FF.........F.

Failures:

  1) ArnoldCPM can take functions as arguments
     Failure/Error: do_it_now _invoker, _forty_two_printer, 1
     NoMethodError:
       undefined method `value' for nil:NilClass
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:319:in `each'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:319:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):2:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:577:in `block (3 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:556:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  2) ArnoldCPM can calculate fibonacci(20) recursively
     Failure/Error: do_it_now _fibonacci, 20
     NoMethodError:
       undefined method `+' for nil:NilClass
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # (eval):22:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # (eval):17:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:753:in `block (3 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:714:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  3) ArnoldCPM can use closures in very convoluted ways
     Failure/Error: do_it_now _create_long_list, 10
     NoMethodError:
       undefined method `-' for nil:NilClass
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # (eval):3:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:323:in `execute_function'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:291:in `do_it_now'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:869:in `block (3 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:765:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  4) ArnoldCPM has algebra that can calculate modulo
     Failure/Error: i_let_him_go 3
     ArgumentError:
       wrong number of arguments (given 2, expected 1)
     # /tmp/d20170103-15620-1td8rg5/solution.rb:297:in `method_missing'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:122:in `block (4 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:118:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  5) ArnoldCPM has algebra that can chain multiple operations
     Failure/Error: i_let_him_go 4
     ArgumentError:
       wrong number of arguments (given 2, expected 1)
     # /tmp/d20170103-15620-1td8rg5/solution.rb:297:in `method_missing'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:140:in `block (4 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:136:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

  6) ArnoldCPM has branching mechanism that can nest if-else statements
     Failure/Error: talk_to_the_hand 44
       (Double "printer").print(44)
           expected: 0 times with arguments: (44)
           received: 1 time with arguments: (44)
     # /tmp/d20170103-15620-1td8rg5/solution.rb:40:in `talk_to_the_hand'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:420:in `block (4 levels) in <top (required)>'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `instance_eval'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:19:in `execute'
     # /tmp/d20170103-15620-1td8rg5/solution.rb:7:in `totally_recall'
     # /tmp/d20170103-15620-1td8rg5/spec.rb:408:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.0393 seconds
29 examples, 6 failures

Failed examples:

rspec /tmp/d20170103-15620-1td8rg5/spec.rb:540 # ArnoldCPM can take functions as arguments
rspec /tmp/d20170103-15620-1td8rg5/spec.rb:695 # ArnoldCPM can calculate fibonacci(20) recursively
rspec /tmp/d20170103-15620-1td8rg5/spec.rb:760 # ArnoldCPM can use closures in very convoluted ways
rspec /tmp/d20170103-15620-1td8rg5/spec.rb:113 # ArnoldCPM has algebra that can calculate modulo
rspec /tmp/d20170103-15620-1td8rg5/spec.rb:130 # ArnoldCPM has algebra that can chain multiple operations
rspec /tmp/d20170103-15620-1td8rg5/spec.rb:378 # ArnoldCPM has branching mechanism that can nest if-else statements

История (3 версии и 1 коментар)

Исмаил обнови решението на 29.12.2016 00:46 (преди почти 8 години)

+class Integer
+ def value
+ self
+ end
+end
+
+module ArnoldCPM
+ def self.printer=(printer)
+ @printer = printer
+ end
+
+ def self.totally_recall(&block)
+ ArnoldCPMInterpreter.new(@printer).execute(&block) if block_given?
+ end
+
+ class ArnoldCPMInterpreter
+ def initialize(printer)
+ @printer = printer
+
+ @scopes = [{}]
+ @condition = true
+ end
+
+ def execute(&block)
+ self.instance_eval &block if block_given?
+ end
+
+ def its_showtime
+ # Start main
+ end
+
+ def you_have_been_terminated
+ # End main
+ end
+
+ def talk_to_the_hand(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ return if @has_returned
+
+ @printer.print var.value if @condition
+ end
+
+ def get_to_the_chopper(var)
+ if @is_in_function
+ append_to_method_body(__method__, var.name)
+
+ return
+ end
+
+ @variable_name = var.name if @condition
+ end
+
+ def here_is_my_invitation(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable = var if @condition
+ end
+
+ def enough_talk
+ if @is_in_function
+ append_to_method_body(__method__)
+
+ return
+ end
+
+ if @condition
+ scope = @scopes.last
+ scope[@variable_name] = @current_variable.value
+ end
+ end
+
+ def get_up(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value += var.value if @condition
+ end
+
+ def get_down(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value -= var.value if @condition
+ end
+
+ def youre_fired(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value *= var.value if @condition
+ end
+
+ def he_had_to_split(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value /= var.value if @condition
+ end
+
+ def i_lied
+ 0
+ end
+
+ def no_problemo
+ 1
+ end
+
+ def consider_that_a_divorce(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value = var.value if @current_variable.value == 0
+ end
+
+ def knock_knock(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value = var.value if @current_variable.value != 0
+ end
+
+ def let_off_some_steam_bennet(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @current_variable.value = @current_variable.value > var.value ? 1 : 0
+ end
+
+ def you_are_not_you_you_are_me(arg)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ if arg.value.is_a? String
+ @current_variable.value = @current_variable == arg ? 1 : 0
+ else
+ @current_variable.value = @current_variable.value == arg.value ? 1 : 0
+ end
+ end
+
+ def because_im_going_to_say_please(condition)
+ var = wrap_to_variable(condition)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @condition = var.value != 0 ? true : false
+ @scopes.push({})
+ end
+
+ def bull_shit
+ if @is_in_function
+ append_to_method_body(__method__)
+
+ return
+ end
+
+ @condition = !@condition
+ end
+
+ def you_have_no_respect_for_logic
+ if @is_in_function
+ append_to_method_body(__method__)
+
+ return
+ end
+
+ @condition = true
+ @scopes.pop
+ end
+
+ def listen_to_me_very_carefully(var)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+ @is_in_inner_method = true
+
+ return
+ end
+
+ @is_in_function = true
+ @function_name = var.name
+ @params = []
+ @method_source = ''
+ end
+
+ def i_need_your_clothes_your_boots_and_your_motorcycle(var)
+ if @is_in_inner_method
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ @params.push(var)
+ end
+
+ def give_these_people_air
+ # Do nothing
+ end
+
+ def ill_be_back(arg = 0)
+ var = wrap_to_variable(arg)
+ if @is_in_function
+ append_to_method_body(__method__, var.name || var.value)
+
+ return
+ end
+
+ return if @has_returned
+
+ if @condition
+ @return_value = var.value
+ @has_returned = true
+ end
+ end
+
+ def hasta_la_vista_baby
+ if @is_in_inner_method
+ append_to_method_body(__method__)
+ @is_in_inner_method = false
+
+ return
+ end
+
+ current_scope = @scopes.last
+ current_scope[@function_name] = @method_source
+
+ @is_in_function = false
+ end
+
+ def get_your_ass_to_mars(var)
+ if @is_in_function
+ append_to_method_body(__method__, var.name)
+
+ return
+ end
+
+ @is_non_void = true
+ @return_variable_name = var.name
+ end
+
+ def do_it_now(var, *args)
+ if @is_in_function
+ append_to_method_body(__method__, [var.name] + args)
+
+ return
+ end
+
+ execute_function(var, args)
+
+ if @is_non_void
+ scope = @scopes.last
+ scope[@return_variable_name] = @return_value
+ end
+
+ @has_returned = false
+ end
+
+ def method_missing(name)
+ @scopes.reverse_each do |scope|
+ return Variable.new(name, scope[name]) if scope.key? name
+ end
+
+ Variable.new(name, nil)
+ end
+
+ private
+
+ def wrap_to_variable(arg)
+ if arg.is_a? Integer
+ Variable.new(nil, arg)
+ else
+ arg
+ end
+ end
+
+ def append_to_method_body(method_name, *args)
+ @method_source += "#{method_name} #{args.join(', ')}\n"
+ end
+
+ def execute_function(var, args)
+ current_scope = {}
+ @scopes.push(current_scope)
+
+ (0...@params.length).each do |i|
+ current_scope[@params[i].name] = args[i].value
+ end
+
+ instance_eval(var.value)
+
+ @scopes.pop
+ end
+ end
+
+ class Variable
+ attr_accessor :name, :value
+
+ def initialize(name, value)
+ @name = name
+ @value = value
+ end
+
+ def ==(other)
+ @name == other.name && @value == other.value
+ end
+ end
+end

Исмаил обнови решението на 29.12.2016 00:55 (преди почти 8 години)

-class Integer
- def value
- self
- end
-end
-
module ArnoldCPM
def self.printer=(printer)
@printer = printer
end
def self.totally_recall(&block)
ArnoldCPMInterpreter.new(@printer).execute(&block) if block_given?
end
class ArnoldCPMInterpreter
def initialize(printer)
@printer = printer
@scopes = [{}]
@condition = true
end
def execute(&block)
self.instance_eval &block if block_given?
end
def its_showtime
# Start main
end
def you_have_been_terminated
# End main
end
def talk_to_the_hand(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
@printer.print var.value if @condition
end
def get_to_the_chopper(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@variable_name = var.name if @condition
end
def here_is_my_invitation(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable = var if @condition
end
def enough_talk
if @is_in_function
append_to_method_body(__method__)
return
end
if @condition
scope = @scopes.last
scope[@variable_name] = @current_variable.value
end
end
def get_up(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value += var.value if @condition
end
def get_down(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value -= var.value if @condition
end
def youre_fired(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value *= var.value if @condition
end
def he_had_to_split(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value /= var.value if @condition
end
def i_lied
0
end
def no_problemo
1
end
def consider_that_a_divorce(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value == 0
end
def knock_knock(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value != 0
end
def let_off_some_steam_bennet(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = @current_variable.value > var.value ? 1 : 0
end
def you_are_not_you_you_are_me(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
- if arg.value.is_a? String
+ if var.value.is_a? String
@current_variable.value = @current_variable == arg ? 1 : 0
else
- @current_variable.value = @current_variable.value == arg.value ? 1 : 0
+ @current_variable.value = @current_variable.value == var.value ? 1 : 0
end
end
def because_im_going_to_say_please(condition)
var = wrap_to_variable(condition)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@condition = var.value != 0 ? true : false
@scopes.push({})
end
def bull_shit
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = !@condition
end
def you_have_no_respect_for_logic
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = true
@scopes.pop
end
def listen_to_me_very_carefully(var)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
@is_in_inner_method = true
return
end
@is_in_function = true
@function_name = var.name
@params = []
@method_source = ''
end
def i_need_your_clothes_your_boots_and_your_motorcycle(var)
if @is_in_inner_method
append_to_method_body(__method__, var.name || var.value)
return
end
@params.push(var)
end
def give_these_people_air
# Do nothing
end
def ill_be_back(arg = 0)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
if @condition
@return_value = var.value
@has_returned = true
end
end
def hasta_la_vista_baby
if @is_in_inner_method
append_to_method_body(__method__)
@is_in_inner_method = false
return
end
current_scope = @scopes.last
current_scope[@function_name] = @method_source
@is_in_function = false
end
def get_your_ass_to_mars(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@is_non_void = true
@return_variable_name = var.name
end
def do_it_now(var, *args)
if @is_in_function
append_to_method_body(__method__, [var.name] + args)
return
end
execute_function(var, args)
if @is_non_void
scope = @scopes.last
scope[@return_variable_name] = @return_value
end
@has_returned = false
end
def method_missing(name)
@scopes.reverse_each do |scope|
return Variable.new(name, scope[name]) if scope.key? name
end
Variable.new(name, nil)
end
private
def wrap_to_variable(arg)
if arg.is_a? Integer
Variable.new(nil, arg)
else
arg
end
end
def append_to_method_body(method_name, *args)
@method_source += "#{method_name} #{args.join(', ')}\n"
end
def execute_function(var, args)
current_scope = {}
@scopes.push(current_scope)
(0...@params.length).each do |i|
- current_scope[@params[i].name] = args[i].value
+ arg = wrap_to_variable(args[i])
+ current_scope[@params[i].name] = arg.value
end
instance_eval(var.value)
@scopes.pop
end
end
class Variable
attr_accessor :name, :value
def initialize(name, value)
@name = name
@value = value
end
def ==(other)
@name == other.name && @value == other.value
end
end
end

Исмаил обнови решението на 29.12.2016 16:02 (преди почти 8 години)

module ArnoldCPM
def self.printer=(printer)
@printer = printer
end
def self.totally_recall(&block)
ArnoldCPMInterpreter.new(@printer).execute(&block) if block_given?
end
class ArnoldCPMInterpreter
def initialize(printer)
@printer = printer
@scopes = [{}]
@condition = true
end
def execute(&block)
self.instance_eval &block if block_given?
end
def its_showtime
# Start main
end
def you_have_been_terminated
# End main
end
def talk_to_the_hand(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
@printer.print var.value if @condition
end
def get_to_the_chopper(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@variable_name = var.name if @condition
end
def here_is_my_invitation(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable = var if @condition
end
def enough_talk
if @is_in_function
append_to_method_body(__method__)
return
end
if @condition
scope = @scopes.last
scope[@variable_name] = @current_variable.value
end
end
def get_up(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value += var.value if @condition
end
def get_down(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value -= var.value if @condition
end
def youre_fired(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value *= var.value if @condition
end
def he_had_to_split(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value /= var.value if @condition
end
def i_lied
0
end
def no_problemo
1
end
def consider_that_a_divorce(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value == 0
end
def knock_knock(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = var.value if @current_variable.value != 0
end
def let_off_some_steam_bennet(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@current_variable.value = @current_variable.value > var.value ? 1 : 0
end
def you_are_not_you_you_are_me(arg)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
if var.value.is_a? String
@current_variable.value = @current_variable == arg ? 1 : 0
else
@current_variable.value = @current_variable.value == var.value ? 1 : 0
end
end
def because_im_going_to_say_please(condition)
var = wrap_to_variable(condition)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
@condition = var.value != 0 ? true : false
@scopes.push({})
end
def bull_shit
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = !@condition
end
def you_have_no_respect_for_logic
if @is_in_function
append_to_method_body(__method__)
return
end
@condition = true
@scopes.pop
end
def listen_to_me_very_carefully(var)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
@is_in_inner_method = true
return
end
@is_in_function = true
@function_name = var.name
@params = []
@method_source = ''
end
def i_need_your_clothes_your_boots_and_your_motorcycle(var)
if @is_in_inner_method
append_to_method_body(__method__, var.name || var.value)
return
end
@params.push(var)
end
def give_these_people_air
# Do nothing
end
def ill_be_back(arg = 0)
var = wrap_to_variable(arg)
if @is_in_function
append_to_method_body(__method__, var.name || var.value)
return
end
return if @has_returned
if @condition
@return_value = var.value
@has_returned = true
end
end
def hasta_la_vista_baby
if @is_in_inner_method
append_to_method_body(__method__)
@is_in_inner_method = false
return
end
current_scope = @scopes.last
current_scope[@function_name] = @method_source
@is_in_function = false
end
def get_your_ass_to_mars(var)
if @is_in_function
append_to_method_body(__method__, var.name)
return
end
@is_non_void = true
@return_variable_name = var.name
end
def do_it_now(var, *args)
+ return if @has_returned
+
+ args.map! { |arg| wrap_to_variable(arg) }
+ method_args = args.map { |arg| arg.name || arg.value }
+
if @is_in_function
- append_to_method_body(__method__, [var.name] + args)
+ append_to_method_body(__method__, [var.name] + method_args)
return
end
execute_function(var, args)
- if @is_non_void
- scope = @scopes.last
- scope[@return_variable_name] = @return_value
- end
-
+ @scopes.last[@return_variable_name] = @return_value if @is_non_void
@has_returned = false
end
def method_missing(name)
@scopes.reverse_each do |scope|
return Variable.new(name, scope[name]) if scope.key? name
end
Variable.new(name, nil)
end
private
def wrap_to_variable(arg)
- if arg.is_a? Integer
- Variable.new(nil, arg)
- else
- arg
- end
+ (arg.is_a? Integer) ? Variable.new(nil, arg) : arg
end
def append_to_method_body(method_name, *args)
@method_source += "#{method_name} #{args.join(', ')}\n"
end
def execute_function(var, args)
current_scope = {}
@scopes.push(current_scope)
(0...@params.length).each do |i|
- arg = wrap_to_variable(args[i])
- current_scope[@params[i].name] = arg.value
+ current_scope[@params[i].name] = args[i].value
end
instance_eval(var.value)
@scopes.pop
end
end
class Variable
attr_accessor :name, :value
def initialize(name, value)
@name = name
@value = value
end
def ==(other)
@name == other.name && @value == other.value
end
end
end

Като цяло добре, няколко забележки:

  • ArnoldCPMInterpreter прави всичко. Може би нямаше да е лошо да отделиш поне method_missing магията някъде.
  • Можеше да DRY-неш някои неща с няколко помощни метода/обекта. Например преобразуването към/от "булева" стойност.
  • Може да погледнеш нашето решение ако ти е интересно как би могъл да избегнеш if @is_in_function ....
  • Поне единия if block_given? е излишен.