fixed + completed type hints
This commit is contained in:
parent
30339f0ece
commit
cce7e96779
10
config.py
10
config.py
@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -29,8 +31,9 @@ class Config:
|
|||||||
|
|
||||||
def __init__(self, path: str = "config.json") -> None:
|
def __init__(self, path: str = "config.json") -> None:
|
||||||
self.load(path)
|
self.load(path)
|
||||||
|
|
||||||
def load(self, path: str) -> None:
|
@staticmethod
|
||||||
|
def load(path: str) -> None:
|
||||||
with open(path, "r") as f:
|
with open(path, "r") as f:
|
||||||
config = json.load(f)
|
config = json.load(f)
|
||||||
|
|
||||||
@ -39,5 +42,6 @@ class Config:
|
|||||||
if hasattr(Config, k):
|
if hasattr(Config, k):
|
||||||
setattr(Config, k, v)
|
setattr(Config, k, v)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def formatKey(key: str) -> str:
|
def formatKey(key: str) -> str:
|
||||||
return re.sub(r"([a-z])([A-Z])", r"\1_\2", key).upper()
|
return re.sub(r"([a-z])([A-Z])", r"\1_\2", key).upper()
|
||||||
|
7
main.py
7
main.py
@ -1,12 +1,13 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from schema import InstructionSetSchema
|
from schema import InstructionSetSchema
|
||||||
|
|
||||||
|
|
||||||
description = """Examples:
|
description = """Examples:
|
||||||
- Default theme (black on white):
|
- Default theme (black on white):
|
||||||
python main.py schema.xml -o out.jpg
|
python main.py schema.xml -o out.jpg
|
||||||
@ -25,7 +26,7 @@ description = """Examples:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def processFile(inPath, outPath, confPath, display):
|
def processFile(inPath: str, outPath: str, confPath: str, display: bool) -> None:
|
||||||
schema = InstructionSetSchema(inPath, confPath, display)
|
schema = InstructionSetSchema(inPath, confPath, display)
|
||||||
schema.save(outPath)
|
schema.save(outPath)
|
||||||
|
|
||||||
@ -66,4 +67,4 @@ if __name__ == "__main__":
|
|||||||
if output is None:
|
if output is None:
|
||||||
output = os.path.splitext(args.schema)[0] + ".png"
|
output = os.path.splitext(args.schema)[0] + ".png"
|
||||||
|
|
||||||
processFile(args.schema, output, args.config, args.display)
|
processFile(args.schema, output, args.config, args.display)
|
||||||
|
31
range.py
31
range.py
@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union, Optional
|
||||||
|
|
||||||
|
|
||||||
class Range:
|
class Range:
|
||||||
@ -9,22 +9,23 @@ class Range:
|
|||||||
end: int,
|
end: int,
|
||||||
name: str,
|
name: str,
|
||||||
description: str = "",
|
description: str = "",
|
||||||
values: dict[str, Union[str, dict]] = None,
|
values: Optional[dict[str, Union[str, dict]]] = None,
|
||||||
dependsOn: str = None) -> None:
|
dependsOn: Optional[tuple[int, int]] = None) -> None:
|
||||||
|
|
||||||
self.start = start
|
self.start: int = start
|
||||||
self.end = end
|
self.end: int = end
|
||||||
self.name = name
|
self.name: str = name
|
||||||
self.description = description
|
self.description: str = description
|
||||||
self.values = values
|
self.values: Optional[dict[str, Union[str, dict]]] = values
|
||||||
self.dependsOn = dependsOn
|
self.dependsOn: Optional[tuple[int, int]] = dependsOn
|
||||||
self.lastValueY = -1
|
self.lastValueY: int = -1
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bits(self) -> int:
|
def bits(self) -> int:
|
||||||
return self.end - self.start + 1
|
return self.end - self.start + 1
|
||||||
|
|
||||||
def load(start: int, end: int, data: dict):
|
@staticmethod
|
||||||
|
def load(start: int, end: int, data: dict) -> Range:
|
||||||
values = None
|
values = None
|
||||||
bits = end - start + 1
|
bits = end - start + 1
|
||||||
|
|
||||||
@ -45,9 +46,11 @@ class Range:
|
|||||||
values,
|
values,
|
||||||
dependsOn)
|
dependsOn)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def parseSpan(span: str) -> tuple[int, int]:
|
def parseSpan(span: str) -> tuple[int, int]:
|
||||||
startEnd = span.split("-")
|
startEnd = span.split("-")
|
||||||
if len(startEnd) == 1: startEnd.append(startEnd[0])
|
if len(startEnd) == 1:
|
||||||
|
startEnd.append(startEnd[0])
|
||||||
start = int(startEnd[1])
|
start = int(startEnd[1])
|
||||||
end = int(startEnd[0])
|
end = int(startEnd[0])
|
||||||
return (start, end)
|
return (start, end)
|
||||||
|
27
renderer.py
27
renderer.py
@ -16,17 +16,23 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
class Renderer:
|
class Renderer:
|
||||||
def __init__(self, config: Config, display: bool = False) -> None:
|
def __init__(self, config: Config, display: bool = False) -> None:
|
||||||
self.config = config
|
self.config: Config = config
|
||||||
self.display = display
|
self.display: bool = display
|
||||||
pygame.init()
|
pygame.init()
|
||||||
if self.display:
|
if self.display:
|
||||||
self.win = pygame.display.set_mode([self.config.WIDTH, self.config.HEIGHT])
|
self.win: pygame.Surface = pygame.display.set_mode([self.config.WIDTH, self.config.HEIGHT])
|
||||||
|
|
||||||
self.surf = pygame.Surface([self.config.WIDTH, self.config.HEIGHT], pygame.SRCALPHA)
|
self.surf: pygame.Surface = pygame.Surface([self.config.WIDTH, self.config.HEIGHT], pygame.SRCALPHA)
|
||||||
self.font = pygame.font.SysFont(self.config.DEFAULT_FONT_FAMILY, self.config.DEFAULT_FONT_SIZE)
|
|
||||||
self.italicFont = pygame.font.SysFont(self.config.ITALIC_FONT_FAMILY, self.config.ITALIC_FONT_SIZE, italic=True)
|
self.font: pygame.font.Font = pygame.font.SysFont(
|
||||||
|
self.config.DEFAULT_FONT_FAMILY,
|
||||||
|
self.config.DEFAULT_FONT_SIZE)
|
||||||
|
|
||||||
|
self.italicFont: pygame.font.Font = pygame.font.SysFont(
|
||||||
|
self.config.ITALIC_FONT_FAMILY,
|
||||||
|
self.config.ITALIC_FONT_SIZE, italic=True)
|
||||||
|
|
||||||
self.margins = self.config.MARGINS
|
self.margins: list[int, int, int, int] = self.config.MARGINS
|
||||||
|
|
||||||
def render(self, schema: InstructionSetSchema) -> None:
|
def render(self, schema: InstructionSetSchema) -> None:
|
||||||
self.surf.fill(self.config.BACKGROUND_COLOR)
|
self.surf.fill(self.config.BACKGROUND_COLOR)
|
||||||
@ -206,8 +212,7 @@ class Renderer:
|
|||||||
|
|
||||||
def drawDependency(self,
|
def drawDependency(self,
|
||||||
struct: Structure,
|
struct: Structure,
|
||||||
structures: dict[str,
|
structures: dict[str, Structure],
|
||||||
Structure],
|
|
||||||
bitsX: float,
|
bitsX: float,
|
||||||
bitsY: float,
|
bitsY: float,
|
||||||
range_: Range,
|
range_: Range,
|
||||||
@ -274,7 +279,7 @@ class Renderer:
|
|||||||
descY + bitH - arrowMargin)
|
descY + bitH - arrowMargin)
|
||||||
|
|
||||||
prevDependY = descY + bitH*2 + arrowMargin
|
prevDependY = descY + bitH*2 + arrowMargin
|
||||||
prevRangeY =prevDependY
|
prevRangeY = prevDependY
|
||||||
dependRange.lastValueY = prevDependY
|
dependRange.lastValueY = prevDependY
|
||||||
descY = self.drawStructure(structures[data["structure"]], structures, rStartX, descY)
|
descY = self.drawStructure(structures[data["structure"]], structures, rStartX, descY)
|
||||||
|
|
||||||
@ -315,4 +320,4 @@ class Renderer:
|
|||||||
self.surf.blit(txt, [
|
self.surf.blit(txt, [
|
||||||
(start.x + end.x - txt.get_width())/2,
|
(start.x + end.x - txt.get_width())/2,
|
||||||
(start.y + end.y)/2 + arrowLabelDist
|
(start.y + end.y)/2 + arrowLabelDist
|
||||||
])
|
])
|
||||||
|
@ -17,9 +17,10 @@ class InstructionSetSchema:
|
|||||||
VALID_EXTENSIONS = ("yaml", "json", "xml")
|
VALID_EXTENSIONS = ("yaml", "json", "xml")
|
||||||
|
|
||||||
def __init__(self, path: str, configPath: str = "config.json", display: bool = False) -> None:
|
def __init__(self, path: str, configPath: str = "config.json", display: bool = False) -> None:
|
||||||
self.config = Config(configPath)
|
self.config: Config = Config(configPath)
|
||||||
self.display = display
|
self.display: bool = display
|
||||||
self.path = path
|
self.path: str = path
|
||||||
|
self.structures: dict[str, Structure] = {}
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
def load(self) -> None:
|
def load(self) -> None:
|
||||||
@ -51,4 +52,4 @@ class InstructionSetSchema:
|
|||||||
renderer.render(self)
|
renderer.render(self)
|
||||||
renderer.save(path)
|
renderer.save(path)
|
||||||
if self.display:
|
if self.display:
|
||||||
input("Press ENTER to quit")
|
input("Press ENTER to quit")
|
||||||
|
15
structure.py
15
structure.py
@ -7,14 +7,15 @@ class Structure:
|
|||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
bits: int,
|
bits: int,
|
||||||
ranges: dict[str, Range],
|
ranges: dict[tuple[int, int], Range],
|
||||||
start: int = 0) -> None:
|
start: int = 0) -> None:
|
||||||
|
|
||||||
self.name = name
|
self.name: str = name
|
||||||
self.bits = bits
|
self.bits: int = bits
|
||||||
self.ranges = ranges
|
self.ranges: dict[tuple[int, int], Range] = ranges
|
||||||
self.start = start
|
self.start: int = start
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def load(id_: str, data: dict) -> Structure:
|
def load(id_: str, data: dict) -> Structure:
|
||||||
ranges = {}
|
ranges = {}
|
||||||
for rSpan, rData in data["ranges"].items():
|
for rSpan, rData in data["ranges"].items():
|
||||||
@ -34,4 +35,4 @@ class Structure:
|
|||||||
|
|
||||||
def getSortedRanges(self) -> list[Range]:
|
def getSortedRanges(self) -> list[Range]:
|
||||||
ranges = self.ranges.values()
|
ranges = self.ranges.values()
|
||||||
return list(sorted(ranges, key=lambda r: r.end))
|
return list(sorted(ranges, key=lambda r: r.end))
|
||||||
|
9
vec.py
9
vec.py
@ -5,8 +5,8 @@ from math import sqrt
|
|||||||
|
|
||||||
class Vec:
|
class Vec:
|
||||||
def __init__(self, x: float = 0, y: float = 0) -> None:
|
def __init__(self, x: float = 0, y: float = 0) -> None:
|
||||||
self.x = x
|
self.x: float = x
|
||||||
self.y = y
|
self.y: float = y
|
||||||
|
|
||||||
def __add__(self, v: Vec) -> Vec:
|
def __add__(self, v: Vec) -> Vec:
|
||||||
return Vec(self.x+v.x, self.y+v.y)
|
return Vec(self.x+v.x, self.y+v.y)
|
||||||
@ -25,5 +25,6 @@ class Vec:
|
|||||||
|
|
||||||
def norm(self) -> Vec:
|
def norm(self) -> Vec:
|
||||||
mag = self.mag()
|
mag = self.mag()
|
||||||
if mag == 0: return Vec()
|
if mag == 0:
|
||||||
return self/mag
|
return Vec()
|
||||||
|
return self / mag
|
||||||
|
@ -7,7 +7,9 @@ from bs4 import BeautifulSoup
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from io import TextIOWrapper
|
from io import TextIOWrapper
|
||||||
|
|
||||||
|
|
||||||
class XMLLoader:
|
class XMLLoader:
|
||||||
|
@staticmethod
|
||||||
def load(file_: TextIOWrapper) -> dict:
|
def load(file_: TextIOWrapper) -> dict:
|
||||||
schema = {}
|
schema = {}
|
||||||
bs = BeautifulSoup(file_.read(), "xml")
|
bs = BeautifulSoup(file_.read(), "xml")
|
||||||
@ -19,10 +21,12 @@ class XMLLoader:
|
|||||||
|
|
||||||
schema["structures"] = structures
|
schema["structures"] = structures
|
||||||
return schema
|
return schema
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def parseStructure(structElmt: any) -> dict:
|
def parseStructure(structElmt: any) -> dict:
|
||||||
struct = {}
|
struct = {
|
||||||
struct["bits"] = structElmt.get("bits")
|
"bits": structElmt.get("bits")
|
||||||
|
}
|
||||||
ranges = {}
|
ranges = {}
|
||||||
rangeElmts = structElmt.findAll("range")
|
rangeElmts = structElmt.findAll("range")
|
||||||
for rangeElmt in rangeElmts:
|
for rangeElmt in rangeElmts:
|
||||||
@ -32,11 +36,14 @@ class XMLLoader:
|
|||||||
struct["ranges"] = ranges
|
struct["ranges"] = ranges
|
||||||
return struct
|
return struct
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def parseRange(rangeElmt: any) -> dict:
|
def parseRange(rangeElmt: any) -> dict:
|
||||||
range_ = {}
|
range_ = {
|
||||||
range_["name"] = rangeElmt.get("name")
|
"name": rangeElmt.get("name")
|
||||||
|
}
|
||||||
desc = rangeElmt.find("description")
|
desc = rangeElmt.find("description")
|
||||||
if desc is not None: range_["description"] = desc.getText()
|
if desc is not None:
|
||||||
|
range_["description"] = desc.getText()
|
||||||
|
|
||||||
valuesElmt = rangeElmt.find("values")
|
valuesElmt = rangeElmt.find("values")
|
||||||
if valuesElmt is not None:
|
if valuesElmt is not None:
|
||||||
@ -47,6 +54,7 @@ class XMLLoader:
|
|||||||
|
|
||||||
return range_
|
return range_
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def parseValues(valuesElmt: any) -> dict:
|
def parseValues(valuesElmt: any) -> dict:
|
||||||
values = {}
|
values = {}
|
||||||
caseElmts = valuesElmt.findAll("case")
|
caseElmts = valuesElmt.findAll("case")
|
||||||
@ -64,4 +72,4 @@ class XMLLoader:
|
|||||||
else:
|
else:
|
||||||
values[val] = desc
|
values[val] = desc
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
Loading…
Reference in New Issue
Block a user