-
-
Save Damephena/76249df430b4dcd5ab88b753066c8769 to your computer and use it in GitHub Desktop.
Pseudocode to Python converter
This file contains 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
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