Finishes assembler without symbols

This commit is contained in:
Nemo 2020-05-30 01:18:04 +05:30
parent 26018e28a1
commit 0d78eaae73
1 changed files with 80 additions and 26 deletions

View File

@ -1,29 +1,32 @@
# frozen_string_literal: true
fn = ARGV[0]
ic = 0
# Not implemented yet
class SymbolTable
end
class Code
DEST_MAP = {
'null' => [0, 0, 0],
'M' => [0, 0, 1],
'D' => [0, 1, 0],
'MD' => [0, 1, 1],
'A' => [1, 0, 0],
'AM' => [1, 0, 1],
'AD' => [1, 1, 0],
'AMD' => [1, 1, 1]
nil => "000",
'M' => "001",
'D' => "010",
'MD' => "011",
'A' => "100",
'AM' => "101",
'AD' => "110",
'AMD' => "111"
}.freeze
JUMP_MAP = {
'null' => [0, 0, 0],
'JGT' => [0, 0, 1],
'JEQ' => [0, 1, 0],
'JGE' => [0, 1, 1],
'JLT' => [1, 0, 0],
'JNE' => [1, 0, 1],
'JLE' => [1, 1, 0],
'JMP' => [1, 1, 1]
nil => "000",
'JGT' => "001",
'JEQ' => "010",
'JGE' => "011",
'JLT' => "100",
'JNE' => "101",
'JLE' => "110",
'JMP' => "111"
}.freeze
COMP_MAP = {
'0' => '101010',
@ -94,17 +97,44 @@ class Parser
end
end
def dest; end
def comp; end
def jump; end
def run
advance while more_commands?
def dest
return nil unless line.include? '='
line.split('=').first
end
def initialize(_file_name)
def comp
if dest and jump
line.split('=').last.split(';').first
elsif dest
line.split('=').first
elsif jump
line.split(';').first
else
line
end
end
def jump
return nil unless line.include? ';'
line.split(';').last
end
def run
res = []
while more_commands?
case command_type
when :A_COMMAND
res << [command_type, [symbol]]
when :C_COMMAND
res << [command_type, [dest, comp, jump]]
when :L_COMMAND
res << [command_type, [symbol]]
end
advance
end
res
end
def initialize(fn)
@ic = 0
@lines = []
File.readlines(fn).each do |line|
@ -116,3 +146,27 @@ class Parser
end
end
end
class Assembler
attr_reader :res
def initialize(fn)
@res = []
parser = Parser.new(fn)
parser.run.each do |command|
instruction = command[0]
case instruction
when :A_COMMAND
symbol = command[1][0]
@res << symbol.to_i.to_s(2).rjust(16, "0")
when :C_COMMAND
dest,comp,jump = command[1]
@res << "111#{Code.comp(comp)}#{Code.dest(dest)}#{Code.jump(jump)}"
end
end
end
end
if ARGV[0]
asm = Assembler.new(fn)
puts asm.res.join("\n")
end