YREA-SLS/SLS_Python/sls_py/repl.py

84 lines
2.2 KiB
Python

from .meta import print_version
from .lexer import LexerInfo, lexical_analysis
from .interpreter import InterpreterState, StackType
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 == StackType.IDENTIFIER:
print(f"#0: ::{item.value}")
elif t == StackType.I64:
print(f"#0: {item.value}")
elif t in {StackType.I32, StackType.I16, StackType.I8}:
print(f"#0: {item.value}:{t}")
elif t in {StackType.U64, StackType.U32, StackType.U16, StackType.U8}:
print(f"#0: {item.value}:{t}")
elif t == StackType.FLOAT:
print(f"#0: {item.value}:f32")
elif t == StackType.DOUBLE:
print(f"#0: {item.value}")
elif t == StackType.CHARACTER:
print(f"#0: {item.value}")
elif t == StackType.BOOLEAN:
print("#0: TRUE" if item.value else "#0: FALSE")
elif t == StackType.TOKEN_STRING:
print("#0: <TOKEN STRING>")
elif t == StackType.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