Implement simple cli

This commit is contained in:
Daniel M 2022-01-28 20:22:21 +01:00
parent 3dacee0be4
commit 5bf989a640
2 changed files with 56 additions and 15 deletions

View File

@ -1,6 +1,6 @@
use std::collections::HashMap; 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)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum Value { pub enum Value {
@ -18,6 +18,18 @@ impl Interpreter {
Self { vartable } 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) { pub fn run(&mut self, prog: Ast) {
for stmt in prog.prog { for stmt in prog.prog {
match stmt { match stmt {

View File

@ -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<String>,
}
fn main() { fn main() {
let mut cfg = CliConfig::default();
let mut code = String::new(); for arg in args().skip(1) {
match arg.as_str() {
std::io::stdin().read_line(&mut code).unwrap(); "--tokens" | "-t" => cfg.print_tokens = true,
let code = code.trim(); "--ast" | "-a" => cfg.print_ast = true,
"--interactive" | "-i" => cfg.interactive = true,
let tokens = lex(&code); file if cfg.file.is_none() => cfg.file = Some(file.to_string()),
_ => panic!("Invalid argument: '{}'", arg),
println!("Tokens: {:?}\n", tokens); }
}
let ast = parse(tokens);
println!("Ast: {:#?}\n", ast);
let mut interpreter = Interpreter::new(); 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);
}
}
} }