Dodal tabelo opcodeu, main, mal prilagodil strukturo
This commit is contained in:
parent
4b2a7a3cc2
commit
195ca3c9fa
13 changed files with 216 additions and 39 deletions
|
|
@ -1,6 +1,10 @@
|
|||
class EmitContext:
|
||||
def __init__(self, opcodes, registers, symtab):
|
||||
REGISTERS = {
|
||||
'A': 0, 'X': 1, 'L': 2,
|
||||
'B': 3, 'S': 4, 'T': 5, 'F': 6
|
||||
}
|
||||
|
||||
def __init__(self, opcodes, symtab):
|
||||
self.opcodes = opcodes
|
||||
self.registers = registers
|
||||
self.symtab = symtab
|
||||
self.base = None
|
||||
|
|
|
|||
Binary file not shown.
BIN
ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc
Normal file
BIN
ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc
Normal file
Binary file not shown.
|
|
@ -2,17 +2,14 @@ from zbirnik.ukazi.node import Node
|
|||
|
||||
class Code:
|
||||
|
||||
REGISTERS = {'A': 0, 'X': 1, 'L': 2, 'B': 3, 'S': 4, 'T': 5, 'F': 6 }
|
||||
|
||||
def __init__(self, name: str | None = None):
|
||||
self.name = name
|
||||
self.nodes = []
|
||||
self.locctr = 0
|
||||
self.symtab = {}
|
||||
self.start_adress = 0
|
||||
self.entry_point = 0
|
||||
self.start_address = 0
|
||||
self.entry_point = None
|
||||
self.program_length = 0
|
||||
self.obj = ""
|
||||
|
||||
def add(self, node: Node):
|
||||
self.nodes.append(node)
|
||||
|
|
|
|||
32
ass3/zbirnik/src/zbirnik/main.py
Normal file
32
ass3/zbirnik/src/zbirnik/main.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
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
|
||||
|
||||
print("Vnesite ime programa (.asm), ki je v istem direktoriju kakor main.py: ")
|
||||
ime = input()
|
||||
|
||||
if not ime.endswith(".asm"):
|
||||
raise ValueError("Ime programa ni v pravi obliki, mora biti: ime.asm")
|
||||
|
||||
code = Code()
|
||||
|
||||
with open(ime) as f:
|
||||
for line in f:
|
||||
ctx = parser.parse(line)
|
||||
|
||||
if ctx is None:
|
||||
continue
|
||||
|
||||
mnemonic = MNEMONICS[ctx.mnemonic]
|
||||
node = mnemonic.parse(ctx)
|
||||
code.add(node)
|
||||
|
||||
|
||||
code.pass1()
|
||||
|
||||
ctx_emit = EmitContext(opcodes=OPCODES,symtab=code.symtab)
|
||||
|
||||
binary = code.pass2(ctx_emit)
|
||||
print(binary.hex())
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from mnemoniki import (
|
||||
from zbirnik.mnemoniki import (
|
||||
mnemonicD, mnemonicDn,
|
||||
mnemonicF1, mnemonicF2n, mnemonicF2r, mnemonicF2rn, mnemonicF2rr,
|
||||
mnemonicF3, mnemonicF3m, mnemonicF4m,
|
||||
|
|
|
|||
61
ass3/zbirnik/src/zbirnik/opcodes.py
Normal file
61
ass3/zbirnik/src/zbirnik/opcodes.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
OPCODES = {
|
||||
"FIX": 0xC4,
|
||||
"FLOAT": 0xC0,
|
||||
"HIO": 0xF4,
|
||||
"NORM": 0xC8,
|
||||
"SIO": 0xF0,
|
||||
"TIO": 0xF8,
|
||||
"ADDR": 0x90,
|
||||
"CLEAR": 0xB4,
|
||||
"COMPR": 0xA0,
|
||||
"DIVR": 0x9C,
|
||||
"MULR": 0x98,
|
||||
"RMO": 0xAC,
|
||||
"SHIFTL": 0xA4,
|
||||
"SHIFTR": 0xA8,
|
||||
"SUBR": 0x94,
|
||||
"SVC": 0xB0,
|
||||
"TIXR": 0xB8,
|
||||
"ADD": 0x18,
|
||||
"ADDF": 0x58,
|
||||
"AND": 0x40,
|
||||
"COMP": 0x28,
|
||||
"COMPF": 0x88,
|
||||
"DIV": 0x24,
|
||||
"DIVF": 0x64,
|
||||
"J": 0x3C,
|
||||
"JEQ": 0x30,
|
||||
"JGT": 0x34,
|
||||
"JLT": 0x38,
|
||||
"JSUB": 0x48,
|
||||
"LDA": 0x00,
|
||||
"LDB": 0x68,
|
||||
"LDCH": 0x50,
|
||||
"LDF": 0x70,
|
||||
"LDL": 0x08,
|
||||
"LDS": 0x6C,
|
||||
"LDT": 0x74,
|
||||
"LDX": 0x04,
|
||||
"LPS": 0xD0,
|
||||
"MUL": 0x20,
|
||||
"MULF": 0x60,
|
||||
"OR": 0x44,
|
||||
"RD": 0xD8,
|
||||
"RSUB": 0x4C,
|
||||
"SSK": 0xEC,
|
||||
"STA": 0x0C,
|
||||
"STB": 0x78,
|
||||
"STCH": 0x54,
|
||||
"STF": 0x80,
|
||||
"STI": 0xD4,
|
||||
"STL": 0x14,
|
||||
"STS": 0x7C,
|
||||
"STSW": 0xE8,
|
||||
"STT": 0x84,
|
||||
"STX": 0x10,
|
||||
"SUB": 0x1C,
|
||||
"SUBF": 0x5C,
|
||||
"TD": 0xE0,
|
||||
"TIX": 0x2C,
|
||||
"WD": 0xDC,
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import ply.lex
|
||||
import ply.yacc
|
||||
import sys
|
||||
from zbirnik.parserctx import ParserContext
|
||||
|
||||
# Lexer.
|
||||
# --------------------
|
||||
# Lexer
|
||||
# --------------------
|
||||
tokens = (
|
||||
'AT',
|
||||
'COMMA',
|
||||
|
|
@ -30,60 +32,91 @@ def t_NUMBER(t):
|
|||
|
||||
def t_COMMENT(t):
|
||||
r'\..*'
|
||||
t.value = t.value[1:].strip()
|
||||
t.value = t.value[1:].strip()
|
||||
return t
|
||||
|
||||
t_ignore = ' \t\n'
|
||||
t_ignore = ' \t\n'
|
||||
|
||||
def t_error(t):
|
||||
print(f'illegal character {t}')
|
||||
print(f"Illegal character {t.value[0]!r}")
|
||||
t.lexer.skip(1)
|
||||
|
||||
lexer = ply.lex.lex()
|
||||
|
||||
# Parser.
|
||||
# --------------------
|
||||
# Parser
|
||||
# --------------------
|
||||
|
||||
def p_start(p):
|
||||
r'''start : LABEL command
|
||||
| COMMENT
|
||||
| command'''
|
||||
| command
|
||||
| COMMENT
|
||||
'''
|
||||
# komentar
|
||||
if len(p) == 2 and isinstance(p[1], str):
|
||||
p[0] = None
|
||||
return
|
||||
|
||||
# brez labela
|
||||
if len(p) == 2:
|
||||
if isinstance(p[1], str):
|
||||
p[0] = ('COMMENT', p[1])
|
||||
else:
|
||||
p[0] = (None, p[1])
|
||||
label = None
|
||||
mnemonic, operands = p[1]
|
||||
else:
|
||||
p[0] = tuple(p[1:])
|
||||
label = p[1]
|
||||
mnemonic, operands = p[2]
|
||||
|
||||
p[0] = ParserContext(label, mnemonic, operands)
|
||||
|
||||
|
||||
def p_command(p):
|
||||
r'''command : MNEMONIC
|
||||
| MNEMONIC args'''
|
||||
p[0] = p[1:]
|
||||
| MNEMONIC 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'''
|
||||
match len(p):
|
||||
case 2: p[0] = (p[1],)
|
||||
case 4: p[0] = (p[1], p[3])
|
||||
| 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
|
||||
| AT address
|
||||
| HASH address
|
||||
| address'''
|
||||
p[0] = p[1:]
|
||||
| AT address
|
||||
| HASH address
|
||||
| address
|
||||
'''
|
||||
if len(p) == 2:
|
||||
p[0] = p[1]
|
||||
else:
|
||||
# @X ali #5 → zadrži znak
|
||||
p[0] = (p[1], p[2])
|
||||
|
||||
|
||||
def p_address(p):
|
||||
r'''address : NUMBER
|
||||
| SYMBOL'''
|
||||
| SYMBOL
|
||||
'''
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_error(p):
|
||||
if p:
|
||||
print('Syntax error at token', p)
|
||||
parser.errok()
|
||||
raise SyntaxError(f"Syntax error at token {p}")
|
||||
else:
|
||||
print('Syntax error at EOF')
|
||||
raise SyntaxError("Syntax error at EOF")
|
||||
|
||||
|
||||
parser = ply.yacc.yacc()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -14,14 +14,14 @@ class f2(Node):
|
|||
opcode = ctx.opcodes[self.mnemonic]
|
||||
|
||||
if isinstance(self.r1, str):
|
||||
r1_val = ctx.registers[self.r1]
|
||||
r1_val = ctx.REGISTERS[self.r1]
|
||||
else:
|
||||
r1_val = self.r1
|
||||
|
||||
if self.r2 is None:
|
||||
r2_val = 0
|
||||
elif isinstance(self.r2, str):
|
||||
r2_val = ctx.registers[self.r2]
|
||||
r2_val = ctx.REGISTERS[self.r2]
|
||||
else:
|
||||
r2_val = self.r2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
from zbirnik.ukazi.node import Node
|
||||
|
||||
class storage(Node):
|
||||
def __init__(self, val : str | int, name : str, label : str | None = None):
|
||||
def __init__(self, value : str | int, name : str, label : str | None = None):
|
||||
super().__init__(label)
|
||||
self.val = val
|
||||
self.value = value
|
||||
self.name = name
|
||||
|
||||
def size(self) -> int:
|
||||
if self.name == "WORD":
|
||||
return 3
|
||||
if self.name == "BYTE":
|
||||
return len(self.emit(None))
|
||||
if self.name == "RESB":
|
||||
return self.value
|
||||
if self.name == "RESW":
|
||||
return 3 * self.value
|
||||
return 0
|
||||
|
||||
|
||||
def emit(self, ctx):
|
||||
if self.name == "WORD":
|
||||
|
|
|
|||
41
ass3/zbirnik/tests/test_passes.py
Normal file
41
ass3/zbirnik/tests/test_passes.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
from zbirnik.code import Code
|
||||
from zbirnik.EmitCtx import EmitContext
|
||||
from zbirnik.ukazi.f3 import f3
|
||||
from zbirnik.ukazi.storage import storage
|
||||
from zbirnik.adressing import AddrMode
|
||||
|
||||
OPCODES = {
|
||||
"LDA": 0x00,
|
||||
"STA": 0x0C,
|
||||
}
|
||||
|
||||
REGISTERS = {
|
||||
"A": 0, "X": 1, "L": 2,
|
||||
"B": 3, "S": 4, "T": 5, "F": 6
|
||||
}
|
||||
|
||||
code = Code("TEST")
|
||||
|
||||
code.add(f3(
|
||||
operand="A",
|
||||
mnemonic="LDA",
|
||||
label=None,
|
||||
index=False,
|
||||
adr_mode=AddrMode.SIMPLE
|
||||
))
|
||||
|
||||
code.add(storage(
|
||||
name="WORD",
|
||||
value=5,
|
||||
label="A"
|
||||
))
|
||||
|
||||
code.pass1()
|
||||
print("SYMTAB:", code.symtab)
|
||||
print("START:", hex(code.start_address))
|
||||
print("LENGTH:", code.program_length)
|
||||
|
||||
ctx = EmitContext(opcodes=OPCODES, symtab=code.symtab)
|
||||
binary = code.pass2(ctx)
|
||||
|
||||
print("BINARY:", binary.hex())
|
||||
Loading…
Add table
Add a link
Reference in a new issue