ppc2arm 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ppc2arm/__init__.py +3 -0
- ppc2arm/__main__.py +4 -0
- ppc2arm/cli.py +443 -0
- ppc2arm/core/__init__.py +0 -0
- ppc2arm/core/engine.py +333 -0
- ppc2arm/core/fuzzy.py +102 -0
- ppc2arm/core/registry.py +119 -0
- ppc2arm/data/__init__.py +0 -0
- ppc2arm/data/arm_instructions.py +1229 -0
- ppc2arm/data/isa_schema.py +77 -0
- ppc2arm/data/isa_trivia.py +797 -0
- ppc2arm/data/mappings.py +903 -0
- ppc2arm/data/ppc_instructions.py +2607 -0
- ppc2arm/gui/__init__.py +0 -0
- ppc2arm/gui/app.py +344 -0
- ppc2arm/gui/easter_eggs.py +300 -0
- ppc2arm/gui/isa_museum.py +471 -0
- ppc2arm/gui/main_panel.py +144 -0
- ppc2arm/gui/mode_bar.py +148 -0
- ppc2arm/gui/result_panel.py +207 -0
- ppc2arm/gui/theme.py +150 -0
- ppc2arm/gui/widgets/__init__.py +0 -0
- ppc2arm/gui/widgets/about_dialog.py +99 -0
- ppc2arm/gui/widgets/searchable_list.py +119 -0
- ppc2arm/gui/widgets/ticker_bar.py +131 -0
- ppc2arm-1.0.0.dist-info/METADATA +504 -0
- ppc2arm-1.0.0.dist-info/RECORD +31 -0
- ppc2arm-1.0.0.dist-info/WHEEL +5 -0
- ppc2arm-1.0.0.dist-info/entry_points.txt +2 -0
- ppc2arm-1.0.0.dist-info/licenses/LICENSE +21 -0
- ppc2arm-1.0.0.dist-info/top_level.txt +1 -0
ppc2arm/__init__.py
ADDED
ppc2arm/__main__.py
ADDED
ppc2arm/cli.py
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
ppc2arm — PowerPC ↔ ARM / AArch64 Instruction Picker
|
|
4
|
+
=====================================================
|
|
5
|
+
|
|
6
|
+
Translate PowerPC mnemonics to their ARM/AArch64 equivalents and vice-versa,
|
|
7
|
+
or launch the retro ISA-museum GUI.
|
|
8
|
+
|
|
9
|
+
Usage examples
|
|
10
|
+
--------------
|
|
11
|
+
Single-shot lookup (PPC → ARM):
|
|
12
|
+
ppc2arm --from ppc --instr lwz
|
|
13
|
+
ppc2arm --from ppc --instr fmadd --mode 64
|
|
14
|
+
|
|
15
|
+
Single-shot lookup (ARM → PPC):
|
|
16
|
+
ppc2arm --from arm --instr LDR
|
|
17
|
+
ppc2arm --from arm --instr FMADD --mode 64
|
|
18
|
+
|
|
19
|
+
Interactive REPL (no arguments, or force with --repl):
|
|
20
|
+
ppc2arm
|
|
21
|
+
ppc2arm --repl
|
|
22
|
+
|
|
23
|
+
Launch the wxPython GUI:
|
|
24
|
+
ppc2arm --gui
|
|
25
|
+
ppc2arm --gui --mode 64
|
|
26
|
+
|
|
27
|
+
REPL commands
|
|
28
|
+
-------------
|
|
29
|
+
lookup <mnemonic> Look up the current source ISA mnemonic
|
|
30
|
+
search <query> Full-text search across all instructions
|
|
31
|
+
set dir ppc|arm Switch source ISA direction
|
|
32
|
+
set mode 32|64 Switch 32/64-bit mode
|
|
33
|
+
list categories List available instruction categories
|
|
34
|
+
info <isa> Show ISA profile card (arm, ppc, sparc, alpha, ...)
|
|
35
|
+
random fact [<isa>] Display a random ISA trivia fact
|
|
36
|
+
help Show this help text
|
|
37
|
+
quit / exit Exit the REPL
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
import argparse
|
|
41
|
+
import sys
|
|
42
|
+
import os
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Colour helpers (ANSI; disabled when not a TTY)
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
_USE_COLOR = sys.stdout.isatty()
|
|
49
|
+
|
|
50
|
+
_C = {
|
|
51
|
+
"reset": "\033[0m",
|
|
52
|
+
"bold": "\033[1m",
|
|
53
|
+
"green": "\033[32m",
|
|
54
|
+
"yellow": "\033[33m",
|
|
55
|
+
"cyan": "\033[36m",
|
|
56
|
+
"red": "\033[31m",
|
|
57
|
+
"blue": "\033[34m",
|
|
58
|
+
"dim": "\033[2m",
|
|
59
|
+
"magenta":"\033[35m",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _c(name: str, text: str) -> str:
|
|
64
|
+
if not _USE_COLOR:
|
|
65
|
+
return text
|
|
66
|
+
return f"{_C[name]}{text}{_C['reset']}"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# ---------------------------------------------------------------------------
|
|
70
|
+
# Engine import (lazy — avoids import cost when --gui branches early)
|
|
71
|
+
# ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
def _get_engine():
|
|
74
|
+
"""Import and return a shared InstructionEngine instance."""
|
|
75
|
+
from ppc2arm.core.engine import InstructionEngine
|
|
76
|
+
return InstructionEngine()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# ---------------------------------------------------------------------------
|
|
80
|
+
# Result formatting
|
|
81
|
+
# ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
_CONF_COLOR = {
|
|
84
|
+
"direct": "green",
|
|
85
|
+
"close": "cyan",
|
|
86
|
+
"suggestion": "yellow",
|
|
87
|
+
"none": "red",
|
|
88
|
+
"fuzzy": "dim",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
_CONF_LABEL = {
|
|
92
|
+
"direct": "[DIRECT]",
|
|
93
|
+
"close": "[CLOSE]",
|
|
94
|
+
"suggestion": "[SUGGESTION]",
|
|
95
|
+
"none": "[NO MATCH]",
|
|
96
|
+
"fuzzy": "[FUZZY]",
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def format_result(result, direction: str) -> str:
|
|
101
|
+
"""Render a LookupResult to a multi-line terminal string."""
|
|
102
|
+
lines = []
|
|
103
|
+
conf = result.confidence
|
|
104
|
+
color = _CONF_COLOR.get(conf, "dim")
|
|
105
|
+
badge = _CONF_LABEL.get(conf, f"[{conf.upper()}]")
|
|
106
|
+
|
|
107
|
+
src = result.source_mnemonic
|
|
108
|
+
si = result.source_instr
|
|
109
|
+
|
|
110
|
+
lines.append("")
|
|
111
|
+
lines.append(_c("bold", f" {src.upper()}") + " " + _c(color, badge))
|
|
112
|
+
if si:
|
|
113
|
+
lines.append(_c("dim", f" {si.get('full_name', '')}"))
|
|
114
|
+
lines.append(f" Syntax : {si.get('syntax', 'n/a')}")
|
|
115
|
+
lines.append(f" {si.get('description', '')}")
|
|
116
|
+
|
|
117
|
+
if conf == "fuzzy":
|
|
118
|
+
lines.append("")
|
|
119
|
+
lines.append(_c("yellow", " No exact match found.") + " Did you mean:")
|
|
120
|
+
for mnem, score in result.alternatives:
|
|
121
|
+
lines.append(f" {_c('cyan', mnem):<20} score={score:.2f}")
|
|
122
|
+
lines.append("")
|
|
123
|
+
return "\n".join(lines)
|
|
124
|
+
|
|
125
|
+
if conf == "none":
|
|
126
|
+
lines.append("")
|
|
127
|
+
lines.append(_c("red", f" {result.notes}"))
|
|
128
|
+
lines.append("")
|
|
129
|
+
return "\n".join(lines)
|
|
130
|
+
|
|
131
|
+
arrow = "→" if direction == "ppc" else "←"
|
|
132
|
+
dest_isa = "ARM" if direction == "ppc" else "PPC"
|
|
133
|
+
lines.append("")
|
|
134
|
+
lines.append(_c("bold", f" {arrow} {dest_isa} analogues:"))
|
|
135
|
+
|
|
136
|
+
for i, tgt in enumerate(result.targets):
|
|
137
|
+
ti = result.target_instrs[i] if i < len(result.target_instrs) else None
|
|
138
|
+
fname = ti.get("full_name", "") if ti else ""
|
|
139
|
+
syn = ti.get("syntax", "") if ti else ""
|
|
140
|
+
desc = ti.get("description", "") if ti else ""
|
|
141
|
+
lines.append(f" {_c('bold', tgt):<22} {fname}")
|
|
142
|
+
if syn:
|
|
143
|
+
lines.append(f" {'':22} Syntax: {syn}")
|
|
144
|
+
if desc:
|
|
145
|
+
lines.append(f" {'':22} {_c('dim', desc[:80])}")
|
|
146
|
+
|
|
147
|
+
if result.notes:
|
|
148
|
+
lines.append("")
|
|
149
|
+
if conf == "suggestion":
|
|
150
|
+
lines.append(_c("yellow", " ⚠ " + result.notes))
|
|
151
|
+
else:
|
|
152
|
+
lines.append(_c("dim", " ℹ " + result.notes))
|
|
153
|
+
|
|
154
|
+
lines.append("")
|
|
155
|
+
return "\n".join(lines)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def format_isa_profile(profile: dict) -> str:
|
|
159
|
+
"""Render an ISA profile dict as a museum-placard style string."""
|
|
160
|
+
import textwrap
|
|
161
|
+
lines = []
|
|
162
|
+
w = 60
|
|
163
|
+
lines.append(" " + "─" * w)
|
|
164
|
+
lines.append(f" {_c('bold', profile['name'])}")
|
|
165
|
+
lines.append(f" Vendor : {profile['vendor']}")
|
|
166
|
+
lines.append(f" Born : {profile['year']} "
|
|
167
|
+
f"Died: {profile.get('died') or 'still alive'}")
|
|
168
|
+
lines.append(f" Bits : {profile['bits']}-bit")
|
|
169
|
+
lines.append(f" Endian : {profile['endian']}")
|
|
170
|
+
lines.append(f" Regs : {profile['registers']} integer registers")
|
|
171
|
+
lines.append("")
|
|
172
|
+
desc = profile.get("description", "")
|
|
173
|
+
for line in textwrap.wrap(desc, width=58):
|
|
174
|
+
lines.append(f" {line}")
|
|
175
|
+
lines.append("")
|
|
176
|
+
lines.append(_c("dim", " Famous for:"))
|
|
177
|
+
for line in textwrap.wrap(profile.get("famous_for", ""), width=58):
|
|
178
|
+
lines.append(f" {line}")
|
|
179
|
+
lines.append(" " + "─" * w)
|
|
180
|
+
return "\n".join(lines)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# ---------------------------------------------------------------------------
|
|
184
|
+
# Argument parser
|
|
185
|
+
# ---------------------------------------------------------------------------
|
|
186
|
+
|
|
187
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
188
|
+
parser = argparse.ArgumentParser(
|
|
189
|
+
prog="ppc2arm",
|
|
190
|
+
description=(
|
|
191
|
+
"PPC2ARM — PowerPC ↔ ARM/AArch64 Instruction Picker.\n\n"
|
|
192
|
+
"Translates PowerPC mnemonics to ARM/AArch64 equivalents (and vice-versa). "
|
|
193
|
+
"Run without arguments to enter the interactive REPL."
|
|
194
|
+
),
|
|
195
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
196
|
+
epilog=__doc__,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
parser.add_argument(
|
|
200
|
+
"--gui", action="store_true",
|
|
201
|
+
help="Launch the wxPython GUI (requires wxPython>=4.2).",
|
|
202
|
+
)
|
|
203
|
+
parser.add_argument(
|
|
204
|
+
"--from",
|
|
205
|
+
dest="source_isa",
|
|
206
|
+
choices=["ppc", "arm"],
|
|
207
|
+
metavar="{ppc,arm}",
|
|
208
|
+
help="Source ISA for a single-shot lookup.",
|
|
209
|
+
)
|
|
210
|
+
parser.add_argument(
|
|
211
|
+
"--instr",
|
|
212
|
+
dest="mnemonic",
|
|
213
|
+
metavar="MNEMONIC",
|
|
214
|
+
help="Instruction mnemonic to look up (e.g. lwz, LDR).",
|
|
215
|
+
)
|
|
216
|
+
parser.add_argument(
|
|
217
|
+
"--mode",
|
|
218
|
+
choices=["32", "64"],
|
|
219
|
+
default="32",
|
|
220
|
+
help="Target bit-mode: 32 (default) or 64.",
|
|
221
|
+
)
|
|
222
|
+
parser.add_argument(
|
|
223
|
+
"--repl",
|
|
224
|
+
action="store_true",
|
|
225
|
+
help="Force interactive REPL.",
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
return parser
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# ---------------------------------------------------------------------------
|
|
232
|
+
# Single-shot
|
|
233
|
+
# ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
def run_single_shot(args: argparse.Namespace) -> None:
|
|
236
|
+
engine = _get_engine()
|
|
237
|
+
result = engine.lookup(args.mnemonic, args.source_isa, args.mode)
|
|
238
|
+
print(format_result(result, args.source_isa))
|
|
239
|
+
sys.exit(0)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
# ---------------------------------------------------------------------------
|
|
243
|
+
# REPL
|
|
244
|
+
# ---------------------------------------------------------------------------
|
|
245
|
+
|
|
246
|
+
_REPL_HELP = """\
|
|
247
|
+
Commands
|
|
248
|
+
--------
|
|
249
|
+
lookup <mnemonic> Translate mnemonic (uses current dir/mode)
|
|
250
|
+
search <query> Full-text search instructions
|
|
251
|
+
set dir ppc|arm Switch direction
|
|
252
|
+
set mode 32|64 Switch bit mode
|
|
253
|
+
list categories List instruction categories
|
|
254
|
+
info <isa> Show ISA profile (arm, ppc, sparc, alpha, mips,
|
|
255
|
+
pa-risc, itanium, 68k, vax, riscv)
|
|
256
|
+
random fact [<isa>] Random ISA trivia fact
|
|
257
|
+
help Show this help
|
|
258
|
+
quit / exit Exit
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _repl_banner() -> str:
|
|
263
|
+
return (
|
|
264
|
+
_c("bold", "\n PPC2ARM — ISA Translation Station ")
|
|
265
|
+
+ _c("magenta", "PowerPC ↔ ARM/AArch64")
|
|
266
|
+
+ _c("dim", " v1.0.0\n")
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def run_repl(args: argparse.Namespace) -> None:
|
|
271
|
+
engine = _get_engine()
|
|
272
|
+
|
|
273
|
+
try:
|
|
274
|
+
import readline # noqa: F401
|
|
275
|
+
except ImportError:
|
|
276
|
+
try:
|
|
277
|
+
import pyreadline3 as readline # noqa: F401
|
|
278
|
+
except ImportError:
|
|
279
|
+
pass
|
|
280
|
+
|
|
281
|
+
from ppc2arm.data.isa_trivia import COMPILER_QUOTES
|
|
282
|
+
import random
|
|
283
|
+
|
|
284
|
+
direction = "ppc"
|
|
285
|
+
mode = getattr(args, "mode", "32")
|
|
286
|
+
|
|
287
|
+
print(_repl_banner())
|
|
288
|
+
print(_c("dim", f" Direction: {direction.upper()} → {'ARM' if direction == 'ppc' else 'PPC'} "
|
|
289
|
+
f"Mode: {mode}-bit"))
|
|
290
|
+
print(_c("dim", " Type 'help' for commands, 'quit' to exit.\n"))
|
|
291
|
+
|
|
292
|
+
print(_c("cyan", f" \"{random.choice(COMPILER_QUOTES)}\"\n"))
|
|
293
|
+
|
|
294
|
+
try:
|
|
295
|
+
while True:
|
|
296
|
+
try:
|
|
297
|
+
prompt = _c("green", f"ppc2arm[{direction}/{mode}]> ")
|
|
298
|
+
line = input(prompt).strip()
|
|
299
|
+
except EOFError:
|
|
300
|
+
print()
|
|
301
|
+
break
|
|
302
|
+
if not line:
|
|
303
|
+
continue
|
|
304
|
+
|
|
305
|
+
parts = line.split(None, 1)
|
|
306
|
+
cmd = parts[0].lower()
|
|
307
|
+
rest = parts[1] if len(parts) > 1 else ""
|
|
308
|
+
|
|
309
|
+
if cmd in ("quit", "exit", "q"):
|
|
310
|
+
break
|
|
311
|
+
|
|
312
|
+
elif cmd == "help":
|
|
313
|
+
print(_REPL_HELP)
|
|
314
|
+
|
|
315
|
+
elif cmd == "lookup" and rest:
|
|
316
|
+
result = engine.lookup(rest.strip(), direction, mode)
|
|
317
|
+
print(format_result(result, direction))
|
|
318
|
+
|
|
319
|
+
elif cmd == "search" and rest:
|
|
320
|
+
isa = direction
|
|
321
|
+
matches = engine.search(rest.strip(), isa, mode)
|
|
322
|
+
if matches:
|
|
323
|
+
print(f"\n {len(matches)} matches in {isa.upper()}:")
|
|
324
|
+
for m in matches:
|
|
325
|
+
print(f" {_c('cyan', m)}")
|
|
326
|
+
else:
|
|
327
|
+
print(_c("yellow", f" No matches for '{rest.strip()}'."))
|
|
328
|
+
print()
|
|
329
|
+
|
|
330
|
+
elif cmd == "set":
|
|
331
|
+
sub_parts = rest.lower().split()
|
|
332
|
+
if len(sub_parts) == 2 and sub_parts[0] == "dir":
|
|
333
|
+
if sub_parts[1] in ("ppc", "arm"):
|
|
334
|
+
direction = sub_parts[1]
|
|
335
|
+
dest = "ARM" if direction == "ppc" else "PPC"
|
|
336
|
+
print(_c("cyan", f" Direction set to {direction.upper()} → {dest}\n"))
|
|
337
|
+
else:
|
|
338
|
+
print(_c("red", " Usage: set dir ppc|arm\n"))
|
|
339
|
+
elif len(sub_parts) == 2 and sub_parts[0] == "mode":
|
|
340
|
+
if sub_parts[1] in ("32", "64"):
|
|
341
|
+
mode = sub_parts[1]
|
|
342
|
+
print(_c("cyan", f" Mode set to {mode}-bit\n"))
|
|
343
|
+
else:
|
|
344
|
+
print(_c("red", " Usage: set mode 32|64\n"))
|
|
345
|
+
else:
|
|
346
|
+
print(_c("red", " Usage: set dir ppc|arm OR set mode 32|64\n"))
|
|
347
|
+
|
|
348
|
+
elif cmd == "list" and rest.lower().startswith("cat"):
|
|
349
|
+
cats = engine.list_categories(direction)
|
|
350
|
+
print(f"\n Categories ({direction.upper()}):")
|
|
351
|
+
for cat in cats:
|
|
352
|
+
print(f" {_c('cyan', cat)}")
|
|
353
|
+
print()
|
|
354
|
+
|
|
355
|
+
elif cmd == "info" and rest:
|
|
356
|
+
isa_name = rest.strip().lower()
|
|
357
|
+
profile = engine.get_isa_profile(isa_name)
|
|
358
|
+
if profile:
|
|
359
|
+
print(format_isa_profile(profile))
|
|
360
|
+
else:
|
|
361
|
+
avail = ", ".join(sorted(
|
|
362
|
+
["arm", "ppc", "sparc", "alpha", "mips", "pa-risc",
|
|
363
|
+
"itanium", "68k", "vax", "riscv", "x86"]
|
|
364
|
+
))
|
|
365
|
+
print(_c("yellow", f" Unknown ISA '{isa_name}'."))
|
|
366
|
+
print(_c("dim", f" Available: {avail}\n"))
|
|
367
|
+
|
|
368
|
+
elif cmd == "random" and rest.lower().startswith("fact"):
|
|
369
|
+
parts2 = rest.split(None, 1)
|
|
370
|
+
isa_filter = parts2[1].strip() if len(parts2) > 1 else None
|
|
371
|
+
fact = engine.random_fact(isa_filter)
|
|
372
|
+
if fact:
|
|
373
|
+
label = fact.get("isa", "").upper()
|
|
374
|
+
cat = fact.get("category", "")
|
|
375
|
+
print(f"\n {_c('bold', label)} {_c('dim', '[' + cat + ']')}")
|
|
376
|
+
import textwrap
|
|
377
|
+
for fl in textwrap.wrap(fact["text"], width=70):
|
|
378
|
+
print(f" {fl}")
|
|
379
|
+
print()
|
|
380
|
+
else:
|
|
381
|
+
print(_c("yellow", f" No facts found for '{isa_filter}'.\n"))
|
|
382
|
+
|
|
383
|
+
else:
|
|
384
|
+
# Interpret whole line as mnemonic lookup
|
|
385
|
+
result = engine.lookup(line, direction, mode)
|
|
386
|
+
print(format_result(result, direction))
|
|
387
|
+
|
|
388
|
+
except KeyboardInterrupt:
|
|
389
|
+
print()
|
|
390
|
+
|
|
391
|
+
sys.exit(0)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# ---------------------------------------------------------------------------
|
|
395
|
+
# GUI
|
|
396
|
+
# ---------------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
def run_gui(args: argparse.Namespace) -> None:
|
|
399
|
+
"""Launch the wxPython GUI."""
|
|
400
|
+
try:
|
|
401
|
+
import wx # noqa: F401
|
|
402
|
+
except ImportError:
|
|
403
|
+
print(
|
|
404
|
+
"wxPython is not installed. Install it with:\n"
|
|
405
|
+
" pipx inject ppc2arm wxPython (if installed with pipx)\n"
|
|
406
|
+
" pip install wxPython (pip / virtualenv)\n"
|
|
407
|
+
"or visit https://wxpython.org/pages/downloads/"
|
|
408
|
+
)
|
|
409
|
+
sys.exit(1)
|
|
410
|
+
try:
|
|
411
|
+
from ppc2arm.gui.app import PPC2ARMApp
|
|
412
|
+
except ImportError:
|
|
413
|
+
print("GUI not yet fully implemented.")
|
|
414
|
+
sys.exit(0)
|
|
415
|
+
app = PPC2ARMApp(initial_mode=args.mode)
|
|
416
|
+
app.MainLoop()
|
|
417
|
+
sys.exit(0)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
# ---------------------------------------------------------------------------
|
|
421
|
+
# Entry point
|
|
422
|
+
# ---------------------------------------------------------------------------
|
|
423
|
+
|
|
424
|
+
def main() -> None:
|
|
425
|
+
parser = build_parser()
|
|
426
|
+
args = parser.parse_args()
|
|
427
|
+
|
|
428
|
+
if args.gui:
|
|
429
|
+
run_gui(args)
|
|
430
|
+
elif args.repl:
|
|
431
|
+
run_repl(args)
|
|
432
|
+
elif args.source_isa and args.mnemonic:
|
|
433
|
+
run_single_shot(args)
|
|
434
|
+
elif args.source_isa and not args.mnemonic:
|
|
435
|
+
parser.error("--from requires --instr MNEMONIC.")
|
|
436
|
+
elif args.mnemonic and not args.source_isa:
|
|
437
|
+
parser.error("--instr requires --from {ppc,arm}.")
|
|
438
|
+
else:
|
|
439
|
+
run_repl(args)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
if __name__ == "__main__":
|
|
443
|
+
main()
|
ppc2arm/core/__init__.py
ADDED
|
File without changes
|