Ясен обнови решението на 15.01.2014 13:18 (преди почти 11 години)
+module Asm
+ def Asm.asm(&block)
+ Assembler.new.assemble &block
+ end
+
+ class Assembler
+ attr_reader :memory, :labels
+
+ def initialize
+ @labels = {}
+ @memory = { ax: 0, bx: 0, cx: 0, dx: 0 }
+ @program = []
+ end
+
+ INSTRUCTIONS = {
+ "mov" => lambda { |register, src|
+ @memory[register] = (src.is_a?(Symbol) ? @memory[src] : src)
+ nil
+ },
+ "inc" => lambda { |register, value = 1|
+ value = @memory[value] if @memory.keys.index value
+ @memory[register] += value
+ nil
+ },
+ "dec" => lambda { |register, value = 1|
+ value = @memory[value] if @memory.keys.index value
+ @memory[register] -= value
+ nil
+ },
+ "cmp" => lambda { |register, value|
+ value = @memory[value] if @memory.keys.index value
+ @last_cmp = @memory[register] <=> value
+ nil
+ },
+ "jmp" => lambda { |destination| jump_to destination },
+ "je" => lambda { |destination| jump_to destination if @last_cmp == 0 },
+ "jne" => lambda { |destination| jump_to destination if @last_cmp != 0 },
+ "jl" => lambda { |destination| jump_to destination if @last_cmp < 0 },
+ "jle" => lambda { |destination| jump_to destination if @last_cmp <= 0 },
+ "jg" => lambda { |destination| jump_to destination if @last_cmp > 0 },
+ "jge" => lambda { |destination| jump_to destination if @last_cmp >= 0 }
+ }
+
+ def jump_to(destination)
+ @labels.keys.index(destination) ? @labels[destination] : destination
+ end
+
+ def method_missing(name, *args)
+ if INSTRUCTIONS.keys.include? name.to_s
+ @program << [name.to_s, args]
+ elsif name.to_s == "label"
+ @labels[args.first] = @program.size
+ else
+ name
+ end
+ end
+
+ def parse(&block)
+ self.instance_eval &block
+ end
+
+ def run
+ pc = 0
+ until pc == @program.length
+ instruction = @program[pc]
+ retval = instance_exec(*instruction[1], &INSTRUCTIONS[instruction[0]])
+ if retval
+ pc = retval
+ else
+ pc += 1
+ end
+ end
+ end
+
+ def assemble(&block)
+ parse &block
+ run
+ @memory
+ end
+ end
+end
Интересно защо не ползваш символи за имената на инструкциите, както и в method_missing
. Там името на метода ти идва като символ така или иначе.
Уф, официално съм супер зле ;(
Бял кахър, сега ще запомниш :)