Решение на Четвърта задача от Сияна Славова

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

Към профила на Сияна Славова

Резултати

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

Код

module Asm
module DefaultExecutableInstructions
def get_value(source)
value = source.kind_of?(Symbol) ? @registers[source] : source
value
end
def move(destination_register, source)
@registers[destination_register] = get_value(source)
end
def increment(destination_register, value = 1)
@registers[destination_register] += get_value(value)
end
def decrement(destination_register, value = 1)
@registers[destination_register] -= get_value(value)
end
def compare(register, value)
@last_compare = @registers[register] - get_value(value)
end
def add_label(label_name)
label_name
end
end
module DefaultInstructions
include DefaultExecutableInstructions
def mov(destination_register, source)
@instruction_number += 1
@instructions << [:move, [destination_register, source], @instruction_number]
end
def inc(destination_register, value = 1)
@instruction_number += 1
@instructions << [:increment, [destination_register, value], @instruction_number]
end
def dec(destination_register, value = 1)
@instruction_number += 1
@instructions << [:decrement, [destination_register, value], @instruction_number]
end
def cmp(register, value)
@instruction_number += 1
@instructions << [:compare, [register, value], @instruction_number]
end
def label(label_name)
@instructions << [:add_label, [label_name], label_name]
end
end
module ExecutableJumpInstructions
def jump(where)
where
end
def jump_equal(where)
@last_compare == 0 ? where : -1
end
def jump_not_equal(where)
@last_compare != 0 ? where : -1
end
def jump_less(where)
@last_compare < 0 ? where : -1
end
def jump_less_equal(where)
@last_compare <= 0 ? where : -1
end
def jump_greater(where)
@last_compare > 0 ? where : -1
end
def jump_greater_equal(where)
@last_compare >= 0 ? where : -1
end
end
module JumpInstructions
include ExecutableJumpInstructions
def jmp(where)
@instruction_number += 1
@instructions << [:jump, [where], @instruction_number, :jump]
end
def je(where)
@instruction_number += 1
@instructions << [:jump_equal, [where], @instruction_number, :jump]
end
def jne(where)
@instruction_number += 1
@instructions << [:jump_not_equal, [where], @instruction_number, :jump]
end
def jl(where)
@instruction_number += 1
@instructions << [:jump_less, [where], @instruction_number, :jump]
end
def jle(where)
@instruction_number += 1
@instructions << [:jump_less_equal, [where], @instruction_number, :jump]
end
def jg(where)
@instruction_number += 1
@instructions << [:jump_greater, [where], @instruction_number, :jump]
end
def jge(where)
@instruction_number += 1
@instructions << [:jump_greater_equal, [where], @instruction_number, :jump]
end
end
class Execute
include DefaultInstructions
include JumpInstructions
def initialize
@registers = {ax: 0, bx: 0, cx: 0, dx: 0}
@instructions = []
@instruction_number = -1
@last_compare = 0
end
def execute
i = 0
while i < @instructions.length do
i = check_for_jumps(@instructions[i], i)
end
@registers.values.to_a
end
def check_for_jumps(current, i)
if current[3] == :jump
i = search_for_index(current, i)
else
i += 1
public_send current[0], *current[1]
end
i
end
def search_for_index(current, i)
previous_i = i
index_where = public_send current[0], *current[1]
if index_where != -1
@instructions.each_with_index do |instruction, index|
i = index if instruction[2] == index_where
end
end
i += 1 if previous_i == i
i
end
def method_missing(method_name, *args, &block)
method_name
end
end
def self.asm(&block)
executor = Execute.new
executor.instance_eval &block
executor.execute
end
end

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

........

Finished in 0.00736 seconds
8 examples, 0 failures

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

Сияна обнови решението на 13.01.2014 20:25 (преди почти 11 години)

