diff --git a/ass2/main.cpp b/ass2/main.cpp index a9999ca..2a0111f 100644 --- a/ass2/main.cpp +++ b/ass2/main.cpp @@ -5,8 +5,8 @@ int main(int argc, char const *argv[]){ machine m; cpu procesor(&m); - m.loadObj("files/arithr.obj"); - //m.loadObj("files/cat.obj"); + //m.loadObj("files/arithr.obj"); + m.loadObj("files/cat.obj"); procesor.setSpeed(100); procesor.start(); /*stuff diff --git a/ass3/zbirnik/src/zbirnik/EmitCtx.py b/ass3/zbirnik/src/zbirnik/EmitCtx.py index d60955a..ba171d3 100644 --- a/ass3/zbirnik/src/zbirnik/EmitCtx.py +++ b/ass3/zbirnik/src/zbirnik/EmitCtx.py @@ -1,10 +1,11 @@ +from zbirnik.opcodes import OPCODES class EmitContext: REGISTERS = { 'A': 0, 'X': 1, 'L': 2, 'B': 3, 'S': 4, 'T': 5, 'F': 6 } - def __init__(self, opcodes, symtab): - self.opcodes = opcodes + def __init__(self, symtab): + self.opcodes = OPCODES self.symtab = symtab self.base = None diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc index f1955e1..9063204 100644 Binary files a/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc and b/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc index 02db896..c7f9fc4 100644 Binary files a/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc and b/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/opcodes.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/opcodes.cpython-310.pyc new file mode 100644 index 0000000..7e6f126 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/__pycache__/opcodes.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/parser.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000..1f6d182 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/__pycache__/parser.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/parserctx.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/parserctx.cpython-310.pyc new file mode 100644 index 0000000..0e4c047 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/__pycache__/parserctx.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/parsetab.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/parsetab.cpython-310.pyc new file mode 100644 index 0000000..526994c Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/__pycache__/parsetab.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/code.py b/ass3/zbirnik/src/zbirnik/code.py index 5ed7455..a709a14 100644 --- a/ass3/zbirnik/src/zbirnik/code.py +++ b/ass3/zbirnik/src/zbirnik/code.py @@ -23,7 +23,7 @@ class Code: # START if node.__class__.__name__ == "directive" and node.name == "START": - self.start_address = node.value + self.start_address = node.operand locctr = self.start_address self.name = node.label node.address = locctr @@ -40,8 +40,8 @@ class Code: # END if node.__class__.__name__ == "directive" and node.name == "END": - if node.value is not None: - self.entry_point = node.value + if node.operand is not None: + self.entry_point = node.operand break locctr += node.size() diff --git a/ass3/zbirnik/src/zbirnik/main.py b/ass3/zbirnik/src/zbirnik/main.py index 929cb4d..bc79da3 100644 --- a/ass3/zbirnik/src/zbirnik/main.py +++ b/ass3/zbirnik/src/zbirnik/main.py @@ -2,10 +2,11 @@ from zbirnik.parser import parser from zbirnik.code import Code from zbirnik.EmitCtx import EmitContext from zbirnik.mnemoniki.mnemoniki_tabela import MNEMONICS -from zbirnik.opcodes import OPCODES +from zbirnik.parserctx import ParserContext +import os -print("Vnesite ime programa (.asm), ki je v istem direktoriju kakor main.py: ") -ime = input() +ime = input("Vnesite ime programa (.asm): ") +ime = os.path.join(os.path.dirname(__file__), ime) if not ime.endswith(".asm"): raise ValueError("Ime programa ni v pravi obliki, mora biti: ime.asm") @@ -14,19 +15,28 @@ code = Code() with open(ime) as f: for line in f: - ctx = parser.parse(line) + print("LINE:", line.rstrip()) + + rez = parser.parse(line) + ctx = ParserContext(rez) + #print("CTX:", ctx) if ctx is None: + print(" -> komentar / prazna vrstica") continue + print(" label =", ctx.label) + print(" mnemonic=", ctx.mnemonic) + print(" operands=", ctx.operands) + print("-" * 40) mnemonic = MNEMONICS[ctx.mnemonic] node = mnemonic.parse(ctx) code.add(node) - + code.pass1() -ctx_emit = EmitContext(opcodes=OPCODES,symtab=code.symtab) +ctx_emit = EmitContext(symtab=code.symtab) binary = code.pass2(ctx_emit) print(binary.hex()) diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/__init__.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..36bb3ea Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/__init__.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonic.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonic.cpython-310.pyc new file mode 100644 index 0000000..4eea10d Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonic.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicD.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicD.cpython-310.pyc new file mode 100644 index 0000000..b58c779 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicD.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicDn.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicDn.cpython-310.pyc new file mode 100644 index 0000000..d9e69e7 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicDn.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF1.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF1.cpython-310.pyc new file mode 100644 index 0000000..d43c1c0 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF1.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2n.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2n.cpython-310.pyc new file mode 100644 index 0000000..6e7c5a0 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2n.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2r.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2r.cpython-310.pyc new file mode 100644 index 0000000..8296718 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2r.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rn.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rn.cpython-310.pyc new file mode 100644 index 0000000..d8780a7 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rn.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rr.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rr.cpython-310.pyc new file mode 100644 index 0000000..86eb1a3 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF2rr.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3.cpython-310.pyc new file mode 100644 index 0000000..331e9a6 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3m.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3m.cpython-310.pyc new file mode 100644 index 0000000..75f01dc Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF3m.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF4m.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF4m.cpython-310.pyc new file mode 100644 index 0000000..f0eee9e Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicF4m.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSd.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSd.cpython-310.pyc new file mode 100644 index 0000000..f8f7dc2 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSd.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSn.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSn.cpython-310.pyc new file mode 100644 index 0000000..a125d91 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemonicSn.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemoniki_tabela.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemoniki_tabela.cpython-310.pyc new file mode 100644 index 0000000..921ac79 Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/mnemoniki/__pycache__/mnemoniki_tabela.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicD.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicD.py index fbe3ffd..fa70488 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicD.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicD.py @@ -1,8 +1,8 @@ from zbirnik.ukazi.directive import directive -from mnemonic import Mnemonic +from zbirnik.mnemoniki.mnemonic import Mnemonic from zbirnik.parserctx import ParserContext class MnemonicD(Mnemonic): def parse(self, parser: ParserContext): - return directive(direktiva=self.name, label=parser.label, + return directive(name=self.name, label=parser.label, operand=None) diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicDn.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicDn.py index 2e37658..3ceb5be 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicDn.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicDn.py @@ -1,8 +1,8 @@ from zbirnik.ukazi.directive import directive -from mnemonic import Mnemonic +from zbirnik.mnemoniki.mnemonic import Mnemonic from zbirnik.parserctx import ParserContext class MnemonicDn(Mnemonic): def parse(self, parser: ParserContext): - return directive(direktiva=self.name, label=parser.label, + return directive(name=self.name, label=parser.label, operand=parser.read_num_sym()) diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF1.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF1.py index 2e10727..5ddbeff 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF1.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF1.py @@ -1,4 +1,4 @@ -from mnemonic import Mnemonic +from zbirnik.mnemoniki.mnemonic import Mnemonic from zbirnik.ukazi.f1 import f1 class MnemonicF1(Mnemonic): diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF2.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF2.py index 464ac67..7896a51 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF2.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicF2.py @@ -3,7 +3,7 @@ from zbirnik.ukazi.f2 import f2 from zbirnik.parserctx import ParserContext -class mnemonicF2(Mnemonic): +class MemonicF2(Mnemonic): def parse(self, parser: ParserContext): return f2(r1=parser.read_reg(), r2=parser.read_reg(), mnemonic=self.name, label=parser.label) \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSd.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSd.py index d582b96..53639e1 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSd.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSd.py @@ -4,4 +4,4 @@ from zbirnik.parserctx import ParserContext class MnemonicSd(Mnemonic): def parse(self, parser: ParserContext): - return storage(label=parser.label, name=self.name, val=parser.read_num_sym()) + return storage(label=parser.label, name=self.name, value=parser.read_num_sym()) diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSn.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSn.py index ab19eea..b8a6d4b 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSn.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemonicSn.py @@ -5,4 +5,4 @@ from zbirnik.parserctx import ParserContext class MnemonicSn(Mnemonic): def parse(self, parser: ParserContext): - return storage(label=parser.label, name=self.name, val=parser.read_num_sym()) + return storage(label=parser.label, name=self.name, value=parser.read_num_sym()) diff --git a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemoniki_tabela.py b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemoniki_tabela.py index d51f052..80bfbb7 100644 --- a/ass3/zbirnik/src/zbirnik/mnemoniki/mnemoniki_tabela.py +++ b/ass3/zbirnik/src/zbirnik/mnemoniki/mnemoniki_tabela.py @@ -1,70 +1,76 @@ -from zbirnik.mnemoniki import ( - mnemonicD, mnemonicDn, - mnemonicF1, mnemonicF2n, mnemonicF2r, mnemonicF2rn, mnemonicF2rr, - mnemonicF3, mnemonicF3m, mnemonicF4m, - mnemonicSd, mnemonicSn -) +from zbirnik.mnemoniki.mnemonicD import MnemonicD +from zbirnik.mnemoniki.mnemonicDn import MnemonicDn +from zbirnik.mnemoniki.mnemonicF1 import MnemonicF1 +from zbirnik.mnemoniki.mnemonicF2n import MnemonicF2n +from zbirnik.mnemoniki.mnemonicF2r import MnemonicF2r +from zbirnik.mnemoniki.mnemonicF2rn import MnemonicF2rn +from zbirnik.mnemoniki.mnemonicF2rr import MnemonicF2rr +from zbirnik.mnemoniki.mnemonicF3 import MnemonicF3 +from zbirnik.mnemoniki.mnemonicF3m import MnemonicF3m +from zbirnik.mnemoniki.mnemonicF4m import MnemonicF4m +from zbirnik.mnemoniki.mnemonicSd import MnemonicSd +from zbirnik.mnemoniki.mnemonicSn import MnemonicSn -# Centralna tabela mnemonikov +# Centralna tabela Mnemonikov MNEMONICS = { # Direktive (brez operandov) - 'NOBASE': mnemonicD('NOBASE'), - 'LTORG': mnemonicD('LTORG'), + 'NOBASE': MnemonicD('NOBASE'), + 'LTORG': MnemonicD('LTORG'), # Direktive (en operand) - 'START': mnemonicDn('START'), - 'END': mnemonicDn('END'), - 'BASE': mnemonicDn('BASE'), + 'START': MnemonicDn('START'), + 'END': MnemonicDn('END'), + 'BASE': MnemonicDn('BASE'), # Format 1 (brez operandov) - 'FIX': mnemonicF1('FIX', opcode=0xC4), - 'FLOAT': mnemonicF1('FLOAT', opcode=0xC0), - 'HIO': mnemonicF1('HIO', opcode=0xF4), - 'NORM': mnemonicF1('NORM', opcode=0xC8), - 'SIO': mnemonicF1('SIO', opcode=0xF0), - 'TIO': mnemonicF1('TIO', opcode=0xF8), + 'FIX': MnemonicF1('FIX', opcode=0xC4), + 'FLOAT': MnemonicF1('FLOAT', opcode=0xC0), + 'HIO': MnemonicF1('HIO', opcode=0xF4), + 'NORM': MnemonicF1('NORM', opcode=0xC8), + 'SIO': MnemonicF1('SIO', opcode=0xF0), + 'TIO': MnemonicF1('TIO', opcode=0xF8), # Format 2 # F2 – en številčni operand - 'SVC': mnemonicF2n('SVC', opcode=0xB0), + 'SVC': MnemonicF2n('SVC', opcode=0xB0), # F2 – en register - 'CLEAR': mnemonicF2r('CLEAR', opcode=0xB4), - 'TIXR': mnemonicF2r('TIXR', opcode=0xB8), + 'CLEAR': MnemonicF2r('CLEAR', opcode=0xB4), + 'TIXR': MnemonicF2r('TIXR', opcode=0xB8), # F2 – register + število - 'SHIFTL': mnemonicF2rn('SHIFTL', opcode=0xA4), - 'SHIFTR': mnemonicF2rn('SHIFTR', opcode=0xA8), + 'SHIFTL': MnemonicF2rn('SHIFTL', opcode=0xA4), + 'SHIFTR': MnemonicF2rn('SHIFTR', opcode=0xA8), # F2 – dva registra - 'ADDR': mnemonicF2rr('ADDR', opcode=0x90), - 'SUBR': mnemonicF2rr('SUBR', opcode=0x94), - 'MULR': mnemonicF2rr('MULR', opcode=0x98), - 'DIVR': mnemonicF2rr('DIVR', opcode=0x9C), - 'COMPR': mnemonicF2rr('COMPR', opcode=0xA0), + 'ADDR': MnemonicF2rr('ADDR', opcode=0x90), + 'SUBR': MnemonicF2rr('SUBR', opcode=0x94), + 'MULR': MnemonicF2rr('MULR', opcode=0x98), + 'DIVR': MnemonicF2rr('DIVR', opcode=0x9C), + 'COMPR': MnemonicF2rr('COMPR', opcode=0xA0), # Format 3 - 'RSUB': mnemonicF3('RSUB', opcode=0x4C), - 'LDA': mnemonicF3m('LDA', opcode=0x00), - 'LDX': mnemonicF3m('LDX', opcode=0x04), - 'LDL': mnemonicF3m('LDL', opcode=0x08), - 'STA': mnemonicF3m('STA', opcode=0x0C), - 'STX': mnemonicF3m('STX', opcode=0x10), - 'STL': mnemonicF3m('STL', opcode=0x14), - 'ADD': mnemonicF3m('ADD', opcode=0x18), - 'SUB': mnemonicF3m('SUB', opcode=0x1C), - 'MUL': mnemonicF3m('MUL', opcode=0x20), - 'DIV': mnemonicF3m('DIV', opcode=0x24), - 'COMP': mnemonicF3m('COMP', opcode=0x28), - 'J': mnemonicF3m('J', opcode=0x3C), - 'JEQ': mnemonicF3m('JEQ', opcode=0x30), - 'JGT': mnemonicF3m('JGT', opcode=0x34), - 'JLT': mnemonicF3m('JLT', opcode=0x38), - 'JSUB': mnemonicF3m('JSUB', opcode=0x48), - 'TD': mnemonicF3m('TD', opcode=0xE0), - 'RD': mnemonicF3m('RD', opcode=0xD8), - 'WD': mnemonicF3m('WD', opcode=0xDC), + 'RSUB': MnemonicF3('RSUB', opcode=0x4C), + 'LDA': MnemonicF3m('LDA', opcode=0x00), + 'LDX': MnemonicF3m('LDX', opcode=0x04), + 'LDL': MnemonicF3m('LDL', opcode=0x08), + 'STA': MnemonicF3m('STA', opcode=0x0C), + 'STX': MnemonicF3m('STX', opcode=0x10), + 'STL': MnemonicF3m('STL', opcode=0x14), + 'ADD': MnemonicF3m('ADD', opcode=0x18), + 'SUB': MnemonicF3m('SUB', opcode=0x1C), + 'MUL': MnemonicF3m('MUL', opcode=0x20), + 'DIV': MnemonicF3m('DIV', opcode=0x24), + 'COMP': MnemonicF3m('COMP', opcode=0x28), + 'J': MnemonicF3m('J', opcode=0x3C), + 'JEQ': MnemonicF3m('JEQ', opcode=0x30), + 'JGT': MnemonicF3m('JGT', opcode=0x34), + 'JLT': MnemonicF3m('JLT', opcode=0x38), + 'JSUB': MnemonicF3m('JSUB', opcode=0x48), + 'TD': MnemonicF3m('TD', opcode=0xE0), + 'RD': MnemonicF3m('RD', opcode=0xD8), + 'WD': MnemonicF3m('WD', opcode=0xDC), # Format 4 (razširjeni) - '+LDA': mnemonicF4m('+LDA', opcode=0x00), - '+JSUB': mnemonicF4m('+JSUB', opcode=0x48), + '+LDA': MnemonicF4m('+LDA', opcode=0x00), + '+JSUB': MnemonicF4m('+JSUB', opcode=0x48), # Pomnilniške direktive # podatki - 'BYTE': mnemonicSd('BYTE'), - 'WORD': mnemonicSd('WORD'), + 'BYTE': MnemonicSd('BYTE'), + 'WORD': MnemonicSd('WORD'), # rezervacija - 'RESB': mnemonicSn('RESB'), - 'RESW': mnemonicSn('RESW'), + 'RESB': MnemonicSn('RESB'), + 'RESW': MnemonicSn('RESW'), } diff --git a/ass3/zbirnik/src/zbirnik/parser.out b/ass3/zbirnik/src/zbirnik/parser.out index 90bdd00..43ff9ae 100644 --- a/ass3/zbirnik/src/zbirnik/parser.out +++ b/ass3/zbirnik/src/zbirnik/parser.out @@ -3,54 +3,79 @@ Created by PLY version 3.11 (http://www.dabeaz.com/ply) Grammar Rule 0 S' -> start -Rule 1 start -> LABEL command -Rule 2 start -> command -Rule 3 command -> MNEMONIC -Rule 4 command -> MNEMONIC args -Rule 5 args -> operand -Rule 6 args -> operand COMMA operand -Rule 7 operand -> REGISTER -Rule 8 operand -> AT address -Rule 9 operand -> HASH address -Rule 10 operand -> address -Rule 11 address -> NUMBER -Rule 12 address -> SYMBOL +Rule 1 start -> LABEL statement +Rule 2 start -> statement +Rule 3 statement -> instruction +Rule 4 statement -> directive +Rule 5 instruction -> MNEMONIC +Rule 6 instruction -> MNEMONIC args +Rule 7 directive -> DIRECTIVE +Rule 8 directive -> DIRECTIVE directive_args +Rule 9 directive_args -> directive_arg +Rule 10 directive_args -> directive_arg COMMA directive_arg +Rule 11 directive_arg -> NUMBER +Rule 12 directive_arg -> SYMBOL +Rule 13 directive_arg -> STRING +Rule 14 directive_arg -> operand +Rule 15 args -> operand +Rule 16 args -> operand COMMA operand +Rule 17 operand -> REGISTER +Rule 18 operand -> AT address +Rule 19 operand -> HASH address +Rule 20 operand -> PLUS address +Rule 21 operand -> address +Rule 22 address -> NUMBER +Rule 23 address -> SYMBOL Terminals, with rules where they appear -AT : 8 -COMMA : 6 -HASH : 9 +AT : 18 +COMMA : 10 16 +DIRECTIVE : 7 8 +HASH : 19 LABEL : 1 -MNEMONIC : 3 4 -NUMBER : 11 -REGISTER : 7 -SYMBOL : 12 +MNEMONIC : 5 6 +NUMBER : 11 22 +PLUS : 20 +REGISTER : 17 +STRING : 13 +SYMBOL : 12 23 error : Nonterminals, with rules where they appear -address : 8 9 10 -args : 4 -command : 1 2 -operand : 5 6 6 +address : 18 19 20 21 +args : 6 +directive : 4 +directive_arg : 9 10 10 +directive_args : 8 +instruction : 3 +operand : 14 15 16 16 start : 0 +statement : 1 2 Parsing method: LALR state 0 (0) S' -> . start - (1) start -> . LABEL command - (2) start -> . command - (3) command -> . MNEMONIC - (4) command -> . MNEMONIC args + (1) start -> . LABEL statement + (2) start -> . statement + (3) statement -> . instruction + (4) statement -> . directive + (5) instruction -> . MNEMONIC + (6) instruction -> . MNEMONIC args + (7) directive -> . DIRECTIVE + (8) directive -> . DIRECTIVE directive_args LABEL shift and go to state 2 - MNEMONIC shift and go to state 4 + MNEMONIC shift and go to state 6 + DIRECTIVE shift and go to state 7 start shift and go to state 1 - command shift and go to state 3 + statement shift and go to state 3 + instruction shift and go to state 4 + directive shift and go to state 5 state 1 @@ -60,160 +85,337 @@ state 1 state 2 - (1) start -> LABEL . command - (3) command -> . MNEMONIC - (4) command -> . MNEMONIC args + (1) start -> LABEL . statement + (3) statement -> . instruction + (4) statement -> . directive + (5) instruction -> . MNEMONIC + (6) instruction -> . MNEMONIC args + (7) directive -> . DIRECTIVE + (8) directive -> . DIRECTIVE directive_args - MNEMONIC shift and go to state 4 + MNEMONIC shift and go to state 6 + DIRECTIVE shift and go to state 7 - command shift and go to state 5 + statement shift and go to state 8 + instruction shift and go to state 4 + directive shift and go to state 5 state 3 - (2) start -> command . + (2) start -> statement . - $end reduce using rule 2 (start -> command .) + $end reduce using rule 2 (start -> statement .) state 4 - (3) command -> MNEMONIC . - (4) command -> MNEMONIC . args - (5) args -> . operand - (6) args -> . operand COMMA operand - (7) operand -> . REGISTER - (8) operand -> . AT address - (9) operand -> . HASH address - (10) operand -> . address - (11) address -> . NUMBER - (12) address -> . SYMBOL + (3) statement -> instruction . - $end reduce using rule 3 (command -> MNEMONIC .) - REGISTER shift and go to state 8 - AT shift and go to state 9 - HASH shift and go to state 11 - NUMBER shift and go to state 12 - SYMBOL shift and go to state 13 + $end reduce using rule 3 (statement -> instruction .) - args shift and go to state 6 - operand shift and go to state 7 - address shift and go to state 10 state 5 - (1) start -> LABEL command . + (4) statement -> directive . - $end reduce using rule 1 (start -> LABEL command .) + $end reduce using rule 4 (statement -> directive .) state 6 - (4) command -> MNEMONIC args . + (5) instruction -> MNEMONIC . + (6) instruction -> MNEMONIC . args + (15) args -> . operand + (16) args -> . operand COMMA operand + (17) operand -> . REGISTER + (18) operand -> . AT address + (19) operand -> . HASH address + (20) operand -> . PLUS address + (21) operand -> . address + (22) address -> . NUMBER + (23) address -> . SYMBOL - $end reduce using rule 4 (command -> MNEMONIC args .) + $end reduce using rule 5 (instruction -> MNEMONIC .) + REGISTER shift and go to state 11 + AT shift and go to state 12 + HASH shift and go to state 14 + PLUS shift and go to state 15 + NUMBER shift and go to state 16 + SYMBOL shift and go to state 17 + args shift and go to state 9 + operand shift and go to state 10 + address shift and go to state 13 state 7 - (5) args -> operand . - (6) args -> operand . COMMA operand + (7) directive -> DIRECTIVE . + (8) directive -> DIRECTIVE . directive_args + (9) directive_args -> . directive_arg + (10) directive_args -> . directive_arg COMMA directive_arg + (11) directive_arg -> . NUMBER + (12) directive_arg -> . SYMBOL + (13) directive_arg -> . STRING + (14) directive_arg -> . operand + (17) operand -> . REGISTER + (18) operand -> . AT address + (19) operand -> . HASH address + (20) operand -> . PLUS address + (21) operand -> . address + (22) address -> . NUMBER + (23) address -> . SYMBOL - $end reduce using rule 5 (args -> operand .) - COMMA shift and go to state 14 + $end reduce using rule 7 (directive -> DIRECTIVE .) + NUMBER shift and go to state 20 + SYMBOL shift and go to state 21 + STRING shift and go to state 22 + REGISTER shift and go to state 11 + AT shift and go to state 12 + HASH shift and go to state 14 + PLUS shift and go to state 15 + directive_args shift and go to state 18 + directive_arg shift and go to state 19 + operand shift and go to state 23 + address shift and go to state 13 state 8 - (7) operand -> REGISTER . + (1) start -> LABEL statement . - COMMA reduce using rule 7 (operand -> REGISTER .) - $end reduce using rule 7 (operand -> REGISTER .) + $end reduce using rule 1 (start -> LABEL statement .) state 9 - (8) operand -> AT . address - (11) address -> . NUMBER - (12) address -> . SYMBOL + (6) instruction -> MNEMONIC args . - NUMBER shift and go to state 12 - SYMBOL shift and go to state 13 + $end reduce using rule 6 (instruction -> MNEMONIC args .) - address shift and go to state 15 state 10 - (10) operand -> address . + (15) args -> operand . + (16) args -> operand . COMMA operand - COMMA reduce using rule 10 (operand -> address .) - $end reduce using rule 10 (operand -> address .) + $end reduce using rule 15 (args -> operand .) + COMMA shift and go to state 24 state 11 - (9) operand -> HASH . address - (11) address -> . NUMBER - (12) address -> . SYMBOL + (17) operand -> REGISTER . - NUMBER shift and go to state 12 - SYMBOL shift and go to state 13 + COMMA reduce using rule 17 (operand -> REGISTER .) + $end reduce using rule 17 (operand -> REGISTER .) - address shift and go to state 16 state 12 - (11) address -> NUMBER . + (18) operand -> AT . address + (22) address -> . NUMBER + (23) address -> . SYMBOL - COMMA reduce using rule 11 (address -> NUMBER .) - $end reduce using rule 11 (address -> NUMBER .) + NUMBER shift and go to state 16 + SYMBOL shift and go to state 17 + address shift and go to state 25 state 13 - (12) address -> SYMBOL . + (21) operand -> address . - COMMA reduce using rule 12 (address -> SYMBOL .) - $end reduce using rule 12 (address -> SYMBOL .) + COMMA reduce using rule 21 (operand -> address .) + $end reduce using rule 21 (operand -> address .) state 14 - (6) args -> operand COMMA . operand - (7) operand -> . REGISTER - (8) operand -> . AT address - (9) operand -> . HASH address - (10) operand -> . address - (11) address -> . NUMBER - (12) address -> . SYMBOL + (19) operand -> HASH . address + (22) address -> . NUMBER + (23) address -> . SYMBOL - REGISTER shift and go to state 8 - AT shift and go to state 9 - HASH shift and go to state 11 - NUMBER shift and go to state 12 - SYMBOL shift and go to state 13 + NUMBER shift and go to state 16 + SYMBOL shift and go to state 17 - operand shift and go to state 17 - address shift and go to state 10 + address shift and go to state 26 state 15 - (8) operand -> AT address . + (20) operand -> PLUS . address + (22) address -> . NUMBER + (23) address -> . SYMBOL - COMMA reduce using rule 8 (operand -> AT address .) - $end reduce using rule 8 (operand -> AT address .) + NUMBER shift and go to state 16 + SYMBOL shift and go to state 17 + address shift and go to state 27 state 16 - (9) operand -> HASH address . + (22) address -> NUMBER . - COMMA reduce using rule 9 (operand -> HASH address .) - $end reduce using rule 9 (operand -> HASH address .) + COMMA reduce using rule 22 (address -> NUMBER .) + $end reduce using rule 22 (address -> NUMBER .) state 17 - (6) args -> operand COMMA operand . + (23) address -> SYMBOL . - $end reduce using rule 6 (args -> operand COMMA operand .) + COMMA reduce using rule 23 (address -> SYMBOL .) + $end reduce using rule 23 (address -> SYMBOL .) + +state 18 + + (8) directive -> DIRECTIVE directive_args . + + $end reduce using rule 8 (directive -> DIRECTIVE directive_args .) + + +state 19 + + (9) directive_args -> directive_arg . + (10) directive_args -> directive_arg . COMMA directive_arg + + $end reduce using rule 9 (directive_args -> directive_arg .) + COMMA shift and go to state 28 + + +state 20 + + (11) directive_arg -> NUMBER . + (22) address -> NUMBER . + + ! reduce/reduce conflict for COMMA resolved using rule 11 (directive_arg -> NUMBER .) + ! reduce/reduce conflict for $end resolved using rule 11 (directive_arg -> NUMBER .) + COMMA reduce using rule 11 (directive_arg -> NUMBER .) + $end reduce using rule 11 (directive_arg -> NUMBER .) + + ! COMMA [ reduce using rule 22 (address -> NUMBER .) ] + ! $end [ reduce using rule 22 (address -> NUMBER .) ] + + +state 21 + + (12) directive_arg -> SYMBOL . + (23) address -> SYMBOL . + + ! reduce/reduce conflict for COMMA resolved using rule 12 (directive_arg -> SYMBOL .) + ! reduce/reduce conflict for $end resolved using rule 12 (directive_arg -> SYMBOL .) + COMMA reduce using rule 12 (directive_arg -> SYMBOL .) + $end reduce using rule 12 (directive_arg -> SYMBOL .) + + ! COMMA [ reduce using rule 23 (address -> SYMBOL .) ] + ! $end [ reduce using rule 23 (address -> SYMBOL .) ] + + +state 22 + + (13) directive_arg -> STRING . + + COMMA reduce using rule 13 (directive_arg -> STRING .) + $end reduce using rule 13 (directive_arg -> STRING .) + + +state 23 + + (14) directive_arg -> operand . + + COMMA reduce using rule 14 (directive_arg -> operand .) + $end reduce using rule 14 (directive_arg -> operand .) + + +state 24 + + (16) args -> operand COMMA . operand + (17) operand -> . REGISTER + (18) operand -> . AT address + (19) operand -> . HASH address + (20) operand -> . PLUS address + (21) operand -> . address + (22) address -> . NUMBER + (23) address -> . SYMBOL + + REGISTER shift and go to state 11 + AT shift and go to state 12 + HASH shift and go to state 14 + PLUS shift and go to state 15 + NUMBER shift and go to state 16 + SYMBOL shift and go to state 17 + + operand shift and go to state 29 + address shift and go to state 13 + +state 25 + + (18) operand -> AT address . + + COMMA reduce using rule 18 (operand -> AT address .) + $end reduce using rule 18 (operand -> AT address .) + + +state 26 + + (19) operand -> HASH address . + + COMMA reduce using rule 19 (operand -> HASH address .) + $end reduce using rule 19 (operand -> HASH address .) + + +state 27 + + (20) operand -> PLUS address . + + COMMA reduce using rule 20 (operand -> PLUS address .) + $end reduce using rule 20 (operand -> PLUS address .) + + +state 28 + + (10) directive_args -> directive_arg COMMA . directive_arg + (11) directive_arg -> . NUMBER + (12) directive_arg -> . SYMBOL + (13) directive_arg -> . STRING + (14) directive_arg -> . operand + (17) operand -> . REGISTER + (18) operand -> . AT address + (19) operand -> . HASH address + (20) operand -> . PLUS address + (21) operand -> . address + (22) address -> . NUMBER + (23) address -> . SYMBOL + + NUMBER shift and go to state 20 + SYMBOL shift and go to state 21 + STRING shift and go to state 22 + REGISTER shift and go to state 11 + AT shift and go to state 12 + HASH shift and go to state 14 + PLUS shift and go to state 15 + + directive_arg shift and go to state 30 + operand shift and go to state 23 + address shift and go to state 13 + +state 29 + + (16) args -> operand COMMA operand . + + $end reduce using rule 16 (args -> operand COMMA operand .) + + +state 30 + + (10) directive_args -> directive_arg COMMA directive_arg . + + $end reduce using rule 10 (directive_args -> directive_arg COMMA directive_arg .) + +WARNING: +WARNING: Conflicts: +WARNING: +WARNING: reduce/reduce conflict in state 20 resolved using rule (directive_arg -> NUMBER) +WARNING: rejected rule (address -> NUMBER) in state 20 +WARNING: reduce/reduce conflict in state 21 resolved using rule (directive_arg -> SYMBOL) +WARNING: rejected rule (address -> SYMBOL) in state 21 diff --git a/ass3/zbirnik/src/zbirnik/parser.py b/ass3/zbirnik/src/zbirnik/parser.py index db9617f..9987e09 100644 --- a/ass3/zbirnik/src/zbirnik/parser.py +++ b/ass3/zbirnik/src/zbirnik/parser.py @@ -1,125 +1,191 @@ import ply.lex import ply.yacc -from zbirnik.parserctx import ParserContext +#import sys -# -------------------- +global at_line_start, seen_mnemonic_or_directive # Lexer -# -------------------- tokens = ( 'AT', 'COMMA', 'HASH', + 'PLUS', 'LABEL', 'REGISTER', 'MNEMONIC', + 'DIRECTIVE', 'SYMBOL', 'NUMBER', - 'COMMENT', + 'STRING', ) t_AT = r'@' t_COMMA = r',' t_HASH = r'\#' -t_LABEL = r'^[a-z_0-9]+' +t_PLUS = r'\+' t_REGISTER = r'\b[ABFLSTX]\b' -t_MNEMONIC = r'\b[A-Z]+\b' -t_SYMBOL = r'[a-z_0-9]+' + +# Assembler directives +directives = { + 'START', 'END', 'BYTE', 'WORD', 'RESB', 'RESW', + 'BASE', 'NOBASE', 'EQU', 'ORG', 'LTORG', 'USE', + 'EXTDEF', 'EXTREF', 'CSECT' +} + +# Track if we're at the start of a line +at_line_start = True +seen_mnemonic_or_directive = False + +def t_WHITESPACE(t): + r'[ \t]+' + global at_line_start + # If we see whitespace at line start, we're no longer at start + if at_line_start: + at_line_start = False + pass # Don't return token + +def t_STRING(t): + r'[CX]\'[^\']*\'' + global at_line_start + at_line_start = False + return t + +def t_IDENTIFIER(t): + r'[a-zA-Z_][a-zA-Z_0-9]*' + global at_line_start, seen_mnemonic_or_directive + + # If at start of line, it's a label + if at_line_start: + t.type = 'LABEL' + at_line_start = False + return t + + # After we've seen a mnemonic/directive, everything else is a symbol + if seen_mnemonic_or_directive: + t.type = 'SYMBOL' + return t + + # First identifier after whitespace - check if it's directive or mnemonic + if t.value in directives: + t.type = 'DIRECTIVE' + seen_mnemonic_or_directive = True + else: + # Assume it's a mnemonic if uppercase, otherwise symbol + if t.value.isupper(): + t.type = 'MNEMONIC' + seen_mnemonic_or_directive = True + else: + t.type = 'SYMBOL' + + return t def t_NUMBER(t): - r'-?\d+' - t.value = int(t.value) + r'-?(?:0[xX][0-9a-fA-F]+|\d+)' + global at_line_start + at_line_start = False + t.value = int(t.value, 0) # Handles hex (0x) and decimal return t -def t_COMMENT(t): - r'\..*' - t.value = t.value[1:].strip() - return t +t_ignore_COMMENT = r'\..*' -t_ignore = ' \t\n' +def t_newline(t): + r'\n+' + global at_line_start, seen_mnemonic_or_directive + at_line_start = True + seen_mnemonic_or_directive = False + t.lexer.lineno += len(t.value) def t_error(t): - print(f"Illegal character {t.value[0]!r}") + print(f'Illegal character {t.value[0]!r}') t.lexer.skip(1) lexer = ply.lex.lex() -# -------------------- # Parser -# -------------------- - def p_start(p): - r'''start : LABEL command - | command - | COMMENT - ''' - # komentar - if len(p) == 2 and isinstance(p[1], str): - p[0] = None - return - - # brez labela - if len(p) == 2: - label = None - mnemonic, operands = p[1] + '''start : LABEL statement + | statement''' + if len(p) == 3: + # Has label + p[0] = (p[1], p[2][0], *p[2][1:]) else: - label = p[1] - mnemonic, operands = p[2] + # No label + p[0] = (None, p[1][0], *p[1][1:]) - p[0] = ParserContext(label, mnemonic, operands) +def p_statement(p): + '''statement : instruction + | directive''' + p[0] = p[1] - -def p_command(p): - r'''command : MNEMONIC - | MNEMONIC args - ''' +def p_instruction(p): + '''instruction : MNEMONIC + | MNEMONIC args''' if len(p) == 2: - p[0] = (p[1], []) + p[0] = [p[1]] else: - p[0] = (p[1], list(p[2])) + p[0] = [p[1]] + list(p[2]) +def p_directive(p): + '''directive : DIRECTIVE + | DIRECTIVE directive_args''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1]] + list(p[2]) -def p_args(p): - r'''args : operand - | operand COMMA operand - ''' +def p_directive_args(p): + '''directive_args : directive_arg + | directive_arg COMMA directive_arg''' if len(p) == 2: p[0] = [p[1]] else: p[0] = [p[1], p[3]] +def p_directive_arg(p): + '''directive_arg : NUMBER + | SYMBOL + | STRING + | operand''' + p[0] = p[1] + +def p_args(p): + '''args : operand + | operand COMMA operand''' + if len(p) == 2: + p[0] = [p[1]] + else: + p[0] = [p[1], p[3]] def p_operand(p): - r'''operand : REGISTER + '''operand : REGISTER | AT address | HASH address - | address - ''' + | PLUS address + | address''' if len(p) == 2: p[0] = p[1] else: - # @X ali #5 → zadrži znak + # Combine prefix with address p[0] = (p[1], p[2]) - def p_address(p): - r'''address : NUMBER - | SYMBOL - ''' + '''address : NUMBER + | SYMBOL''' p[0] = p[1] - def p_error(p): if p: - raise SyntaxError(f"Syntax error at token {p}") + print(f'Syntax error at token {p.type}={p.value!r}') else: - raise SyntaxError("Syntax error at EOF") - + print('Syntax error at EOF') parser = ply.yacc.yacc() -if __name__ == '__main__': - import sys - parser = ply.yacc.yacc() - for line in sys.stdin: - print(parser.parse(line)) +#if __name__ == '__main__': +# for line in sys.stdin: +# line = line.rstrip('\n\r') +# if line and not line.lstrip().startswith('.'): +# at_line_start = True +# seen_mnemonic_or_directive = False +# result = parser.parse(line, lexer=lexer) +# print(result) \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/parserctx.py b/ass3/zbirnik/src/zbirnik/parserctx.py index 8baf37e..fbfcb83 100644 --- a/ass3/zbirnik/src/zbirnik/parserctx.py +++ b/ass3/zbirnik/src/zbirnik/parserctx.py @@ -1,12 +1,6 @@ class ParserContext: - def __init__(self, parsed): - """ - parsed je rezultat PLY parserja, npr.: - ('loop', ('LDA', (('#', 5),))) - (None, ('FIX',)) - ('COMMENT', 'to je komentar') - """ + # Handle COMMENT special case (if you still need it) if isinstance(parsed, tuple) and parsed[0] == 'COMMENT': self.label = None self.mnemonic = 'COMMENT' @@ -14,11 +8,16 @@ class ParserContext: self.comment = parsed[1] return - self.label, command = parsed - self.mnemonic = command[0] - self.operands = list(command[1]) if len(command) > 1 else [] + # New parser format: (label, mnemonic, *operands) + if not isinstance(parsed, tuple) or len(parsed) < 2: + raise ValueError(f"Invalid parsed format: {parsed}") + + self.label = parsed[0] # Can be None + self.mnemonic = parsed[1] + # All remaining elements are operands + self.operands = list(parsed[2:]) if len(parsed) > 2 else [] self.comment = None - + def has_operand(self) -> bool: return len(self.operands) > 0 @@ -28,35 +27,59 @@ class ParserContext: return self.operands.pop(0) def read_reg(self) -> str: + """Read a register operand (e.g., 'A', 'X', 'L')""" op = self.next_op() - return op[0] + # If it's a plain string, return it + if isinstance(op, str): + return op + # If it's a tuple (shouldn't happen for registers), take first element + if isinstance(op, tuple): + return op[0] + return str(op) def read_num_sym(self): + """Read a number or symbol operand""" op = self.next_op() - if (len(op) == 1): + # If it's already a simple value (number or string), return it + if isinstance(op, (int, str)): + return op + # If it's a tuple with prefix (like ('@', 'buffer')), return the value + if isinstance(op, tuple) and len(op) == 2: + return op[1] + # If it's a single-element tuple, unwrap it + if isinstance(op, tuple) and len(op) == 1: return op[0] - return op[1] + return op def read_addressed_operand(self): - - from adressing import AddrMode - + """Read an operand with addressing mode information""" + from zbirnik.adressing import AddrMode + indexed = False addr_mode = AddrMode.SIMPLE - - op = self.next_operand() - - # immediate / indirect - if len(op) == 2: + op = self.next_op() + + # Check if operand has a prefix (immediate/indirect/indexed) + if isinstance(op, tuple) and len(op) == 2: prefix, value = op - addr_mode = {'#': AddrMode.IMMEDIATE, '@': AddrMode.INDIRECT}[prefix] + if prefix == '#': + addr_mode = AddrMode.IMMEDIATE + elif prefix == '@': + addr_mode = AddrMode.INDIRECT + elif prefix == '+': + # Extended format (SIC/XE) + addr_mode = AddrMode.EXTENDED + else: + # Unknown prefix, treat as simple + value = op else: - value = op[0] - - #indeksiranje - if self.operands and self.operands[0] == ('X',): + # Simple operand (no prefix) + value = op + + # Check for indexed addressing (X register) + # In new parser, indexed would be a second operand that's just 'X' + if self.operands and self.operands[0] == 'X': self.operands.pop(0) indexed = True - - return addr_mode, value, indexed - + + return addr_mode, value, indexed \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/parsetab.py b/ass3/zbirnik/src/zbirnik/parsetab.py index 3538469..713b141 100644 --- a/ass3/zbirnik/src/zbirnik/parsetab.py +++ b/ass3/zbirnik/src/zbirnik/parsetab.py @@ -6,9 +6,9 @@ _tabversion = '3.10' _lr_method = 'LALR' -_lr_signature = 'AT COMMA HASH LABEL MNEMONIC NUMBER REGISTER SYMBOLstart : LABEL command\n | commandcommand : MNEMONIC\n | MNEMONIC argsargs : operand\n | operand COMMA operandoperand : REGISTER\n | AT address\n | HASH address\n | addressaddress : NUMBER\n | SYMBOL' +_lr_signature = 'AT COMMA DIRECTIVE HASH LABEL MNEMONIC NUMBER PLUS REGISTER STRING SYMBOLstart : LABEL statement\n | statementstatement : instruction\n | directiveinstruction : MNEMONIC\n | MNEMONIC argsdirective : DIRECTIVE\n | DIRECTIVE directive_argsdirective_args : directive_arg\n | directive_arg COMMA directive_argdirective_arg : NUMBER\n | SYMBOL\n | STRING\n | operandargs : operand\n | operand COMMA operandoperand : REGISTER\n | AT address\n | HASH address\n | PLUS address\n | addressaddress : NUMBER\n | SYMBOL' -_lr_action_items = {'LABEL':([0,],[2,]),'MNEMONIC':([0,2,],[4,4,]),'$end':([1,3,4,5,6,7,8,10,12,13,15,16,17,],[0,-2,-3,-1,-4,-5,-7,-10,-11,-12,-8,-9,-6,]),'REGISTER':([4,14,],[8,8,]),'AT':([4,14,],[9,9,]),'HASH':([4,14,],[11,11,]),'NUMBER':([4,9,11,14,],[12,12,12,12,]),'SYMBOL':([4,9,11,14,],[13,13,13,13,]),'COMMA':([7,8,10,12,13,15,16,],[14,-7,-10,-11,-12,-8,-9,]),} +_lr_action_items = {'LABEL':([0,],[2,]),'MNEMONIC':([0,2,],[6,6,]),'DIRECTIVE':([0,2,],[7,7,]),'$end':([1,3,4,5,6,7,8,9,10,11,13,16,17,18,19,20,21,22,23,25,26,27,29,30,],[0,-2,-3,-4,-5,-7,-1,-6,-15,-17,-21,-22,-23,-8,-9,-11,-12,-13,-14,-18,-19,-20,-16,-10,]),'REGISTER':([6,7,24,28,],[11,11,11,11,]),'AT':([6,7,24,28,],[12,12,12,12,]),'HASH':([6,7,24,28,],[14,14,14,14,]),'PLUS':([6,7,24,28,],[15,15,15,15,]),'NUMBER':([6,7,12,14,15,24,28,],[16,20,16,16,16,16,20,]),'SYMBOL':([6,7,12,14,15,24,28,],[17,21,17,17,17,17,21,]),'STRING':([7,28,],[22,22,]),'COMMA':([10,11,13,16,17,19,20,21,22,23,25,26,27,],[24,-17,-21,-22,-23,28,-11,-12,-13,-14,-18,-19,-20,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): @@ -17,7 +17,7 @@ for _k, _v in _lr_action_items.items(): _lr_action[_x][_k] = _y del _lr_action_items -_lr_goto_items = {'start':([0,],[1,]),'command':([0,2,],[3,5,]),'args':([4,],[6,]),'operand':([4,14,],[7,17,]),'address':([4,9,11,14,],[10,15,16,10,]),} +_lr_goto_items = {'start':([0,],[1,]),'statement':([0,2,],[3,8,]),'instruction':([0,2,],[4,4,]),'directive':([0,2,],[5,5,]),'args':([6,],[9,]),'operand':([6,7,24,28,],[10,23,29,23,]),'address':([6,7,12,14,15,24,28,],[13,13,25,26,27,13,13,]),'directive_args':([7,],[18,]),'directive_arg':([7,28,],[19,30,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): @@ -27,16 +27,27 @@ for _k, _v in _lr_goto_items.items(): del _lr_goto_items _lr_productions = [ ("S' -> start","S'",1,None,None,None), - ('start -> LABEL command','start',2,'p_start','parser.py',41), - ('start -> command','start',1,'p_start','parser.py',42), - ('command -> MNEMONIC','command',1,'p_command','parser.py',48), - ('command -> MNEMONIC args','command',2,'p_command','parser.py',49), - ('args -> operand','args',1,'p_args','parser.py',53), - ('args -> operand COMMA operand','args',3,'p_args','parser.py',54), - ('operand -> REGISTER','operand',1,'p_operand','parser.py',60), - ('operand -> AT address','operand',2,'p_operand','parser.py',61), - ('operand -> HASH address','operand',2,'p_operand','parser.py',62), - ('operand -> address','operand',1,'p_operand','parser.py',63), - ('address -> NUMBER','address',1,'p_address','parser.py',67), - ('address -> SYMBOL','address',1,'p_address','parser.py',68), + ('start -> LABEL statement','start',2,'p_start','parser.py',92), + ('start -> statement','start',1,'p_start','parser.py',93), + ('statement -> instruction','statement',1,'p_statement','parser.py',102), + ('statement -> directive','statement',1,'p_statement','parser.py',103), + ('instruction -> MNEMONIC','instruction',1,'p_instruction','parser.py',107), + ('instruction -> MNEMONIC args','instruction',2,'p_instruction','parser.py',108), + ('directive -> DIRECTIVE','directive',1,'p_directive','parser.py',115), + ('directive -> DIRECTIVE directive_args','directive',2,'p_directive','parser.py',116), + ('directive_args -> directive_arg','directive_args',1,'p_directive_args','parser.py',123), + ('directive_args -> directive_arg COMMA directive_arg','directive_args',3,'p_directive_args','parser.py',124), + ('directive_arg -> NUMBER','directive_arg',1,'p_directive_arg','parser.py',131), + ('directive_arg -> SYMBOL','directive_arg',1,'p_directive_arg','parser.py',132), + ('directive_arg -> STRING','directive_arg',1,'p_directive_arg','parser.py',133), + ('directive_arg -> operand','directive_arg',1,'p_directive_arg','parser.py',134), + ('args -> operand','args',1,'p_args','parser.py',138), + ('args -> operand COMMA operand','args',3,'p_args','parser.py',139), + ('operand -> REGISTER','operand',1,'p_operand','parser.py',146), + ('operand -> AT address','operand',2,'p_operand','parser.py',147), + ('operand -> HASH address','operand',2,'p_operand','parser.py',148), + ('operand -> PLUS address','operand',2,'p_operand','parser.py',149), + ('operand -> address','operand',1,'p_operand','parser.py',150), + ('address -> NUMBER','address',1,'p_address','parser.py',158), + ('address -> SYMBOL','address',1,'p_address','parser.py',159), ] diff --git a/ass3/zbirnik/src/zbirnik/program.asm b/ass3/zbirnik/src/zbirnik/program.asm new file mode 100644 index 0000000..6b69200 --- /dev/null +++ b/ass3/zbirnik/src/zbirnik/program.asm @@ -0,0 +1,6 @@ +TEST START 0 + LDA NUM + STA RES +NUM WORD 5 +RES RESW 1 + END TEST diff --git a/ass3/zbirnik/tests/test_emit.py b/ass3/zbirnik/src/zbirnik/test_emit.py similarity index 100% rename from ass3/zbirnik/tests/test_emit.py rename to ass3/zbirnik/src/zbirnik/test_emit.py diff --git a/ass3/zbirnik/tests/test_passes.py b/ass3/zbirnik/src/zbirnik/test_passes.py similarity index 100% rename from ass3/zbirnik/tests/test_passes.py rename to ass3/zbirnik/src/zbirnik/test_passes.py diff --git a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/directive.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/directive.cpython-310.pyc new file mode 100644 index 0000000..fb43c3b Binary files /dev/null and b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/directive.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f2.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f2.cpython-310.pyc index 13390d0..23c9532 100644 Binary files a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f2.cpython-310.pyc and b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f2.cpython-310.pyc differ diff --git a/ass3/zbirnik/src/zbirnik/ukazi/directive.py b/ass3/zbirnik/src/zbirnik/ukazi/directive.py index 1e7c8f6..61908ed 100644 --- a/ass3/zbirnik/src/zbirnik/ukazi/directive.py +++ b/ass3/zbirnik/src/zbirnik/ukazi/directive.py @@ -1,8 +1,8 @@ from zbirnik.ukazi.node import Node class directive(Node): - def __init__(self, direktiva : str, operand : str | int | None, label : str | None = None): - self.direktiva = direktiva + def __init__(self, name : str, operand : str | int | None, label : str | None = None): + self.name = name super().__init__(label) self.operand = operand @@ -12,10 +12,10 @@ class directive(Node): def emit(self, ctx): # BASE directive if self.name == "BASE": - if isinstance(self.value, str): - ctx.base = ctx.symtab[self.value] - elif isinstance(self.value, int): - ctx.base = self.value + if isinstance(self.operand, str): + ctx.base = ctx.symtab[self.operand] + elif isinstance(self.operand, int): + ctx.base = self.operand else: raise ValueError("Invalid BASE operand") return None