regs: add register_python

This commit is contained in:
Zack Buhman 2025-05-21 04:05:25 -05:00
parent d0a87b06a9
commit 0aac1f134c
2 changed files with 77 additions and 10 deletions

View File

@ -1,20 +1,28 @@
from csv_input import read_input
from generate import renderer
from register import parse_row, group_by_block
from register_java import generate_classes
import register_java
import register_python
import sys
generators = {
"java": register_java.generate_classes,
"python": register_python.generate_decoder,
}
if __name__ == "__main__":
rows = read_input(sys.argv[1])
block_name = sys.argv[2]
package_name = sys.argv[3]
class_name = sys.argv[4]
base_address = int(sys.argv[5], 16)
generator_type = sys.argv[2]
block_name = sys.argv[3]
package_name = sys.argv[4]
class_name = sys.argv[5]
base_address = int(sys.argv[6], 16)
generator = generators[generator_type]
blocks = group_by_block(map(parse_row, rows))
render, out = renderer(indent_length=4)
render(generate_classes(block_name,
package_name,
class_name,
base_address,
blocks))
render(generator(block_name,
package_name,
class_name,
base_address,
blocks))
sys.stdout.write(out.getvalue())

59
regs/register_python.py Normal file
View File

@ -0,0 +1,59 @@
def generate_dataclass(block_name, registers):
yield "@dataclass"
yield f"class {block_name.capitalize()}:"
for register in registers:
if register.size == 4:
yield f" {register.name}: int"
elif register.size > 4:
yield f" {register.name}: list[int]"
else:
assert False, register.size
yield ""
yield " def __init__(self):"
yield " pass"
yield ""
yield " def __repr__(self):"
yield ' return (f"{self.__class__.__qualname__}(" +'
yield ' ",\\n ".join(['
for register in registers:
if register.size == 4:
yield f' f"{register.name}={{self.{register.name}:08x}}",'
elif register.size > 4:
#yield f' (f"{register.name}=" + ",\\n".join(['
#yield f' f"{{i:08x}}" for i in self.{register.name}'
#yield " ])),"
pass
else:
assert False, register.size
yield ' ]) +'
yield ' ")")'
yield ""
def generate_struct_decoder(block_name, registers):
yield f"def decode_{block_name.lower()}(buf: bytes) -> {block_name.capitalize()}:"
yield " mem = memoryview(buf)"
yield f" {block_name.lower()} = {block_name.capitalize()}()"
for register in registers:
lhs = f"{block_name.lower()}.{register.name}"
mem = f"{hex(register.address)}:{hex(register.address + register.size)}"
if register.size == 4:
yield f" {lhs}, = struct.unpack('<I', mem[{mem}])"
elif register.size > 4:
assert register.size % 4 == 0, register.size
length = register.size // 4
fmt = f"('I' * {length})"
yield f" {lhs} = struct.unpack('<' + {fmt}, mem[{mem}])"
else:
assert False, register.size
yield f" return {block_name.lower()}"
yield ""
def generate_decoder(block_name, package_name, class_name, base_address, blocks):
yield "from dataclasses import dataclass"
yield "import struct"
yield ""
for block, registers, in blocks:
if block.lower() != block_name.lower():
continue
yield from generate_dataclass(block_name, registers)
yield from generate_struct_decoder(block_name, registers)