From b3e31727b0bad416973241d97d6ae75a878c7760 Mon Sep 17 00:00:00 2001 From: FantasyPvP <80643031+FantasyPvP@users.noreply.github.com> Date: Thu, 28 Sep 2023 00:30:51 +0100 Subject: [PATCH] calc functions and zxq5 logo in fetch - changed the crystalfetch text - added functions to the calculator --- Cargo.lock | 7 +++ Cargo.toml | 1 + src/user/bin/{ => calc}/calc.rs | 74 +++++++++++++++++++++++++++++-- src/user/bin/calc/functions.rs | 27 +++++++++++ src/user/bin/calc/mod.rs | 4 ++ src/user/bin/crystalfetch.rs | 56 ++++++++++------------- src/user/bin/gigachad_detector.rs | 22 ++++----- 7 files changed, 145 insertions(+), 46 deletions(-) rename src/user/bin/{ => calc}/calc.rs (85%) create mode 100644 src/user/bin/calc/functions.rs create mode 100644 src/user/bin/calc/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7fdc641..8bf9cb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,7 @@ dependencies = [ "futures-util", "hashbrown", "lazy_static", + "libm", "linked_list_allocator", "pc-keyboard", "pic8259", @@ -192,6 +193,12 @@ dependencies = [ "spin", ] +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "linked_list_allocator" version = "0.10.5" diff --git a/Cargo.toml b/Cargo.toml index ac19b30..f618f47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ rgb = "0.8" rand = { version = "0.8.5", default-features = false, features = ["small_rng"]} hashbrown = "0.13.2" cmos-rtc = "0.1.2" +libm = "0.2.7" [dependencies.lazy_static] version = "1.0" diff --git a/src/user/bin/calc.rs b/src/user/bin/calc/calc.rs similarity index 85% rename from src/user/bin/calc.rs rename to src/user/bin/calc/calc.rs index 2bfef6e..2899a79 100755 --- a/src/user/bin/calc.rs +++ b/src/user/bin/calc/calc.rs @@ -4,13 +4,16 @@ use alloc::string::ToString; use alloc::borrow::ToOwned; use crate::{println, print, mknode, std}; - use async_trait::async_trait; +use lazy_static::lazy_static; use crate::std::application::{ Application, Error as ShellError }; + + + struct Parser { tokens: Vec, idx: i32, @@ -34,9 +37,25 @@ impl Interpreter { Node::UnaryOperation(_) => return self.visit_unary_operation(node), Node::Number(_) => return self.visit_number(node), Node::Operator(_) => return self.visit_operator(node), + Node::Function(_) => return self.visit_function(node), } } + fn visit_function(&mut self, node: Node) -> Result { // function calls such as sqrt(5) within the expression are evaluated here + let func = if let Node::Function(x) = node.clone() { + x + } else { + return Err(Error::Other(String::from("value is not a function"))) + }; + let function_name = func.name; + + let inner = self.visit(self.get_node(node.clone(), "argument")?.expect("returned none").to_owned())?; + if let Value::Number(x) = inner { + return Ok(Value::Number(super::functions::run_func(function_name, x).unwrap())); + } else { + return Err(Error::Other(String::from("function argument is not a number"))) + } + } fn visit_number(&mut self, node: Node) -> Result { @@ -168,6 +187,13 @@ impl Interpreter { None } }, + "argument" => { + if let Node::Function(x) = node { + Some(x.arg) + } else { + None + } + } _ => return Err(Error::Other(String::from("invalid param for get_Node"))) }; Ok(result) @@ -258,6 +284,24 @@ impl Parser { let token = self.current.clone(); match token { + Token::Func(x) => { + self.advance()?; + if let Token::Bracket('(') = self.current { + self.advance()?; + } else { + return Err(Error::InvalidSyntax(self.idx as usize)) + }; + let arg = self.expr()?; + if let Token::Bracket(')') = self.current { + self.advance()?; + } else { + return Err(Error::InvalidSyntax(self.idx as usize)) + }; + + return Ok(Node::Function(Box::new(FunctionCall { name: x, arg }))) + }, + + Token::Operator(Operator::Add) | Token::Operator(Operator::Sub) => { self.advance()?; let operator = mknode!(token).expect("mknode returned none"); @@ -343,13 +387,21 @@ impl Application for Calculator { } match calculate_inner(inp) { Ok(_) => (), - Err(_) => { println!("your input must be a valid mathematical expression contaning only numbers (including floats) and the operators: [ +, -, *, **, /, //, % ]"); return Err(ShellError::CommandFailed(String::from("failed"))) }, + Err(e) => { + println!("your input must be a valid mathematical expression contaning only numbers (including floats) and the operators: [ +, -, *, **, /, //, % ]"); + println!("{:?}", e); + return Err(ShellError::CommandFailed(String::from("failed"))) + }, }; } } else { match calculate_inner(args.into_iter().collect()) { Ok(x) => x, - Err(_) => { println!("your input must be a valid mathematical expression contaning only numbers (including floats) and the operators: [ +, -, *, **, /, //, % ]"); return Err(ShellError::CommandFailed(String::from("failed"))) }, + Err(e) => { + println!("your input must be a valid mathematical expression contaning only numbers (including floats) and the operators: [ +, -, *, **, /, //, % ]"); + println!("{:?}", e); + return Err(ShellError::CommandFailed(String::from("failed"))) + }, }; Ok(()) } @@ -422,6 +474,7 @@ fn tokenise(equation: &str) -> Result, Error> { 'a'..='z' => { is_var = true; current_string.push(character); + continue; } _ => { if is_var { @@ -522,6 +575,7 @@ enum Error { enum Node { Number(f64), Operator(Operator), + Function(Box), BinaryOperation(Box), UnaryOperation(Box) } @@ -540,6 +594,11 @@ struct UnaryOperation { other: Node, } +#[derive(Debug, Clone, PartialEq)] +struct FunctionCall { + name: String, + arg: Node, +} @@ -565,6 +624,14 @@ impl fmt::Display for UnaryOperation { } } +impl fmt::Display for FunctionCall { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write! ( + f, "{}({})", self.name, self.arg + ) + } +} + impl fmt::Display for Node { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -578,6 +645,7 @@ impl fmt::Display for Node { let inner = *x.clone(); write!(f, "{}", inner) } + Node::Function(x) => write!(f, "{}", x), } } } diff --git a/src/user/bin/calc/functions.rs b/src/user/bin/calc/functions.rs new file mode 100644 index 0000000..08f93d0 --- /dev/null +++ b/src/user/bin/calc/functions.rs @@ -0,0 +1,27 @@ +use alloc::format; +use alloc::string::String; +use crate::println; + +pub fn run_func(func: String, x: f64) -> Result { + println!("function being run: {}({})", func, x); + + match func.as_str() { + "sqrt" => sqrt(x), + "ln" => ln(x), + _ => Err(String::from(format!("unrecognised function name: {}", func))), + } +} + +fn sqrt(x: f64) -> Result { + if x < 0.0 { + return Err(String::from("Cannot take the square root of a negative number")); + } + Ok(libm::sqrt(x)) +} + +fn ln(x: f64) -> Result { + if x < 0.0 { + return Err(String::from("Cannot take the natural log of a negative number")); + } + Ok(libm::log(x)) +} \ No newline at end of file diff --git a/src/user/bin/calc/mod.rs b/src/user/bin/calc/mod.rs new file mode 100644 index 0000000..9b3ef2f --- /dev/null +++ b/src/user/bin/calc/mod.rs @@ -0,0 +1,4 @@ +pub mod calc; +mod functions; + +pub use calc::*; diff --git a/src/user/bin/crystalfetch.rs b/src/user/bin/crystalfetch.rs index 212a6e9..6ed5cb7 100644 --- a/src/user/bin/crystalfetch.rs +++ b/src/user/bin/crystalfetch.rs @@ -1,15 +1,10 @@ use async_trait::async_trait; use alloc::{boxed::Box, string::String, vec::Vec}; -use crate::{ - std::os::OS, - std::io::{Color, write}, - println, - std::application::{ - Application, - Error, - }, -}; +use crate::{std::os::OS, std::io::{Color, write, clear}, println, std::application::{ + Application, + Error, +}, std}; pub struct CrystalFetch {} @@ -26,33 +21,30 @@ impl Application for CrystalFetch { let os = OS.lock().os.clone(); let version = OS.lock().version.clone(); + clear(); write(format_args!(" -──────────────────────────────────────────────────────── - _____ _ _ ____ _____ - / ____| | | | |/ __ \\ / ____| - | | _ __ _ _ ___| |_ __ _| | | | | (___ - | | | '__| | | / __| __/ _` | | | | |\\___ \\ - | |____| | | |_| \\__ \\ || (_| | | |__| |____) | - \\_____|_| \\__, |___/\\__\\__,_|_|\\____/|_____/ - __/ | - |___/ -"), (Color::Magenta, Color::Black)); - + /$$$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$ /$$ + |_____ $$ | $$ / $$ /$$__ $$ /$$__ $$ /$$__ $$ /$$$$ + /$$/ | $$/ $$/| $$ \\ $$| $$ \\ $$| $$ \\__/ /$$ /$$|_ $$ + /$$/ \\ $$$$/ | $$ | $$| $$ | $$| $$$$$$ | $$ /$$/ | $$ + /$$/ >$$ $$ | $$ | $$| $$ | $$ \\____ $$ \\ $$/$$/ | $$ + /$$/ /$$/\\ $$| $$/$$ $$| $$ | $$ /$$ \\ $$ \\ $$$/ | $$ + /$$$$$$$$| $$ \\ $$| $$$$$$/| $$$$$$/| $$$$$$/ \\ $/ /$$$$$$ + |________/|__/ |__/ \\____ $$$ \\______/ \\______/ \\_/ |______/ +"), (Color::Cyan, Color::Black)); println!(" - ╔═══════════════════════════════ - ║ - ║ OS » {} - ║ BUILD » {} - ║ RAM » idk - ║ Shell » CrystalSH - ║ API » CrystalAPI - ║ Pkgs » 4 - ║ Fetch » CrystalFetch - ║ - ╚═══════════════════════════════ -──────────────────────────────────────────────────────── + + [ OS » {} + [ BUILD » {} + [ Shell » CrySH + [ Github » https://github.com/FantasyPvP/CrystalOS-Restructured + [ Author » FantasyPvP / ZXQ5 + + + + ", os, version); Ok(()) } diff --git a/src/user/bin/gigachad_detector.rs b/src/user/bin/gigachad_detector.rs index d216227..f62db88 100644 --- a/src/user/bin/gigachad_detector.rs +++ b/src/user/bin/gigachad_detector.rs @@ -11,7 +11,7 @@ use crate::{ }, }; -const GIGACHAD: &'static str = "fantasypvp"; +const GIGACHAD: [&'static str; 3] = ["fantasypvp", "zxq5", "ZXQ5"]; pub struct GigachadDetector {} @@ -31,18 +31,18 @@ impl Application for GigachadDetector { impl GigachadDetector { pub fn detect_gigachad_by_username(&self, username: &str) { - if username == GIGACHAD { + if GIGACHAD.contains(&username) { println!("{} is a gigachad B'YES", username); println!(" - /$$$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ - |_____ $$ | $$ / $$ /$$__ $$| $$____/ - /$$/ | $$/ $$/| $$ \\ $$| $$ - /$$/ \\ $$$$/ | $$ | $$| $$$$$$$ - /$$/ >$$ $$ | $$ | $$|_____ $$ - /$$/ /$$/\\ $$| $$/$$ $$ /$$ \\ $$ - /$$$$$$$$| $$ \\ $$| $$$$$$/| $$$$$$/ - |________/|__/ |__/ \\____ $$$ \\______/ - \\__/ + /$$ /$$$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$ /$$ /$$ + /$$/|_____ $$ | $$ / $$ /$$__ $$| $$____/ /$$/| $$| $$ + /$$/ /$$/ | $$/ $$/| $$ \\ $$| $$ /$$/ \\ $$\\ $$ + /$$/ /$$/ \\ $$$$/ | $$ | $$| $$$$$$$ /$$/ \\ $$\\ $$ +| $$ /$$/ >$$ $$ | $$ | $$|_____ $$ /$$/ /$$/ /$$/ + \\ $$ /$$/ /$$/\\ $$| $$/$$ $$ /$$ \\ $$ /$$/ /$$/ /$$/ + \\ $$ /$$$$$$$$| $$ \\ $$| $$$$$$/| $$$$$$//$$/ /$$/ /$$/ + \\__/|________/|__/ |__/ \\____ $$$ \\______/|__/ |__/ |__/ + \\__/ ") } else { println!("{} is not a gigachad", username);