Skip to content

Commit

Permalink
Merge pull request #24 from kcelebi/dev
Browse files Browse the repository at this point in the history
Package Organization Fix, SB & Jump Fixed
  • Loading branch information
kcelebi authored Apr 10, 2023
2 parents 90e2daa + ff759d3 commit aac5b4e
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 35 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ dist
riscv_assembler.egg-info
build
.pytest_cache/
deprc_setup.py
deprc_setup.py
__pycache__/
Binary file modified src/riscv_assembler/__pycache__/convert.cpython-38.pyc
Binary file not shown.
Binary file modified src/riscv_assembler/__pycache__/instr_arr.cpython-38.pyc
Binary file not shown.
Binary file modified src/riscv_assembler/__pycache__/parse.cpython-38.pyc
Binary file not shown.
36 changes: 19 additions & 17 deletions src/riscv_assembler/instr_arr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

__all__ = [
'R_instr', 'I_instr', 'S_instr',
'SB_instr', 'U_instr', 'UJ_instr','pseudo_instr',
'SB_instr', 'U_instr', 'UJ_instr','pseudo_instr', 'JUMP',
'R', 'I', 'S', 'SB', 'U', 'UJ',
'Rp', 'Ip', 'Sp', 'SBp', 'Up', 'UJp', 'Psp']

Expand Down Expand Up @@ -69,7 +69,8 @@ def compute_instr(self, instr, rs1, imm, rd):
@staticmethod
def immediate(imm):
#return int(imm) - ((int(imm)>>12)<<12) # imm[11:0]
return format(int(imm), '012b')
return format(((1 << 12) - 1) & int(imm), '012b')
#return format(int(imm), '012b')

class _S(Instruction):
def __repr__(self):
Expand Down Expand Up @@ -97,7 +98,7 @@ def immediate(imm, n):
mod_imm_2 = int(imm) - ((int(imm) >> 5) << 5) # imm[4:0]
return mod_imm, mod_imm_2'''
mod_imm = format(((1 << 13) - 1) & int(imm), '013b')
mod_imm = format(((1 << 12) - 1) & int(imm), '012b')
if n == 1:
return mod_imm[0] + mod_imm[12-10 : 12-4]
return mod_imm[12-4 : 12 - 0] + mod_imm[1]
Expand Down Expand Up @@ -127,8 +128,8 @@ def compute_instr(self, instr, rs1, rs2, imm):
def immediate(imm, n):
mod_imm = format(((1 << 13) - 1) & int(imm), '013b')
if n == 1:
return mod_imm[12-12] + mod_imm[12-10:12-5]
return mod_imm[12-4:12-1] + mod_imm[12-11]
return mod_imm[12-12] + mod_imm[12-11:12-5]
return mod_imm[12-4:12-0] + mod_imm[12-11]

class _U(Instruction):
def __repr__(self):
Expand Down Expand Up @@ -201,10 +202,11 @@ def __str__(self):
return "I Parser"

def organize(self, tokens):
line_num, code = tokens[-2], tokens[-1]
instr, rs1, imm, rd = tokens[0], None, None, None
if instr == "jalr":
if len(tokens) == 4:
rs1, imm, rd = reg_map[tokens[2]], JUMP(tokens[3]), reg_map[tokens[1]]
rs1, imm, rd = reg_map[tokens[2]], JUMP(tokens[3], line_num, code), reg_map[tokens[1]]
else:
rs1, imm, rd = reg_map[tokens[1]], 0, reg_map["x1"]
elif instr == "lw":
Expand Down Expand Up @@ -235,7 +237,8 @@ def __str__(self):
return "SB Parser"

def organize(self, tokens):
instr, rs1, rs2, imm = tokens[0], reg_map[tokens[1]], reg_map[tokens[2]], JUMP(tokens[3])
line_num, code = tokens[-2], tokens[-1]
instr, rs1, rs2, imm = tokens[0], reg_map[tokens[1]], reg_map[tokens[2]], JUMP(tokens[3], line_num, code)
return SB(instr, rs1, rs2, imm)

class _U_parse(InstructionParser):
Expand All @@ -259,11 +262,12 @@ def __str__(self):
return "UJ Parser"

def organize(self, tokens):
line_num, code = tokens[-2], tokens[-1]
instr, imm, rd = tokens[0], None, None
if len(tokens) == 3:
imm, rd = JUMP(tokens[2]), reg_map[tokens[1]]
imm, rd = JUMP(tokens[2], line_num, code), reg_map[tokens[1]]
else:
imm, rd = JUMP(tokens[1]), reg_map["x1"]
imm, rd = JUMP(tokens[1], line_num, code), reg_map["x1"]

return UJ(instr, imm, rd)

Expand Down Expand Up @@ -292,27 +296,25 @@ def organize(self, tokens):

return BadInstructionError()

def JUMP(x : str, line_num : int) -> int:
raise NotImplementedError()

def JUMP(x : str, line_num : int, code: list) -> int:
# search forward
skip_labels = 0
for i in range(line_num, len(self.code)):
if x+":" == self.code[i]:
for i in range(line_num, len(code)):
if x+":" == code[i]:
jump_size = (i - line_num - skip_labels) * 4 # how many instructions to jump ahead
return jump_size

if self.code[i][-1] == ':':
if code[i][-1] == ':':
skip_labels += 1

# search backward
skip_labels = 0
for i in range(line_num, -1, -1):
# substruct correct label itself
if self.code[i][-1] == ':':
if code[i][-1] == ':':
skip_labels += 1

if x+":" == self.code[i]:
if x+":" == code[i]:
jump_size = (i - line_num + skip_labels) * 4 # how many instructions to jump behind
return jump_size

Expand Down
30 changes: 15 additions & 15 deletions src/riscv_assembler/parse.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from riscv_assembler.instr_arr import *
from types import FunctionType as function
from os.path import exists
__all__ = ['Parser']

class _Parser:
Expand All @@ -18,13 +19,12 @@ class _Parser:
'''

