diff --git a/src/main.rs b/src/main.rs index 3210ace..cf601d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ use std::{ env::args, fs, - io::{stdin, stdout, Write}, process::exit, + // io::{stdin, stdout, Write}, + process::exit, }; use nek_lang::interpreter::Interpreter; @@ -11,7 +12,7 @@ struct CliConfig { print_tokens: bool, print_ast: bool, no_optimizations: bool, - interactive: bool, + // interactive: bool, file: Option, } @@ -24,7 +25,7 @@ fn main() { "--token" | "-t" => conf.print_tokens = true, "--ast" | "-a" => conf.print_ast = true, "--no-opt" | "-n" => conf.no_optimizations = true, - "--interactive" | "-i" => conf.interactive = true, + // "--interactive" | "-i" => conf.interactive = true, "--help" | "-h" => print_help(), file if conf.file.is_none() => conf.file = Some(file.to_string()), _ => panic!("Invalid argument: '{}'", arg), @@ -42,23 +43,28 @@ fn main() { interpreter.run_str(&code); } - if conf.interactive || conf.file.is_none() { - let mut code = String::new(); + // TODO: The interactive prompt is currently broken due to the precalculated stack positions. + // For this to still work, there needs to be a way to keep the stack in the interpreter after + // runing once. Also somehow the stringstore and var stack from the last parsing stages would + // need to be reused for the parser to work correctly - loop { - print!(">> "); - stdout().flush().unwrap(); + // if conf.interactive || conf.file.is_none() { + // let mut code = String::new(); - code.clear(); - stdin().read_line(&mut code).unwrap(); + // loop { + // print!(">> "); + // stdout().flush().unwrap(); - if code.trim() == "exit" { - break; - } + // code.clear(); + // stdin().read_line(&mut code).unwrap(); - interpreter.run_str(&code); - } - } + // if code.trim() == "exit" { + // break; + // } + + // interpreter.run_str(&code); + // } + // } } fn print_help() { @@ -67,7 +73,7 @@ fn print_help() { println!("-t, --token Print the lexed tokens"); println!("-a, --ast Print the abstract syntax tree"); println!("-n, --no-opt Disable the AST optimizations"); - println!("-i, --interactive Interactive mode"); + // println!("-i, --interactive Interactive mode"); println!("-h, --help Show this help screen"); exit(0); } diff --git a/src/parser.rs b/src/parser.rs index 8f8d707..f2bd3ec 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2,7 +2,7 @@ use std::iter::Peekable; use thiserror::Error; use crate::{ - ast::{Ast, BinOpType, BlockScope, Expression, If, Loop, Statement, UnOpType}, + ast::{Ast, BinOpType, BlockScope, Expression, If, Loop, Statement}, stringstore::{Sid, StringStore}, token::Token, T, @@ -282,25 +282,11 @@ impl> Parser { inner_expr } - // Unary negation - T![-] => { - let operand = self.parse_primary()?; - Expression::UnOp(UnOpType::Negate, operand.into()) - } - - // Unary bitwise not (bitflip) - T![~] => { - let operand = self.parse_primary()?; - Expression::UnOp(UnOpType::BNot, operand.into()) - } - - // Unary logical not - T![!] => { - let operand = self.parse_primary()?; - Expression::UnOp(UnOpType::LNot, operand.into()) - } - - tok => return Err(ParseErr::UnexpectedToken(tok, "primary".to_string())), + // Unary operations or invalid token + tok => match tok.try_to_unop() { + Some(uot) => Expression::UnOp(uot, self.parse_primary()?.into()), + None => return Err(ParseErr::UnexpectedToken(tok, "primary".to_string())), + }, }; Ok(primary) diff --git a/src/token.rs b/src/token.rs index 5624512..fe15f60 100644 --- a/src/token.rs +++ b/src/token.rs @@ -1,4 +1,4 @@ -use crate::{ast::BinOpType, T}; +use crate::{ast::{BinOpType, UnOpType}, T}; /// Language keywords #[derive(Debug, PartialEq, Eq)] @@ -168,6 +168,16 @@ impl Token { _ => return None, }) } + + pub fn try_to_unop(&self) -> Option { + Some(match self { + T![-] => UnOpType::Negate, + T![!] => UnOpType::LNot, + T![~] => UnOpType::BNot, + + _ => return None, + }) + } } /// Macro to quickly create a token of the specified kind