calc functions and zxq5 logo in fetch

- changed the crystalfetch text
- added functions to the calculator
This commit is contained in:
FantasyPvP
2023-09-28 00:30:51 +01:00
parent 60a648c861
commit b3e31727b0
7 changed files with 145 additions and 46 deletions
@@ -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<Token>,
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<Value, Error> { // 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<Value, Error> {
@@ -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<Vec<Token>, 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<FunctionCall>),
BinaryOperation(Box<BinaryOperation>),
UnaryOperation(Box<UnaryOperation>)
}
@@ -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),
}
}
}
+27
View File
@@ -0,0 +1,27 @@
use alloc::format;
use alloc::string::String;
use crate::println;
pub fn run_func(func: String, x: f64) -> Result<f64, String> {
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<f64, String> {
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<f64, String> {
if x < 0.0 {
return Err(String::from("Cannot take the natural log of a negative number"));
}
Ok(libm::log(x))
}
+4
View File
@@ -0,0 +1,4 @@
pub mod calc;
mod functions;
pub use calc::*;
+24 -32
View File
@@ -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(())
}
+11 -11
View File
@@ -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);