+module DefaultExecutableInstructions
+ def move(destination_register, source)
+ value = source.kind_of?(Symbol) ? @registers[source] : source
+ @registers[destination_register] = value
+ end
+
+ def increment (destination_register, value = 1)
+ value = value.kind_of?(Symbol) ? @registers[value] : value
+ @registers[destination_register] += value
+ end
+
+ def decrement (destination_register, value = 1)
+ value = value.kind_of?(Symbol) ? @registers[value] : value
+ @registers[destination_register] -= value
+ end
+
+ def compare (register, value)
+ value = value.kind_of?(Symbol) ? @registers[value] : value
+ @last_compare = @registers[register] - value
+ end
+
+ def add_label (label_name)
+ label_name
+ end
+end
+
+module DefaultInstructions
+ include DefaultExecutableInstructions
+ def mov (destination_register, source)
+ @instruction_number += 1
+ @instructions << [:move, [destination_register, source], @instruction_number]
+ end
+
+ def inc (destination_register, value = 1)
+ @instruction_number += 1
+ @instructions << [:increment, [destination_register, value], @instruction_number]
+ end
+
+ def dec (destination_register, value = 1)
+ @instruction_number += 1
+ @instructions << [:decrement, [destination_register, value], @instruction_number]
+ end
+
+ def cmp (register, value)
+ @instruction_number += 1
+ @instructions << [:compare, [register, value], @instruction_number]
+ end
+
+ def label (label_name)
+ @instructions << [:add_label, [label_name], label_name]
+ end
+end
+
+module ExecutableJumpInstructions
+ def jump (where)
+ where
+ end
+
+ def jump_equal (where)
+ @last_compare == 0 ? where : -1
+ end
+
+ def jump_not_equal (where)
+ @last_compare != 0 ? where : -1
+ end
+
+ def jump_less (where)
+ @last_compare < 0 ? where : -1
+ end
+
+ def jump_less_equal (where)
+ @last_compare <= 0 ? where : -1
+ end
+
+ def jump_greater (where)
+ @last_compare > 0 ? where : -1
+ end
+
+ def jump_greater_equal (where)
+ @last_compare >= 0 ? where : -1
+ end
+end
+
+module JumpInstructions
+ include ExecutableJumpInstructions
+ def jmp (where)
+ @instruction_number += 1
+ @instructions << [:jump, [where], @instruction_number, :jump]
+ end
+
+ def je (where)
+ @instruction_number += 1
+ @instructions << [:jump_equal, [where], @instruction_number, :jump]
+ end
+
+ def jne (where)
+ @instruction_number += 1
+ @instructions << [:jump_not_equal, [where], @instruction_number, :jump]
+ end
+
+ def jl (where)
+ @instruction_number += 1
+ @instructions << [:jump_less, [where], @instruction_number, :jump]
+ end
+
+ def jle (where)
+ @instruction_number += 1
+ @instructions << [:jump_less_equal, [where], @instruction_number, :jump]
+ end
+
+ def jg (where)
+ @instruction_number += 1
+ @instructions << [:jump_greater, [where], @instruction_number, :jump]
+ end
+
+ def jge (where)
+ @instruction_number += 1
+ @instructions << [:jump_greater_equal, [where], @instruction_number, :jump]
+ end
+
+end
+
+
+module Asm
+ class Execute
+ include DefaultInstructions
+ include JumpInstructions
+
+ def initialize
+ @registers = {ax: 0, bx: 0, cx: 0, dx: 0}
+ @instructions = []
+ @instruction_number = -1
+ @last_compare = 0
+ end
+
+ def execute
+ i = 0
+ while i < @instructions.length do
+ i = check_for_jumps(@instructions[i], i)
+ end
+ @registers.values.to_a
+ end
+
+ def check_for_jumps (current, i)
+ if current[3] == :jump
+ i = search_for_index(current, i)
+ else
+ i += 1
+ public_send current[0], *current[1]
+ end
+ i
+ end
+
+ def search_for_index (current, i)
+ previous_i = i
+ index_where = public_send current[0], *current[1]
+ if index_where != -1
+ @instructions.each_with_index do |instruction, index|
+ i = index if instruction[2] == index_where
+ end
+ end
+ i += 1 if previous_i == i
+ i
+ end
+
+ def method_missing (method_name, *args, &block)
+ method_name
+ end
+ end
+
+ def self.asm(&block)
+ executor = Execute.new
+ executor.instance_eval &block
+ executor.execute
+ end
+end
+
+Asm.asm do
+ mov ax, 40
+ mov bx, 32
+ label cycle
+ cmp ax, bx
+ je finish
+ jl asmaller
+ dec ax, bx
+ jmp cycle
+ label asmaller
+ dec bx, ax
+ jmp cycle
+ label finish
+end
+
+Asm.asm do
+ mov ax, 2
+ mov bx, 2
+ cmp ax, bx
+ je 5
+ mov cx, 3
+ mov dx, 3
+end

Сияна обнови решението на 13.01.2014 20:34 (преди почти 11 години)

module DefaultExecutableInstructions
def move(destination_register, source)
value = source.kind_of?(Symbol) ? @registers[source] : source
@registers[destination_register] = value
end
def increment (destination_register, value = 1)
value = value.kind_of?(Symbol) ? @registers[value] : value
@registers[destination_register] += value
end
def decrement (destination_register, value = 1)
value = value.kind_of?(Symbol) ? @registers[value] : value
@registers[destination_register] -= value
end
def compare (register, value)
value = value.kind_of?(Symbol) ? @registers[value] : value
@last_compare = @registers[register] - value
end
def add_label (label_name)
label_name
end
end
module DefaultInstructions
include DefaultExecutableInstructions
def mov (destination_register, source)
@instruction_number += 1
@instructions << [:move, [destination_register, source], @instruction_number]
end
def inc (destination_register, value = 1)
@instruction_number += 1
@instructions << [:increment, [destination_register, value], @instruction_number]
end
def dec (destination_register, value = 1)
@instruction_number += 1
@instructions << [:decrement, [destination_register, value], @instruction_number]
end
def cmp (register, value)
@instruction_number += 1
@instructions << [:compare, [register, value], @instruction_number]
end
def label (label_name)
@instructions << [:add_label, [label_name], label_name]
end
end
module ExecutableJumpInstructions
def jump (where)
where
end
def jump_equal (where)
@last_compare == 0 ? where : -1
end
def jump_not_equal (where)
@last_compare != 0 ? where : -1
end
def jump_less (where)
@last_compare < 0 ? where : -1
end
def jump_less_equal (where)
@last_compare <= 0 ? where : -1
end
def jump_greater (where)
@last_compare > 0 ? where : -1
end
def jump_greater_equal (where)
@last_compare >= 0 ? where : -1
end
end
module JumpInstructions
include ExecutableJumpInstructions
def jmp (where)
@instruction_number += 1
@instructions << [:jump, [where], @instruction_number, :jump]
end
def je (where)
@instruction_number += 1
@instructions << [:jump_equal, [where], @instruction_number, :jump]
end
def jne (where)
@instruction_number += 1
@instructions << [:jump_not_equal, [where], @instruction_number, :jump]
end
def jl (where)
@instruction_number += 1
@instructions << [:jump_less, [where], @instruction_number, :jump]
end
def jle (where)
@instruction_number += 1
@instructions << [:jump_less_equal, [where], @instruction_number, :jump]
end
def jg (where)
@instruction_number += 1
@instructions << [:jump_greater, [where], @instruction_number, :jump]
end
def jge (where)
@instruction_number += 1
@instructions << [:jump_greater_equal, [where], @instruction_number, :jump]
end
-
end
module Asm
class Execute
include DefaultInstructions
include JumpInstructions
def initialize
@registers = {ax: 0, bx: 0, cx: 0, dx: 0}
@instructions = []
@instruction_number = -1
@last_compare = 0
end
def execute
i = 0
while i < @instructions.length do
i = check_for_jumps(@instructions[i], i)
end
@registers.values.to_a
end
def check_for_jumps (current, i)
if current[3] == :jump
i = search_for_index(current, i)
else
i += 1
public_send current[0], *current[1]
end
i
end
def search_for_index (current, i)
previous_i = i
index_where = public_send current[0], *current[1]
if index_where != -1
@instructions.each_with_index do |instruction, index|
i = index if instruction[2] == index_where
end
end
i += 1 if previous_i == i
i
end
def method_missing (method_name, *args, &block)
method_name
end
end
def self.asm(&block)
executor = Execute.new
executor.instance_eval &block
executor.execute
end
-end
-
-Asm.asm do
- mov ax, 40
- mov bx, 32
- label cycle
- cmp ax, bx
- je finish
- jl asmaller
- dec ax, bx
- jmp cycle
- label asmaller
- dec bx, ax
- jmp cycle
- label finish
-end
-
-Asm.asm do
- mov ax, 2
- mov bx, 2
- cmp ax, bx
- je 5
- mov cx, 3
- mov dx, 3
end
  • Вкарай допълнителните модули вътре в Asm, за да няма излишен шум в глобалното пространство от имена.
  • Повторението на този код value = value.kind_of?(Symbol) ? @registers[value] : value е code smell. По-конкретно нарушава DRY принципа. Абстрахирай го в помощен метод.
  • Интервалите между името на метод и списъкът с аргументи при дефиниция на метод ще бъдат наказани с точка, ако не ги махнеш. (не трябва да има def some_method ( ... ))

