from parsing import (
    InstDef,
    Macro,
    Pseudo,
    Family,
    Parser,
    Context,
    CacheEffect,
    StackEffect,
    InputEffect,
    OpName,
    AstNode,
)


def prettify_filename(filename: str) -> str:
    # Make filename more user-friendly and less platform-specific,
    # it is only used for error reporting at this point.
    filename = filename.replace("\\", "/")
    if filename.startswith("./"):
        filename = filename[2:]
    if filename.endswith(".new"):
        filename = filename[:-4]
    return filename


BEGIN_MARKER = "// BEGIN BYTECODES //"
END_MARKER = "// END BYTECODES //"


def parse_files(filenames: list[str]) -> list[AstNode]:
    result: list[AstNode] = []
    for filename in filenames:
        with open(filename) as file:
            src = file.read()

        psr = Parser(src, filename=prettify_filename(filename))

        # Skip until begin marker
        while tkn := psr.next(raw=True):
            if tkn.text == BEGIN_MARKER:
                break
        else:
            raise psr.make_syntax_error(
                f"Couldn't find {BEGIN_MARKER!r} in {psr.filename}"
            )
        start = psr.getpos()

        # Find end marker, then delete everything after it
        while tkn := psr.next(raw=True):
            if tkn.text == END_MARKER:
                break
        del psr.tokens[psr.getpos() - 1 :]

        # Parse from start
        psr.setpos(start)
        thing_first_token = psr.peek()
        while node := psr.definition():
            assert node is not None
            result.append(node)  # type: ignore[arg-type]
        if not psr.eof():
            psr.backup()
            raise psr.make_syntax_error(
                f"Extra stuff at the end of {filename}", psr.next(True)
            )
    return result
