diff --git a/fall-2024/soft-skills/Ethics/.~lock.Ethics - Thanawin Pattanaphol.odt# b/fall-2024/soft-skills/Ethics/.~lock.Ethics - Thanawin Pattanaphol.odt#
deleted file mode 100644
index c54dd00..0000000
--- a/fall-2024/soft-skills/Ethics/.~lock.Ethics - Thanawin Pattanaphol.odt#
+++ /dev/null
@@ -1 +0,0 @@
-,winsdominoes,fedora,14.12.2024 11:59,file:///home/winsdominoes/.var/app/org.libreoffice.LibreOffice/config/libreoffice/4;
\ No newline at end of file
diff --git a/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.odt b/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.odt
index 44649eb..30c31b4 100644
Binary files a/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.odt and b/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.odt differ
diff --git a/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.pdf b/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.pdf
new file mode 100644
index 0000000..7d9efb7
Binary files /dev/null and b/fall-2024/soft-skills/Ethics/Ethics - Thanawin Pattanaphol.pdf differ
diff --git a/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.odt b/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.odt
new file mode 100644
index 0000000..949a569
Binary files /dev/null and b/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.odt differ
diff --git a/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.pdf b/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.pdf
new file mode 100644
index 0000000..ffbbc53
Binary files /dev/null and b/fall-2024/soft-skills/Proactiveness/Proactiveness - Thanawin Pattanaphol.pdf differ
diff --git a/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.odt b/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.odt
new file mode 100644
index 0000000..c71d4bd
Binary files /dev/null and b/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.odt differ
diff --git a/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.pdf b/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.pdf
new file mode 100644
index 0000000..d576698
Binary files /dev/null and b/fall-2024/soft-skills/Professionalism/Professionalism - Thanawin Pattanaphol.pdf differ
diff --git a/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.odt b/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.odt
new file mode 100644
index 0000000..ec3d316
Binary files /dev/null and b/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.odt differ
diff --git a/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.pdf b/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.pdf
new file mode 100644
index 0000000..184e87c
Binary files /dev/null and b/fall-2024/soft-skills/Self-Learning/Self-Learning - Thanawin Pattanaphol.pdf differ
diff --git a/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.odt b/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.odt
new file mode 100644
index 0000000..8eaa284
Binary files /dev/null and b/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.odt differ
diff --git a/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.pdf b/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.pdf
new file mode 100644
index 0000000..ab4fb83
Binary files /dev/null and b/fall-2024/soft-skills/Teamwork/Teamwork - Thanawin Pattanaphol.pdf differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/._eval b/spring-2025/sen-109/00020/eval/__MACOSX/._eval
new file mode 100755
index 0000000..eb62a54
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/._eval differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.DS_Store b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.DS_Store
new file mode 100644
index 0000000..a5b28df
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.DS_Store differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.idea b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.idea
new file mode 100755
index 0000000..5829a1f
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._.idea differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/._Cargo.toml b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._Cargo.toml
new file mode 100644
index 0000000..b274884
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._Cargo.toml differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/._src b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._src
new file mode 100755
index 0000000..134bf95
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/._src differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._.gitignore b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._.gitignore
new file mode 100644
index 0000000..7a38672
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._.gitignore differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._eval.iml b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._eval.iml
new file mode 100644
index 0000000..46cd8b7
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._eval.iml differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._modules.xml b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._modules.xml
new file mode 100644
index 0000000..0449522
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._modules.xml differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._vcs.xml b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._vcs.xml
new file mode 100644
index 0000000..9ba1bfe
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._vcs.xml differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._workspace.xml b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._workspace.xml
new file mode 100644
index 0000000..c105a93
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/.idea/._workspace.xml differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._.DS_Store b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._.DS_Store
new file mode 100644
index 0000000..a5b28df
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._.DS_Store differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._main.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._main.rs
new file mode 100644
index 0000000..a13a95a
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._main.rs differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._parsemath b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._parsemath
new file mode 100755
index 0000000..94c3363
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/._parsemath differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._ast.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._ast.rs
new file mode 100644
index 0000000..37c9bcf
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._ast.rs differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._mod.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._mod.rs
new file mode 100644
index 0000000..cc72d1b
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._mod.rs differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._parser.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._parser.rs
new file mode 100644
index 0000000..cb7184e
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._parser.rs differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._token.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._token.rs
new file mode 100644
index 0000000..42eaf41
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._token.rs differ
diff --git a/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._tokenizer.rs b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._tokenizer.rs
new file mode 100644
index 0000000..d149bbd
Binary files /dev/null and b/spring-2025/sen-109/00020/eval/__MACOSX/eval/src/parsemath/._tokenizer.rs differ
diff --git a/spring-2025/sen-109/00020/eval/eval/.idea/.gitignore b/spring-2025/sen-109/00020/eval/eval/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/spring-2025/sen-109/00020/eval/eval/.idea/eval.iml b/spring-2025/sen-109/00020/eval/eval/.idea/eval.iml
new file mode 100644
index 0000000..cf84ae4
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/.idea/eval.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-2025/sen-109/00020/eval/eval/.idea/modules.xml b/spring-2025/sen-109/00020/eval/eval/.idea/modules.xml
new file mode 100644
index 0000000..f0c1a8c
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-2025/sen-109/00020/eval/eval/.idea/vcs.xml b/spring-2025/sen-109/00020/eval/eval/.idea/vcs.xml
new file mode 100644
index 0000000..d843f34
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/.idea/vcs.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/spring-2025/sen-109/00020/eval/eval/Cargo.toml b/spring-2025/sen-109/00020/eval/eval/Cargo.toml
new file mode 100644
index 0000000..f813e8c
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "expression-eval"
+version = "0.1.0"
+authors = ["cmkl"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/spring-2025/sen-109/00020/eval/eval/src/main.rs b/spring-2025/sen-109/00020/eval/eval/src/main.rs
new file mode 100644
index 0000000..6907f7c
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/main.rs
@@ -0,0 +1,44 @@
+/// This is the main command-line application for arithmetic expression evaluator
+// Standard library
+use std::io;
+
+// code for arithmetic expression evaluation is in parsemath module
+mod parsemath;
+use parsemath::ast;
+use parsemath::parser::{ParseError, Parser};
+
+// Function to invoke Parser and evaluate expression
+fn evaluate(expr: String) -> Result {
+ let expr = expr.split_whitespace().collect::(); // remove whitespace chars
+ let mut math_parser = Parser::new(&expr)?;
+ let ast = math_parser.parse()?;
+ println!("The generated AST is {:?}", ast);
+
+ Ok(ast::eval(ast)?)
+}
+
+// Main function reads arithmetic expression from command-line and displays result and error.
+// It calls the evaluate function to perform computation.
+
+fn main() {
+ println!("Hello! Welcome to Arithmetic expression evaluator.");
+ println!("You can calculate value for expression such as 2*3+(4-5)+2^3/4. ");
+ println!("Allowed numbers: positive, negative and decimals.");
+ println!("Supported operations: Add, Subtract, Multiply, Divide, PowerOf(^). ");
+ println!("Enter your arithmetic expression below:");
+ loop {
+ let mut input = String::new();
+ match io::stdin().read_line(&mut input) {
+ Ok(_) => {
+ match evaluate(input) {
+ Ok(val) => println!("The computed number is {}\n", val),
+ Err(_) => {
+ println!("Error in evaluating expression. Please enter valid expression\n");
+ }
+ };
+ }
+
+ Err(error) => println!("error: {}", error),
+ }
+ }
+}
diff --git a/spring-2025/sen-109/00020/eval/eval/src/parsemath/ast.rs b/spring-2025/sen-109/00020/eval/eval/src/parsemath/ast.rs
new file mode 100644
index 0000000..9a3e154
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/parsemath/ast.rs
@@ -0,0 +1,64 @@
+/// This program contains list of valid AST nodes that can be constructed and also evaluates an AST to compute a value
+// Standard lib
+use std::error;
+
+//structs
+
+// List of allowed AST nodes that can be constructed by Parser
+// Tokens can be arithmetic operators or a Number
+#[derive(Debug, Clone, PartialEq)]
+pub enum Node {
+ // WARNING: Bitwise And and Or operation only works on integer value
+ And(Box, Box),
+ Or(Box, Box),
+
+ Add(Box, Box),
+ Subtract(Box, Box),
+ Multiply(Box, Box),
+ Divide(Box, Box),
+ Caret(Box, Box),
+ Negative(Box),
+ Number(f64),
+}
+
+// Given an AST, calculate the numeric value.
+pub fn eval(expr: Node) -> Result> {
+ use self::Node::*;
+ match expr {
+ Number(i) => Ok(i),
+ Add(expr1, expr2) => Ok(eval(*expr1)? + eval(*expr2)?),
+
+ // TODO: complete the match expression to evaluate the numeric value
+ _ => panic!()
+ }
+}
+
+//Unit tests
+#[cfg(test)]
+mod tests {
+ use super::*;
+ #[test]
+ fn test_expr1() {
+ use crate::parsemath::parser::Parser;
+
+ let ast = Parser::new("1+2-3").unwrap().parse().unwrap();
+ let value = eval(ast).unwrap();
+ assert_eq!(value, 0.0);
+ }
+ #[test]
+ fn test_expr2() {
+ use crate::parsemath::parser::Parser;
+
+ let ast = Parser::new("3+2-1*5/4").unwrap().parse().unwrap();
+ let value = eval(ast).unwrap();
+ assert_eq!(value, 3.75);
+ }
+ #[test]
+ fn test_expr3() {
+ use crate::parsemath::parser::Parser;
+
+ let ast = Parser::new("3+3 | 4").unwrap().parse().unwrap();
+ let value = eval(ast).unwrap();
+ assert_eq!(value, 6.0);
+ }
+}
diff --git a/spring-2025/sen-109/00020/eval/eval/src/parsemath/mod.rs b/spring-2025/sen-109/00020/eval/eval/src/parsemath/mod.rs
new file mode 100644
index 0000000..dba3699
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/parsemath/mod.rs
@@ -0,0 +1,5 @@
+/// Module Parsemath
+pub mod ast;
+pub mod parser;
+pub mod token;
+pub mod tokenizer;
diff --git a/spring-2025/sen-109/00020/eval/eval/src/parsemath/parser.rs b/spring-2025/sen-109/00020/eval/eval/src/parsemath/parser.rs
new file mode 100644
index 0000000..518912a
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/parsemath/parser.rs
@@ -0,0 +1,174 @@
+/// This program reads tokens returned by Tokenizer and converts them into AST.
+// Standard lib
+use std::fmt;
+
+// Internal modules
+use super::ast::Node;
+use super::token::{OperPrec, Token};
+use super::tokenizer::Tokenizer;
+
+//Structs and constants
+
+// Parser struct
+pub struct Parser<'a> {
+ tokenizer: Tokenizer<'a>,
+ current_token: Token,
+}
+
+// Public methods of Parser
+
+impl<'a> Parser<'a> {
+ // Create a new instance of Parser
+ pub fn new(expr: &'a str) -> Result {
+ let mut lexer = Tokenizer::new(expr);
+ let cur_token = match lexer.next() {
+ Some(token) => token,
+ None => return Err(ParseError::InvalidOperator("Invalid character".into())),
+ };
+ Ok(Parser {
+ tokenizer: lexer,
+ current_token: cur_token,
+ })
+ }
+
+ // Take an arithmetic expression as input and return an AST
+
+ pub fn parse(&mut self) -> Result {
+ let ast = self.generate_ast(OperPrec::DefaultZero);
+ match ast {
+ // TODO: Replace this with proper handling of return value from generate_ast result
+ _ => panic!()
+ }
+ }
+}
+
+// Private methods of Parser
+
+impl<'a> Parser<'a> {
+ // Retrieve the next token from arithmetic expression and set it to current_token field in Parser struct
+ fn get_next_token(&mut self) -> Result<(), ParseError> {
+ let next_token = match self.tokenizer.next() {
+ Some(token) => token,
+ None => return Err(ParseError::InvalidOperator("Invalid character".into())),
+ };
+ self.current_token = next_token;
+ Ok(())
+ }
+
+ // Main workhorse method that is called recursively
+
+ fn generate_ast(&mut self, oper_prec: OperPrec) -> Result {
+ let mut left_expr = self.parse_number()?;
+
+ while oper_prec < self.current_token.get_oper_prec() {
+ if self.current_token == Token::EOF {
+ break;
+ }
+ let right_expr = self.convert_token_to_node(left_expr.clone())?;
+ left_expr = right_expr;
+ }
+ Ok(left_expr)
+ }
+
+ // Construct AST node for numbers, taking into account negative prefixes while handling parenthesis
+
+ fn parse_number(&mut self) -> Result {
+ let token = self.current_token.clone();
+ match token {
+ Token::Subtract => {
+ self.get_next_token()?;
+ let expr = self.generate_ast(OperPrec::Negative)?;
+ Ok(Node::Negative(Box::new(expr)))
+ }
+ Token::Num(i) => {
+ self.get_next_token()?;
+ Ok(Node::Number(i))
+ }
+ Token::LeftParen => {
+ self.get_next_token()?;
+
+ // TODO: Replace the following code to check for matching parenthesis;
+ // also convert (x)(y) to x times y
+ let expr = self.generate_ast(OperPrec::DefaultZero)?;
+ Ok(expr)
+ }
+ _ => Err(ParseError::UnableToParse("Unable to parse".to_string())),
+ }
+ }
+
+ // Check for balancing parenthesis
+ fn check_paren(&mut self, expected: Token) -> Result<(), ParseError> {
+ if expected == self.current_token {
+ self.get_next_token()?;
+ Ok(())
+ } else {
+ Err(ParseError::InvalidOperator(format!(
+ "Expected {:?}, got {:?}",
+ expected, self.current_token
+ )))
+ }
+ }
+
+ // Construct Operator AST nodes
+ fn convert_token_to_node(&mut self, left_expr: Node) -> Result {
+ match self.current_token {
+ Token::Add => {
+ self.get_next_token()?;
+ //Get right-side expression
+ let right_expr = self.generate_ast(OperPrec::AddSub)?;
+ Ok(Node::Add(Box::new(left_expr), Box::new(right_expr)))
+ }
+ // TODO: Complete the node construction for other tokens
+
+ _ => Err(ParseError::InvalidOperator(format!(
+ "Please enter valid operator {:?}",
+ self.current_token
+ ))),
+ }
+ }
+}
+
+// Custom error handler for Parser
+#[derive(Debug)]
+pub enum ParseError {
+ UnableToParse(String),
+ InvalidOperator(String),
+}
+
+impl fmt::Display for ParseError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match &self {
+ ParseError::UnableToParse(e) => write!(f, "Error in evaluating {}", e),
+ ParseError::InvalidOperator(e) => write!(f, "Error in evaluating {}", e),
+ }
+ }
+}
+
+// Handle error thrown from AST module
+
+impl From> for ParseError {
+ fn from(_evalerr: Box) -> Self {
+ ParseError::UnableToParse("Unable to parse".into())
+ }
+}
+
+// Unit tests
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::parsemath::ast::Node::{Add, Or, Number};
+ #[test]
+ fn test_addition() {
+ let mut parser = Parser::new("1+2").unwrap();
+ let expected = Add(Box::new(Number(1.0)), Box::new(Number(2.0)));
+ assert_eq!(parser.parse().unwrap(), expected);
+ }
+
+ #[test]
+ fn test_bitwise_or() {
+ let mut parser = Parser::new("6|2").unwrap();
+ let expected = Or(Box::new(Number(6.0)), Box::new(Number(2.0)));
+ assert_eq!(parser.parse().unwrap(), expected);
+ }
+}
diff --git a/spring-2025/sen-109/00020/eval/eval/src/parsemath/token.rs b/spring-2025/sen-109/00020/eval/eval/src/parsemath/token.rs
new file mode 100644
index 0000000..bd70900
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/parsemath/token.rs
@@ -0,0 +1,48 @@
+/// This contains enum for list of Tokens, and handles Operator precedence rules.
+
+// List of valid tokens that can be constructed from arithmetic expression by Tokenizer
+
+#[derive(Debug, PartialEq, Clone)]
+pub enum Token {
+ And, // &
+ Or, // |
+ Add, // +
+ Subtract, // -
+ Multiply, // *
+ Divide, // /
+ Caret, // ^
+ LeftParen, // (
+ RightParen, // )
+ Num(f64), // 12.34
+ EOF,
+}
+
+// Order of operators as per operator precedence rules (low to high)
+
+#[derive(Debug, PartialEq, PartialOrd)]
+/// Defines all the OperPrec levels, from lowest to highest.
+pub enum OperPrec {
+ DefaultZero,
+ AndOr,
+ AddSub,
+ MulDiv,
+ Power,
+ Negative,
+}
+
+// This contains methods to retrieve operator precedence for a given arithmetic operator
+
+impl Token {
+ pub fn get_oper_prec(&self) -> OperPrec {
+ use self::OperPrec::*;
+ use self::Token::*;
+ match *self {
+ And | Or => AndOr,
+ Add | Subtract => AddSub,
+ Multiply | Divide => MulDiv,
+ Caret => Power,
+
+ _ => DefaultZero,
+ }
+ }
+}
diff --git a/spring-2025/sen-109/00020/eval/eval/src/parsemath/tokenizer.rs b/spring-2025/sen-109/00020/eval/eval/src/parsemath/tokenizer.rs
new file mode 100644
index 0000000..7e76a82
--- /dev/null
+++ b/spring-2025/sen-109/00020/eval/eval/src/parsemath/tokenizer.rs
@@ -0,0 +1,70 @@
+/// This module reads characters in arithmetic expression and converts them to tokens.
+/// The allowed tokens are defined in ast module.
+// Standard lib
+use std::iter::Peekable;
+use std::str::Chars;
+
+//Other internal modules
+use super::token::Token;
+
+// Other structs
+
+// Tokenizer struct contains a Peekable iterator on the arithmetic expression
+pub struct Tokenizer<'a> {
+ expr: Peekable>,
+}
+
+// Constructs a new instance of Tokenizer
+impl<'a> Tokenizer<'a> {
+ pub fn new(new_expr: &'a str) -> Self {
+ Tokenizer {
+ expr: new_expr.chars().peekable(),
+ }
+ }
+}
+
+// Implement Iterator trait for Tokenizer struct.
+// With this, we can use next() method on tokenizer to retrieve the next token from arithmetic expression
+
+impl<'a> Iterator for Tokenizer<'a> {
+ type Item = Token;
+
+ fn next(&mut self) -> Option {
+ let next_char = self.expr.next();
+
+ match next_char {
+ Some('0'..='9') => {
+ // TODO: Iterate & peeking through the next characters to create Num token
+ // Make sure to return None if the value is not parsable
+ None
+ },
+
+ // TODO: return the appropriate tokens for available symbols
+
+ None => Some(Token::EOF),
+ Some(_) => None,
+ }
+ }
+}
+
+// Unit tests
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_positive_integer() {
+ let mut tokenizer = Tokenizer::new("34");
+ assert_eq!(tokenizer.next().unwrap(), Token::Num(34.0))
+ }
+ #[test]
+ fn test_decimal_number() {
+ let mut tokenizer = Tokenizer::new("34.5");
+ assert_eq!(tokenizer.next().unwrap(), Token::Num(34.5))
+ }
+ #[test]
+ fn test_invalid_char() {
+ let mut tokenizer = Tokenizer::new("#$%");
+ assert_eq!(tokenizer.next(), None);
+ }
+}