mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-01-23 21:48:35 +01:00
Implemented factorial.
This commit is contained in:
parent
dc59d7cac2
commit
456b61bf08
@ -55,7 +55,7 @@ fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
|||||||
fn eval_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
fn eval_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right),
|
Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right),
|
||||||
Expr::Unary(_, expr) => eval_unary_expr(context, expr),
|
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr),
|
||||||
Expr::Unit(expr, kind) => eval_unit_expr(context, expr, kind),
|
Expr::Unit(expr, kind) => eval_unit_expr(context, expr, kind),
|
||||||
Expr::Var(identifier) => eval_var_expr(context, identifier),
|
Expr::Var(identifier) => eval_var_expr(context, identifier),
|
||||||
Expr::Literal(value) => eval_literal_expr(context, value),
|
Expr::Literal(value) => eval_literal_expr(context, value),
|
||||||
@ -85,8 +85,14 @@ fn eval_binary_expr(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_unary_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
fn eval_unary_expr(context: &mut Context, op: &TokenKind, expr: &Expr) -> Result<f64, String> {
|
||||||
eval_expr(context, &expr).clone()
|
let expr_value = eval_expr(context, &expr)?.clone();
|
||||||
|
|
||||||
|
match op {
|
||||||
|
TokenKind::Minus => Ok(-expr_value),
|
||||||
|
TokenKind::Exclamation => Ok(prelude::funcs::factorial(expr_value)),
|
||||||
|
_ => Err(String::from("Invalid operator for unary expression.")),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_unit_expr(context: &mut Context, expr: &Expr, kind: &TokenKind) -> Result<f64, String> {
|
fn eval_unit_expr(context: &mut Context, expr: &Expr, kind: &TokenKind) -> Result<f64, String> {
|
||||||
|
@ -12,6 +12,7 @@ pub enum TokenKind {
|
|||||||
Slash,
|
Slash,
|
||||||
Power,
|
Power,
|
||||||
Equals,
|
Equals,
|
||||||
|
Exclamation,
|
||||||
|
|
||||||
Deg,
|
Deg,
|
||||||
Rad,
|
Rad,
|
||||||
@ -106,6 +107,10 @@ impl<'a> Lexer<'a> {
|
|||||||
self.advance();
|
self.advance();
|
||||||
self.build(TokenKind::Equals, "")
|
self.build(TokenKind::Equals, "")
|
||||||
}
|
}
|
||||||
|
'!' => {
|
||||||
|
self.advance();
|
||||||
|
self.build(TokenKind::Exclamation, "")
|
||||||
|
}
|
||||||
',' => {
|
',' => {
|
||||||
self.advance();
|
self.advance();
|
||||||
self.build(TokenKind::Comma, "")
|
self.build(TokenKind::Comma, "")
|
||||||
|
@ -30,7 +30,6 @@ pub fn parse(context: &mut Context, input: &str, angle_unit: Unit) -> Result<Opt
|
|||||||
while !is_at_end(context) {
|
while !is_at_end(context) {
|
||||||
statements.push(parse_stmt(context)?);
|
statements.push(parse_stmt(context)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut interpreter = interpreter::Context::new(angle_unit, &mut context.symbol_table);
|
let mut interpreter = interpreter::Context::new(angle_unit, &mut context.symbol_table);
|
||||||
interpreter.interpret(statements)
|
interpreter.interpret(statements)
|
||||||
}
|
}
|
||||||
@ -147,7 +146,7 @@ fn parse_unary(context: &mut Context) -> Result<Expr, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_exponent(context: &mut Context) -> Result<Expr, String> {
|
fn parse_exponent(context: &mut Context) -> Result<Expr, String> {
|
||||||
let left = parse_primary(context)?;
|
let left = parse_factorial(context)?;
|
||||||
|
|
||||||
if match_token(context, TokenKind::Power) {
|
if match_token(context, TokenKind::Power) {
|
||||||
let op = advance(context).kind.clone();
|
let op = advance(context).kind.clone();
|
||||||
@ -158,6 +157,17 @@ fn parse_exponent(context: &mut Context) -> Result<Expr, String> {
|
|||||||
Ok(left)
|
Ok(left)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_factorial(context: &mut Context) -> Result<Expr, String> {
|
||||||
|
let expr = parse_primary(context)?;
|
||||||
|
|
||||||
|
Ok(if match_token(context, TokenKind::Exclamation) {
|
||||||
|
advance(context);
|
||||||
|
Expr::Unary(TokenKind::Exclamation, Box::new(expr))
|
||||||
|
} else {
|
||||||
|
expr
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_primary(context: &mut Context) -> Result<Expr, String> {
|
fn parse_primary(context: &mut Context) -> Result<Expr, String> {
|
||||||
let expr = match peek(context).kind {
|
let expr = match peek(context).kind {
|
||||||
TokenKind::OpenParenthesis => parse_group(context)?,
|
TokenKind::OpenParenthesis => parse_group(context)?,
|
||||||
|
@ -56,6 +56,7 @@ pub const BINARY_FUNCS: phf::Map<&'static str, BinaryFuncInfo> = phf::phf_map! {
|
|||||||
"min" => BinaryFuncInfo(min, Other),
|
"min" => BinaryFuncInfo(min, Other),
|
||||||
"hyp" => BinaryFuncInfo(hyp, Other),
|
"hyp" => BinaryFuncInfo(hyp, Other),
|
||||||
"log" => BinaryFuncInfo(logx, Other),
|
"log" => BinaryFuncInfo(logx, Other),
|
||||||
|
"sqrt" => BinaryFuncInfo(nth_sqrt, Other),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FuncType {
|
enum FuncType {
|
||||||
@ -124,7 +125,7 @@ fn from_angle_unit(x: f64, angle_unit: &Unit) -> f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod funcs {
|
pub mod funcs {
|
||||||
pub fn abs(x: f64) -> f64 {
|
pub fn abs(x: f64) -> f64 {
|
||||||
x.abs()
|
x.abs()
|
||||||
}
|
}
|
||||||
@ -212,6 +213,15 @@ mod funcs {
|
|||||||
x.exp()
|
x.exp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn factorial(x: f64) -> f64 {
|
||||||
|
let mut value = 1;
|
||||||
|
for i in 1..=x as i32 {
|
||||||
|
value *= i;
|
||||||
|
}
|
||||||
|
|
||||||
|
value as f64
|
||||||
|
}
|
||||||
|
|
||||||
pub fn floor(x: f64) -> f64 {
|
pub fn floor(x: f64) -> f64 {
|
||||||
x.floor()
|
x.floor()
|
||||||
}
|
}
|
||||||
@ -268,6 +278,10 @@ mod funcs {
|
|||||||
x.sqrt()
|
x.sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn nth_sqrt(x: f64, n: f64) -> f64 {
|
||||||
|
x.powf(1f64 / n)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tan(x: f64) -> f64 {
|
pub fn tan(x: f64) -> f64 {
|
||||||
x.tan()
|
x.tan()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user