use std::io::{self, Write}; use crate::lexer::{Lexer, LexerInfo, lexical_analysis}; use crate::meta::print_version; use crate::interpreter::{InterpreterState, StackType}; use crate::string::{SlsStr}; use crate::errors::{LexerTokenResult, LexerResult}; static REPL_FILE_NAME: &str = ""; fn print_top_of_stack(state: &InterpreterState) { let Some(item) = state.stack_top() else { println!("#0: "); return; }; match &item.value { StackType::Identifier(id) => { println!("#0: ::{}", id.name); } StackType::I64(v) => println!("#0: {}", v), StackType::I32(v) => println!("#0: {}:i32", v), StackType::I16(v) => println!("#0: {}:i16", v), StackType::I8(v) => println!("#0: {}:i8", v), StackType::U64(v) => println!("#0: {}:u64", v), StackType::U32(v) => println!("#0: {}:u32", v), StackType::U16(v) => println!("#0: {}:u16", v), StackType::U8(v) => println!("#0: {}:u8", v), StackType::F32(v) => println!("#0: {}:f32", v), StackType::F64(v) => println!("#0: {}", v), StackType::Character(ch) => println!("#0: {}", ch), StackType::Boolean(b) => println!("#0: {}", if *b { "TRUE" } else { "FALSE" }), StackType::TokenString(_) => println!("#0: "), StackType::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 = match InterpreterState::new() { Some(i) => i, None => 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; } let code = SlsStr::from_string(buf.clone()); let mut lexer_info = LexerInfo::new(REPL_FILE_NAME.into(), code.clone()); let result = lexical_analysis(&mut lexer_info); match result { LexerResult::Error(err) => { println!("{}", err.message); } LexerResult::Ok(mut head) => { let mut node = Some(head.as_mut()); while let Some(tok_node) = node { match tok_node { LexerTokenResult::Error(err) => { println!("{}", err.message); break; } LexerTokenResult::Token(tok) => { if !interpreter.execute(tok) { println!("A runtime error occurred!"); break; } } LexerTokenResult::Next(_, next) => { node = next.as_deref_mut(); continue; } } node = None; } print_top_of_stack(&interpreter); } } } }