Created
January 29, 2023 06:32
-
-
Save wangkuiyi/f57de13df6fa7a32abd8968c8509e397 to your computer and use it in GitHub Desktop.
Converts a Python script that prints an MLIR into a Markdown section
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Run the following command to convert 01-double.py into a Markdown section. | |
| # | |
| # python interweave_python_mlir.py python_file | |
| # | |
| # Requirements: | |
| # | |
| # 1. Running the python_file must prints the MLIR source code. | |
| # | |
| # 2. If there is a comments of a number before a Python code block in | |
| # python_file, the number is the number of lines of the MLIR source | |
| # code should be matched with the Python code block. | |
| # | |
| # Outputs: | |
| # | |
| # 1. The Markdown section header is the script file name. | |
| # | |
| # 2. The section content is the content of the multi-line string at | |
| # the beginning of the Python script file, if there is one. | |
| # | |
| # 3. The following table typesets interweaved content from python_file | |
| # and the MLIR source code. | |
| # | |
| from typing import List, Tuple | |
| def capture_stdout(python_script: str) -> List[str]: | |
| """ Execute a Python script, capture the stdout, and split it by lines. """ | |
| import subprocess | |
| process = subprocess.Popen(["python", python_script], stdout=subprocess.PIPE) | |
| (output, err) = process.communicate() | |
| if process.wait() < 0: | |
| raise Exception(f"capture_stdout failed with {err.decode('utf-8')}") | |
| return output.decode('utf-8').split('\n') | |
| def is_end_of_block(line: str) -> Tuple[bool, int]: | |
| """ Returns (true, 0) if line is empty, or (true, n) if line comments a number n """ | |
| line = line.strip() | |
| if line == "": | |
| return (True, 0) | |
| if line[0] == '#' and line[1:].strip().isdigit(): | |
| return (True, int(line[1:])) | |
| return (False, 0) | |
| def is_multiline_string_quote(line: str) -> bool: | |
| return line.strip() == '"""' | |
| def weave(py_buf: List[str], mlir_lines: List[str], emitted: int, to_emit: int): | |
| print("<tr><td>") | |
| print("```") | |
| for l in py_buf: | |
| print(l, end="") | |
| print("```") | |
| if to_emit == 0: | |
| print("</td></tr>") | |
| return | |
| print("</td><td>") | |
| print("```") | |
| for i in range(emitted, emitted + to_emit): | |
| print(mlir_lines[i]) | |
| print("```") | |
| print("</td></tr>") | |
| BEGIN = 0 | |
| PREAMBLE = 1 | |
| WEAVING = 2 | |
| def switch_to(to: int) -> int: | |
| if to == WEAVING: | |
| print() | |
| print("<table>") | |
| return to | |
| def interweave(python_script: str) -> str: | |
| mlir_lines = capture_stdout(python_script) | |
| py_buf: List[str] = [] # the current Python code block. | |
| num_mlir_lines = 0 # the number of MLIR lines of the current block | |
| emitted_mlir_lines = 0 | |
| with open(python_script) as py: | |
| print(f"## {python_script}\n") | |
| state: int = BEGIN | |
| while (line := py.readline()): | |
| if state == BEGIN: | |
| if is_multiline_string_quote(line): | |
| state = switch_to(PREAMBLE) | |
| else: | |
| state = switch_to(WEAVING) | |
| elif state == PREAMBLE: | |
| if is_multiline_string_quote(line): | |
| state = switch_to(WEAVING) | |
| else: | |
| print(line) | |
| elif state == WEAVING: | |
| sep, n = is_end_of_block(line) | |
| if sep: | |
| weave(py_buf, mlir_lines, emitted_mlir_lines, num_mlir_lines) | |
| py_buf = [] | |
| emitted_mlir_lines += num_mlir_lines | |
| num_mlir_lines = n | |
| else: | |
| py_buf.append(line) | |
| print("</table>") | |
| import sys | |
| interweave(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment