Skip to content

Instantly share code, notes, and snippets.

@Damephena
Last active August 31, 2022 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Damephena/76249df430b4dcd5ab88b753066c8769 to your computer and use it in GitHub Desktop.
Save Damephena/76249df430b4dcd5ab88b753066c8769 to your computer and use it in GitHub Desktop.
Pseudocode to Python converter
import re
TYPES = {
"integer": "int",
"double": "float",
"float": "float",
"boolean": "bool",
"character": "str",
"string": "str",
}
CONVERTIBLES = [
("\t", ""),
("”", '"'),
("MOD", "%"),
("CASE", "case"),
("FALSE", "False"),
("TRUE", "True"),
("false", "False"),
("true", "True"),
("ELSE IF", "ELIF"),
("ELSEIF", "ELIF"),
("ELSIF", "ELIF"),
("END WHILE", "ENDWHILE"),
("END IF", "ENDIF"),
("THEN", ""),
("RANDOM", "random"),
("AND", "and"),
("OR", "or"),
("NOT", "not"),
]
ex1 = """
DECLARE String user_name;
DECLARE Character first_name;
DECLARE Integer current_index;
SET user_name = "vibes-driven-dev";
SET first_name = "I";
SET currentIndex = 0;
WHILE currentIndex < 5;
DISPLAY "My real name is Ifenna and it starts with the letter: " + first_name;
SET currentIndex = currentIndex + 1;
ENDWHILE;
IF currentIndex >= 5:
DISPLAY "Just kidding call me The " + user_name;
ENDIF;
"""
ex2 = """
DECLARE String user_name;
DECLARE Character first_name;
DECLARE Integer current_index;
"""
ex3 = """
DECLARE String user_name;
DECLARE Character first_name;
DECLARE Integer current_index;
SET user_name = "vibes-driven-dev";
SET first_name = "I";
SET currentIndex = 0;
"""
ex4 = ex4 = """
DECLARE String user_name;
DECLARE Character first_name;
DECLARE Integer current_index;
SET user_name = "vibes-driven-dev";
SET first_name = "I";
SET currentIndex = 0;
WHILE currentIndex < 5;
DISPLAY "My real name is Ifenna and it starts with the letter: " + first_name;
SET currentIndex = currentIndex + 1;
END WHILE;
IF currentIndex >= 5:
DISPLAY "Just kidding call me The " + user_name;
END IF;
"""
user_input = ex4
pseudo_no_empty_strings = list(filter(None, user_input.splitlines()))
re_flags = re.VERBOSE
re_remainder = re.compile(""" \s* ( \w+ )(?: \s* \[ \s* \] )? \s* """, re_flags)
re_first_construct = re.compile(
"""
DECLARE # Start of DECLARE statement
\s* ( \w+ ) # Type
\s+ ( \w+ )(?: \s* \[ \s* \] )? # Variable name
\s* """,
re_flags,
)
var_types: dict = {}
preprocessed_pseudocode = []
for codeline, line in enumerate(pseudo_no_empty_strings, start=1):
line = re.sub("\s*[;:]\s*$", "", line)
if line.startswith("DECLARE"):
first_word, *args = line.split(",")
var_type, first_var = re_first_construct.match(first_word).groups()
extra_vars = list(map(lambda x: re_remainder.match(x).groups()[0], args))
for varName in [first_var] + extra_vars:
if var_type.lower() not in TYPES.keys():
print(f"Line {codeline}: Unknown variable type '{var_type}'")
print("Expected variable type in: ", list(TYPES.keys()))
exit(1)
var_types[varName] = TYPES[var_type.lower()]
for old, new in CONVERTIBLES:
line = line.replace(old, new)
preprocessed_pseudocode.append(line)
output = ""
while_level = 0
if_level = 0
converted_psuedocode = []
for codeline, line in enumerate(preprocessed_pseudocode, start=1):
indent_level = while_level + if_level # Will be unindented on ELSE and ELIF lines
if (
line.startswith("DECLARE")
or line.startswith("PROGRAM")
or line.startswith("START")
or line.startswith("BEGIN")
):
output = ""
elif line.startswith("DISPLAY"):
line = re.sub("DISPLAY ?", "print(", line).strip() + ")"
line = re.sub('("[^"]*?")\s*\+\s*', "\\1, ", line) # removes "+"
output = re.sub('\s*\+\s*("[^"]*?")', ", \\1", line)
elif line.startswith("SET"):
output = line.replace("SET", "").strip()
elif line.startswith("WHILE"):
while_level += 1
output = line.replace("WHILE", "while").strip() + ":"
elif line.startswith("IF"):
if_level += 1
output = line.replace("IF", "if").strip() + ":"
elif line.startswith("ENDIF"):
if if_level == 0:
print(f"line {codeline}: no IF block for ENDIF.")
exit(1)
if_level -= 1
output = ""
elif line.startswith("ENDWHILE"):
if while_level == 0:
print(f"line {codeline}: no WHILE block for ENDWHILE.")
exit(1)
output = ""
while_level -= 1
elif line.startswith("ELSE"):
if if_level == 0:
print(f"line {codeline}: ELSE with no preceding IF.")
exit(1)
output = "else:"
indent_level -= 1
elif line.startswith("ELIF"):
if if_level == 0:
print(f"line {codeline}: no IF block for ELSEIF.")
exit(1)
output = line.replace("ELIF", "elif").strip() + ":"
indent_level -= 1
else:
print(f'Error: line {codeline}: Cannot figure out: "{line.strip()}"')
exit(1)
indentation = indent_level * " "
if not isinstance(output, list):
output = [output]
converted_psuedocode.extend(
indentation + python_line for python_line in output if python_line != ""
)
print("---CONVERTED PSUEDOCODE SANITY CHECK---\n")
for python in converted_psuedocode:
print(python)
# with open("sanity-check.py", "w") as python_file:
# for python_output in converted_psuedocode:
# print("Output: ", python_output)
# python_file.write(python_output + "\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment