Cable/Implementations
Jump to navigation
Jump to search
import operator
import re
# ---------------- OPS ----------------
ops = {
"+=": operator.add,
"-=": operator.sub,
"*=": operator.mul,
"//=": operator.floordiv,
"%=": operator.mod,
}
# ---------------- HELPERS ----------------
def parse_string_literal(s):
"""Extract string literal from quotes and handle escape sequences."""
if s.startswith('"') and s.endswith('"'):
content = s[1:-1]
# Handle escape sequences
content = content.replace('\\n', '\n')
content = content.replace('\\t', '\t')
content = content.replace('\\\\', '\\')
return content
return None
def eval_expression(expr, variables):
"""Evaluate an expression that may contain operators and parentheses."""
expr = expr.strip()
# Check if it's just a string literal first - if so, return it directly
string_val = parse_string_literal(expr)
if string_val is not None:
return string_val
# Handle parentheses recursively
while '(' in expr:
# Find innermost parentheses
match = re.search(r'\(([^()]+)\)', expr)
if match:
inner = match.group(1)
result = eval_expression(inner, variables)
expr = expr[:match.start()] + str(result) + expr[match.end():]
else:
break
# Handle comparison operators (return 0 or 1)
for op in ['==', '!=', '<=', '>=', '<', '>']:
if op in expr:
parts = expr.split(op, 1)
if len(parts) == 2:
left = eval_expression(parts[0].strip(), variables)
right = eval_expression(parts[1].strip(), variables)
comparisons = {
"==": left == right,
"!=": left != right,
"<": left < right,
"<=": left <= right,
">": left > right,
">=": left >= right,
}
return 1 if comparisons[op] else 0
# Handle string/int concatenation with +
if '+' in expr:
# Need to carefully parse to handle string literals
parts = []
current = ""
in_string = False
for i, ch in enumerate(expr):
if ch == '"':
in_string = not in_string
current += ch
elif ch == '+' and not in_string:
if current.strip():
parts.append(current.strip())
current = ""
else:
current += ch
if current.strip():
parts.append(current.strip())
if len(parts) > 1:
# Evaluate each part and concatenate
result = eval_expression(parts[0], variables)
for part in parts[1:]:
right = eval_expression(part, variables)
# String concatenation or integer addition
if isinstance(result, str) or isinstance(right, str):
result = str(result) + str(right)
else:
result = result + right
return result
# Handle arithmetic operators (left to right for same precedence)
# Multiplication and division first
for op_str, op_func in [('*', operator.mul), ('//', operator.floordiv), ('%', operator.mod)]:
if op_str in expr:
parts = expr.split(op_str, 1)
if len(parts) == 2:
left = eval_expression(parts[0].strip(), variables)
right = eval_expression(parts[1].strip(), variables)
return op_func(left, right)
# Then subtraction (addition handled above for string concat)
if '-' in expr:
idx = expr.rfind('-')
if idx > 0: # Make sure it's not a negative sign at start
left = eval_expression(expr[:idx].strip(), variables)
right = eval_expression(expr[idx+1:].strip(), variables)
return operator.sub(left, right)
# Base case: resolve single value
return resolve(expr, variables)
def resolve(token, variables):
"""Resolve a token to its value (int or string)."""
token = token.strip()
# String literal
string_val = parse_string_literal(token)
if string_val is not None:
return string_val
# Integer
if token.lstrip("-").isdigit():
return int(token)
# Variable
if token in variables:
return variables[token]
raise ValueError(f"Unknown value: {token}")
def count_blocks(s):
depth = 0
count = 0
for c in s:
if c == "[":
if depth == 0:
count += 1
depth += 1
elif c == "]":
depth -= 1
return count
def extract_first_block(s):
if not s.startswith("["):
return None, s
depth = 0
for i, ch in enumerate(s):
if ch == "[":
depth += 1
elif ch == "]":
depth -= 1
if depth == 0:
return s[1:i], s[i + 1:]
return None, s
def parse_print_expression(expr, variables):
"""Parse PRINT expression that may contain string concatenation."""
return str(eval_expression(expr, variables))
# ---------------- INTERPRETER ----------------
prgm = """
[A = 1]
[Duplicate][Append [Print A][A += 1][Newline][If A == 10][Delete][Duplicate]]
"""
prgm = prgm.strip()
prgm = re.sub(r'\]\s*\[', '][', prgm)
variables = {}
while count_blocks(prgm) > 0:
block, prgm = extract_first_block(prgm)
if not block:
break
block = block.strip()
parts = block.split()
# ---------- ASSIGNMENTS ----------
if len(parts) >= 3 and any(op in parts[1] for op in ['=', '+=', '-=', '*=', '//=', '%=']):
var = parts[0]
op = parts[1]
expr = ' '.join(parts[2:])
if op == '=':
variables[var] = eval_expression(expr, variables)
elif op == '+=':
current = variables.get(var, 0)
value = eval_expression(expr, variables)
# Handle string concatenation
if isinstance(current, str) or isinstance(value, str):
variables[var] = str(current) + str(value)
else:
variables[var] = current + value
elif op == '-=':
variables[var] = variables.get(var, 0) - eval_expression(expr, variables)
elif op == '*=':
variables[var] = variables.get(var, 0) * eval_expression(expr, variables)
elif op == '//=':
variables[var] = variables.get(var, 0) // eval_expression(expr, variables)
elif op == '%=':
variables[var] = variables.get(var, 0) % eval_expression(expr, variables)
else:
lower_block = block.lower()
# ---------- INTEGER ----------
if lower_block.startswith("integer"):
var = parts[1]
if var in variables:
val = variables[var]
# Convert to int
if isinstance(val, str):
try:
variables[var] = int(val)
except ValueError:
variables[var] = 0 # Default to 0 if conversion fails
# If already int, keep it as is
# ---------- LOWER ----------
elif lower_block.startswith("lower"):
var = parts[1]
if var in variables:
val = variables[var]
if isinstance(val, str):
variables[var] = val.lower()
# If int, keep as int
# ---------- UPPER ----------
elif lower_block.startswith("upper"):
var = parts[1]
if var in variables:
val = variables[var]
if isinstance(val, str):
variables[var] = val.upper()
# If int, keep as int
# ---------- INPUT ----------
elif lower_block.startswith("input"):
var = parts[1]
variables[var] = input()
# ---------- DELETE ----------
elif lower_block.startswith("delete"):
_, prgm = extract_first_block(prgm)
# ---------- APPEND ----------
elif lower_block.startswith("append"):
_, rest = block.split(" ", 1)
prgm = rest + prgm
# ---------- IF ----------
elif lower_block.startswith("if"):
condition = block[2:].strip()
if not eval_expression(condition, variables):
_, prgm = extract_first_block(prgm)
# ---------- PRINT ----------
elif lower_block.startswith("print"):
expr = block[5:].strip()
result = parse_print_expression(expr, variables)
print(result, end = "")
# ---------- NEWLINE ----------
elif lower_block.startswith("newline"):
print()
# ---------- DUPLICATE ----------
elif lower_block.startswith("duplicate"):
parts = block.split()
count = 2 if len(parts) == 1 else resolve(parts[1], variables)
next_block, prgm = extract_first_block(prgm)
if next_block is not None and count > 0:
duplicated = "".join(f"[{next_block}]" for _ in range(count))
prgm = duplicated + prgm
#print(prgm)
#print(variables)