Skip to content

Commit afc753e

Browse files
committed
First Refactor to pytest
Signed-off-by: Afonso Oliveira <[email protected]>
1 parent 1a14ba8 commit afc753e

File tree

6 files changed

+88
-47
lines changed

6 files changed

+88
-47
lines changed
549 Bytes
Binary file not shown.
8.88 KB
Binary file not shown.
1.95 KB
Binary file not shown.

ext/auto-inst/parsing.py

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import re
44
import sys
55
from collections import defaultdict
6-
import yaml
6+
import yaml
77

8-
REPO_INSTRUCTIONS = {}
8+
REPO_INSTRUCTIONS = {}
99
REPO_DIRECTORY = None
1010

1111
def safe_get(data, key, default=""):
@@ -123,7 +123,7 @@ def parse_location(loc_str):
123123
else:
124124
json_var_fields.append('?')
125125

126-
# Extract field names from something like varName[index]. After normalizing, vm and others won't have indices.
126+
# Extract field names
127127
field_names = set(re.findall(r'([A-Za-z0-9]+)(?:\[\d+\]|\[\?\])?', ' '.join(json_var_fields)))
128128
if len(field_names) == 0:
129129
differences.append(f"Variable {var_name}: No corresponding field found in JSON bits {high}-{low}")
@@ -162,27 +162,6 @@ def safe_print_instruction_details(name: str, data: dict, output_stream):
162162
except:
163163
output_stream.write("Outputs: N/A\n")
164164

