From 2601dcd274eb78a7ed07f0e87b126386d166aee9 Mon Sep 17 00:00:00 2001 From: Charlie Root Date: Sat, 29 Mar 2025 00:57:25 +0100 Subject: [PATCH] werks --- src/main.rs | 138 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index 00af292..692b899 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,8 @@ -use std::io; +use std::{error::Error, io}; #[derive(Debug, PartialEq, Eq)] enum Symbol { - Number(i32), - + Number { value: u64 }, LeftBracket, RightBracket, Add, @@ -13,6 +12,26 @@ enum Symbol { Exp, } +#[derive(Clone, Debug)] +enum Node { + Add { left: Box, right: Box }, + Sub { left: Box, right: Box }, + Mul { left: Box, right: Box }, + Number { value: u64 }, +} + +fn eval(expr: &Node) -> i64 { + match expr { + Node::Add { left, right } => eval(left) + eval(right), + Node::Sub { left, right } => eval(left) - eval(right), + Node::Mul { left, right } => eval(left) * eval(right), + Node::Number { value } => { + // println!("Evaling number {value}"); + *value as i64 + } + } +} + #[derive(Debug)] enum ParseError { WrongTokenError { pos: usize }, @@ -23,8 +42,19 @@ fn main() { let user_input = get_user_input().expect("No input"); match tokenize(&user_input) { Ok(tokenized_input) => { - for el in &tokenized_input { - println!("{:?}", el); + // for el in &tokenized_input { + // println!("lol {:?}", el); + // } + let ast = ast(tokenized_input); + // println!("{:?}", ast); + match ast { + Ok(ast) => { + let evaled = eval(&ast); + println!("{}", evaled); + } + _ => { + continue; + } } } Err(ParseError::WrongTokenError { pos }) => { @@ -51,11 +81,31 @@ fn try_tokenizing() { let tokenized_input: Vec> = input.iter().map(|s| tokenize(s).unwrap()).collect(); let result: Vec> = vec![ - vec![Symbol::Number(1), Symbol::Add, Symbol::Number(2)], - vec![Symbol::Number(3), Symbol::Sub, Symbol::Number(4)], - vec![Symbol::Number(5), Symbol::Mul, Symbol::Number(6)], - vec![Symbol::Number(7), Symbol::Div, Symbol::Number(8)], - vec![Symbol::Number(8), Symbol::Exp, Symbol::Number(9)], + vec![ + Symbol::Number { value: 1 }, + Symbol::Add, + Symbol::Number { value: 2 }, + ], + vec![ + Symbol::Number { value: 3 }, + Symbol::Sub, + Symbol::Number { value: 4 }, + ], + vec![ + Symbol::Number { value: 5 }, + Symbol::Mul, + Symbol::Number { value: 6 }, + ], + vec![ + Symbol::Number { value: 7 }, + Symbol::Div, + Symbol::Number { value: 8 }, + ], + vec![ + Symbol::Number { value: 8 }, + Symbol::Exp, + Symbol::Number { value: 9 }, + ], ]; assert!(tokenized_input == result); } @@ -66,7 +116,11 @@ fn tokenize(input: &str) -> Result, ParseError> { for (i, c) in input.chars().enumerate() { if !c.is_ascii_digit() && !acc.is_empty() { - tokens.push(Symbol::Number(acc.parse().unwrap_or(0))); + tokens.push(Symbol::Number { + value: acc + .parse() + .map_err(|_| ParseError::WrongTokenError { pos: 1 })?, + }); acc.clear(); }; match c { @@ -87,8 +141,68 @@ fn tokenize(input: &str) -> Result, ParseError> { } } if !acc.is_empty() { - tokens.push(Symbol::Number(acc.parse().unwrap_or(0))); + tokens.push(Symbol::Number { + value: acc + .parse() + .map_err(|_| ParseError::WrongTokenError { pos: 1 })?, + }); } Ok(tokens) } + +fn ast(input: Vec) -> Result { + let mut stack = Vec::::new(); + // println!("{}", input.len()); + let length = input.len(); + let mut i = 0; + + while i < length { + // println!("Count: {}", i); + let s = &input[i]; + // println!("Symbol: {:?}", s); + match s { + Symbol::Number { value } => { + stack.push(Node::Number { value: *value }); + // println!("pushed {value}") + } + Symbol::Add => { + let left = stack.pop(); + // increment + let right = input.get(i + 1); + i += 1; + + match (left, right) { + (Some(left), Some(right)) => { + match right { + Symbol::Number { value } => { + stack.push(Node::Add { + left: (Box::new(left)), + right: (Box::new(Node::Number { value: *value })), + }); + } + _ => return Err(ParseError::WrongTokenError { pos: 1 }), + } + {} + } + _ => { + return Err(ParseError::WrongTokenError { pos: 1 }); + } + } + } + Symbol::Sub => {} + Symbol::Mul => {} + Symbol::Div => {} + _ => { + continue; + } + } + i += 1; + } + // println!("Stack length: {}", stack.len()); + // println!("Stack: {:?}", stack); + if stack.len() != 1 { + return Err(ParseError::WrongTokenError { pos: 1 }); + } + Ok(stack[0].clone()) +}