use std::io::{self, Write}; use std::fs; use serde_json; use crate::lexer::{LexerInfo, LexResult, lexical_analysis}; use crate::print_version; use crate::interpreter::{InterpreterState, StackValue}; static REPL_FILE_NAME: &str = ""; fn print_top_of_stack(state: &InterpreterState) { let Some(item) = state.stack_top() else { println!("#0: "); return; }; match &item { StackValue::Identifier(id) => { println!("#0: ::{}", id.name); } StackValue::I64(v) => println!("#0: {}", v), StackValue::I32(v) => println!("#0: {}:i32", v), StackValue::I16(v) => println!("#0: {}:i16", v), StackValue::I8(v) => println!("#0: {}:i8", v), StackValue::U64(v) => println!("#0: {}:u64", v), StackValue::U32(v) => println!("#0: {}:u32", v), StackValue::U16(v) => println!("#0: {}:u16", v), StackValue::U8(v) => println!("#0: {}:u8", v), StackValue::F32(v) => println!("#0: {}:f32", v), StackValue::F64(v) => println!("#0: {}", v), StackValue::Character(ch) => println!("#0: {}", ch), StackValue::Boolean(b) => println!("#0: {}", if *b { "TRUE" } else { "FALSE" }), StackValue::TokenString(_) => println!("#0: "), StackValue::Callable(_) => println!("#0: "), }; } pub fn repl() -> i32 { print_version(); println!("===== YREA SLS REPL ====="); println!("Type `#exit` to exit."); io::stdout().flush().unwrap(); let mut interpreter = InterpreterState::new(); if !interpreter.init() { return 1; } let stdin = io::stdin(); let mut buf = String::new(); loop { buf.clear(); if stdin.read_line(&mut buf).is_err() { return 1; } if buf.trim_end() == "#exit" { return 0; } if let Some(file) = buf.trim_end().strip_prefix("#save ") { match serde_json::to_string(&interpreter) { Ok(json) => { if let Err(err) = fs::write(file, json) { eprintln!("Failed to save state: {}", err); } else { println!("State saved to {}", file); } } Err(err) => eprintln!("Serialization error: {}", err), } continue; } if let Some(file) = buf.trim_end().strip_prefix("#load ") { match fs::read_to_string(file) { Ok(json) => match serde_json::from_str(&json) { Ok(state) => { interpreter = state; println!("State restored from {}", file); } Err(err) => eprintln!("Deserialization error: {}", err), }, Err(err) => eprintln!("Failed to read file: {}", err), } continue; } let code = buf.clone(); let mut lexer_info = LexerInfo::new(REPL_FILE_NAME, code.clone()); let result = lexical_analysis(&mut lexer_info); match result { LexResult::Ok(tokens) => { for token in tokens { if !interpreter.execute(&token) { eprintln!("A runtime error occured!"); break; } } print_top_of_stack(&interpreter); } LexResult::Err(err) => { dbg!(err); } } } }