From b6e5f3d5932abb5f4f92bce099c68418e4690158 Mon Sep 17 00:00:00 2001 From: Timon Date: Mon, 5 Jan 2026 16:43:07 +0100 Subject: [PATCH] Dodal generator za obj datoteke, in teste, popravil parserctx da pravilno obravnava RSUB --- ass3/zbirnik/src/zbirnik/EmitCtx.py | 7 +- .../__pycache__/EmitCtx.cpython-310.pyc | Bin 653 -> 649 bytes .../__pycache__/adressing.cpython-310.pyc | Bin 443 -> 461 bytes .../zbirnik/__pycache__/code.cpython-310.pyc | Bin 1533 -> 1533 bytes .../__pycache__/gen_obj.cpython-310.pyc | Bin 0 -> 2479 bytes .../__pycache__/parser.cpython-310.pyc | Bin 3995 -> 3995 bytes .../__pycache__/parserctx.cpython-310.pyc | Bin 2246 -> 2214 bytes ass3/zbirnik/src/zbirnik/adressing.py | 1 + ass3/zbirnik/src/zbirnik/gen_obj.py | 89 ++++++++++++++++++ ass3/zbirnik/src/zbirnik/main.py | 24 +++-- .../mnemoniki_tabela.cpython-310.pyc | Bin 2246 -> 2273 bytes .../src/zbirnik/mnemoniki/mnemoniki_tabela.py | 1 + ass3/zbirnik/src/zbirnik/output/test1.obj | 3 + ass3/zbirnik/src/zbirnik/output/test2.obj | 6 ++ ass3/zbirnik/src/zbirnik/parser.py | 11 --- ass3/zbirnik/src/zbirnik/parserctx.py | 23 ++--- ass3/zbirnik/src/zbirnik/program.obj | 3 + .../src/zbirnik/{program.asm => test1.asm} | 0 ass3/zbirnik/src/zbirnik/test2.asm | 23 +++++ ass3/zbirnik/src/zbirnik/test_emit.py | 20 +--- .../__pycache__/directive.cpython-310.pyc | Bin 1123 -> 1123 bytes .../ukazi/__pycache__/f2.cpython-310.pyc | Bin 1133 -> 1133 bytes .../ukazi/__pycache__/f3.cpython-310.pyc | Bin 1775 -> 1859 bytes .../ukazi/__pycache__/f4.cpython-310.pyc | Bin 1623 -> 1623 bytes .../ukazi/__pycache__/storage.cpython-310.pyc | Bin 1659 -> 1659 bytes ass3/zbirnik/src/zbirnik/ukazi/directive.py | 4 +- ass3/zbirnik/src/zbirnik/ukazi/f2.py | 5 + ass3/zbirnik/src/zbirnik/ukazi/f3.py | 11 +++ ass3/zbirnik/src/zbirnik/ukazi/f4.py | 1 + ass3/zbirnik/src/zbirnik/ukazi/storage.py | 2 +- 30 files changed, 177 insertions(+), 57 deletions(-) create mode 100644 ass3/zbirnik/src/zbirnik/__pycache__/gen_obj.cpython-310.pyc create mode 100644 ass3/zbirnik/src/zbirnik/gen_obj.py create mode 100644 ass3/zbirnik/src/zbirnik/output/test1.obj create mode 100644 ass3/zbirnik/src/zbirnik/output/test2.obj create mode 100644 ass3/zbirnik/src/zbirnik/program.obj rename ass3/zbirnik/src/zbirnik/{program.asm => test1.asm} (100%) create mode 100644 ass3/zbirnik/src/zbirnik/test2.asm diff --git a/ass3/zbirnik/src/zbirnik/EmitCtx.py b/ass3/zbirnik/src/zbirnik/EmitCtx.py index ba171d3..8a29781 100644 --- a/ass3/zbirnik/src/zbirnik/EmitCtx.py +++ b/ass3/zbirnik/src/zbirnik/EmitCtx.py @@ -1,9 +1,8 @@ from zbirnik.opcodes import OPCODES + class EmitContext: - REGISTERS = { - 'A': 0, 'X': 1, 'L': 2, - 'B': 3, 'S': 4, 'T': 5, 'F': 6 - } + + REGISTERS = {'A': 0, 'X': 1, 'L': 2,'B': 3, 'S': 4, 'T': 5, 'F': 6} def __init__(self, symtab): self.opcodes = OPCODES diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/EmitCtx.cpython-310.pyc index 9063204f1ca873fb35e24ca843234085cd14e010..990566a21b152efde562772e0c2bf4c097aad201 100644 GIT binary patch delta 51 zcmeBW?PTT4=jG*M0D>O}qceXqY~)+X$jCl<2V)68Gf=RY4M=b>h%oUmO}1z9Wn=;X DJ2?tQ delta 55 zcmeBV?PcZ5=jG*M0D`57QJFl98~Ii;GIC7b!B`^91QaX=NpUc+F>x@m{o`SsY|Z4$ G$Or%^l?kZ; diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/adressing.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/adressing.cpython-310.pyc index a67d4073051461433281b8c8f4154ef5daebf24e..1ca25d9c46070037f9cec875f5f99304b7727f7c 100644 GIT binary patch delta 138 zcmdnZe3qFvpO=@50SI;XX delta 142 zcmX@hyqlRfpO=@50SMv^A~Rbi@|GCN0XeA*QH&`JQB0}K%?wd2V3HL~vZXKvGiWm1 z;&4n!De}!vN%hlYpSZ(~b0tF&H&9;@_hdoFG&T+(lY?P$J)?>iL=-FqB6xtrEe@O9 V{FKt1R69l>ub2f$2r!B;0RV1r8^-_u diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/code.cpython-310.pyc index c7f9fc498332f83b0e366ecf5330f6662a3b0403..674f57b26fc7541705ac97447bfa02f237a6ea73 100644 GIT binary patch delta 20 acmey%{g<0NpO=@50SLTqMQ`N(#0mgC?FHcg delta 20 acmey%{g<0NpO=@50SKI1qBe4WVg&#@vju|y diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/gen_obj.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/gen_obj.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47d535c5cb2c9758e1f8ff6c9ea7399ea2e4b5a0 GIT binary patch literal 2479 zcmZ`*TW=dh6rS6zH;!|u+oqJFwn9R%m53`U6@e;L(U!skp`sw6RAjaBOdUJ+I-Omk z#M(%RlwVO*N*?=rka(C^p7IY+pZLyfHcdji)|@>vb7s!{TaV}Fnhek3Ur+kaT8#Ze zlar6c0FEW5UY}`%OKIm8Nc)Sv_Z3UM|%0dI76*C*&6OIjqbd-P6|RF4#7m{wV-KD715Ag!y9!9fBnsJ~Tzv-@N|K zkKc73Kl-7QZ;e0wEghInn&-DV)Ahc^ZYQ_hW4>oHa%6dH$3;of&)`Qw+H)cy4|$VM zFP?OHxt4OFHO0hcT@K0mQDA6zpO?XuY@Z#lU3k9F@rKv?0&l7LzASkUak#`v+2fbk z0Y`krisQ{#xpT0qitcDEhs0|nyC@nV<~vPfBS&Mrj0S3wa=R!;h3VFo$+Tv>=hOIPzs{FW`39?oO;VS&_WSu$!ybNH6q|Iu~>|CfTNo zj&-!Ej!C@G*)%WW?)NeB+aQW7w0KLjxDpDqiJ9VpM-q)MTatE~yd@*v`d9p}W@)Cx z^xE5tqBbD6ACLo0uRqagk)Fauk1P=IWkObzNFCZj7OWIVBee+Hf$+j(MSvDTTcAah zr@?WH*!M_}y!jbg>=!r8whJZ*wvEFos$`VCN#q(ygjI_GBg}R}Fn%^t zA3^Fq#t{wZNtj4rZyR8|qL^1!5u#U`JqEo&xlxUB-$Np& z4~gRMiu|$cDGU4=obwiZ4aVaRu&59vFXW!E=PM*a-&Ob&qEk51L0xvm?}g}KT0v4? z3gD7lnTiK%KJam)D*9OzsohDofV+ij_Va#*ip{#l$-J;G%y&jby6$Ap6uvHEQDJl7 zkDU$rIhgqfBgcOZz;9Dr005)>#JiBF2J@A8k-lJrjY;B~NirJi$&mO~l02KF!)nJ; zP^=_E8tfND=;Q41S_MpKVC33u#=v_pkpsZcFhcfw+yJ4&0azk4|yjaXaE2lG+8 zv2>$7)0TdBB@SHc=nK5;%Z)5?3-yx!7gTIlrqOk8)8nE$m0Mp?W%+M(i?w)L{0EJc BPdESo literal 0 HcmV?d00001 diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/parser.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/parser.cpython-310.pyc index 1f6d182f9e7d54fa75836bfef44bf4e53c1eb497..1a565f966b880c5d54318065f426e259fddd01fc 100644 GIT binary patch delta 128 zcmV-`0Du3RADbTzZw(C!00000V8mN#r4O+VjRFBBlbix?0WGr(10VqbGm|X@w*gR- z(8UX>FlL-xs0jZOg4Y&cWvri5c0RaS)We+yHlPIGlL-xs0jiUh4Y&cXvri5c0RaV*We+yx@hKkw diff --git a/ass3/zbirnik/src/zbirnik/__pycache__/parserctx.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/__pycache__/parserctx.cpython-310.pyc index 0e4c047e57dd896f3d8f21d708e695b3274f6efa..991c1b54c4e4f176ab1ddff6caa703fc5912670f 100644 GIT binary patch delta 135 zcmX>mxJ-~QpO=@50SIm!kIvNR+Q|2kSw#-WtzlTeu#lmav4pXPv4p9asffFVF_@u* zsfMu`NNX}q)@9Kb)MPG_0IDrw0}{8Gi%W_om$PW{Z~%E6Ok7MXj2ujxH?XiUGOBIf h%F4mSXfk;pyF5E18xsq&2=nA8>?;{LC--q!008Q?9B=>t delta 167 zcmZ1`cubHlpO=@50SGSDL}h;B-pKco*~|dQtzlTeu#lmav4pXPv4p9asffFVF_;0& zV+Qg>Y8X=(B^iJsOf`(nKp9P@$D2+QOn>?;|$C+Bfk F008CFAs7Gv diff --git a/ass3/zbirnik/src/zbirnik/adressing.py b/ass3/zbirnik/src/zbirnik/adressing.py index cf00b06..bd3107a 100644 --- a/ass3/zbirnik/src/zbirnik/adressing.py +++ b/ass3/zbirnik/src/zbirnik/adressing.py @@ -5,3 +5,4 @@ class AddrMode(Enum): SIMPLE = auto() IMMEDIATE = auto() INDIRECT = auto() + EXTENDED = auto() diff --git a/ass3/zbirnik/src/zbirnik/gen_obj.py b/ass3/zbirnik/src/zbirnik/gen_obj.py new file mode 100644 index 0000000..d875d03 --- /dev/null +++ b/ass3/zbirnik/src/zbirnik/gen_obj.py @@ -0,0 +1,89 @@ +from zbirnik.code import Code +from zbirnik.EmitCtx import EmitContext + +class Generate_obj: + + def __init__(self, code: Code, emit_ctx: EmitContext): + self.code = code + self.records = [] + self.emit_ctx = emit_ctx + + def generate(self) -> str: + h_record = self.generate_h_record() + t_records = self.generate_t_records() + #m_records = self.generate_m_records() nimam podpore za EXTREF tako da ne bo M recordou + e_record = self.generate_e_record() + + return '\n'.join([h_record] + t_records + [e_record]) + + def generate_h_record(self) -> str: + ime = (self.code.name).ljust(6) + start = f"{self.code.start_address:06X}" + dolzina= f"{self.code.program_length:06X}" + return f"H^{ime}^{start}^{dolzina}" + + + def generate_t_records(self) -> list[str]: + t_records = [] + current_start_addr = None + current_bytes = bytearray() + + for node in self.code.nodes: + chunk = node.emit(self.emit_ctx) + # If node generates no code (like RESB, RESW, START, END) + if not chunk: + # Flush current T record if we have accumulated bytes + if current_bytes: + t_record = self._make_t_record(current_start_addr, current_bytes) + t_records.append(t_record) + current_bytes = bytearray() + current_start_addr = None + continue + + # If this is the first byte in a new T record, set starting address + if current_start_addr is None: + current_start_addr = node.address + + # Add this node's bytes to current accumulation + current_bytes.extend(chunk) + + # If we've accumulated 30 or more bytes, flush a T record + while len(current_bytes) >= 30: + # Take first 30 bytes + record_bytes = current_bytes[:30] + t_record = self._make_t_record(current_start_addr, record_bytes) + t_records.append(t_record) + + # Remove those bytes and update start address + current_bytes = current_bytes[30:] + current_start_addr += 30 + + # Flush any remaining bytes + if current_bytes: + t_record = self._make_t_record(current_start_addr, current_bytes) + t_records.append(t_record) + + return t_records + + def _make_t_record(self, start_address: int, bytes_data: bytearray) -> str: + start = f"{start_address:06X}" + length = f"{len(bytes_data):02X}" + hex_code = bytes_data.hex().upper() + + return f"T^{start}^{length}^{hex_code}" + + + + def generate_m_records(self) -> list[str]: + pass + + def generate_e_record(self) -> str: + entry = self.code.entry_point + + if isinstance(entry, str): + entry = self.code.symtab.get(entry, self.code.start_address) + + if entry is None: + entry = self.code.start_address + + return f"E^{entry:06X}" \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/main.py b/ass3/zbirnik/src/zbirnik/main.py index bc79da3..f90f042 100644 --- a/ass3/zbirnik/src/zbirnik/main.py +++ b/ass3/zbirnik/src/zbirnik/main.py @@ -3,17 +3,18 @@ from zbirnik.code import Code from zbirnik.EmitCtx import EmitContext from zbirnik.mnemoniki.mnemoniki_tabela import MNEMONICS from zbirnik.parserctx import ParserContext +from zbirnik.gen_obj import Generate_obj import os ime = input("Vnesite ime programa (.asm): ") -ime = os.path.join(os.path.dirname(__file__), ime) +ime1 = os.path.join(os.path.dirname(__file__), ime) -if not ime.endswith(".asm"): +if not ime1.endswith(".asm"): raise ValueError("Ime programa ni v pravi obliki, mora biti: ime.asm") code = Code() -with open(ime) as f: +with open(ime1) as f: for line in f: print("LINE:", line.rstrip()) @@ -35,8 +36,19 @@ with open(ime) as f: code.pass1() - ctx_emit = EmitContext(symtab=code.symtab) - binary = code.pass2(ctx_emit) -print(binary.hex()) + +print("Rezultat pass2: " + binary.hex()) +print("-"*40) +obj_generator = Generate_obj(code=code, emit_ctx=ctx_emit) + +obj_data = obj_generator.generate() + +izhod = "output/"+ ime.replace(".asm", ".obj") +izhod = os.path.join(os.path.dirname(__file__), izhod) + +with open(izhod, "w") as obj: + obj.write(obj_data) + +print(obj_data) 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 index 921ac79d3d888cb71da5faef1ca626f4323afb28..19b674bcbbf4791de11472e1ffd0e9ddeb0bd1f3 100644 GIT binary patch delta 195 zcmX>m_)t(gpO=@50SH8{MrV5RFfcp@agc!kkmCTv#m_csuV8W(Oo>W~P7N)=9t zNnwDpVpD>_EYXy>X2w*}lz1R1o{|726Pp=RlIHL&WsH(YNe*VvOxeuC9K^(ai#fzI z;-${yXjV-|zR9hunv*xP3iB5w0<9`a0up|jlDDKM3$RITe#$zRk*xqEUNE_Xy@v6? PWLAzXlecs5F&+j0FM~0H delta 167 zcmaDTcuY_`pO=@50SLAxM`cR$Ffcp@agYH&kmCTv#dkJpuVAtiPKiokND=8}N)=9t zP6-CHL{nm#8B;}5Vu7T1N*tJsZ)QwMn8Ul2F-jsOF_=L!X|ot}5Yyx$Ry9W6$un6s v8Dl2zV-??gpLGu-TOQE(qP)oq*=rd0O_t->!pp?P$i~dZ$i~FR$a4e$Cxj 2 else [] self.comment = None @@ -29,12 +29,10 @@ class ParserContext: def read_reg(self) -> str: """Read a register operand (e.g., 'A', 'X', 'L')""" op = self.next_op() - # 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): @@ -59,25 +57,22 @@ class ParserContext: addr_mode = AddrMode.SIMPLE op = self.next_op() - # Check if operand has a prefix (immediate/indirect/indexed) + # Check for prefix (immediate/indirect/indexed) if isinstance(op, tuple) and len(op) == 2: prefix, value = op if prefix == '#': addr_mode = AddrMode.IMMEDIATE elif prefix == '@': addr_mode = AddrMode.INDIRECT - elif prefix == '+': - # Extended format (SIC/XE) + elif prefix == '+': addr_mode = AddrMode.EXTENDED else: - # Unknown prefix, treat as simple value = op else: - # Simple operand (no prefix) + # Simple 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 diff --git a/ass3/zbirnik/src/zbirnik/program.obj b/ass3/zbirnik/src/zbirnik/program.obj new file mode 100644 index 0000000..0a677ba --- /dev/null +++ b/ass3/zbirnik/src/zbirnik/program.obj @@ -0,0 +1,3 @@ +H^TEST ^000000^00000C +T^000000^09^0320030F2003000005 +E^000000 \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/program.asm b/ass3/zbirnik/src/zbirnik/test1.asm similarity index 100% rename from ass3/zbirnik/src/zbirnik/program.asm rename to ass3/zbirnik/src/zbirnik/test1.asm diff --git a/ass3/zbirnik/src/zbirnik/test2.asm b/ass3/zbirnik/src/zbirnik/test2.asm new file mode 100644 index 0000000..2adeec3 --- /dev/null +++ b/ass3/zbirnik/src/zbirnik/test2.asm @@ -0,0 +1,23 @@ +COPY START 1000 + LDA ALPHA + ADD BETA + STA GAMMA + LDX ZERO +LOOP LDA BUFFER,X + ADD #1 + STA BUFFER,X + TIX COUNT + JLT LOOP + LDA @PTR + COMP #100 + JEQ DONE + J LOOP +DONE RSUB +ALPHA WORD 10 +BETA WORD 20 +GAMMA RESW 1 +ZERO WORD 0 +COUNT WORD 5 +BUFFER RESW 10 +PTR WORD GAMMA + END COPY \ No newline at end of file diff --git a/ass3/zbirnik/src/zbirnik/test_emit.py b/ass3/zbirnik/src/zbirnik/test_emit.py index f81e021..69bf254 100644 --- a/ass3/zbirnik/src/zbirnik/test_emit.py +++ b/ass3/zbirnik/src/zbirnik/test_emit.py @@ -1,25 +1,7 @@ -OPCODES = { - "FIX": 0xC4, - "ADDR": 0x90, - "LDA": 0x00, - "STA": 0x0C, - "JSUB": 0x48, -} - -REGISTERS = { - "A": 0, - "X": 1, - "L": 2, - "B": 3, - "S": 4, - "T": 5, - "F": 6, -} - from zbirnik.ukazi.f1 import f1 from zbirnik.EmitCtx import EmitContext -ctx = EmitContext(OPCODES, REGISTERS, {}) +ctx = EmitContext({}) node = f1("FIX", None) result = node.emit(ctx) diff --git a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/directive.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/directive.cpython-310.pyc index fb43c3b4262f0166874422a1ff469e08fefb9436..6c528a41542056cca794f432513e6865ca151a29 100644 GIT binary patch delta 22 ccmaFN@tA`*pO=@50SLAoj?Pry$Q#B207lCN^8f$< delta 22 ccmaFN@tA`*pO=@50SI_oqB1Qv@`kYh06#Sa8~^|S 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 23c9532cf7e026449c9592b6e830d44073e27157..ec955180bb2a3723806935dee0a8aa37da8a0701 100644 GIT binary patch delta 43 vcmaFM@s@)xpO=@50SK56M`!vlZ{#aw=4a+(WMk%HW@F@G0_S60l z(=Q0%aReSlcoTwXPQp`B?RY_A03o5|Py`v2PrM|#2Se~`2q7gEGTwPDeCjiwze;9! z04o;jB()qVR=T@VaGOgsWpqF(>rPqNl}k8d_%UURa!%Gc#2kUPO()BzTL}cP6vHpnJV!eJ0JUZ%!d_v!-d5g$?s<+x`Mkq4XWHd*BU~?ffjQwP#5$ zuC$J(s}F##4S2XA^P1Lq@RtVLzrH`0PY#|9&;RiY_Qg3r98|pv(}aCdU7+mu;zPL| zC-P-BS4Z#a<4OE2kK;h?nl`+>K<`ASZpBY(b7P++G!{vYIj*7P&tfj(ncBi6{!vdi Xb~s@!kH+ISm2L{JH|BnPlz#mW5Fd#^ delta 549 zcmYk2Jx?4l5Qb;Gw)cCN1af>-fM^g!B+^78A}6X;X`qRehGkZW1MMNRNJO%Ah?7#J zNV5e^ddesreg4H(X{quDQe^h-K)9HB{dnHdcz$Pp(`=Zg5%AfupHA-duk5E76$oH) z02T(g3{F@<*azqFUDVz{o(l7d#Ao58Q`O3hDyFOC&1gQOn&}qF8I`q9YK%8%Ju6A? z!X8+)2TpT!VBV3gkbF1t>ySZI$75kWbjk&l=7Ew<^FRUTl!8TYp$%-f1TJD*Oxh(B z+DL*2r)WxwIG$Akp;C|U)jIdd2rkilXD{oi`^j}p@rZ5TDuuw)Cf&5$IOYaP)y+R8 zzDuo7=`PrqvdKRZ$|pIcxk--b#e1Naeg31%Y((?C!Mx6`wwcY3y)o{?=EBE^f4url z@xU7g)0=3MKEL#uTe%)~FQ&uIy)2qFRr;+ezSQMK^Hsgx!mC!-hvvAfTXBBWN;vC{o~Ad=AGH$nxlw`vHgkFnMYF9BdK-*dSqz6~CShq7y70F7q3`|!)Wv}i diff --git a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f4.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/f4.cpython-310.pyc index 19b6a58aaa68639e8dfb171a909eae82b8ac7d9d..2b16771e5d0823ec594f284ccc7fa600b084e7f7 100644 GIT binary patch delta 29 jcmcc4bDf7bpO=@50SLAnj?PTq$Scpv$h29PRf`b-bV~;Q delta 29 icmcc4bDf7bpO=@50R(CzGvhY$%Cj;uZq{YhVgvwWV+HsC diff --git a/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/storage.cpython-310.pyc b/ass3/zbirnik/src/zbirnik/ukazi/__pycache__/storage.cpython-310.pyc index e155d0454951d26511a5b98973cc57104f77e7a6..da4a2e051d568faeb9d04a7138b80ae591303501 100644 GIT binary patch delta 22 ccmey(^P7h^pO=@50SHu&L}%{Y$eYIo07+H`M*si- delta 22 ccmey(^P7h^pO=@50SMTAqcV4G