//! Interpret the Lox language. Either compile (interpret for now though) some source code or run a //! REPL. use std::{ fs::{self}, io::{self, Write}, path::Path, }; use tracing::{error, info}; pub mod cli; pub mod expression; pub mod keywords; pub mod parser; pub mod scanner; pub mod token; pub mod tokenizer { pub mod comment; pub mod identifier; pub mod interface; pub mod lookahead; pub mod newline; pub mod number; pub mod single_char; pub mod string; pub mod whitespace; } /// Read the source code in a file and scan it to tokens. pub fn compile(source: &Path) -> Result<(), io::Error> { let input = fs::read_to_string(source)?; let tokens = scanner::tokenize(&input); match parser::generate_ast(tokens) { Ok(ast) => info!("{ast:?}"), Err(e) => error!("{e}"), } Ok(()) } /// Run a Lox REPL until SIGINT. pub fn repl() { loop { print!("> "); let _ = io::stdout().flush(); let mut input = String::new(); match io::stdin().read_line(&mut input) { Ok(_) => {} Err(e) => error!("{}", e), } let input = input.trim().to_string(); let tokens = scanner::tokenize(&input); match parser::generate_ast(tokens) { Ok(ast) => info!("{ast:?}"), Err(e) => error!("{e}"), } } }