Решение на Четвърта задача от Веселин Генадиев

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

Към профила на Веселин Генадиев

Резултати

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

Код

module Asm
def self.asm(&block)
memory = Memory.new
memory.read(&block)
end
class BasicOperations
def initialize memory
@memory = memory
end
def cmp register, value
@memory.last_compare = @memory.registers[register] <=> get_value(value)
nil
end
def dec destination_register, value
@memory.registers[destination_register] -= get_value(value)
nil
end
def inc destination_register, value
@memory.registers[destination_register] += get_value(value)
nil
end
def mov destination_register, source
@memory.registers[destination_register] = get_value(source)
nil
end
private
def get_value source
if source.is_a?(Symbol)
@memory.registers[source]
else
source
end
end
end
class JumpOperations
def initialize memory
@memory = memory
end
def jmp where
@memory.labels[where]
end
def je where
return @memory.labels[where] if @memory.last_compare == 0
nil
end
def jne where
return @memory.labels[where] if @memory.last_compare != 0
nil
end
def jl where
return @memory.labels[where] if @memory.last_compare < 0
nil
end
def jle where
return @memory.labels[where] if @memory.last_compare <= 0
nil
end
def jg where
return @memory.labels[where] if @memory.last_compare > 0
nil
end
def jge where
return @memory.labels[where] if @memory.last_compare >= 0
nil
end
end
class Memory
attr_accessor :registers, :instructions, :labels, :last_compare
BASIC_OPERATIONS = ["mov", "inc", "dec", "cmp"]
JUMP_OPERATIONS = ["jmp", "je", "jne", "jl", "jle", "jg", "jge"]
def initialize
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
@instructions = []
@labels = {}
@last_compare = 0
@basic_operations = Asm::BasicOperations.new self
@jump_operations = Asm::JumpOperations.new self
end
def method_missing(name, *args)
if BASIC_OPERATIONS.include?(name.to_s) || JUMP_OPERATIONS.include?(name.to_s)
@instructions << [name.to_s, args]
elsif name.to_s == "label"
@labels[args.first] = @instructions.length
else
name
end
end
def respond_to?(method_name, include_private = false)
BASIC_OPERATIONS.include?(method_name) || JUMP_OPERATIONS.include?(method_name)
end
def load(&block)
self.instance_exec(&block)
end
def run
instruction_index = 0
until(instruction_index == @instructions.length)
instruction = @instructions[instruction_index]
operation_result = execute_operation(instruction[0], *instruction[1])
if operation_result
instruction_index = operation_result
else
instruction_index += 1
end
end
end
def read(&block)
load(&block)
run
@registers.values
end
private
def execute_operation operation, *args
if BASIC_OPERATIONS.include?(operation)
@basic_operations.send(operation, *args)
elsif JUMP_OPERATIONS.include?(operation)
@jump_operations.send(operation, *args)
else
::Kernel.raise "Unknown operation!"
end
end
end
end

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

..FFF.F.

Failures:

  1) Asm.asm implements INC
     Failure/Error: Asm.asm do
     ArgumentError:
       wrong number of arguments (1 for 2)
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:22:in `inc'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:139:in `execute_operation'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:120:in `run'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:131:in `read'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:4:in `asm'
     # /tmp/d20140115-8451-1wbc1mk/spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Asm.asm implements DEC
     Failure/Error: Asm.asm do
     ArgumentError:
       wrong number of arguments (1 for 2)
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:17:in `dec'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:139:in `execute_operation'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:120:in `run'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:131:in `read'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:4:in `asm'
     # /tmp/d20140115-8451-1wbc1mk/spec.rb:23:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) Asm.asm implements CMP
     Failure/Error: Asm.asm do
       
       expected: [2, 2, 0, 3]
            got: [2, 2, 3, 3]
       
       (compared using ==)
     # /tmp/d20140115-8451-1wbc1mk/spec.rb:34:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) Asm.asm implements LABEL
     Failure/Error: Asm.asm do
     ArgumentError:
       wrong number of arguments (1 for 2)
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:22:in `inc'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:139:in `execute_operation'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:120:in `run'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:131:in `read'
     # /tmp/d20140115-8451-1wbc1mk/solution.rb:4:in `asm'
     # /tmp/d20140115-8451-1wbc1mk/spec.rb:78:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01009 seconds
8 examples, 4 failures

Failed examples:

rspec /tmp/d20140115-8451-1wbc1mk/spec.rb:14 # Asm.asm implements INC
rspec /tmp/d20140115-8451-1wbc1mk/spec.rb:22 # Asm.asm implements DEC
rspec /tmp/d20140115-8451-1wbc1mk/spec.rb:33 # Asm.asm implements CMP
rspec /tmp/d20140115-8451-1wbc1mk/spec.rb:77 # Asm.asm implements LABEL

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

Веселин обнови решението на 14.01.2014 23:46 (преди почти 11 години)

