class LadderDrive::AsmLine
Constants
- MNEMONIC_DEF
- OPERAND_TYPE_NONE
- OPERAND_TYPE_TYPE_AND_NUMBER
- OPERAND_TYPE_TYPE_AND_NUMBER_NUMBER
Attributes
address[R]
codes[R]
endian[R]
line[R]
Public Class Methods
new(line, address = 0, endian = nil)
click to toggle source
# File lib/ladder_drive/asm.rb, line 85 def initialize line, address = 0, endian = nil @endian = endian || Asm::LITTLE_ENDIAN @line = line.upcase.chomp @codes = [] @address = address parse end
Public Instance Methods
dump()
click to toggle source
# File lib/ladder_drive/asm.rb, line 97 def dump @codes.map do |c| c.to_s(16).rjust(2, "0") end .join(" ") .ljust(12) end
dump_line()
click to toggle source
# File lib/ladder_drive/asm.rb, line 93 def dump_line "#{dump}\t#{line}" end
next_address()
click to toggle source
# File lib/ladder_drive/asm.rb, line 105 def next_address address + codes.size end
Private Instance Methods
counter_value(value)
click to toggle source
# File lib/ladder_drive/asm.rb, line 246 def counter_value value raise SyntaxError.new "It must be required count value." unless /^\d+$/ =~ value v = value.to_i case endian when Asm::LITTLE_ENDIAN codes = [v & 0xff, (v & 0xff00) >> 8] when Asm::BIG_ENDIAN codes = [(v & 0xff00) >> 8, v & 0xff] end end
encode_mnemonic(mnemonic)
click to toggle source
# File lib/ladder_drive/asm.rb, line 172 def encode_mnemonic mnemonic mnemonic_dict[mnemonic] end
mnemonic_dict()
click to toggle source
# File lib/ladder_drive/asm.rb, line 157 def mnemonic_dict @@mnemonic_dict ||= begin h = {} MNEMONIC_DEF.dup.split(/\n/)[2..-1].each_with_index do |line, upper| line.split(/\|/)[2..-1].each_with_index do |mnemonic, lower| mnemonic.strip! next if mnemonic.nil? || mnemonic.length == 0 code = (upper << 4) | lower h[mnemonic] = code end end h end end
operand_type(mnemonic)
click to toggle source
# File lib/ladder_drive/asm.rb, line 128 def operand_type mnemonic case mnemonic when /LD/, /AND/, /ANI/, /OR[^B]?$/, /OUT/, "SET", "RST", "PLS", "PLF", "FF", /SF(L|R)/ OPERAND_TYPE_TYPE_AND_NUMBER else OPERAND_TYPE_NONE end end
parse()
click to toggle source
# File lib/ladder_drive/asm.rb, line 115 def parse /([^#]*)/ =~ line a = $1.split(/\s+/) mnemonic, operand1, operand2 = a if mnemonic @codes << encode_mnemonic(mnemonic) case operand_type(mnemonic) when OPERAND_TYPE_TYPE_AND_NUMBER @codes += parse_type_and_number(mnemonic, operand1, operand2) end end end
parse_type_and_number(mnemonic, operand, value)
click to toggle source
# File lib/ladder_drive/asm.rb, line 176 def parse_type_and_number mnemonic, operand, value /([[:alpha:]]*)(\d+[0-9A-Fa-f]*)\.?(\d*)?/ =~ operand suffix = $1 number = $2 bit = $3 len = 16 case suffix when "X", "Y" number = number.to_i(16) else number = number.to_i end type_code = %W(X Y M - C T L SC CC TC D NOP - CS TS H SD).index(suffix) raise "undefind suffix: #{suffix}" if type_code.nil? case (type_code & 0xc) >> 2 when 0, 1 type_code |= 0x80 else type_code |= 0xa0 end if number < 256 codes = [type_code, number] else case endian when Asm::LITTLE_ENDIAN codes = [type_code | 0x10, number & 0xff, (number & 0xff00) >> 8] when Asm::BIG_ENDIAN codes = [type_code | 0x10, (number & 0xff00) >> 8, number & 0xff] end end # If mnemonic is out/outi and device type is timer or counter, append time or count. case mnemonic when /OUT/ case suffix when 'T' codes += time_value(value) when 'C' codes += counter_value(value) end end codes end
time_value(value)
click to toggle source
# File lib/ladder_drive/asm.rb, line 223 def time_value value raise SyntaxError.new "It must be required time value." unless /^\d*\.?\d*$/ =~ value t = value.to_f g = 0 codes = [] while t < 16384 && g <= 3 t *= 10.0 g += 1 end t /= 10.0 g -= 1 v = (g << 14) | t.to_i case endian when Asm::LITTLE_ENDIAN codes = [v & 0xff, (v & 0xff00) >> 8] when Asm::BIG_ENDIAN codes = [(v & 0xff00) >> 8, v & 0xff] end codes #rdlsf@de end