Сияна обнови решението на 13.01.2014 22:56 (преди почти 11 години)

-module DefaultExecutableInstructions
- def move(destination_register, source)
+module Asm
+ module DefaultExecutableInstructions
+ def get_value(source)
value = source.kind_of?(Symbol) ? @registers[source] : source
- @registers[destination_register] = value
- end
+ value
+ end
+ def move(destination_register, source)
+ @registers[destination_register] = get_value(source)
+ end
- def increment (destination_register, value = 1)
- value = value.kind_of?(Symbol) ? @registers[value] : value
- @registers[destination_register] += value
- end
+ def increment(destination_register, value = 1)
+ @registers[destination_register] += get_value(value)
+ end
- def decrement (destination_register, value = 1)
- value = value.kind_of?(Symbol) ? @registers[value] : value
- @registers[destination_register] -= value
- end
+ def decrement(destination_register, value = 1)
+ @registers[destination_register] -= get_value(value)
+ end
- def compare (register, value)
- value = value.kind_of?(Symbol) ? @registers[value] : value
- @last_compare = @registers[register] - value
- end
+ def compare(register, value)
+ @last_compare = @registers[register] - get_value(value)
+ end
- def add_label (label_name)
- label_name
+ def add_label(label_name)
+ label_name
+ end
end
-end
-module DefaultInstructions
- include DefaultExecutableInstructions
- def mov (destination_register, source)
- @instruction_number += 1
- @instructions << [:move, [destination_register, source], @instruction_number]
- end
+ module DefaultInstructions
+ include DefaultExecutableInstructions
+ def mov(destination_register, source)
+ @instruction_number += 1
+ @instructions << [:move, [destination_register, source], @instruction_number]
+ end
- def inc (destination_register, value = 1)
- @instruction_number += 1
- @instructions << [:increment, [destination_register, value], @instruction_number]
- end
+ def inc(destination_register, value = 1)
+ @instruction_number += 1
+ @instructions << [:increment, [destination_register, value], @instruction_number]
+ end
- def dec (destination_register, value = 1)
- @instruction_number += 1
- @instructions << [:decrement, [destination_register, value], @instruction_number]
- end
+ def dec(destination_register, value = 1)
+ @instruction_number += 1
+ @instructions << [:decrement, [destination_register, value], @instruction_number]
+ end
- def cmp (register, value)
- @instruction_number += 1
- @instructions << [:compare, [register, value], @instruction_number]
- end
+ def cmp(register, value)
+ @instruction_number += 1
+ @instructions << [:compare, [register, value], @instruction_number]
+ end
- def label (label_name)
- @instructions << [:add_label, [label_name], label_name]
+ def label(label_name)
+ @instructions << [:add_label, [label_name], label_name]
+ end
end
-end
-module ExecutableJumpInstructions
- def jump (where)
- where
- end
+ module ExecutableJumpInstructions
+ def jump(where)
+ where
+ end
- def jump_equal (where)
- @last_compare == 0 ? where : -1
- end
+ def jump_equal(where)
+ @last_compare == 0 ? where : -1
+ end
- def jump_not_equal (where)
- @last_compare != 0 ? where : -1
- end
+ def jump_not_equal(where)
+ @last_compare != 0 ? where : -1
+ end
- def jump_less (where)
- @last_compare < 0 ? where : -1
- end
+ def jump_less(where)
+ @last_compare < 0 ? where : -1
+ end
- def jump_less_equal (where)
- @last_compare <= 0 ? where : -1
- end
+ def jump_less_equal(where)
+ @last_compare <= 0 ? where : -1
+ end
- def jump_greater (where)
- @last_compare > 0 ? where : -1
- end
+ def jump_greater(where)
+ @last_compare > 0 ? where : -1
+ end
- def jump_greater_equal (where)
- @last_compare >= 0 ? where : -1
+ def jump_greater_equal(where)
+ @last_compare >= 0 ? where : -1
+ end
end
-end
-module JumpInstructions
- include ExecutableJumpInstructions
- def jmp (where)
- @instruction_number += 1
- @instructions << [:jump, [where], @instruction_number, :jump]
- end
+ module JumpInstructions
+ include ExecutableJumpInstructions
+ def jmp(where)
+ @instruction_number += 1
+ @instructions << [:jump, [where], @instruction_number, :jump]
+ end
- def je (where)
- @instruction_number += 1
- @instructions << [:jump_equal, [where], @instruction_number, :jump]
- end
+ def je(where)
+ @instruction_number += 1
+ @instructions << [:jump_equal, [where], @instruction_number, :jump]
+ end
- def jne (where)
- @instruction_number += 1
- @instructions << [:jump_not_equal, [where], @instruction_number, :jump]
- end
+ def jne(where)
+ @instruction_number += 1
+ @instructions << [:jump_not_equal, [where], @instruction_number, :jump]
+ end
- def jl (where)
- @instruction_number += 1
- @instructions << [:jump_less, [where], @instruction_number, :jump]
- end
+ def jl(where)
+ @instruction_number += 1
+ @instructions << [:jump_less, [where], @instruction_number, :jump]
+ end
- def jle (where)
- @instruction_number += 1
- @instructions << [:jump_less_equal, [where], @instruction_number, :jump]
- end
+ def jle(where)
+ @instruction_number += 1
+ @instructions << [:jump_less_equal, [where], @instruction_number, :jump]
+ end
- def jg (where)
- @instruction_number += 1
- @instructions << [:jump_greater, [where], @instruction_number, :jump]
- end
+ def jg(where)
+ @instruction_number += 1
+ @instructions << [:jump_greater, [where], @instruction_number, :jump]
+ end
- def jge (where)
- @instruction_number += 1
- @instructions << [:jump_greater_equal, [where], @instruction_number, :jump]
+ def jge(where)
+ @instruction_number += 1
+ @instructions << [:jump_greater_equal, [where], @instruction_number, :jump]
+ end
end
-end
-
-
-module Asm
class Execute
include DefaultInstructions
include JumpInstructions
def initialize
@registers = {ax: 0, bx: 0, cx: 0, dx: 0}
@instructions = []
@instruction_number = -1
@last_compare = 0
end
def execute
i = 0
while i < @instructions.length do
i = check_for_jumps(@instructions[i], i)
end
@registers.values.to_a
end
- def check_for_jumps (current, i)
+ def check_for_jumps(current, i)
if current[3] == :jump
i = search_for_index(current, i)
else
i += 1
public_send current[0], *current[1]
end
i
end
- def search_for_index (current, i)
+ def search_for_index(current, i)
previous_i = i
index_where = public_send current[0], *current[1]
if index_where != -1
@instructions.each_with_index do |instruction, index|
i = index if instruction[2] == index_where
end
end
i += 1 if previous_i == i
i
end
- def method_missing (method_name, *args, &block)
+ def method_missing(method_name, *args, &block)
method_name
end
end
def self.asm(&block)
executor = Execute.new
executor.instance_eval &block
executor.execute
end
-end
+end