Skip to content

Commit

Permalink
improve and fix main parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Lilaa3 committed Sep 22, 2024
1 parent a6ad1c7 commit 4ea8f44
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 23 deletions.
39 changes: 19 additions & 20 deletions fast64_internal/sm64/animation/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CArrayDeclaration:
name: str = ""
path: os.PathLike = ""
file_name: str = ""
values: list[str] = dataclasses.field(default_factory=str)
values: list[str] | dict[str, str] = dataclasses.field(default_factory=str)


@dataclasses.dataclass
Expand Down Expand Up @@ -408,26 +408,25 @@ def read_c(
header.file_name = header_decl.file_name

# Place the values into a dictionary, handles designated initialization
var_defs = [
"flags",
"animYTransDivisor",
"startFrame",
"loopStart",
"loopEnd",
"unusedBoneCount",
"values",
"index",
"length",
]
designated = {}
for i, value in enumerate(header_decl.values):
var_value_split: list[str] = value.split("=")
value = var_value_split[-1].strip()
if len(var_value_split) == 2:
var = var_value_split[0].replace(".", "", 1).strip()
if isinstance(header_decl.values, list):
designated = {}
for value, var in zip(
header_decl.values,
[
"flags",
"animYTransDivisor",
"startFrame",
"loopStart",
"loopEnd",
"unusedBoneCount",
"values",
"index",
"length",
],
):
designated[var] = value
else:
designated[var_defs[i]] = value
else:
designated = header_decl.values

# Read from the dict
header.flags = SM64_AnimFlags.evaluate(designated["flags"])
Expand Down
27 changes: 24 additions & 3 deletions fast64_internal/sm64/animation/importing.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,16 +472,37 @@ def import_tables(


DECL_PATTERN = re.compile(
r"(static\s+const\s+struct\s+Animation|static\s+const\s+u16|static\s+const\s+s16)\s+(\w+)\s*?(?:\[.*?\])?\s*?=\s*?\{(.*?)\};",
r"(static\s+const\s+struct\s+Animation|static\s+const\s+u16|static\s+const\s+s16)\s+"
r"(\w+)\s*?(?:\[.*?\])?\s*?=\s*?\{(.*?)\};",
re.DOTALL,
)
VALUE_SPLIT_PATTERN = re.compile(r"\s*([^,\s]+)\s*(?:,|$)")
VALUE_SPLIT_PATTERN = re.compile(r"\s*(?:(?:\.(?P<var>\w+)|\[\s*(?P<designator>.*?)\s*\])\s*=\s*)?(?P<val>.+?)(?:,|\Z)")


def find_decls(c_data: str, path: Path, decl_list: dict[str, list[CArrayDeclaration]]):
matches = DECL_PATTERN.findall(c_data)
for decl_type, name, value_text in matches:
values = VALUE_SPLIT_PATTERN.findall(value_text)
values = []
for match in VALUE_SPLIT_PATTERN.finditer(value_text):
var, designator, val = match.group("var"), match.group("designator"), match.group("val")
assert val is not None
if designator is not None:
if isinstance(values, dict):
raise PluginError("Invalid mix of designated initializers")
designator = math_eval(designator, object())
first_val = values[0] if values else "0"
values.extend([first_val] * (len(values) - designator))
values[designator] = val
elif var is not None:
if not values:
values = {}
elif isinstance(values, list):
raise PluginError("Mix of designated and positional variable assignment")
values[var] = val
else:
if isinstance(values, dict):
raise PluginError("Mix of designated and positional variable assignment")
values.append(val)
decl_list[decl_type].append(CArrayDeclaration(name, path, path.name, values))


Expand Down

0 comments on commit 4ea8f44

Please sign in to comment.