Spaces:
Sleeping
Sleeping
File size: 8,006 Bytes
02215ec 870b155 02215ec 870b155 02215ec 870b155 02215ec 870b155 02215ec 14a97bc 02215ec 14a97bc 02215ec 870b155 02215ec 870b155 02215ec 14a97bc 02215ec 14a97bc 02215ec 14a97bc 02215ec 14a97bc 02215ec 14a97bc 02215ec |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
class ErasCompiler:
def __init__(self):
self.KEYWORDS = {
"ARE YOU READY FOR IT?": "BEGIN_MAIN",
"LONG LIVE": "END_MAIN",
"BLANK SPACE": "DECLARE_VAR",
"YOU BELONG WITH ME": "ASSIGN_VAL",
"SHAKE IT OFF": "BEGIN_MATH",
"MINE": "ADD",
"BACK TO DECEMBER": "SUBTRACT",
"CALL IT WHAT YOU WANT": "END_MATH",
"SPEAK NOW": "PRINT",
"I KNEW YOU WERE TROUBLE": "IF",
"YOU'RE ON YOUR OWN, KID": "ELSE",
"EXILE": "END_IF",
"STAY STAY STAY": "==",
"LET'S GO BATTLE": ">",
"FROM THE VAULT": "BEGIN_FUNC",
"THE STORY OF US": "FUNC_ARG",
"CLEAN": "END_FUNC",
"IMGONNAGETYOUBACK": "RETURN",
"ME!": "AND",
"THE 1": "OR",
"LOOK WHAT YOU MADE ME DO": "NOT",
"QUESTION...?": "INPUT",
"WE ARE NEVER EVER GETTING BACK TOGETHER": "BREAK",
"IS IT OVER NOW?": "WHILE",
"OUT OF THE WOODS": "END_WHILE",
}
def transpile(self, source_code: str) -> str:
lines = source_code.splitlines()
python_output = ["enchanted = 1\nexile = 0\nthirteen = 13\n"]
indent_level = 0
math_target = None
last_var = None
in_function_def = False # Track if we're building a function definition
func_arg_count = 0 # Count function arguments
for line in lines:
raw = line # Save original line for counting
line = line.strip()
if not line or line.startswith("DEAR JOHN"):
continue
token = None
payload = ""
for lyric, t in self.KEYWORDS.items():
if line.startswith(lyric):
token = t
payload = line.replace(lyric, "").strip()
break
if not token:
continue
# If we're in a function definition and encounter a non-FUNC_ARG/END_FUNC token,
# close the function definition first
if in_function_def and token not in ["FUNC_ARG", "END_FUNC"]:
if python_output and not python_output[-1].endswith(":\n"):
if python_output[-1].endswith("("):
python_output[-1] += "):\n"
else:
python_output[-1] += "):\n"
indent_level += 1 # Increment for function body
in_function_def = False
func_arg_count = 0
# Replace comparison operators in payload
payload = payload.replace("STAY STAY STAY", "==")
payload = payload.replace("LET'S GO BATTLE", ">")
# Replace input keyword in payload - this handles "YOU BELONG WITH ME QUESTION...?"
payload = payload.replace("QUESTION...?", "int(input())")
# Remove PLAY keyword (used for function calls)
payload = payload.replace("PLAY ", "")
current_indent = " " * indent_level
# Core Logic Mapping
if token == "BEGIN_MAIN":
python_output.append("def main():\n")
indent_level += 1
elif token == "END_MAIN":
python_output.append("\nmain()\n") # Simplified for API execution
elif token == "DECLARE_VAR":
last_var = payload
python_output.append(f"{current_indent}{payload} = 0\n")
elif token == "ASSIGN_VAL":
# payload already has "int(input())" if it contained "QUESTION...?"
val = payload
if math_target:
python_output.append(f"{current_indent}_acc = {val}\n")
else:
python_output.append(f"{current_indent}{last_var} = {val}\n")
elif token == "BEGIN_MATH":
math_target = payload
# Initialize accumulator with the target variable
python_output.append(f"{current_indent}_acc = {payload}\n")
elif token == "END_MATH":
# Use payload if provided, otherwise use math_target
target_var = payload if payload else math_target
if target_var:
python_output.append(f"{current_indent}{target_var} = _acc\n")
math_target = None
elif token == "ADD":
python_output.append(f"{current_indent}_acc += {payload}\n")
elif token == "SUBTRACT":
python_output.append(f"{current_indent}_acc -= {payload}\n")
elif token == "AND":
python_output.append(f"{current_indent}_acc = int(bool(_acc) and bool({payload}))\n")
elif token == "OR":
python_output.append(f"{current_indent}_acc = int(bool(_acc) or bool({payload}))\n")
elif token == "NOT":
# Count how many times Taylor told you to look
flip_count = raw.count("LOOK WHAT YOU MADE ME DO")
# We start with the value (either the payload variable or the current accumulator)
target = payload if payload else "_acc"
# Use modulo 2 instead of spamming nots
if flip_count % 2 == 1:
python_output.append(f"{current_indent}_acc = int(not bool({target}))\n")
else:
python_output.append(f"{current_indent}_acc = int(bool({target}))\n")
elif token == "==":
python_output.append(f"{current_indent}_acc = int(_acc == {payload})\n")
elif token == "WHILE":
python_output.append(f"{current_indent}while {payload}:\n")
indent_level += 1
elif token == "END_WHILE":
indent_level -= 1
elif token == "IF":
python_output.append(f"{current_indent}if {payload}:\n")
indent_level += 1
elif token == "ELSE":
indent_level -= 1
python_output.append(f"{' ' * indent_level}else:\n")
indent_level += 1
elif token == "END_IF":
indent_level -= 1
elif token == "PRINT":
python_output.append(f"{current_indent}print({payload})\n")
elif token == "BREAK":
python_output.append(f"{current_indent}break\n")
elif token == "INPUT":
python_output.append(f"{current_indent}{last_var} = int(input())\n")
elif token == "BEGIN_FUNC":
python_output.append(f"{current_indent}def {payload}(")
in_function_def = True
func_arg_count = 0
elif token == "FUNC_ARG":
func_arg_count += 1
# Check if this is the first argument (last line ends with "(")
if python_output and python_output[-1].endswith("("):
python_output[-1] += payload
else:
# Add comma and argument
python_output[-1] += f", {payload}"
elif token == "END_FUNC":
# Close the function definition if it's still open
if in_function_def and python_output and not python_output[-1].endswith(":\n"):
if python_output[-1].endswith("("):
# No arguments, close with ):
python_output[-1] += "):\n"
else:
# Has arguments, close with ):
python_output[-1] += "):\n"
in_function_def = False
func_arg_count = 0
indent_level -= 1
elif token == "RETURN":
python_output.append(f"{current_indent}return {payload}\n")
return "".join(python_output)
|