Решение на Четвърта задача от Георги Шопов

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

Към профила на Георги Шопов

Резултати

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

Код

module Asm
def self.asm(&instructions)
Cpu.new.execute &instructions
end
class Cpu
def execute(&instructions)
microcode = DecodeUnit.new.decode &instructions
ExecutionUnit.new(*microcode).execute
end
end
class ExecutionUnit
REGISTER_NAMES = [:ax, :bx, :cx, :dx]
attr_accessor :registers, :labels, :flag, :instruction_pointer
def initialize(microinstructions, labels)
@labels = labels
@instructions = microinstructions
@flag = 0
@instruction_pointer = 0
@registers = Hash.new do |hash, key|
REGISTER_NAMES.member?(key) ? 0 : key
end
end
def execute
while @instruction_pointer < @instructions.length
instance_eval &@instructions[@instruction_pointer]
@instruction_pointer += 1
end
REGISTER_NAMES.map { |register| @registers[register] }
end
end
module TransferInstructions
def mov(register, value)
@microinstructions << proc { registers[register] = registers[value] }
end
end
module ArithmeticInstructions
def inc(register, value = 1)
@microinstructions << proc { registers[register] += registers[value] }
end
def dec(register, value = 1)
@microinstructions << proc { registers[register] -= registers[value] }
end
end
module LogicalInstructions
def cmp(register, value)
@microinstructions << proc do
self.flag = registers[register] <=> registers[value]
end
end
end
module BranchInstructions
branch_conditions = {
jmp: ->(x) { true },
je: ->(x) { x == 0 },
jne: ->(x) { x != 0 },
jl: ->(x) { x < 0 },
jle: ->(x) { x <= 0 },
jg: ->(x) { x > 0 },
jge: ->(x) { x >= 0 },
}
jump_instruction = proc do |instruction_index, condition|
proc do
if condition.call(flag)
self.instruction_pointer = labels[instruction_index] - 1
end
end
end
branch_conditions.each do |instruction_name, condition|
define_method instruction_name do |instruction_index|
@microinstructions << jump_instruction.call(instruction_index, condition)
end
end
end
class DecodeUnit
include TransferInstructions
include ArithmeticInstructions
include LogicalInstructions
include BranchInstructions
ExecutionUnit::REGISTER_NAMES.each { |name| attr_reader name }
def initialize
@microinstructions = []
@labels = Hash.new { |hash, key| key }
ExecutionUnit::REGISTER_NAMES.each do |name|
instance_variable_set("@#{name}", name)
end
end
def decode(&instructions)
instance_eval &instructions
[@microinstructions, @labels]
end
def label(name)
@labels[name] = @microinstructions.length
end
def method_missing(method, *args, &block)
method
end
end
end

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

........

Finished in 0.00836 seconds
8 examples, 0 failures

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

Георги обнови решението на 15.01.2014 15:33 (преди почти 11 години)

