summaryrefslogtreecommitdiff
path: root/nandgame/assembler/assembler.py
blob: a622891ad8c3877567f47ace737df3df06f17917 (plain)
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