diff --git a/src/interpreter.rs b/src/interpreter.rs index 0447643..5c01a8f 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::parser::{Expr, BinOpType, UnOpType, Ast, Stmt}; +use crate::{parser::{Expr, BinOpType, UnOpType, Ast, Stmt, parse}, lexer::lex}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum Value { @@ -18,6 +18,18 @@ impl Interpreter { Self { vartable } } + pub fn run_text(&mut self, code: &str, print_tokens: bool, print_ast: bool) { + let tokens = lex(code); + if print_tokens { + println!("Tokens: {:?}", tokens); + } + let ast = parse(tokens); + if print_ast { + println!("Ast:\n{:#?}", ast); + } + self.run(ast); + } + pub fn run(&mut self, prog: Ast) { for stmt in prog.prog { match stmt { diff --git a/src/main.rs b/src/main.rs index d7500eb..8cc4edb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,52 @@ -use nek_lang::{lexer::lex, parser::parse, interpreter::Interpreter}; +use std::{env::args, io::Write}; +use nek_lang::interpreter::Interpreter; + +#[derive(Debug, Default)] +struct CliConfig { + print_tokens: bool, + print_ast: bool, + interactive: bool, + file: Option, +} fn main() { + let mut cfg = CliConfig::default(); - let mut code = String::new(); - - std::io::stdin().read_line(&mut code).unwrap(); - let code = code.trim(); - - let tokens = lex(&code); - - println!("Tokens: {:?}\n", tokens); - - let ast = parse(tokens); - - println!("Ast: {:#?}\n", ast); + for arg in args().skip(1) { + match arg.as_str() { + "--tokens" | "-t" => cfg.print_tokens = true, + "--ast" | "-a" => cfg.print_ast = true, + "--interactive" | "-i" => cfg.interactive = true, + file if cfg.file.is_none() => cfg.file = Some(file.to_string()), + _ => panic!("Invalid argument: '{}'", arg), + } + } let mut interpreter = Interpreter::new(); - interpreter.run(ast); + if let Some(file) = &cfg.file { + let code = std::fs::read_to_string(file).expect(&format!("File not found: '{}'", file)); + interpreter.run_text(&code, cfg.print_tokens, cfg.print_ast); + } + if cfg.interactive || cfg.file.is_none() { + + let mut code = String::new(); + + loop { + print!(">> "); + std::io::stdout().flush().unwrap(); + + code.clear(); + std::io::stdin().read_line(&mut code).unwrap(); + let code = code.trim(); + + if code == "exit" { + break; + } + + interpreter.run_text(&code, cfg.print_tokens, cfg.print_ast); + } + } }