def __call__(self, *args) -> list:
if _Parser.is_file(*args):
return _Parser.interpret_file(_Parser.read_file(*args))
return [_Parser.interpret(_Parser.tokenize(x)) for x in args[0].split("\n") if len(_Parser.tokenize(x)) > 0]

@staticmethod
def is_file(x : str) -> bool:
return True if '.s' in x or '/' in x else False
if exists(*args):
return _Parser.interpret_arr(_Parser.read_file(*args))
#return [_Parser.interpret(_Parser.tokenize(x)) for x in args[0].split("\n") if len(_Parser.tokenize(x)) > 0]
elif type(args[0]) == str:
return _Parser.interpret_arr(args[0].split('\n'))
return _Parser.interpret_arr(*args)

'''
In read_file(), Check if the inputted line is appropriate before
Expand All @@ -35,7 +35,7 @@ def valid_line(x : str, allow_colon : bool = False) -> bool:
if x[0][0] == "#" or x[0][0] == "\n" or x[0][0] == "" or x[0][0] == ".":
return False

if not allow_colon and x[0][-1] == ":" :
if not allow_colon and x[-1] == ":" :
return False
return True

Expand Down Expand Up @@ -76,13 +76,13 @@ def read_file(file : str) -> list:
file.close()
return code'''
with open(file) as f:
return f.readlines()
return [x.strip() for x in f.readlines() if x != '\n']

@staticmethod
def interpret_file(code : list) -> list:
def interpret_arr(code : list) -> list:
int_code = []
for line in code:
tokens = _Parser.tokenize(line)
for line_num, line in enumerate(code):
tokens = _Parser.tokenize(line, line_num, code)
int_code += [_Parser.interpret(tokens) for _ in range(1) if len(tokens) != 0]

return int_code
Expand All @@ -91,12 +91,12 @@ def interpret_file(code : list) -> list:
Tokenize a given line
'''
@staticmethod
def tokenize(line : str) -> list:
def tokenize(line : str, line_num: int = None, code : list = None) -> list:
line = line.strip()
if len(line) > 0 and _Parser.valid_line(line, True):
if len(line) > 0 and _Parser.valid_line(line):
tokens = _Parser.handle_inline_comments(line).split()
tokens = _Parser.handle_specific_instr(tokens)
return tokens
return tokens + [line_num, code] if line_num != None and code != None else tokens
return []

'''
Expand Down
Binary file modified tests/__pycache__/test_class.cpython-38-pytest-7.2.2.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions tests/test_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ def test_11():
assert func11() == []

# Test file test2.s, need to implement JUMP
#def test_12():
# assert func12() == ['0x00a00413', '0x00a00493', '0x00848263', '0xfe040493']
def test_12():
assert func12() == ['0x00a00413', '0x00a00493', '0x00848263', '0xfe040493']

def test_13():
assert func13() == ['0x00812023']
Expand Down

0 comments on commit aac5b4e

Please sign in to comment.