+module Asm
+ def self.asm(&block)
+ Cpu.new.execute &block
+ end
+
+ module TransferInstructions
+ def mov(register, value)
+ @microinstructions << proc { registers[register] = registers[value] }
+ end
+ end
+
+ module ArithmeticInstructions
+ def inc(register, value = 1)
+ @microinstructions << proc { registers[register] += registers[value] }
+ end
+
+ def dec(register, value = 1)
+ @microinstructions << proc { registers[register] -= registers[value] }
+ end
+ end
+
+ module LogicalInstructions
+ def cmp(register, value)
+ @microinstructions << proc do
+ registers[:flag] = registers[register] <=> registers[value]
+ end
+ end
+ end
+
+ module BranchInstructions
+ branch_conditions = {
+ jmp: ->(x) { true },
+ je: ->(x) { x == 0 },
+ jne: ->(x) { x != 0 },
+ jl: ->(x) { x < 0 },
+ jle: ->(x) { x <= 0 },
+ jg: ->(x) { x > 0 },
+ jge: ->(x) { x >= 0 },
+ }
+
+ jump_instruction = proc do |instruction_index, condition|
+ proc do
+ if condition.call(registers[:flag])
+ @instruction_pointer = labels[instruction_index] - 1
+ end
+ end
+ end
+
+ branch_conditions.each do |instruction_name, condition|
+ define_method instruction_name do |instruction_index|
+ @microinstructions << jump_instruction.call(instruction_index, condition)
+ end
+ end
+ end
+
+ class DecodeUnit
+ include TransferInstructions
+ include ArithmeticInstructions
+ include LogicalInstructions
+ include BranchInstructions
+
+ attr_reader :ax, :bx, :cx, :dx, :flag
+
+ def initialize
+ @ax = :ax
+ @bx = :bx
+ @cx = :cx
+ @dx = :dx
+ @flag = :flag
+
+ @microinstructions = []
+ @labels = Hash.new { |hash, key| key }
+ end
+
+ def decode(&block)
+ instance_eval &block
+
+ [@microinstructions, @labels]
+ end
+
+ def method_missing(method, *args, &block)
+ method
+ end
+
+ def label(name)
+ @labels[name] = @microinstructions.length
+ end
+ end
+
+ class ExecutionUnit
+ REGISTER_NAMES = [:ax, :bx, :cx, :dx, :flag]
+
+ attr_accessor :registers, :labels, :instruction_pointer
+
+ def initialize(microinstructions, labels)
+ @labels = labels
+ @instructions = microinstructions
+ @instruction_pointer = 0
+
+ @registers = Hash.new do |hash, key|
+ REGISTER_NAMES.member?(key) ? 0 : key
+ end
+ end
+
+ def execute
+ while @instruction_pointer < @instructions.length
+ instance_eval &@instructions[@instruction_pointer]
+ @instruction_pointer += 1
+ end
+
+ REGISTER_NAMES[0...-1].map { |register| @registers[register] }
+ end
+ end
+
+ class Cpu
+ def execute(&block)
+ microcode = DecodeUnit.new.decode(&block)
+ ExecutionUnit.new(*microcode).execute
+ end
+ end
+end

Георги обнови решението на 15.01.2014 17:07 (преди почти 11 години)

module Asm
def self.asm(&block)
Cpu.new.execute &block
end
+ class Cpu
+ def execute(&block)
+ microcode = DecodeUnit.new.decode(&block)
+ ExecutionUnit.new(*microcode).execute
+ end
+ end
+
+ class ExecutionUnit
+ REGISTER_NAMES = [:ax, :bx, :cx, :dx]
+
+ attr_accessor :registers, :flag, :labels, :instruction_pointer
+
+ def initialize(microinstructions, labels)
+ @labels = labels
+ @instructions = microinstructions
+
+ @flag = 0
+ @instruction_pointer = 0
+
+ @registers = Hash.new do |hash, key|
+ REGISTER_NAMES.member?(key) ? 0 : key
+ end
+ end
+
+ def execute
+ while @instruction_pointer < @instructions.length
+ instance_eval &@instructions[@instruction_pointer]
+ @instruction_pointer += 1
+ end
+
+ REGISTER_NAMES.map { |register| @registers[register] }
+ end
+ end
+
module TransferInstructions
def mov(register, value)
@microinstructions << proc { registers[register] = registers[value] }
end
end
module ArithmeticInstructions
def inc(register, value = 1)
@microinstructions << proc { registers[register] += registers[value] }
end
def dec(register, value = 1)
@microinstructions << proc { registers[register] -= registers[value] }
end
end
module LogicalInstructions
def cmp(register, value)
@microinstructions << proc do
- registers[:flag] = registers[register] <=> registers[value]
+ self.flag = registers[register] <=> registers[value]
end
end
end
module BranchInstructions
branch_conditions = {
jmp: ->(x) { true },
je: ->(x) { x == 0 },
jne: ->(x) { x != 0 },
jl: ->(x) { x < 0 },
jle: ->(x) { x <= 0 },
jg: ->(x) { x > 0 },
jge: ->(x) { x >= 0 },
}
jump_instruction = proc do |instruction_index, condition|
proc do
- if condition.call(registers[:flag])
- @instruction_pointer = labels[instruction_index] - 1
+ if condition.call(flag)
+ self.instruction_pointer = labels[instruction_index] - 1
end
end
end
branch_conditions.each do |instruction_name, condition|
define_method instruction_name do |instruction_index|
@microinstructions << jump_instruction.call(instruction_index, condition)
end
end
end
class DecodeUnit
include TransferInstructions
include ArithmeticInstructions
include LogicalInstructions
include BranchInstructions
- attr_reader :ax, :bx, :cx, :dx, :flag
+ ExecutionUnit::REGISTER_NAMES.each { |name| attr_reader name }
def initialize
- @ax = :ax
- @bx = :bx
- @cx = :cx
- @dx = :dx
- @flag = :flag
-
@microinstructions = []
@labels = Hash.new { |hash, key| key }
+
+ ExecutionUnit::REGISTER_NAMES.each do |name|
+ instance_variable_set("@#{name}", name)
+ end
end
def decode(&block)
instance_eval &block
[@microinstructions, @labels]
end
def method_missing(method, *args, &block)
method
end
def label(name)
@labels[name] = @microinstructions.length
- end
- end
-
- class ExecutionUnit
- REGISTER_NAMES = [:ax, :bx, :cx, :dx, :flag]
-
- attr_accessor :registers, :labels, :instruction_pointer
-
- def initialize(microinstructions, labels)
- @labels = labels
- @instructions = microinstructions
- @instruction_pointer = 0
-
- @registers = Hash.new do |hash, key|
- REGISTER_NAMES.member?(key) ? 0 : key
- end
- end
-
- def execute
- while @instruction_pointer < @instructions.length
- instance_eval &@instructions[@instruction_pointer]
- @instruction_pointer += 1
- end
-
- REGISTER_NAMES[0...-1].map { |register| @registers[register] }
- end
- end
-
- class Cpu
- def execute(&block)
- microcode = DecodeUnit.new.decode(&block)
- ExecutionUnit.new(*microcode).execute
end
end
end

