From c49a5ec0e2e434f8bab61a7ad342da8256726dd6 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Mon, 31 Jan 2022 16:24:25 +0100 Subject: [PATCH] Implement simple CLI - Implement running files - Implement interactive mode - Enable printing tokens & ast with flags --- src/interpreter.rs | 16 +++++++++++- src/main.rs | 63 ++++++++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index b9bda3f..707fd7b 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::parser::{Expression, BinOpType, UnOpType, Ast, Statement}; +use crate::{parser::{Expression, BinOpType, UnOpType, Ast, Statement, parse}, lexer::lex}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum Value { @@ -19,6 +19,20 @@ impl Interpreter { } } + pub fn run_str(&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); + } + + 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 3e5cb39..12b382e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,34 +1,55 @@ -use nek_lang::{lexer::lex, parser::parse, interpreter::Interpreter}; +use std::{env::args, fs, io::{stdout, Write, stdin}}; +use nek_lang::interpreter::Interpreter; + + +#[derive(Debug, Default)] +struct CliConfig { + print_tokens: bool, + print_ast: bool, + interactive: bool, + file: Option, +} fn main() { + let mut conf = CliConfig::default(); + + // Go through all commandline arguments except the first (filename) + for arg in args().skip(1) { + match arg.as_str() { + "--token" | "-t" => conf.print_tokens = true, + "--ast" | "-a" => conf.print_ast = true, + "--interactive" | "-i" => conf.interactive = true, + file if conf.file.is_none() => conf.file = Some(file.to_string()), + _ => panic!("Invalid argument: '{}'", arg), + } + } + let mut interpreter = Interpreter::new(); - // let mut code = String::new(); - let code = " - a <- 5; - // nek-lang best lang - a * 2; - "; + if let Some(file) = &conf.file { + let code = fs::read_to_string(file).expect(&format!("File not found: '{}'", file)); + interpreter.run_str(&code, conf.print_tokens, conf.print_ast); + } - // loop { - // print!(">> "); - // std::io::stdout().flush().unwrap(); + if conf.interactive || conf.file.is_none() { + let mut code = String::new(); - // code.clear(); - // std::io::stdin().read_line(&mut code).unwrap(); - // let code = code.trim(); + loop { + print!(">> "); + stdout().flush().unwrap(); - let tokens = lex(&code); + code.clear(); + stdin().read_line(&mut code).unwrap(); + + if code.trim() == "exit" { + break; + } - println!("Tokens: {:?}\n", tokens); + interpreter.run_str(&code, conf.print_tokens, conf.print_ast); + } - let ast = parse(tokens); - - println!("Ast: {:#?}\n", ast); - - interpreter.run(ast); - // } + } }