Решение на Четвърта задача от Кристиан Ташков

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

Към профила на Кристиан Ташков

Резултати

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

Код

module Asm
class << self
def asm(&block)
assembly = Assembly.new
assembly.instance_eval(&block)
assembly.run
end
end
end
module BasicInstructions
def mov_exec(args)
set_register_value(args[0], args[1])
end
def inc_exec(args)
args[1] = args[1] || 1
old_value = get_register_value(args[0])
set_register_value(args[0], old_value + get_real_value(args[1]))
end
def dec_exec(args)
args[1] = args[1] || 1
old_value = get_register_value(args[0])
set_register_value(args[0], old_value - get_real_value(args[1]))
end
def cmp_exec(args)
@last_cmp = get_register_value(args[0]) <=> get_real_value(args[1])
end
end
module JumpInstructions
def jmp_exec(args)
if(args[0].is_a? String)
@current_instruction = @labels[args[0]]
else
@current_instruction = args[0]
end
end
def je_exec(args)
jmp_exec(args) if @last_cmp.zero?
end
def jne_exec(args)
jmp_exec(args) unless @last_cmp.zero?
end
def jl_exec(args)
jmp_exec(args) if @last_cmp < 0
end
def jle_exec(args)
jmp_exec(args) if @last_cmp <= 0
end
def jg_exec(args)
jmp_exec(args) if @last_cmp > 0
end
def jge_exec(args)
jmp_exec(args) if @last_cmp >= 0
end
end
module Registers
def ax
:ax
end
def bx
:bx
end
def cx
:cx
end
def dx
:dx
end
def get_register_value(register)
instance_variable_get("@#{register.to_s}")
end
def set_register_value(register, value)
instance_variable_set("@#{register.to_s}", get_real_value(value))
end
end
class Instruction
attr_reader :name
attr_reader :args
def initialize(name, args)
@name = name
@args = args
end
end
class Assembly
include BasicInstructions
include JumpInstructions
include Registers
VALID_INSTRUCTIONS = [:mov, :inc, :dec, :cmp, :jmp, :je, :jl, :jle, :jg, :jge, :jne]
def initialize
@ax, @bx, @cx, @dx = 0, 0, 0, 0
@instructions = {}
@labels = {}
end
def method_missing(name, *args, &block)
if(name == :label)
@labels[args[0]] = @instructions.count
elsif(VALID_INSTRUCTIONS.include? name)
@instructions[@instructions.count] = Instruction.new(name, args)
else
name.to_s
end
end
def get_real_value(value)
if(value.is_a? Symbol)
get_register_value(value)
else
value
end
end
def run
@current_instruction = 0
while @current_instruction < @instructions.count
instruction = @instructions[@current_instruction]
@current_instruction += 1
send("#{instruction.name}_exec", instruction.args)
end
[@ax, @bx, @cx, @dx]
end
end

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

........

Finished in 0.00839 seconds
8 examples, 0 failures

История (2 версии и 0 коментара)

Кристиан обнови решението на 15.01.2014 12:31 (преди почти 11 години)