Георги обнови решението на 15.01.2014 17:21 (преди почти 11 години)

module Asm
- def self.asm(&block)
- Cpu.new.execute &block
+ def self.asm(&instructions)
+ Cpu.new.execute &instructions
end
class Cpu
- def execute(&block)
- microcode = DecodeUnit.new.decode(&block)
+ def execute(&instructions)
+ microcode = DecodeUnit.new.decode &instructions
ExecutionUnit.new(*microcode).execute
end
end
class ExecutionUnit
REGISTER_NAMES = [:ax, :bx, :cx, :dx]
- attr_accessor :registers, :flag, :labels, :instruction_pointer
+ attr_accessor :registers, :labels, :flag, :instruction_pointer
def initialize(microinstructions, labels)
@labels = labels
@instructions = microinstructions
@flag = 0
@instruction_pointer = 0
@registers = Hash.new do |hash, key|
REGISTER_NAMES.member?(key) ? 0 : key
end
end
def execute
while @instruction_pointer < @instructions.length
instance_eval &@instructions[@instruction_pointer]
@instruction_pointer += 1
end
REGISTER_NAMES.map { |register| @registers[register] }
end
end
module TransferInstructions
def mov(register, value)
@microinstructions << proc { registers[register] = registers[value] }
end
end
module ArithmeticInstructions
def inc(register, value = 1)
@microinstructions << proc { registers[register] += registers[value] }
end
def dec(register, value = 1)
@microinstructions << proc { registers[register] -= registers[value] }
end
end
module LogicalInstructions
def cmp(register, value)
@microinstructions << proc do
self.flag = registers[register] <=> registers[value]
end
end
end
module BranchInstructions
branch_conditions = {
jmp: ->(x) { true },
je: ->(x) { x == 0 },
jne: ->(x) { x != 0 },
jl: ->(x) { x < 0 },
jle: ->(x) { x <= 0 },
jg: ->(x) { x > 0 },
jge: ->(x) { x >= 0 },
}
jump_instruction = proc do |instruction_index, condition|
proc do
if condition.call(flag)
self.instruction_pointer = labels[instruction_index] - 1
end
end
end
branch_conditions.each do |instruction_name, condition|
define_method instruction_name do |instruction_index|
@microinstructions << jump_instruction.call(instruction_index, condition)
end
end
end
class DecodeUnit
include TransferInstructions
include ArithmeticInstructions
include LogicalInstructions
include BranchInstructions
ExecutionUnit::REGISTER_NAMES.each { |name| attr_reader name }
def initialize
@microinstructions = []
@labels = Hash.new { |hash, key| key }
ExecutionUnit::REGISTER_NAMES.each do |name|
instance_variable_set("@#{name}", name)
end
end
- def decode(&block)
- instance_eval &block
+ def decode(&instructions)
+ instance_eval &instructions
[@microinstructions, @labels]
end
- def method_missing(method, *args, &block)
- method
- end
-
def label(name)
@labels[name] = @microinstructions.length
+ end
+
+ def method_missing(method, *args, &block)
+ method
end
end
end