1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#!/usr/bin/env python3
import sys
from typing import Iterable, Tuple
from parser import parser
from parsetypes import *
def check_num_args(instruction: Instruction) -> Tuple[int, int]:
return (0, 20)
def check_supports_jump(instruction: Instruction) -> bool:
return True
def check_instructions(
instructions: Iterable[Instruction],
) -> Iterable[ErrorInstruction]:
for i in instructions:
if isinstance(i, ErrorInstruction):
yield i
continue
(min, max) = check_num_args(i)
if not (min <= i.num_args <= max):
yield ErrorInstruction.from_instruction(
i, f"Expected between {min} and {max} args, got {i.num_args}."
)
if not check_supports_jump(i) and i.jumptarget:
yield ErrorInstruction.from_instruction(
i, f"OPcode got jump, but it's not supported here."
)
labels: dict[str,int] = {}
def assemble(program: Iterable[Instruction|JumpTarget]) -> None:
pc = 0
for ins in program:
if isinstance(ins, JumpTarget):
pass
with open(sys.argv[1], "rb") as f:
data = f.read()
data2 = data.decode("ascii")
result: list[Instruction | JumpTarget]
result = parser.parse(data2, tracking=True)
errors = check_instructions(ins for ins in result if isinstance(ins, Instruction))
if errors:
for e in errors:
print(f"On line {e.lineno}: {e.opcode} : {e.error_message}")
sys.exit(1)
assemble(result)
pass
|