3 changed files with 401 additions and 34 deletions
@ -0,0 +1,90 @@ |
|||
|
|||
from typing import * |
|||
|
|||
from perrepeat import * |
|||
from pertoken import * |
|||
|
|||
|
|||
T32GroupAttr = Literal['h', 'r', 's', 'w'] |
|||
T32FieldAttr = Literal['a','r','hex','event','setclr'] |
|||
T32MaskAttr = Literal['dec','hex','rhex'] |
|||
T32TreeVisibility = Literal['open','closed'] |
|||
|
|||
|
|||
class T32Field(NamedTuple): |
|||
attr: T32FieldAttr |
|||
qual: PerTokenQual |
|||
thing: int |
|||
bitrange: Tuple[int, int] # inclusive |
|||
name: str |
|||
description: str |
|||
values: Sequence[str] |
|||
|
|||
|
|||
class T32Mask(NamedTuple): |
|||
attr: T32MaskAttr |
|||
qual: Tuple[PerTokenQual, PerTokenQual] |
|||
thing: int |
|||
bitrange: Tuple[int, int] # inclusive |
|||
mask: int |
|||
name: str |
|||
description: str |
|||
values: Sequence[str] |
|||
|
|||
|
|||
class T32Line(NamedTuple): |
|||
hidden: bool |
|||
qual: PerTokenQual |
|||
offset: int |
|||
name: str |
|||
description: str |
|||
field:s Sequence[Union[T32Field, T32Mask]] |
|||
|
|||
|
|||
class T32Group(NamedTuple): |
|||
attrs: T32GroupAttr |
|||
qual: PerTokenQual |
|||
address: Union[T32Address, T32AddressRange] |
|||
description: str |
|||
regs: Sequence[T32Line] |
|||
copy: bool = False |
|||
|
|||
|
|||
class T32GroupRepeat(NamedTuple): |
|||
repeat: T32Repeat |
|||
width: int |
|||
groups: Sequence[T32Group] |
|||
class T32GroupRepeatReplay(NamedTuple): |
|||
pass |
|||
|
|||
|
|||
class T32Tree(NamedTuple): |
|||
base: T32Address |
|||
width: int |
|||
visibility: T32TreeVisibility |
|||
groups: Sequence[Union[T32Group, T32GroupRepeat, T32GroupRepeatReplay]] |
|||
subtrees: Sequence[Union[T32TreeRepeat, T32Tree]] |
|||
|
|||
|
|||
class T32TreeRepeat(NamedTuple): |
|||
repeat: T32Repeat |
|||
subtrees: Sequence[Union[T32TreeRepeat, T32Tree]] |
|||
|
|||
|
|||
class T32Per(NamedTuple): |
|||
title: str |
|||
props: str |
|||
author: str |
|||
changelog: Sequence[str] |
|||
manufacturer: str |
|||
doc: str |
|||
core: str |
|||
chip: Sequence[str] |
|||
copyright: str |
|||
description: str |
|||
keywords: str |
|||
date: str |
|||
id: str |
|||
config: Tuple[int, int] |
|||
trees: Union[T32Tree, T32TreeRepeat] |
|||
|
@ -0,0 +1,128 @@ |
|||
|
|||
from typing import * |
|||
|
|||
|
|||
class T32SpacedAddress(NamedTuple): |
|||
addrspace: str |
|||
address: int |
|||
|
|||
def __add__(self, other): |
|||
if isinstance(other, int): |
|||
return T32SpacedAddress(self.addrspace, self.address+other) |
|||
elif isinstance(other, T32SpacedAddress): |
|||
assert self.addrspace == other.addrspace |
|||
return T32SpacedAddress(self.addrspace, self.address+other.address) |
|||
else: |
|||
raise TypeError("cannot add %s to T32SpacedAddress"%type(other)) |
|||
|
|||
def __repr__(self): |
|||
return "T32SpacedAddress(%s, %s)"%(repr(self.addrspace),hex(self.address)) |
|||
def __str__(self): |
|||
return "%s:%s"%(self.addrspace,hex(self.address)) |
|||
|
|||
|
|||
T32Address = Union[str, int, T32SpacedAddress] |
|||
T32RepeatVarType = Literal['strings','list','increment'] |
|||
|
|||
|
|||
class T32RepeatVar(NamedTuple): |
|||
type: T32RepeatVarType |
|||
args: Sequence[T32Address] |
|||
|
|||
|
|||
class T32AddressRange(NamedTuple): |
|||
base: T32Address |
|||
size: int |
|||
|
|||
|
|||
class T32Repeat(NamedTuple): |
|||
count: int |
|||
vars: Sequence[T32RepeatVar] |
|||
|
|||
def get_value(self, repind: int, varind: int): |
|||
assert repind >= 0 and repind < self.count, "%d vs %s"%(repind,self) |
|||
assert varind >= 0 and varind < len(self.vars), "%d vs %s"%(varind,self) |
|||
v = self.vars[varind] |
|||
if v.type == 'increment': |
|||
vvv = v.args[0] + v.args[1]*repind |
|||
#print("repind %s -> %s"%(repind,vvv), self) |
|||
return v.args[0] + v.args[1]*repind |
|||
else: |
|||
#print("repind %s -> %s"%(repind,v.args[repind]), self) |
|||
return v.args[repind] |
|||
|
|||
def eval(self, repind: int, s: str) -> str: |
|||
if len(self.vars) == 0: return s |
|||
if "$" not in s: return s |
|||
|
|||
for i in range(self.count): |
|||
t = "$%d" % (i+1) |
|||
if t in s: |
|||
s = s.replace(t, str(self.get_value(repind, i))) |
|||
return s |
|||
|
|||
|
|||
|
|||
def parse_spacedAddress(s: str) -> T32SpacedAddress: |
|||
sp = s.split(':') |
|||
assert len(sp) == 2 |
|||
return T32SpacedAddress(sp[0], parse_int(sp[1], False)) |
|||
|
|||
|
|||
def parse_int(s: str, spaced: bool = True): |
|||
assert s is not None and len(s) > 0, "'%s'"%s |
|||
if ':' in s: |
|||
return parse_spacedAddress(s) |
|||
elif s[-1] == '.': |
|||
return int(s[:-1]) |
|||
elif s.startswith('0x') or s.startswith('0X'): |
|||
return int(s[2:], 16) |
|||
else: |
|||
return int(s, 0) # shrug |
|||
|
|||
|
|||
def parse_repeatvar(s: str) -> T32RepeatVar: |
|||
assert (s[0] == '(' and s[-1] == ')'), "badly formatted repeatvar: %s"%s |
|||
s = s[1:-1] |
|||
sl = s.lower() |
|||
|
|||
typ = None |
|||
rest = None |
|||
if sl.startswith('strings '): |
|||
typ = 'strings' |
|||
rest = [] |
|||
start = len(typ)+1 |
|||
instr = False |
|||
for i in range(start, len(s)): |
|||
if s[i] == ' ' and not instr: |
|||
continue |
|||
if s[i] == '"': |
|||
if not instr: |
|||
instr = True |
|||
start = i+1 |
|||
else: |
|||
rest.append(s[start:i]) |
|||
instr = False |
|||
elif sl.startswith('list '): |
|||
typ = 'list' |
|||
rest = sl[len(typ)+1:].strip().split() |
|||
elif sl.startswith('increment '): |
|||
typ = 'increment' |
|||
rest = sl[len(typ)+1:].strip().split() |
|||
assert len(rest) == 2, "bad increment repeatvar args: %s"%s |
|||
rest = [parse_int(x) for x in rest] |
|||
else: |
|||
assert False, "bad repeatvar type: %s"%s |
|||
|
|||
return T32RepeatVar(typ, rest) |
|||
|
|||
|
|||
def parse_repeat(args: Sequence[str]) -> T32Repeat: |
|||
assert len(args) >= 1 |
|||
count = parse_int(args[0], False) |
|||
vars = tuple(parse_repeatvar(x) for x in args[1:]) |
|||
for v in vars: |
|||
if v.type != 'increment': |
|||
assert len(v.args) == count |
|||
return T32Repeat(count, vars) |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue