Добромира обнови решението на 29.12.2016 17:46 (преди почти 8 години)
+module ArnoldCPM
+ module DSL
+ def self.conditionalize(meth)
+ orig_meth = "#{meth}_unconditionalized"
+ alias_method orig_meth, meth
+
+ define_method(meth) do |*args, &block|
+ return if @skip_stack.any? { |s| s == true }
+
+ l = -> { public_send(orig_meth, *args, &block) }
+
+ @definng_fn ? @defining_fn.push(l) : l.call
+ end
+ end
+
+ def i_lied
+ 0
+ end
+
+ def value_of(int_or_var)
+ int_or_var.is_a?(Integer) ? int_or_var : int_or_var[:value]
+ end
+
+ # TODO
+ def its_showtime
+ @skip_stack = []
+ end
+
+ def you_have_been_terminated
+ @local_store = []
+ end
+
+ def get_to_the_chopper(var_data)
+ @variable_for_assign = var_data[:name]
+ end
+
+ def here_is_my_invitation(number)
+ @variable_store[@variable_for_assign] = number
+ end
+
+ def youre_fired(number)
+ @variable_store[@variable_for_assign] *= value_of(number)
+ end
+
+ def get_up(number)
+ @variable_store[@variable_for_assign] += value_of(number)
+ end
+
+ def get_down(number)
+ @variable_store[@variable_for_assign] -= value_of(number)
+ end
+
+ def he_had_to_split(number)
+ @variable_store[@variable_for_assign] /= value_of(number)
+ end
+
+ def i_let_him_go(number)
+ @variable_store[@variable_for_assign] %= value_of(number)
+ end
+
+ def let_off_some_steam_bennet(var)
+ @variable_store[@variable_for_assign] > value_of(var)
+ end
+
+ def you_are_not_you_you_are_me(var)
+ @variable_store[@variable_for_assign] == value_of(var)
+ end
+
+ def enough_talk
+ end
+
+ def talk_to_the_hand(number_or_var_data)
+ number = number_or_var_data
+ number = number[:value] if number.is_a?(Hash)
+ @printer.print number
+ end
+
+ def because_im_going_to_say_please(cond)
+ l = -> { @skip_stack.unshift(value_of(cond) == 0) }
+ @defining_fn ? @defining_fn.push(l) : l.call
+ end
+
+ def bull_shit
+ l = -> { @skip_stack[0] = !@skip_stack[0] }
+ @defining_fn ? @defining_fn.push(l) : l.call
+ end
+
+ def consider_that_a_divorce(var)
+ @variable_store[@variable_for_assign] |= value_of(var)
+ end
+
+ def knock_knock(var)
+ @variable_store[@variable_for_assign] &= value_of(var)
+ end
+
+ def you_have_no_respect_for_logic
+ l = -> { @skip_stack.shift }
+ @defining_fn ? @defining_fn.push(l) : l.call
+ end
+
+ def listen_to_me_very_carefully(var)
+ @defining_fn = []
+ @variable_store[var[:name]] = @defining_fn
+ @local_store = []
+ end
+
+ def hasta_la_vista_baby
+ return if @skip_stack.any? { |s| s == true }
+ @defining_fn = nil
+ end
+
+ def do_it_now(var)
+ var[:value].each { |l| l.call }
+ end
+
+ def give_these_people_air
+ end
+
+ def ill_be_back(var)
+ @variable_store[@return_target] = value_of(var)
+ end
+
+ def get_your_ass_to_mars(var)
+ @return_target = var[:name]
+ end
+
+ def i_need_your_clothes_your_boots_and_your_motorcycle(number)
+
+ end
+
+ conditionalize :value_of
+ conditionalize :get_to_the_chopper
+ conditionalize :here_is_my_invitation
+ conditionalize :youre_fired
+ conditionalize :get_up
+ conditionalize :get_down
+ conditionalize :he_had_to_split
+ conditionalize :i_let_him_go
+ conditionalize :let_off_some_steam_bennet
+ conditionalize :you_are_not_you_you_are_me
+ conditionalize :enough_talk
+ conditionalize :talk_to_the_hand
+ conditionalize :listen_to_me_very_carefully
+ conditionalize :do_it_now
+ end
+end
+
+module ArnoldCPM
+ extend ArnoldCPM::DSL
+
+ def self.printer=(value)
+ @printer = value
+ end
+
+ def self.totally_recall(&block)
+ @variable_store = {}
+ @skip_stack = []
+ define_singleton_method(:_recall, block)
+ _recall
+ end
+
+ def self.method_missing(name, *_params, &_block)
+ { name: name, value: @variable_store[name] }
+ end
+end
+
+ArnoldCPM.printer = Kernel