+module Asm
+ def self.asm(&block)
+ memory = Memory.new
+ memory.read(&block)
+ end
+
+ class BasicOperations
+ def initialize memory
+ @memory = memory
+ end
+
+ def cmp register, value
+ @memory.last_compare = @memory.registers[register] <=> get_value(value)
+ puts @memory.last_compare
+ nil
+ end
+
+ def dec destination_register, value
+ @memory.registers[destination_register] -= get_value(value)
+ nil
+ end
+
+ def inc destination_register, value
+ @memory.registers[destination_register] += get_value(value)
+ nil
+ end
+
+ def mov destination_register, source
+ @memory.registers[destination_register] = get_value(source)
+ nil
+ end
+
+ private
+
+ def get_value source
+ if source.is_a?(Symbol)
+ @memory.registers[source]
+ else
+ source
+ end
+ end
+ end
+
+ class JumpOperations
+ def initialize memory
+ @memory = memory
+ end
+
+ def jmp where
+ @memory.labels[where]
+ end
+
+ def je where
+ return @memory.labels[where] if @memory.last_compare == 0
+ nil
+ end
+
+ def jne where
+ return @memory.labels[where] if @memory.last_compare != 0
+ nil
+ end
+
+ def jl where
+ return @memory.labels[where] if @memory.last_compare < 0
+ nil
+ end
+
+ def jle where
+ return @memory.labels[where] if @memory.last_compare <= 0
+ nil
+ end
+
+ def jg where
+ return @memory.labels[where] if @memory.last_compare > 0
+ nil
+ end
+
+ def jge where
+ return @memory.labels[where] if @memory.last_compare >= 0
+ nil
+ end
+ end
+
+ class Memory
+ attr_accessor :registers, :instructions, :labels, :last_compare
+
+ BASIC_OPERATIONS = ["mov", "inc", "dec", "cmp"]
+ JUMP_OPERATIONS = ["jmp", "je", "jne", "jl", "jle", "jg", "jge"]
+
+ def initialize
+ @registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
+ @instructions = []
+ @labels = {}
+ @last_compare = 0
+ @basic_operations = Asm::BasicOperations.new self
+ @jump_operations = Asm::JumpOperations.new self
+ end
+
+ def method_missing(name, *args)
+ if BASIC_OPERATIONS.include?(name.to_s) || JUMP_OPERATIONS.include?(name.to_s)
+ @instructions << [name.to_s, args]
+ elsif name.to_s == "label"
+ @labels[args.first] = @instructions.length
+ else
+ name
+ end
+ end
+
+ def respond_to?(method_name, include_private = false)
+ BASIC_OPERATIONS.include?(method_name) || JUMP_OPERATIONS.include?(method_name)
+ end
+
+ def load(&block)
+ self.instance_exec(&block)
+ end
+
+ def run
+ instruction_index = 0
+ until(instruction_index == @instructions.length)
+ instruction = @instructions[instruction_index]
+ operation_result = execute_operation(instruction[0], *instruction[1])
+ if operation_result
+ instruction_index = operation_result
+ else
+ instruction_index += 1
+ end
+ end
+ end
+
+ def read(&block)
+ load(&block)
+ run
+ @registers.values
+ end
+
+ private
+
+ def execute_operation operation, *args
+ if BASIC_OPERATIONS.include?(operation)
+ @basic_operations.send(operation, *args)
+ elsif JUMP_OPERATIONS.include?(operation)
+ @jump_operations.send(operation, *args)
+ else
+ ::Kernel.raise "Unknown operation!"
+ end
+ end
+ end
+end

Веселин обнови решението на 14.01.2014 23:48 (преди почти 11 години)

module Asm
def self.asm(&block)
memory = Memory.new
memory.read(&block)
end
class BasicOperations
def initialize memory
@memory = memory
end
def cmp register, value
@memory.last_compare = @memory.registers[register] <=> get_value(value)
- puts @memory.last_compare
nil
end
def dec destination_register, value
@memory.registers[destination_register] -= get_value(value)
nil
end
def inc destination_register, value
@memory.registers[destination_register] += get_value(value)
nil
end
def mov destination_register, source
@memory.registers[destination_register] = get_value(source)
nil
end
private
def get_value source
if source.is_a?(Symbol)
@memory.registers[source]
else
source
end
end
end
class JumpOperations
def initialize memory
@memory = memory
end
def jmp where
@memory.labels[where]
end
def je where
return @memory.labels[where] if @memory.last_compare == 0
nil
end
def jne where
return @memory.labels[where] if @memory.last_compare != 0
nil
end
def jl where
return @memory.labels[where] if @memory.last_compare < 0
nil
end
def jle where
return @memory.labels[where] if @memory.last_compare <= 0
nil
end
def jg where
return @memory.labels[where] if @memory.last_compare > 0
nil
end
def jge where
return @memory.labels[where] if @memory.last_compare >= 0
nil
end
end
class Memory
attr_accessor :registers, :instructions, :labels, :last_compare
BASIC_OPERATIONS = ["mov", "inc", "dec", "cmp"]
JUMP_OPERATIONS = ["jmp", "je", "jne", "jl", "jle", "jg", "jge"]
def initialize
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
@instructions = []
@labels = {}
@last_compare = 0
@basic_operations = Asm::BasicOperations.new self
@jump_operations = Asm::JumpOperations.new self
end
def method_missing(name, *args)
if BASIC_OPERATIONS.include?(name.to_s) || JUMP_OPERATIONS.include?(name.to_s)
@instructions << [name.to_s, args]
elsif name.to_s == "label"
@labels[args.first] = @instructions.length
else
name
end
end
def respond_to?(method_name, include_private = false)
BASIC_OPERATIONS.include?(method_name) || JUMP_OPERATIONS.include?(method_name)
end
def load(&block)
self.instance_exec(&block)
end
def run
instruction_index = 0
until(instruction_index == @instructions.length)
instruction = @instructions[instruction_index]
operation_result = execute_operation(instruction[0], *instruction[1])
if operation_result
instruction_index = operation_result
else
instruction_index += 1
end
end
end
def read(&block)
load(&block)
run
@registers.values
end
private
def execute_operation operation, *args
if BASIC_OPERATIONS.include?(operation)
@basic_operations.send(operation, *args)
elsif JUMP_OPERATIONS.include?(operation)
@jump_operations.send(operation, *args)
else
::Kernel.raise "Unknown operation!"
end
end
end
end