Dodal tabelo opcodeu, main, mal prilagodil strukturo

This commit is contained in:
Timon 2026-01-04 13:39:51 +01:00
parent 4b2a7a3cc2
commit 195ca3c9fa
13 changed files with 216 additions and 39 deletions

View file

@ -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

View file

@ -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)

View 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())

View file

@ -1,4 +1,4 @@
from mnemoniki import (
from zbirnik.mnemoniki import (
mnemonicD, mnemonicDn,
mnemonicF1, mnemonicF2n, mnemonicF2r, mnemonicF2rn, mnemonicF2rr,
mnemonicF3, mnemonicF3m, mnemonicF4m,

View 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,
}

View file

@ -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

View file

@ -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

View file

@ -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":

View 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())