165-
# # Instruction Properties
166-
# output_stream.write("\nInstruction Properties:\n")
167-
# output_stream.write("-" * 20 + "\n")
168-
# output_stream.write(f"Commutable: {'Yes' if safe_get(data, 'isCommutable', 0) else 'No'}\n")
169-
# output_stream.write(f"Memory Load: {'Yes' if safe_get(data, 'mayLoad', 0) else 'No'}\n")
170-
# output_stream.write(f"Memory Store: {'Yes' if safe_get(data, 'mayStore', 0) else 'No'}\n")
171-
# output_stream.write(f"Side Effects: {'Yes' if safe_get(data, 'hasSideEffects', 0) else 'No'}\n")
172-
173-
# # Scheduling Info
174-
# sched = safe_get(data, 'SchedRW', [])
175-
# if sched:
176-
# output_stream.write("\nScheduling Information:\n")
177-
# output_stream.write("-" * 20 + "\n")
178-
# output_stream.write("Operations:\n")
179-
# try:
180-
# for op in sched:
181-
# if isinstance(op, dict):
182-
# output_stream.write(f" - {op.get('printable', 'N/A')}\n")
183-
# except:
184-
# output_stream.write(" - Unable to parse scheduling information\n")
185-
186165
# Encoding
187166
output_stream.write("\nEncoding Pattern:\n")
188167
output_stream.write("-" * 20 + "\n")
@@ -234,18 +213,11 @@ def get_repo_instructions(repo_directory):
234213
"""
235214
repo_instructions = {}
236215
for root, _, files in os.walk(repo_directory):
237-
rel_path = os.path.relpath(root, repo_directory)
238-
if rel_path == '.':
239-
category = "Other"
240-
else:
241-
parts = rel_path.split(os.sep)
242-
category = parts[0] if parts else "Other"
243-
244216
for file in files:
245217
if file.endswith(".yaml"):
246218
instr_name = os.path.splitext(file)[0]
247-
# Store lowercase key for easy lookup
248-
repo_instructions[instr_name.lower()] = category
219+
relative_path = os.path.relpath(root, repo_directory)
220+
repo_instructions[instr_name.lower()] = relative_path
249221
return repo_instructions
250222

251223
def find_json_key(instr_name, json_data):
@@ -269,29 +241,29 @@ def find_json_key(instr_name, json_data):
269241
return v
270242
return None
271243

272-
def main():
244+
def run_parser(json_file, repo_directory, output_file="output.txt"):
245+
"""
246+
Run the parser logic:
247+
1. Get instructions from the repo directory.
248+
2. Parse the JSON file and match instructions.
249+
3. Generate output.txt with instruction details.
250+
"""
273251
global REPO_INSTRUCTIONS, REPO_DIRECTORY
274-
275-
if len(sys.argv) != 3:
276-
print("Usage: python riscv_parser.py <tablegen_json_file> <arch_inst_directory>")
277-
sys.exit(1)
278-
279-
json_file = sys.argv[1]
280-
REPO_DIRECTORY = sys.argv[2]
252+
REPO_DIRECTORY = repo_directory
281253

282254
# Get instructions and categories from the repository structure
283255
REPO_INSTRUCTIONS = get_repo_instructions(REPO_DIRECTORY)
284256
if not REPO_INSTRUCTIONS:
285257
print("No instructions found in the provided repository directory.")
286-
sys.exit(1)
258+
return None
287259

288260
try:
289261
# Read and parse JSON
290262
with open(json_file, 'r') as f:
291263
data = json.loads(f.read())
292264
except Exception as e:
293265
print(f"Error reading file: {str(e)}")
294-
sys.exit(1)
266+
return None
295267

296268
all_instructions = []
297269

@@ -313,7 +285,7 @@ def main():
313285
# Sort all instructions by name
314286
all_instructions.sort(key=lambda x: x[0].lower())
315287

316-
with open("output.txt", "w") as outfile:
288+
with open(output_file, "w") as outfile:
317289
outfile.write("RISC-V Instruction Summary\n")
318290
outfile.write("=" * 50 + "\n")
319291
total = len(all_instructions)
@@ -324,11 +296,24 @@ def main():
324296
outfile.write("\nDETAILED INSTRUCTION INFORMATION\n")
325297
outfile.write("=" * 80 + "\n")
326298

327-
# Print details for each instruction directly, no category splitting
299+
# Print details for each instruction directly
328300
for name, instr_data in all_instructions:
329301
safe_print_instruction_details(name, instr_data, outfile)
330302

331-
print("Output has been written to output.txt")
303+
print(f"Output has been written to {output_file}")
304+
return output_file
305+
306+
def main():
307+
if len(sys.argv) != 3:
308+
print("Usage: python riscv_parser.py <tablegen_json_file> <arch_inst_directory>")
309+
sys.exit(1)
310+
311+
json_file = sys.argv[1]
312+
repo_directory = sys.argv[2]
313+
314+
result = run_parser(json_file, repo_directory, output_file="output.txt")
315+
if result is None:
316+
sys.exit(1)
332317

333318
if __name__ == '__main__':
334319
main()

ext/auto-inst/test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import pytest
2+
import os
3+
from parsing import run_parser
4+
5+
@pytest.fixture
6+
def setup_paths(request):
7+
json_file = request.config.getoption("--json_file")
8+
repo_dir = request.config.getoption("--repo_dir")
9+
10+
# Resolve absolute paths
11+
json_file = os.path.abspath(json_file)
12+
repo_dir = os.path.abspath(repo_dir)
13+
output_file = os.path.join(repo_dir, "output.txt")
14+
15+
print(f"Using JSON File: {json_file}")
16+
print(f"Using Repository Directory: {repo_dir}")
17+
print(f"Output File Path: {output_file}")
18+
19+
return json_file, repo_dir, output_file
20+
21+
def test_run_parser_mimic_old_behavior(setup_paths):
22+
json_file, repo_dir, output_file = setup_paths
23+
24+
# Run the parser (similar to old behavior)
25+
result = run_parser(json_file, repo_dir, output_file=output_file)
26+
27+
if result is None:
28+
print("WARNING: No instructions found or an error occurred. (Mimic old script warning)")
29+
# You could fail here if this was previously considered a hard error
30+
pytest.fail("No output produced by run_parser.")
31+
32+
# Check output file content
33+
if not os.path.exists(output_file):
34+
print("ERROR: output.txt was not created. (Mimic old script error)")
35+
pytest.fail("Output file was not created.")
36+
37+
with open(output_file, 'r') as f:
38+
content = f.read()
39+
40+
# Mimic old behavior: print warnings if no instructions found
41+
if "Total Instructions Found: 0" in content:
42+
print("WARNING: No instructions found in output.txt (Mimic old script warning)")
43+
44+
# Check for encoding differences
45+
# In the original script, encoding mismatches were printed like:
46+
# "Encodings do not match. Differences:"
47+
# If we find that line, we mimic the old error messages
48+
if "Encodings do not match. Differences:" in content:
49+
# Extract differences lines
50+
lines = content.splitlines()
51+
diff_lines = [line for line in lines if line.strip().startswith("-")]
52+
print("ERROR: Encoding differences found! (Mimic old script error)")
53+
pytest.fail("Encodings do not match as per old behavior.")
54+
55+
# If we reach here, we mimic the old success output
56+
print("No warnings or errors detected. Test passes but mimics old success behavior.")

ext/riscv-opcodes

Submodule riscv-opcodes updated 131 files

0 commit comments

Comments
 (0)