+module Asm
+ class << self
+ def asm(&block)
+ assembly = Assembly.new
+ assembly.instance_eval(&block)
+ assembly.run
+ end
+ end
+end
+
+module BasicOperations
+ def mov_exec(args)
+ set_register_value(args[0], args[1])
+ end
+
+ def inc_exec(args)
+ args[1] = args[1] || 1
+ old_value = get_real_value(args[0])
+ set_register_value(args[0], old_value + get_real_value(args[1]))
+ end
+
+ def dec_exec(args)
+ args[1] = args[1] || 1
+ old_value = get_real_value(args[0])
+ set_register_value(args[0], old_value - get_real_value(args[1]))
+ end
+
+ def cmp_exec(args)
+ @last_cmp = get_real_value(args[0]) <=> get_real_value(args[1])
+ end
+end
+
+module JumpInstructions
+ def jmp_exec(args)
+ if(args[0].is_a? String)
+ @current_instruction = @labels[args[0]]
+ else
+ @current_instruction = args[0]
+ end
+ end
+
+ def je_exec(args)
+ jmp_exec(args) if @last_cmp.zero?
+ end
+
+ def jne_exec(args)
+ jmp_exec(args) unless @last_cmp.zero?
+ end
+
+ def jl_exec(args)
+ jmp_exec(args) if @last_cmp < 0
+ end
+
+ def jle_exec(args)
+ jmp_exec(args) if @last_cmp <= 0
+ end
+
+ def jg_exec(args)
+ jmp_exec(args) if @last_cmp > 0
+ end
+
+ def jge_exec(args)
+ jmp_exec(args) if @last_cmp >= 0
+ end
+end
+
+module Registers
+ def ax
+ :ax
+ end
+
+ def bx
+ :bx
+ end
+
+ def cx
+ :cx
+ end
+
+ def dx
+ :dx
+ end
+
+ def get_register_value(register)
+ instance_variable_get("@#{register.to_s}")
+ end
+
+ def set_register_value(register, value)
+ instance_variable_set("@#{register.to_s}", get_real_value(value))
+ end
+end
+
+class Instruction
+ attr_reader :name
+ attr_reader :args
+ def initialize(name, args)
+ @name = name
+ @args = args
+ end
+end
+
+class Assembly
+ include BasicOperations
+ include JumpInstructions
+ include Registers
+
+ VALID_INSTRUCTIONS = [:mov, :inc, :dec, :cmp, :jmp, :je, :jl, :jle, :jg, :jge, :jne]
+ def initialize
+ @ax, @bx, @cx, @dx = 0, 0, 0, 0
+ @instructions = {}
+ @labels = {}
+ end
+
+ def method_missing(name, *args, &block)
+ if(name == :label)
+ @labels[args[0]] = @instructions.count
+ elsif(VALID_INSTRUCTIONS.include? name)
+ @instructions[@instructions.count] = Instruction.new(name, args)
+ else
+ name.to_s
+ end
+ end
+
+ def get_real_value(value)
+ if(value.is_a? Symbol)
+ get_register_value(value)
+ else
+ value
+ end
+ end
+
+ def run
+ @current_instruction = 0
+ while @current_instruction < @instructions.count
+ instruction = @instructions[@current_instruction]
+ @current_instruction += 1
+ send("#{instruction.name}_exec", instruction.args)
+ end
+
+ [@ax, @bx, @cx, @dx]
+ end
+end

Кристиан обнови решението на 15.01.2014 12:41 (преди почти 11 години)

module Asm
class << self
def asm(&block)
assembly = Assembly.new
assembly.instance_eval(&block)
assembly.run
end
end
end
-module BasicOperations
+module BasicInstructions
def mov_exec(args)
set_register_value(args[0], args[1])
end
def inc_exec(args)
args[1] = args[1] || 1
- old_value = get_real_value(args[0])
+ old_value = get_register_value(args[0])
set_register_value(args[0], old_value + get_real_value(args[1]))
end
def dec_exec(args)
args[1] = args[1] || 1
- old_value = get_real_value(args[0])
+ old_value = get_register_value(args[0])
set_register_value(args[0], old_value - get_real_value(args[1]))
end
def cmp_exec(args)
- @last_cmp = get_real_value(args[0]) <=> get_real_value(args[1])
+ @last_cmp = get_register_value(args[0]) <=> get_real_value(args[1])
end
end
module JumpInstructions
def jmp_exec(args)
if(args[0].is_a? String)
@current_instruction = @labels[args[0]]
else
@current_instruction = args[0]
end
end
def je_exec(args)
jmp_exec(args) if @last_cmp.zero?
end
def jne_exec(args)
jmp_exec(args) unless @last_cmp.zero?
end
def jl_exec(args)
jmp_exec(args) if @last_cmp < 0
end
def jle_exec(args)
jmp_exec(args) if @last_cmp <= 0
end
def jg_exec(args)
jmp_exec(args) if @last_cmp > 0
end
def jge_exec(args)
jmp_exec(args) if @last_cmp >= 0
end
end
module Registers
def ax
:ax
end
def bx
:bx
end
def cx
:cx
end
def dx
:dx
end
def get_register_value(register)
instance_variable_get("@#{register.to_s}")
end
def set_register_value(register, value)
instance_variable_set("@#{register.to_s}", get_real_value(value))
end
end
class Instruction
attr_reader :name
attr_reader :args
def initialize(name, args)
@name = name
@args = args
end
end
class Assembly
- include BasicOperations
+ include BasicInstructions
include JumpInstructions
include Registers
VALID_INSTRUCTIONS = [:mov, :inc, :dec, :cmp, :jmp, :je, :jl, :jle, :jg, :jge, :jne]
def initialize
@ax, @bx, @cx, @dx = 0, 0, 0, 0
@instructions = {}
@labels = {}
end
def method_missing(name, *args, &block)
if(name == :label)
@labels[args[0]] = @instructions.count
elsif(VALID_INSTRUCTIONS.include? name)
@instructions[@instructions.count] = Instruction.new(name, args)
else
name.to_s
end
end
def get_real_value(value)
if(value.is_a? Symbol)
get_register_value(value)
else
value
end
end
def run
@current_instruction = 0
while @current_instruction < @instructions.count
instruction = @instructions[@current_instruction]
@current_instruction += 1
send("#{instruction.name}_exec", instruction.args)
end
[@ax, @bx, @cx, @dx]
end
end