mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-01-21 20:48:34 +01:00
Store number literals as f64
This commit is contained in:
parent
4ddb2bf33f
commit
56145c2f45
@ -19,5 +19,5 @@ pub enum Expr {
|
|||||||
Var(String),
|
Var(String),
|
||||||
Group(Box<Expr>),
|
Group(Box<Expr>),
|
||||||
FnCall(String, Vec<Expr>),
|
FnCall(String, Vec<Expr>),
|
||||||
Literal(String),
|
Literal(f64),
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,13 @@ impl<'a> Context<'a> {
|
|||||||
String::from("ans"),
|
String::from("ans"),
|
||||||
Box::new(Expr::Unit(
|
Box::new(Expr::Unit(
|
||||||
num.unit.clone(),
|
num.unit.clone(),
|
||||||
Box::new(Expr::Literal(num.value.clone().to_string())),
|
Box::new(Expr::Literal(num.value.to_f64())),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Stmt::VarDecl(
|
Stmt::VarDecl(
|
||||||
String::from("ans"),
|
String::from("ans"),
|
||||||
Box::new(Expr::Literal(num.value.clone().to_string())),
|
Box::new(Expr::Literal(num.value.to_f64())),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ fn eval_expr(context: &mut Context, expr: &Expr, unit: &str) -> Result<KalkNum,
|
|||||||
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr, unit),
|
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr, unit),
|
||||||
Expr::Unit(identifier, expr) => eval_unit_expr(context, identifier, expr),
|
Expr::Unit(identifier, expr) => eval_unit_expr(context, identifier, expr),
|
||||||
Expr::Var(identifier) => eval_var_expr(context, identifier, unit),
|
Expr::Var(identifier) => eval_var_expr(context, identifier, unit),
|
||||||
Expr::Literal(value) => eval_literal_expr(context, value, unit),
|
Expr::Literal(value) => eval_literal_expr(context, *value, unit),
|
||||||
Expr::Group(expr) => eval_group_expr(context, &expr, unit),
|
Expr::Group(expr) => eval_group_expr(context, &expr, unit),
|
||||||
Expr::FnCall(identifier, expressions) => {
|
Expr::FnCall(identifier, expressions) => {
|
||||||
eval_fn_call_expr(context, identifier, expressions, unit)
|
eval_fn_call_expr(context, identifier, expressions, unit)
|
||||||
@ -200,7 +200,7 @@ fn eval_var_expr(
|
|||||||
) -> Result<KalkNum, CalcError> {
|
) -> Result<KalkNum, CalcError> {
|
||||||
// If there is a constant with this name, return a literal expression with its value
|
// If there is a constant with this name, return a literal expression with its value
|
||||||
if let Some(value) = prelude::CONSTANTS.get(identifier) {
|
if let Some(value) = prelude::CONSTANTS.get(identifier) {
|
||||||
return eval_expr(context, &Expr::Literal((*value).to_string()), unit);
|
return eval_expr(context, &Expr::Literal(*value), unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for the variable in the symbol table
|
// Look for the variable in the symbol table
|
||||||
@ -211,14 +211,11 @@ fn eval_var_expr(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_literal_expr(context: &mut Context, value: &str, unit: &str) -> Result<KalkNum, CalcError> {
|
fn eval_literal_expr(context: &mut Context, value: f64, unit: &str) -> Result<KalkNum, CalcError> {
|
||||||
match Float::parse(value) {
|
Ok(KalkNum::new(
|
||||||
Ok(parsed_value) => Ok(KalkNum::new(
|
Float::with_val(context.precision, value),
|
||||||
Float::with_val(context.precision, parsed_value),
|
unit.into(),
|
||||||
unit.into(),
|
))
|
||||||
)),
|
|
||||||
Err(_) => Err(CalcError::InvalidNumberLiteral(value.into())),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_group_expr(context: &mut Context, expr: &Expr, unit: &str) -> Result<KalkNum, CalcError> {
|
fn eval_group_expr(context: &mut Context, expr: &Expr, unit: &str) -> Result<KalkNum, CalcError> {
|
||||||
@ -269,7 +266,7 @@ fn eval_fn_call_expr(
|
|||||||
let mut sum = Float::with_val(context.precision, 0);
|
let mut sum = Float::with_val(context.precision, 0);
|
||||||
|
|
||||||
for n in start..=end {
|
for n in start..=end {
|
||||||
let n_expr = Expr::Literal(n.to_string());
|
let n_expr = Expr::Literal(n as f64);
|
||||||
|
|
||||||
// Update the variable "n" in the symbol table on every iteration,
|
// Update the variable "n" in the symbol table on every iteration,
|
||||||
// then calculate the expression and add it to the total sum.
|
// then calculate the expression and add it to the total sum.
|
||||||
@ -328,7 +325,7 @@ mod tests {
|
|||||||
binary(
|
binary(
|
||||||
var(crate::parser::DECL_UNIT),
|
var(crate::parser::DECL_UNIT),
|
||||||
TokenKind::Star,
|
TokenKind::Star,
|
||||||
literal("180"),
|
literal(180f64),
|
||||||
),
|
),
|
||||||
TokenKind::Slash,
|
TokenKind::Slash,
|
||||||
var("pi"),
|
var("pi"),
|
||||||
@ -340,7 +337,7 @@ mod tests {
|
|||||||
binary(
|
binary(
|
||||||
binary(var(crate::parser::DECL_UNIT), TokenKind::Star, var("pi")),
|
binary(var(crate::parser::DECL_UNIT), TokenKind::Star, var("pi")),
|
||||||
TokenKind::Slash,
|
TokenKind::Slash,
|
||||||
literal("180"),
|
literal(180f64),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -370,18 +367,18 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_literal() {
|
fn test_literal() {
|
||||||
let stmt = Stmt::Expr(literal("1"));
|
let stmt = Stmt::Expr(literal(1f64));
|
||||||
|
|
||||||
assert_eq!(interpret(stmt).unwrap().unwrap().to_f64(), 1f64);
|
assert_eq!(interpret(stmt).unwrap().unwrap().to_f64(), 1f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_binary() {
|
fn test_binary() {
|
||||||
let add = Stmt::Expr(binary(literal("2"), Plus, literal("3")));
|
let add = Stmt::Expr(binary(literal(2f64), Plus, literal(3f64)));
|
||||||
let sub = Stmt::Expr(binary(literal("2"), Minus, literal("3")));
|
let sub = Stmt::Expr(binary(literal(2f64), Minus, literal(3f64)));
|
||||||
let mul = Stmt::Expr(binary(literal("2"), Star, literal("3")));
|
let mul = Stmt::Expr(binary(literal(2f64), Star, literal(3f64)));
|
||||||
let div = Stmt::Expr(binary(literal("2"), Slash, literal("4")));
|
let div = Stmt::Expr(binary(literal(2f64), Slash, literal(4f64)));
|
||||||
let pow = Stmt::Expr(binary(literal("2"), Power, literal("3")));
|
let pow = Stmt::Expr(binary(literal(2f64), Power, literal(3f64)));
|
||||||
|
|
||||||
assert_eq!(interpret(add).unwrap().unwrap().to_f64(), 5f64);
|
assert_eq!(interpret(add).unwrap().unwrap().to_f64(), 5f64);
|
||||||
assert_eq!(interpret(sub).unwrap().unwrap().to_f64(), -1f64);
|
assert_eq!(interpret(sub).unwrap().unwrap().to_f64(), -1f64);
|
||||||
@ -393,9 +390,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_percent() {
|
fn test_percent() {
|
||||||
let stmt = Stmt::Expr(binary(
|
let stmt = Stmt::Expr(binary(
|
||||||
literal("5"),
|
literal(5f64),
|
||||||
Percent,
|
Percent,
|
||||||
group(binary(literal("3"), Plus, unary(Percent, literal("2")))),
|
group(binary(literal(3f64), Plus, unary(Percent, literal(2f64)))),
|
||||||
));
|
));
|
||||||
|
|
||||||
assert!(cmp(interpret(stmt).unwrap().unwrap(), 1.94f64));
|
assert!(cmp(interpret(stmt).unwrap().unwrap(), 1.94f64));
|
||||||
@ -403,8 +400,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unary() {
|
fn test_unary() {
|
||||||
let neg = Stmt::Expr(unary(Minus, literal("1")));
|
let neg = Stmt::Expr(unary(Minus, literal(1f64)));
|
||||||
let fact = Stmt::Expr(unary(Exclamation, literal("5")));
|
let fact = Stmt::Expr(unary(Exclamation, literal(5f64)));
|
||||||
|
|
||||||
assert_eq!(interpret(neg).unwrap().unwrap().to_f64(), -1f64);
|
assert_eq!(interpret(neg).unwrap().unwrap().to_f64(), -1f64);
|
||||||
assert_eq!(interpret(fact).unwrap().unwrap().to_f64(), 120f64);
|
assert_eq!(interpret(fact).unwrap().unwrap().to_f64(), 120f64);
|
||||||
@ -412,9 +409,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_angle_units() {
|
fn test_angle_units() {
|
||||||
let rad_explicit = Stmt::Expr(fn_call("sin", vec![*unit("rad", literal("1"))]));
|
let rad_explicit = Stmt::Expr(fn_call("sin", vec![*unit("rad", literal(1f64))]));
|
||||||
let deg_explicit = Stmt::Expr(fn_call("sin", vec![*unit("deg", literal("1"))]));
|
let deg_explicit = Stmt::Expr(fn_call("sin", vec![*unit("deg", literal(1f64))]));
|
||||||
let implicit = Stmt::Expr(fn_call("sin", vec![*literal("1")]));
|
let implicit = Stmt::Expr(fn_call("sin", vec![*literal(1f64)]));
|
||||||
|
|
||||||
assert!(cmp(interpret(rad_explicit).unwrap().unwrap(), 0.84147098));
|
assert!(cmp(interpret(rad_explicit).unwrap().unwrap(), 0.84147098));
|
||||||
assert!(cmp(interpret(deg_explicit).unwrap().unwrap(), 0.01745240));
|
assert!(cmp(interpret(deg_explicit).unwrap().unwrap(), 0.01745240));
|
||||||
@ -449,7 +446,7 @@ mod tests {
|
|||||||
|
|
||||||
// Prepare by inserting a variable declaration in the symbol table.
|
// Prepare by inserting a variable declaration in the symbol table.
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
symbol_table.insert(var_decl("x", literal("1")));
|
symbol_table.insert(var_decl("x", literal(1f64)));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -470,7 +467,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_var_decl() {
|
fn test_var_decl() {
|
||||||
let stmt = var_decl("x", literal("1"));
|
let stmt = var_decl("x", literal(1f64));
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
Context::new(&mut symbol_table, "rad", PRECISION)
|
Context::new(&mut symbol_table, "rad", PRECISION)
|
||||||
.interpret(vec![stmt])
|
.interpret(vec![stmt])
|
||||||
@ -481,14 +478,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fn() {
|
fn test_fn() {
|
||||||
let stmt = Stmt::Expr(fn_call("f", vec![*literal("1")]));
|
let stmt = Stmt::Expr(fn_call("f", vec![*literal(1f64)]));
|
||||||
|
|
||||||
// Prepare by inserting a variable declaration in the symbol table.
|
// Prepare by inserting a variable declaration in the symbol table.
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
symbol_table.insert(fn_decl(
|
symbol_table.insert(fn_decl(
|
||||||
"f",
|
"f",
|
||||||
vec![String::from("x")],
|
vec![String::from("x")],
|
||||||
binary(var("x"), TokenKind::Plus, literal("2")),
|
binary(var("x"), TokenKind::Plus, literal(2f64)),
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
||||||
@ -500,7 +497,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_undefined_fn() {
|
fn test_undefined_fn() {
|
||||||
let stmt = Stmt::Expr(fn_call("f", vec![*literal("1")]));
|
let stmt = Stmt::Expr(fn_call("f", vec![*literal(1f64)]));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
interpret(stmt),
|
interpret(stmt),
|
||||||
@ -508,15 +505,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case("1", "2", 9f64)]
|
#[test_case(1f64, 2f64, 9f64)]
|
||||||
#[test_case("1.2", "2.3", 9f64)]
|
#[test_case(1.2f64, 2.3f64, 9f64)]
|
||||||
fn test_sum_fn(start: &str, to: &str, result: f64) {
|
fn test_sum_fn(start: f64, to: f64, result: f64) {
|
||||||
let stmt = Stmt::Expr(fn_call(
|
let stmt = Stmt::Expr(fn_call(
|
||||||
"sum",
|
"sum",
|
||||||
vec![
|
vec![
|
||||||
*literal(start),
|
*literal(start),
|
||||||
*literal(to),
|
*literal(to),
|
||||||
*binary(var("n"), TokenKind::Plus, literal("3")),
|
*binary(var("n"), TokenKind::Plus, literal(3f64)),
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ fn invert_binary(
|
|||||||
symbol_table,
|
symbol_table,
|
||||||
left,
|
left,
|
||||||
&TokenKind::Plus,
|
&TokenKind::Plus,
|
||||||
&multiply_into(&Expr::Literal(String::from("-1")), inside_group)?,
|
&multiply_into(&Expr::Literal(-1f64), inside_group)?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ fn invert_fn_call(
|
|||||||
Expr::Binary(
|
Expr::Binary(
|
||||||
Box::new(target_expr),
|
Box::new(target_expr),
|
||||||
TokenKind::Power,
|
TokenKind::Power,
|
||||||
Box::new(Expr::Literal(String::from("2"))),
|
Box::new(Expr::Literal(2f64)),
|
||||||
),
|
),
|
||||||
arguments[0].clone(),
|
arguments[0].clone(),
|
||||||
));
|
));
|
||||||
@ -361,49 +361,49 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_binary() {
|
fn test_binary() {
|
||||||
let ladd = binary(decl_unit(), Plus, literal("1"));
|
let ladd = binary(decl_unit(), Plus, literal(1f64));
|
||||||
let lsub = binary(decl_unit(), Minus, literal("1"));
|
let lsub = binary(decl_unit(), Minus, literal(1f64));
|
||||||
let lmul = binary(decl_unit(), Star, literal("1"));
|
let lmul = binary(decl_unit(), Star, literal(1f64));
|
||||||
let ldiv = binary(decl_unit(), Slash, literal("1"));
|
let ldiv = binary(decl_unit(), Slash, literal(1f64));
|
||||||
|
|
||||||
let radd = binary(literal("1"), Plus, decl_unit());
|
let radd = binary(literal(1f64), Plus, decl_unit());
|
||||||
let rsub = binary(literal("1"), Minus, decl_unit());
|
let rsub = binary(literal(1f64), Minus, decl_unit());
|
||||||
let rmul = binary(literal("1"), Star, decl_unit());
|
let rmul = binary(literal(1f64), Star, decl_unit());
|
||||||
let rdiv = binary(literal("1"), Slash, decl_unit());
|
let rdiv = binary(literal(1f64), Slash, decl_unit());
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ladd.invert(&mut symbol_table).unwrap(),
|
ladd.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Minus, literal("1"))
|
*binary(decl_unit(), Minus, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lsub.invert(&mut symbol_table).unwrap(),
|
lsub.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Plus, literal("1"))
|
*binary(decl_unit(), Plus, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lmul.invert(&mut symbol_table).unwrap(),
|
lmul.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Slash, literal("1"))
|
*binary(decl_unit(), Slash, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ldiv.invert(&mut symbol_table).unwrap(),
|
ldiv.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Star, literal("1"))
|
*binary(decl_unit(), Star, literal(1f64))
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
radd.invert(&mut symbol_table).unwrap(),
|
radd.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Minus, literal("1"))
|
*binary(decl_unit(), Minus, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rsub.invert(&mut symbol_table).unwrap(),
|
rsub.invert(&mut symbol_table).unwrap(),
|
||||||
*unary(Minus, binary(decl_unit(), Plus, literal("1")))
|
*unary(Minus, binary(decl_unit(), Plus, literal(1f64)))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rmul.invert(&mut symbol_table).unwrap(),
|
rmul.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Slash, literal("1"))
|
*binary(decl_unit(), Slash, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rdiv.invert(&mut symbol_table).unwrap(),
|
rdiv.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Star, literal("1"))
|
*binary(decl_unit(), Star, literal(1f64))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,34 +417,34 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fn_call() {
|
fn test_fn_call() {
|
||||||
let call_with_literal = binary(fn_call("f", vec![*literal("2")]), Plus, decl_unit());
|
let call_with_literal = binary(fn_call("f", vec![*literal(2f64)]), Plus, decl_unit());
|
||||||
let call_with_decl_unit = fn_call("f", vec![*decl_unit()]);
|
let call_with_decl_unit = fn_call("f", vec![*decl_unit()]);
|
||||||
let call_with_decl_unit_and_literal =
|
let call_with_decl_unit_and_literal =
|
||||||
fn_call("f", vec![*binary(decl_unit(), Plus, literal("2"))]);
|
fn_call("f", vec![*binary(decl_unit(), Plus, literal(2f64))]);
|
||||||
let decl = fn_decl(
|
let decl = fn_decl(
|
||||||
"f",
|
"f",
|
||||||
vec![String::from("x")],
|
vec![String::from("x")],
|
||||||
binary(var("x"), Plus, literal("1")),
|
binary(var("x"), Plus, literal(1f64)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
symbol_table.insert(decl);
|
symbol_table.insert(decl);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
call_with_literal.invert(&mut symbol_table).unwrap(),
|
call_with_literal.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Minus, fn_call("f", vec![*literal("2")])),
|
*binary(decl_unit(), Minus, fn_call("f", vec![*literal(2f64)])),
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
call_with_decl_unit.invert(&mut symbol_table).unwrap(),
|
call_with_decl_unit.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(decl_unit(), Minus, literal("1"))
|
*binary(decl_unit(), Minus, literal(1f64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
call_with_decl_unit_and_literal
|
call_with_decl_unit_and_literal
|
||||||
.invert(&mut symbol_table)
|
.invert(&mut symbol_table)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(decl_unit(), Minus, literal("1")),
|
binary(decl_unit(), Minus, literal(1f64)),
|
||||||
Minus,
|
Minus,
|
||||||
literal("2")
|
literal(2f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -452,84 +452,100 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_group() {
|
fn test_group() {
|
||||||
let group_x = binary(
|
let group_x = binary(
|
||||||
group(binary(decl_unit(), Plus, literal("3"))),
|
group(binary(decl_unit(), Plus, literal(3f64))),
|
||||||
Star,
|
Star,
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
);
|
);
|
||||||
let group_unary_minus = binary(
|
let group_unary_minus = binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Minus,
|
Minus,
|
||||||
group(binary(decl_unit(), Plus, literal("3"))),
|
group(binary(decl_unit(), Plus, literal(3f64))),
|
||||||
);
|
);
|
||||||
let x_group_add = binary(
|
let x_group_add = binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Star,
|
Star,
|
||||||
group(binary(decl_unit(), Plus, literal("3"))),
|
group(binary(decl_unit(), Plus, literal(3f64))),
|
||||||
);
|
);
|
||||||
let x_group_sub = binary(
|
let x_group_sub = binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Star,
|
Star,
|
||||||
group(binary(decl_unit(), Minus, literal("3"))),
|
group(binary(decl_unit(), Minus, literal(3f64))),
|
||||||
);
|
);
|
||||||
let x_group_mul = binary(
|
let x_group_mul = binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Star,
|
Star,
|
||||||
group(binary(decl_unit(), Star, literal("3"))),
|
group(binary(decl_unit(), Star, literal(3f64))),
|
||||||
);
|
);
|
||||||
let x_group_div = binary(
|
let x_group_div = binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Star,
|
Star,
|
||||||
group(binary(decl_unit(), Slash, literal("3"))),
|
group(binary(decl_unit(), Slash, literal(3f64))),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
group_x.invert(&mut symbol_table).unwrap(),
|
group_x.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(decl_unit(), Minus, binary(literal("2"), Star, literal("3"))),
|
binary(
|
||||||
|
decl_unit(),
|
||||||
|
Minus,
|
||||||
|
binary(literal(2f64), Star, literal(3f64))
|
||||||
|
),
|
||||||
Slash,
|
Slash,
|
||||||
literal("2")
|
literal(2f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
group_unary_minus.invert(&mut symbol_table).unwrap(),
|
group_unary_minus.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(
|
binary(
|
||||||
binary(decl_unit(), Minus, literal("2")),
|
binary(decl_unit(), Minus, literal(2f64)),
|
||||||
Minus,
|
Minus,
|
||||||
binary(literal("-1"), Star, literal("3"))
|
binary(literal(-1f64), Star, literal(3f64))
|
||||||
),
|
),
|
||||||
Slash,
|
Slash,
|
||||||
literal("-1")
|
literal(-1f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
x_group_add.invert(&mut symbol_table).unwrap(),
|
x_group_add.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(decl_unit(), Minus, binary(literal("2"), Star, literal("3"))),
|
binary(
|
||||||
|
decl_unit(),
|
||||||
|
Minus,
|
||||||
|
binary(literal(2f64), Star, literal(3f64))
|
||||||
|
),
|
||||||
Slash,
|
Slash,
|
||||||
literal("2")
|
literal(2f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
x_group_sub.invert(&mut symbol_table).unwrap(),
|
x_group_sub.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(decl_unit(), Plus, binary(literal("2"), Star, literal("3"))),
|
binary(
|
||||||
|
decl_unit(),
|
||||||
|
Plus,
|
||||||
|
binary(literal(2f64), Star, literal(3f64))
|
||||||
|
),
|
||||||
Slash,
|
Slash,
|
||||||
literal("2")
|
literal(2f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
x_group_mul.invert(&mut symbol_table).unwrap(),
|
x_group_mul.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(
|
*binary(
|
||||||
binary(decl_unit(), Slash, literal("3")),
|
binary(decl_unit(), Slash, literal(3f64)),
|
||||||
Slash,
|
Slash,
|
||||||
literal("2")
|
literal(2f64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
x_group_div.invert(&mut symbol_table).unwrap(),
|
x_group_div.invert(&mut symbol_table).unwrap(),
|
||||||
*binary(binary(decl_unit(), Star, literal("3")), Slash, literal("2"))
|
*binary(
|
||||||
|
binary(decl_unit(), Star, literal(3f64)),
|
||||||
|
Slash,
|
||||||
|
literal(2f64)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ impl KalkNum {
|
|||||||
) -> Option<KalkNum> {
|
) -> Option<KalkNum> {
|
||||||
let result = crate::interpreter::convert_unit(
|
let result = crate::interpreter::convert_unit(
|
||||||
context,
|
context,
|
||||||
&Expr::Literal(self.value.to_string()), // TODO: Store as f64, jeez...
|
&Expr::Literal(self.value.to_f64()),
|
||||||
&self.unit,
|
&self.unit,
|
||||||
to_unit,
|
to_unit,
|
||||||
);
|
);
|
||||||
|
@ -339,7 +339,7 @@ fn parse_primary(context: &mut Context) -> Result<Expr, CalcError> {
|
|||||||
TokenKind::OpenParenthesis => parse_group(context)?,
|
TokenKind::OpenParenthesis => parse_group(context)?,
|
||||||
TokenKind::Pipe | TokenKind::OpenCeil | TokenKind::OpenFloor => parse_group_fn(context)?,
|
TokenKind::Pipe | TokenKind::OpenCeil | TokenKind::OpenFloor => parse_group_fn(context)?,
|
||||||
TokenKind::Identifier => parse_identifier(context)?,
|
TokenKind::Identifier => parse_identifier(context)?,
|
||||||
TokenKind::Literal => Expr::Literal(advance(context).value.clone()),
|
TokenKind::Literal => Expr::Literal(advance(context).value.parse::<f64>().unwrap()),
|
||||||
_ => return Err(CalcError::UnableToParseExpression),
|
_ => return Err(CalcError::UnableToParseExpression),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ fn parse_identifier(context: &mut Context) -> Result<Expr, CalcError> {
|
|||||||
if match_token(context, TokenKind::Literal) {
|
if match_token(context, TokenKind::Literal) {
|
||||||
// If there is a function with this name, parse it as a function, with the next token as the argument.
|
// If there is a function with this name, parse it as a function, with the next token as the argument.
|
||||||
if context.symbol_table.contains_fn(&identifier.value) {
|
if context.symbol_table.contains_fn(&identifier.value) {
|
||||||
let parameter = Expr::Literal(advance(context).value.clone());
|
let parameter = Expr::Literal(advance(context).value.parse::<f64>().unwrap());
|
||||||
return Ok(Expr::FnCall(identifier.value, vec![parameter]));
|
return Ok(Expr::FnCall(identifier.value, vec![parameter]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,15 +508,15 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(tokens).unwrap(),
|
parse(tokens).unwrap(),
|
||||||
Stmt::Expr(binary(
|
Stmt::Expr(binary(
|
||||||
literal("1"),
|
literal(1f64),
|
||||||
Plus,
|
Plus,
|
||||||
binary(
|
binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Star,
|
Star,
|
||||||
group(binary(
|
group(binary(
|
||||||
literal("3"),
|
literal(3f64),
|
||||||
Minus,
|
Minus,
|
||||||
binary(literal("4"), Slash, literal("5"))
|
binary(literal(4f64), Slash, literal(5f64))
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
@ -542,16 +542,16 @@ mod tests {
|
|||||||
parse(tokens).unwrap(),
|
parse(tokens).unwrap(),
|
||||||
Stmt::Expr(binary(
|
Stmt::Expr(binary(
|
||||||
binary(
|
binary(
|
||||||
literal("1"),
|
literal(1f64),
|
||||||
Star,
|
Star,
|
||||||
binary(
|
binary(
|
||||||
literal("2"),
|
literal(2f64),
|
||||||
Power,
|
Power,
|
||||||
binary(literal("3"), Power, literal("4")),
|
binary(literal(3f64), Power, literal(4f64)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Plus,
|
Plus,
|
||||||
literal("5")
|
literal(5f64)
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -571,9 +571,9 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(tokens).unwrap(),
|
parse(tokens).unwrap(),
|
||||||
Stmt::Expr(binary(
|
Stmt::Expr(binary(
|
||||||
binary(literal("1"), Percent, literal("1"),),
|
binary(literal(1f64), Percent, literal(1f64)),
|
||||||
Plus,
|
Plus,
|
||||||
unary(Percent, literal("5"))
|
unary(Percent, literal(5f64))
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -589,7 +589,7 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_with_context(&mut context, tokens).unwrap(),
|
parse_with_context(&mut context, tokens).unwrap(),
|
||||||
Stmt::Expr(unit("a", literal("1")))
|
Stmt::Expr(unit("a", literal(1f64)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,7 +606,10 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(tokens).unwrap(),
|
parse(tokens).unwrap(),
|
||||||
Stmt::VarDecl(String::from("x"), binary(literal("1"), Plus, literal("2")))
|
Stmt::VarDecl(
|
||||||
|
String::from("x"),
|
||||||
|
binary(literal(1f64), Plus, literal(2f64))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,7 +632,7 @@ mod tests {
|
|||||||
Stmt::FnDecl(
|
Stmt::FnDecl(
|
||||||
String::from("f"),
|
String::from("f"),
|
||||||
vec![String::from("x")],
|
vec![String::from("x")],
|
||||||
binary(literal("1"), Plus, literal("2"))
|
binary(literal(1f64), Plus, literal(2f64))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -654,7 +657,7 @@ mod tests {
|
|||||||
context.symbol_table.set(Stmt::FnDecl(
|
context.symbol_table.set(Stmt::FnDecl(
|
||||||
String::from("f"),
|
String::from("f"),
|
||||||
vec![String::from("x")],
|
vec![String::from("x")],
|
||||||
literal("1"),
|
literal(1f64),
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -662,10 +665,10 @@ mod tests {
|
|||||||
Stmt::Expr(binary(
|
Stmt::Expr(binary(
|
||||||
Box::new(Expr::FnCall(
|
Box::new(Expr::FnCall(
|
||||||
String::from("f"),
|
String::from("f"),
|
||||||
vec![*binary(literal("1"), Plus, literal("2"))]
|
vec![*binary(literal(1f64), Plus, literal(2f64))]
|
||||||
)),
|
)),
|
||||||
Plus,
|
Plus,
|
||||||
literal("3")
|
literal(3f64)
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,15 @@ use FuncType::*;
|
|||||||
pub const INIT: &'static str = "unit deg = (rad*180)/pi";
|
pub const INIT: &'static str = "unit deg = (rad*180)/pi";
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref CONSTANTS: HashMap<&'static str, &'static str> = {
|
pub static ref CONSTANTS: HashMap<&'static str, f64> = {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert("pi", "3.14159265");
|
m.insert("pi", 3.14159265);
|
||||||
m.insert("π", "3.14159265");
|
m.insert("π", 3.14159265);
|
||||||
m.insert("e", "2.71828182");
|
m.insert("e", 2.71828182);
|
||||||
m.insert("tau", "6.28318530");
|
m.insert("tau", 6.28318530);
|
||||||
m.insert("τ", "6.28318530");
|
m.insert("τ", 6.28318530);
|
||||||
m.insert("phi", "1.61803398");
|
m.insert("phi", 1.61803398);
|
||||||
m.insert("ϕ", "1.61803398");
|
m.insert("ϕ", 1.61803398);
|
||||||
m
|
m
|
||||||
};
|
};
|
||||||
pub static ref UNARY_FUNCS: HashMap<&'static str, (UnaryFuncInfo, &'static str)> = {
|
pub static ref UNARY_FUNCS: HashMap<&'static str, (UnaryFuncInfo, &'static str)> = {
|
||||||
@ -154,9 +154,14 @@ fn to_angle_unit(context: &mut interpreter::Context, x: Float, angle_unit: &str)
|
|||||||
match angle_unit {
|
match angle_unit {
|
||||||
"rad" => x,
|
"rad" => x,
|
||||||
_ => {
|
_ => {
|
||||||
interpreter::convert_unit(context, &Expr::Literal(x.to_string()), "rad", angle_unit)
|
interpreter::convert_unit(
|
||||||
.unwrap()
|
context,
|
||||||
.value
|
&Expr::Literal(x.to_f64_round(rug::float::Round::Nearest)),
|
||||||
|
"rad",
|
||||||
|
angle_unit,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,9 +170,14 @@ fn from_angle_unit(context: &mut interpreter::Context, x: Float, angle_unit: &st
|
|||||||
match angle_unit {
|
match angle_unit {
|
||||||
"rad" => x,
|
"rad" => x,
|
||||||
_ => {
|
_ => {
|
||||||
interpreter::convert_unit(context, &Expr::Literal(x.to_string()), angle_unit, "rad")
|
interpreter::convert_unit(
|
||||||
.unwrap()
|
context,
|
||||||
.value
|
&Expr::Literal(x.to_f64_round(rug::float::Round::Nearest)),
|
||||||
|
angle_unit,
|
||||||
|
"rad",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ pub fn token(kind: TokenKind, value: &str) -> Token {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn literal(value: &str) -> Box<Expr> {
|
pub fn literal(value: f64) -> Box<Expr> {
|
||||||
Box::new(Expr::Literal(value.into()))
|
Box::new(Expr::Literal(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var(identifier: &str) -> Box<Expr> {
|
pub fn var(identifier: &str) -> Box<Expr> {
|
||||||
|
Loading…
Reference in New Issue
Block a user