YREA-SLS/SLS_Python/sls/repl.py

82 lines
2.0 KiB
Python

from .meta import print_version
from .lexer import LexerInfo, lexical_analysis
from .interpreter import InterpreterState
REPL_FILE_NAME = "<STDIN>"
def print_top_of_stack(interpreter: InterpreterState) -> None:
"""Pretty-print top of the stack."""
item = interpreter.top()
if item is None:
print("#0: <STACK IS EMPTY>")
return
t = item.type
if t == "Identifier":
print(f"#0: ::{item.value}")
elif t in {"i64", "i32", "i16", "i8"}:
print(f"#0: {item.value}:{t}")
elif t in {"u64", "u32", "u16", "u8"}:
print(f"#0: {item.value}:{t}")
elif t == "f32":
print(f"#0: {item.value}:f32")
elif t == "f64":
print(f"#0: {item.value}")
elif t == "char":
print(f"#0: {item.value}")
elif t == "bool":
print("#0: TRUE" if item.value else "#0: FALSE")
elif t == "TokenString":
print("#0: <TOKEN STRING>")
elif t == "Callable":
print("#0: <CALLABLE>")
else:
print(f"#0: <UNKNOWN {t}>")
def repl() -> int:
"""Interactive interpreter loop."""
print_version()
print("===== YREA SLS REPL =====")
print("Type `#exit` to exit.")
interpreter = InterpreterState()
while True:
try:
line = input("> ")
except EOFError:
break
if line.strip() == "#exit":
return 0
# Create a fresh lexer each iteration
lexer_info = LexerInfo(filename=REPL_FILE_NAME, source_code=line)
try:
tokens = lexical_analysis(lexer_info)
except Exception as err:
print(err)
continue
# Execute tokens in order
for token in tokens:
try:
ok = interpreter.execute(token)
if not ok:
print("A runtime error occurred!")
break
except Exception as err:
print(err)
break
print_top_of_stack(interpreter)
return 1