rust-crafting-interpreters-.../src/main.rs

81 lines
1.8 KiB
Rust
Raw Normal View History

2022-12-30 23:50:02 +01:00
mod ast;
mod errors;
2022-12-30 23:50:33 +01:00
mod parser;
mod scanner;
2022-12-30 16:47:30 +01:00
mod tokens;
use std::{
env, fs,
io::{self, Write},
process::ExitCode,
};
2022-12-30 16:33:34 +01:00
2022-12-31 00:50:31 +01:00
use ast::AstDumper;
use errors::ErrorHandler;
2022-12-30 23:50:33 +01:00
use parser::Parser;
use scanner::Scanner;
2022-12-30 16:17:46 +01:00
/// Execute a script.
fn run(source: String) -> ErrorHandler {
let mut error_handler = ErrorHandler::default();
2022-12-30 23:50:33 +01:00
2022-12-30 16:33:34 +01:00
let scanner = Scanner::new(source);
let tokens = scanner.scan_tokens(&mut error_handler);
2022-12-30 23:50:33 +01:00
for token in tokens.iter() {
println!("{:#?}", token);
2022-12-30 16:33:34 +01:00
}
2022-12-30 23:50:33 +01:00
2022-12-31 00:50:31 +01:00
let parser = Parser::new(tokens);
match parser.parse(&mut error_handler) {
None => (),
Some(ast) => {
println!("AST generated ! {}", ast.dump())
}
}
2022-12-30 23:50:33 +01:00
2022-12-30 16:33:34 +01:00
error_handler
2022-12-30 16:17:46 +01:00
}
/// Run the REPL.
fn run_prompt() {
let mut buffer = String::new();
let stdin = io::stdin();
let mut stdout = io::stdout();
loop {
print!("slox> ");
stdout.flush().unwrap();
buffer.clear();
2022-12-30 16:47:30 +01:00
let n_read = stdin
.read_line(&mut buffer)
.expect("Failed to read from stdin");
2022-12-30 16:33:34 +01:00
let _ = match n_read {
2022-12-30 16:17:46 +01:00
0 => return,
_ => run(buffer.clone()),
2022-12-30 16:33:34 +01:00
};
2022-12-30 16:17:46 +01:00
}
}
/// Load a file and run the script it contains.
2022-12-30 16:33:34 +01:00
fn run_file(file: &str) -> ErrorHandler {
let contents = fs::read_to_string(file)
.unwrap_or_else(|_| panic!("Could not load {}", file));
2022-12-30 16:17:46 +01:00
run(contents)
}
/// Main program. Either load a script from a file, or start the REPL.
2022-12-30 16:33:34 +01:00
fn main() -> Result<(), ExitCode> {
2022-12-30 16:17:46 +01:00
let args: Vec<String> = env::args().skip(1).collect();
let n_args = args.len();
if n_args == 0 {
run_prompt()
} else if n_args == 1 {
2022-12-30 16:33:34 +01:00
if run_file(&args[0]).had_error() {
return Err(ExitCode::from(65));
}
2022-12-30 16:17:46 +01:00
} else {
println!("Usage: slox [script]");
}
2022-12-30 16:33:34 +01:00
Ok(())
2022-12-30 15:53:19 +01:00
}