Chapter 7

This commit is contained in:
Moritz Gmeiner 2023-01-20 16:10:03 +01:00
commit 42dbe531ad
15 changed files with 1112 additions and 0 deletions

94
src/interpreter.rs Normal file
View file

@ -0,0 +1,94 @@
use std::io::Write;
use crate::error::LoxError;
use crate::lexer::{scan_tokens, Token};
use crate::parser::parser::parse_tokens;
pub fn interpreter_main() {
let args: Vec<String> = std::env::args().collect();
match args.len() {
1 => run_repl(),
2 => run_file(&args[1]),
_ => {
eprintln!("Usage: rlox [script]");
std::process::exit(64);
}
}
}
fn run_file(script_path: &str) {
let source_code = std::fs::read_to_string(script_path).unwrap_or_else(|err| {
eprintln!("Reading script file {} failed: {}", script_path, err);
std::process::exit(66);
});
if let Err(err) = run(&source_code) {
eprintln!("{}", err);
std::process::exit(65);
}
}
fn run_repl() {
let stdin = std::io::stdin();
'outer: loop {
let mut input_buf = String::new();
print!("> ");
std::io::stdout().flush().unwrap();
'inner: loop {
stdin.read_line(&mut input_buf).unwrap_or_else(|err| {
eprintln!("Could not read from stdin: {}", err);
std::process::exit(66);
});
let num_open_braces = (input_buf.matches('{').count() as i64) - (input_buf.matches('}').count() as i64);
let num_open_parens = (input_buf.matches('(').count() as i64) - (input_buf.matches(')').count() as i64);
let num_open_brackets = (input_buf.matches('[').count() as i64) - (input_buf.matches(']').count() as i64);
// all braces/parens/brackets closed => break
if num_open_braces == 0 && num_open_parens == 0 && num_open_brackets == 0 {
break 'inner;
}
// any braces/parens/brackets more closing than opening => break (will be parse error)
if num_open_braces < 0 || num_open_parens < 0 || num_open_brackets < 0 {
break 'inner;
}
print!("< ");
std::io::stdout().flush().unwrap();
}
input_buf = input_buf.trim().to_owned();
if input_buf.is_empty() || input_buf == "exit" || input_buf == "quit" {
break 'outer;
}
match run(&input_buf) {
Ok(()) => {}
Err(err) => eprintln!("{}", err),
}
}
}
fn run(code_string: &str) -> Result<(), LoxError> {
let tokens: Vec<Token> = scan_tokens(code_string)?;
/* let token_str = tokens
.iter()
.map(|token| format!("{token}"))
.collect::<Vec<String>>()
.join(" ");
println!("{token_str}"); */
let expr = parse_tokens(tokens)?;
println!("{expr}");
Ok(())
}