84 lines
2.2 KiB
Python
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.F32:
|
|
print(f"#0: {item.value}:f32")
|
|
elif t == StackType.F64:
|
|
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
|