Решение на Четвърта задача от Николай Генов

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

Към профила на Николай Генов

Резултати

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

Код

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
@operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
@registers[destination].public_send operation, get_value(other)
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end

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

........

Finished in 0.00735 seconds
8 examples, 0 failures

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

Николай обнови решението на 15.01.2014 02:40 (преди почти 11 години)

+module Asm
+ class Evaluator
+ operations = {
+ mov: :initialize_reg,
+ inc: :increase,
+ dec: :decrease,
+ cmp: :compare,
+ jmp: :jmp,
+ }
+
+ operations.each do |operation_name, operation|
+ define_method operation_name do |destination, value = 1|
+ @operations_queue << [operation, destination, value ]
+ end
+ end
+
+ help_operations = {
+ initialize_reg: :+,
+ increase: :+,
+ decrease: :-,
+ }
+
+ help_operations.each do |operation_name, operation|
+ define_method operation_name do |destination ,other|
+ @registers[destination] =
+ @registers[destination].method(operation).call get_value other
+ end
+ end
+
+ def initialize(&block)
+ @ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
+ @cmp, @current_position = 0, 0
+ @operations_queue = []
+ @label_names = {}
+ @jumps_list = {
+ jmp: :+,
+ je: :==,
+ jne: :!=,
+ jl: :<,
+ jle: :<=,
+ jg: :>,
+ jge: :>=,
+ }
+ @registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
+ instance_eval &block
+ end
+
+ def perform_operations
+ while (@current_position != @operations_queue.length)
+ [@operations_queue[@current_position]].each do |operation, destination, arguments|
+ if @jumps_list.has_key? operation
+ label_position = @label_names.fetch(destination, destination)
+ call_jump operation, label_position
+ else
+ public_send operation, destination, arguments
+ @current_position += 1
+ end
+ end
+ end
+ @registers.values.to_a
+ end
+
+ def method_missing(name, *arguments)
+ @operations_queue << [name, *arguments] if @jumps_list.has_key? name
+ name
+ end
+
+ def compare(destination, other)
+ @cmp = @registers[destination] <=> get_value(other)
+ end
+
+ private
+
+ def get_value(value)
+ @registers[value] or value
+ end
+
+ def call_jump(type, label_position)
+ if @cmp.method(@jumps_list[type]).call 0
+ @current_position = label_position
+ else
+ @current_position += 1
+ end
+ end
+
+ def label(name)
+ @label_names[name] = @operations_queue.length
+ end
+ end
+
+ def self.asm(&block)
+ Evaluator.new(&block).perform_operations
+ end
+end

Много добре. Дреболиите са следните:

  • Не оставяш празен ред над реда, който връща стойност в методите. Не е проблем, ако програмата случайно стане по-дълга от 100 реда. :)
  • Имаш странно индентиране на някои места.

Николай обнови решението на 15.01.2014 11:32 (преди почти 11 години)

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
- @operations_queue << [operation, destination, value ]
+ @operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
@registers[destination].method(operation).call get_value other
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end

Николай обнови решението на 15.01.2014 11:53 (преди почти 11 години)

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
@operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
@registers[destination].method(operation).call get_value other
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
+
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end

Николай обнови решението на 15.01.2014 11:54 (преди почти 11 години)

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
@operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
@registers[destination].method(operation).call get_value other
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
+
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end

Николай обнови решението на 15.01.2014 17:11 (преди почти 11 години)

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
@operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
- @registers[destination].method(operation).call get_value other
+ @registers[destination].send operation, get_value(other)
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end

Николай обнови решението на 15.01.2014 17:13 (преди почти 11 години)

module Asm
class Evaluator
operations = {
mov: :initialize_reg,
inc: :increase,
dec: :decrease,
cmp: :compare,
jmp: :jmp,
}
operations.each do |operation_name, operation|
define_method operation_name do |destination, value = 1|
@operations_queue << [operation, destination, value ]
end
end
help_operations = {
initialize_reg: :+,
increase: :+,
decrease: :-,
}
help_operations.each do |operation_name, operation|
define_method operation_name do |destination ,other|
@registers[destination] =
- @registers[destination].send operation, get_value(other)
+ @registers[destination].public_send operation, get_value(other)
end
end
def initialize(&block)
@ax, @bx, @cx, @dx = :ax, :bx, :cx, :dx
@cmp, @current_position = 0, 0
@operations_queue = []
@label_names = {}
@jumps_list = {
jmp: :+,
je: :==,
jne: :!=,
jl: :<,
jle: :<=,
jg: :>,
jge: :>=,
}
@registers = { ax: 0, bx: 0, cx: 0, dx: 0 }
instance_eval &block
end
def perform_operations
while (@current_position != @operations_queue.length)
[@operations_queue[@current_position]].each do |operation, destination, arguments|
if @jumps_list.has_key? operation
label_position = @label_names.fetch(destination, destination)
call_jump operation, label_position
else
public_send operation, destination, arguments
@current_position += 1
end
end
end
@registers.values.to_a
end
def method_missing(name, *arguments)
@operations_queue << [name, *arguments] if @jumps_list.has_key? name
name
end
def compare(destination, other)
@cmp = @registers[destination] <=> get_value(other)
end
private
def get_value(value)
@registers[value] or value
end
def call_jump(type, label_position)
if @cmp.method(@jumps_list[type]).call 0
@current_position = label_position
else
@current_position += 1
end
end
def label(name)
@label_names[name] = @operations_queue.length
end
end
def self.asm(&block)
Evaluator.new(&block).perform_operations
end
end