Исмаил обнови решението на 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