Usecode pseudocode
This commit is contained in:
parent
f92d1504fa
commit
c12bb39437
1362 changed files with 71072 additions and 38056 deletions
|
|
@ -2,7 +2,12 @@ from __future__ import annotations
|
|||
|
||||
import unittest
|
||||
|
||||
from tools.poc_crusader_usecode_parser import render_structured_pseudocode
|
||||
from tools.poc_crusader_usecode_parser import (
|
||||
get_intrinsic_hints,
|
||||
intrinsic_display_name,
|
||||
render_partially_structured_blocks,
|
||||
render_structured_pseudocode,
|
||||
)
|
||||
|
||||
|
||||
class UsecodeStructuringTests(unittest.TestCase):
|
||||
|
|
@ -49,6 +54,100 @@ class UsecodeStructuringTests(unittest.TestCase):
|
|||
|
||||
self.assertIsNone(render_structured_pseudocode(blocks))
|
||||
|
||||
def test_if_else_branch_renders_as_structured_else(self) -> None:
|
||||
blocks = [
|
||||
("entry", ["if (Item.getMapNum(arg_06) != 0) goto block_015C;"]),
|
||||
("block_00FD", ["if Intrinsic0000() goto block_0132;"]),
|
||||
("block_0108", ["spawn class_0A18_slot_20(pid, 0, *(arg_06), arg_06);", "suspend;", "goto block_01C0;"]),
|
||||
("block_0132", ["spawn class_0A18_slot_20(pid, 1, *(arg_06), arg_06);", "suspend;", "goto block_01C0;"]),
|
||||
("block_015C", ["if Intrinsic0000() goto block_0195;"]),
|
||||
("block_0167", ["spawn class_0A18_slot_20(pid, (0 + 0x0080), *(arg_06), arg_06);", "suspend;", "goto block_01C0;"]),
|
||||
("block_0195", ["spawn class_0A18_slot_20(pid, (1 + 0x0080), *(arg_06), arg_06);", "suspend;"]),
|
||||
("block_01C0", ["return;"]),
|
||||
]
|
||||
|
||||
rendered = render_structured_pseudocode(blocks)
|
||||
|
||||
self.assertIsNotNone(rendered)
|
||||
text = "\n".join(rendered or [])
|
||||
self.assertIn("if (Item.getMapNum(arg_06) == 0) {", text)
|
||||
self.assertIn("else {", text)
|
||||
self.assertNotIn("goto block_01C0;", text)
|
||||
|
||||
def test_loop_header_and_back_edge_render_as_while(self) -> None:
|
||||
blocks = [
|
||||
("entry", ["/* loopscr value_u8=0x24 */"]),
|
||||
("block_0118", ["if condition goto block_0151;"]),
|
||||
("block_011B", ["if (Item.getFrame(item) != 0) goto block_014D;"]),
|
||||
("block_012D", ["suspend;"]),
|
||||
("block_014D", ["/* loopnext */", "goto block_0118;"]),
|
||||
("block_0151", ["return;"]),
|
||||
]
|
||||
|
||||
rendered = render_structured_pseudocode(blocks)
|
||||
|
||||
self.assertIsNotNone(rendered)
|
||||
text = "\n".join(rendered or [])
|
||||
self.assertIn("while (!condition) {", text)
|
||||
self.assertNotIn("goto block_0118;", text)
|
||||
|
||||
def test_selector_ladder_renders_as_else_if_chain(self) -> None:
|
||||
blocks = [
|
||||
("entry", ["if (dir != 0) goto block_0358;"]),
|
||||
("block_0339", ["x = 0;", "y = -1;", "goto block_0469;"]),
|
||||
("block_0358", ["if (dir != 1) goto block_037F;"]),
|
||||
("block_0360", ["x = 1;", "y = -1;", "goto block_0469;"]),
|
||||
("block_037F", ["if (dir != 2) goto block_03A6;"]),
|
||||
("block_0387", ["x = 1;", "y = 0;", "goto block_0469;"]),
|
||||
("block_03A6", ["if (dir != 3) goto block_0469;"]),
|
||||
("block_03AE", ["x = 1;", "y = 1;", "goto block_0469;"]),
|
||||
("block_0469", ["return;"]),
|
||||
]
|
||||
|
||||
rendered = render_structured_pseudocode(blocks)
|
||||
|
||||
self.assertIsNotNone(rendered)
|
||||
text = "\n".join(rendered or [])
|
||||
self.assertIn("if (dir == 0) {", text)
|
||||
self.assertIn("else if (dir == 1) {", text)
|
||||
self.assertIn("else if (dir == 2) {", text)
|
||||
self.assertIn("else if (dir == 3) {", text)
|
||||
self.assertNotIn("goto block_0469;", text)
|
||||
|
||||
def test_intrinsic_overlay_prefers_crusader_specific_names(self) -> None:
|
||||
regret_intrinsics = get_intrinsic_hints("regret")
|
||||
|
||||
self.assertEqual(intrinsic_display_name(regret_intrinsics.get(0x0013), 0x0013), "UCMachine.rndRange")
|
||||
self.assertEqual(intrinsic_display_name(regret_intrinsics.get(0x0027), 0x0027), "SpriteProcess.createSprite")
|
||||
|
||||
def test_remorse_intrinsic_overlay_uses_local_table(self) -> None:
|
||||
remorse_intrinsics = get_intrinsic_hints("remorse")
|
||||
|
||||
self.assertEqual(intrinsic_display_name(remorse_intrinsics.get(0x0018), 0x0018), "UCMachine.rndRange")
|
||||
self.assertEqual(intrinsic_display_name(remorse_intrinsics.get(0x0015), 0x0015), "AudioProcess.playSFXCru")
|
||||
|
||||
def test_selector_ladder_renders_in_raw_fallback(self) -> None:
|
||||
blocks = [
|
||||
("entry", ["goto block_0331;"]),
|
||||
("block_0331", ["if (dir != 0) goto block_0358;"]),
|
||||
("block_0339", ["x = 0;", "y = -1;", "goto block_0469;"]),
|
||||
("block_0358", ["if (dir != 1) goto block_037F;"]),
|
||||
("block_0360", ["x = 1;", "y = -1;", "goto block_0469;"]),
|
||||
("block_037F", ["if (dir != 2) goto block_0469;"]),
|
||||
("block_0387", ["x = 1;", "y = 0;", "goto block_0469;"]),
|
||||
("block_0469", ["return;"]),
|
||||
]
|
||||
|
||||
rendered = render_partially_structured_blocks(blocks)
|
||||
|
||||
text = "\n".join(rendered)
|
||||
self.assertIn("block_0331:", text)
|
||||
self.assertIn("if (dir == 0) {", text)
|
||||
self.assertIn("else if (dir == 1) {", text)
|
||||
self.assertIn("else if (dir == 2) {", text)
|
||||
self.assertNotIn("block_0358:", text)
|
||||
self.assertNotIn("goto block_0469;", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue