mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-06-25 20:21:44 +02:00
Integrated the angle unit system with then new dynamic unit system.
This commit is contained in:
parent
1d19f40e9f
commit
83668bbb84
@ -1,7 +1,6 @@
|
|||||||
use crate::ast::{Expr, Stmt};
|
use crate::ast::{Expr, Stmt};
|
||||||
use crate::lexer::TokenKind;
|
use crate::lexer::TokenKind;
|
||||||
use crate::parser::CalcError;
|
use crate::parser::CalcError;
|
||||||
use crate::parser::Unit;
|
|
||||||
use crate::parser::DECL_UNIT;
|
use crate::parser::DECL_UNIT;
|
||||||
use crate::prelude;
|
use crate::prelude;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
@ -10,14 +9,14 @@ use rug::Float;
|
|||||||
|
|
||||||
pub struct Context<'a> {
|
pub struct Context<'a> {
|
||||||
symbol_table: &'a mut SymbolTable,
|
symbol_table: &'a mut SymbolTable,
|
||||||
angle_unit: Unit,
|
angle_unit: String,
|
||||||
precision: u32,
|
precision: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a> Context<'a> {
|
||||||
pub fn new(symbol_table: &'a mut SymbolTable, angle_unit: &Unit, precision: u32) -> Self {
|
pub fn new(symbol_table: &'a mut SymbolTable, angle_unit: &str, precision: u32) -> Self {
|
||||||
Context {
|
Context {
|
||||||
angle_unit: angle_unit.clone(),
|
angle_unit: angle_unit.into(),
|
||||||
symbol_table,
|
symbol_table,
|
||||||
precision,
|
precision,
|
||||||
}
|
}
|
||||||
@ -68,7 +67,7 @@ fn eval_expr(context: &mut Context, expr: &Expr) -> Result<Float, CalcError> {
|
|||||||
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(op, expr) => eval_unary_expr(context, op, expr),
|
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr),
|
||||||
Expr::Unit(_, expr) => eval_unit_expr(context, expr),
|
Expr::Unit(identifier, expr) => eval_unit_expr(context, identifier, expr),
|
||||||
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),
|
||||||
Expr::Group(expr) => eval_group_expr(context, &expr),
|
Expr::Group(expr) => eval_group_expr(context, &expr),
|
||||||
@ -118,11 +117,20 @@ fn eval_unary_expr(context: &mut Context, op: &TokenKind, expr: &Expr) -> Result
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_unit_expr(context: &mut Context, expr: &Expr) -> Result<Float, CalcError> {
|
fn eval_unit_expr(
|
||||||
|
context: &mut Context,
|
||||||
|
identifier: &str,
|
||||||
|
expr: &Expr,
|
||||||
|
) -> Result<Float, CalcError> {
|
||||||
|
let angle_unit = &context.angle_unit.clone();
|
||||||
|
if (identifier == "rad" || identifier == "deg") && angle_unit != identifier {
|
||||||
|
return convert_unit(context, expr, identifier, angle_unit);
|
||||||
|
}
|
||||||
|
|
||||||
eval_expr(context, expr)
|
eval_expr(context, expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_unit(
|
pub fn convert_unit(
|
||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
from_unit: &str,
|
from_unit: &str,
|
||||||
@ -175,12 +183,12 @@ fn eval_fn_call_expr(
|
|||||||
let prelude_func = match expressions.len() {
|
let prelude_func = match expressions.len() {
|
||||||
1 => {
|
1 => {
|
||||||
let x = eval_expr(context, &expressions[0])?;
|
let x = eval_expr(context, &expressions[0])?;
|
||||||
prelude::call_unary_func(identifier, x, &context.angle_unit)
|
prelude::call_unary_func(context, identifier, x, &context.angle_unit.clone())
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let x = eval_expr(context, &expressions[0])?;
|
let x = eval_expr(context, &expressions[0])?;
|
||||||
let y = eval_expr(context, &expressions[1])?;
|
let y = eval_expr(context, &expressions[1])?;
|
||||||
prelude::call_binary_func(identifier, x, y, &context.angle_unit)
|
prelude::call_binary_func(context, identifier, x, y, &context.angle_unit.clone())
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
@ -259,10 +267,16 @@ mod tests {
|
|||||||
|
|
||||||
fn interpret(stmt: Stmt) -> Result<Option<Float>, CalcError> {
|
fn interpret(stmt: Stmt) -> Result<Option<Float>, CalcError> {
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
let mut context = Context::new(&mut symbol_table, &Unit::Radians, PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
||||||
|
|
||||||
context.interpret(vec![stmt])
|
context.interpret(vec![stmt])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmp(x: Float, y: f64) -> bool {
|
||||||
|
println!("{} = {}", x.to_f64(), y);
|
||||||
|
(x.to_f64() - y).abs() < 0.0001
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_literal() {
|
fn test_literal() {
|
||||||
let stmt = Stmt::Expr(literal("1"));
|
let stmt = Stmt::Expr(literal("1"));
|
||||||
@ -292,26 +306,38 @@ mod tests {
|
|||||||
fn test_unary() {
|
fn test_unary() {
|
||||||
let neg = Stmt::Expr(unary(Minus, literal("1")));
|
let neg = Stmt::Expr(unary(Minus, literal("1")));
|
||||||
let fact = Stmt::Expr(unary(Exclamation, literal("5")));
|
let fact = Stmt::Expr(unary(Exclamation, literal("5")));
|
||||||
let fact_dec = Stmt::Expr(unary(Exclamation, literal("5.2")));
|
|
||||||
|
|
||||||
assert_eq!(interpret(neg).unwrap().unwrap(), -1);
|
assert_eq!(interpret(neg).unwrap().unwrap(), -1);
|
||||||
assert_eq!(interpret(fact).unwrap().unwrap(), 120);
|
assert_eq!(interpret(fact).unwrap().unwrap(), 120);
|
||||||
|
|
||||||
let fact_dec_result = interpret(fact_dec).unwrap().unwrap();
|
|
||||||
assert!(fact_dec_result > 169.406 && fact_dec_result < 169.407);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#[test]
|
#[test]
|
||||||
fn test_unit() {
|
fn test_angle_units() {
|
||||||
let rad = Stmt::Expr(Box::new(Expr::Unit(literal("1"), Rad)));
|
let rad_explicit = Stmt::Expr(fn_call("sin", vec![*unit("rad", literal("1"))]));
|
||||||
let deg = Stmt::Expr(Box::new(Expr::Unit(literal("1"), Deg)));
|
let deg_explicit = Stmt::Expr(fn_call("sin", vec![*unit("deg", literal("1"))]));
|
||||||
|
//let implicit = Stmt::Expr(fn_call("sin", vec![*literal("1")]));
|
||||||
|
|
||||||
assert_eq!(interpret(rad).unwrap().unwrap(), 1);
|
assert!(cmp(interpret(rad_explicit).unwrap().unwrap(), 0.84147098));
|
||||||
assert!(
|
assert!(cmp(interpret(deg_explicit).unwrap().unwrap(), 0.01745240));
|
||||||
(interpret(deg).unwrap().unwrap() - Float::with_val(PRECISION, 0.017456)).abs()
|
|
||||||
< Float::with_val(PRECISION, 0.0001)
|
// TODO: Get this to work.
|
||||||
);
|
/*let mut rad_symbol_table = SymbolTable::new();
|
||||||
}*/
|
let mut deg_symbol_table = SymbolTable::new();
|
||||||
|
let mut rad_context = Context::new(&mut rad_symbol_table, "rad", PRECISION);
|
||||||
|
let mut deg_context = Context::new(&mut deg_symbol_table, "deg", PRECISION);
|
||||||
|
|
||||||
|
assert!(cmp(
|
||||||
|
rad_context
|
||||||
|
.interpret(vec![implicit.clone()])
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
0.84147098
|
||||||
|
));
|
||||||
|
assert!(cmp(
|
||||||
|
deg_context.interpret(vec![implicit]).unwrap().unwrap(),
|
||||||
|
0.01745240
|
||||||
|
));*/
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_var() {
|
fn test_var() {
|
||||||
@ -321,7 +347,7 @@ mod tests {
|
|||||||
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("1")));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, &Unit::Radians, PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
||||||
assert_eq!(context.interpret(vec![stmt]).unwrap().unwrap(), 1);
|
assert_eq!(context.interpret(vec![stmt]).unwrap().unwrap(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +365,7 @@ mod tests {
|
|||||||
fn test_var_decl() {
|
fn test_var_decl() {
|
||||||
let stmt = var_decl("x", literal("1"));
|
let stmt = var_decl("x", literal("1"));
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
Context::new(&mut symbol_table, &Unit::Radians, PRECISION)
|
Context::new(&mut symbol_table, "rad", PRECISION)
|
||||||
.interpret(vec![stmt])
|
.interpret(vec![stmt])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -358,7 +384,7 @@ mod tests {
|
|||||||
binary(var("x"), TokenKind::Plus, literal("2")),
|
binary(var("x"), TokenKind::Plus, literal("2")),
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, &Unit::Radians, PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
||||||
assert_eq!(context.interpret(vec![stmt]).unwrap().unwrap(), 3);
|
assert_eq!(context.interpret(vec![stmt]).unwrap().unwrap(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,7 @@ pub enum TokenKind {
|
|||||||
Exclamation,
|
Exclamation,
|
||||||
|
|
||||||
UnitKeyword,
|
UnitKeyword,
|
||||||
To,
|
ToKeyword,
|
||||||
Deg,
|
|
||||||
Rad,
|
|
||||||
|
|
||||||
Pipe,
|
Pipe,
|
||||||
OpenCeil,
|
OpenCeil,
|
||||||
@ -170,10 +168,8 @@ impl<'a> Lexer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let kind = match value.as_ref() {
|
let kind = match value.as_ref() {
|
||||||
"deg" | "°" => TokenKind::Deg,
|
|
||||||
"rad" => TokenKind::Rad,
|
|
||||||
"unit" => TokenKind::UnitKeyword,
|
"unit" => TokenKind::UnitKeyword,
|
||||||
"to" => TokenKind::To,
|
"to" => TokenKind::ToKeyword,
|
||||||
_ => TokenKind::Identifier,
|
_ => TokenKind::Identifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use crate::{
|
|||||||
use rug::Float;
|
use rug::Float;
|
||||||
|
|
||||||
pub const DECL_UNIT: &'static str = ".u";
|
pub const DECL_UNIT: &'static str = ".u";
|
||||||
|
pub const DEFAULT_ANGLE_UNIT: &'static str = "rad";
|
||||||
|
|
||||||
/// Struct containing the current state of the parser. It stores user-defined functions and variables.
|
/// Struct containing the current state of the parser. It stores user-defined functions and variables.
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -20,7 +21,7 @@ pub struct Context {
|
|||||||
tokens: Vec<Token>,
|
tokens: Vec<Token>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
symbol_table: SymbolTable,
|
symbol_table: SymbolTable,
|
||||||
angle_unit: Unit,
|
angle_unit: String,
|
||||||
/// This is true whenever the parser is currently parsing a unit declaration.
|
/// This is true whenever the parser is currently parsing a unit declaration.
|
||||||
/// It is necessary to keep track of this in order to know when to find (figure out) units that haven't been defined yet.
|
/// It is necessary to keep track of this in order to know when to find (figure out) units that haven't been defined yet.
|
||||||
/// Unit names are instead treated as variables.
|
/// Unit names are instead treated as variables.
|
||||||
@ -32,18 +33,22 @@ pub struct Context {
|
|||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Context {
|
let mut context = Self {
|
||||||
tokens: Vec::new(),
|
tokens: Vec::new(),
|
||||||
pos: 0,
|
pos: 0,
|
||||||
symbol_table: SymbolTable::new(),
|
symbol_table: SymbolTable::new(),
|
||||||
angle_unit: Unit::Radians,
|
angle_unit: DEFAULT_ANGLE_UNIT.into(),
|
||||||
parsing_unit_decl: false,
|
parsing_unit_decl: false,
|
||||||
unit_decl_base_unit: None,
|
unit_decl_base_unit: None,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
parse(&mut context, crate::prelude::INIT).unwrap();
|
||||||
|
|
||||||
|
context
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_angle_unit(mut self, unit: Unit) -> Self {
|
pub fn set_angle_unit(mut self, unit: &str) -> Self {
|
||||||
self.angle_unit = unit;
|
self.angle_unit = unit.into();
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -55,13 +60,6 @@ impl Default for Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mathematical unit used in calculations.
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum Unit {
|
|
||||||
Radians,
|
|
||||||
Degrees,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error that occured during parsing or evaluation.
|
/// Error that occured during parsing or evaluation.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum CalcError {
|
pub enum CalcError {
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
use crate::ast::Expr;
|
||||||
|
use crate::interpreter;
|
||||||
use rug::Float;
|
use rug::Float;
|
||||||
use FuncType::*;
|
use FuncType::*;
|
||||||
|
|
||||||
|
pub const INIT: &'static str = "unit deg = (rad*180)/pi";
|
||||||
|
|
||||||
pub const CONSTANTS: phf::Map<&'static str, &'static str> = phf::phf_map! {
|
pub const CONSTANTS: phf::Map<&'static str, &'static str> = phf::phf_map! {
|
||||||
"pi" => "3.14159265",
|
"pi" => "3.14159265",
|
||||||
"π" => "3.14159265",
|
"π" => "3.14159265",
|
||||||
@ -11,7 +15,6 @@ pub const CONSTANTS: phf::Map<&'static str, &'static str> = phf::phf_map! {
|
|||||||
"ϕ" => "1.61803398",
|
"ϕ" => "1.61803398",
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::parser::Unit;
|
|
||||||
use funcs::*;
|
use funcs::*;
|
||||||
pub const UNARY_FUNCS: phf::Map<&'static str, UnaryFuncInfo> = phf::phf_map! {
|
pub const UNARY_FUNCS: phf::Map<&'static str, UnaryFuncInfo> = phf::phf_map! {
|
||||||
"cos" => UnaryFuncInfo(cos, Trig),
|
"cos" => UnaryFuncInfo(cos, Trig),
|
||||||
@ -75,57 +78,76 @@ pub struct UnaryFuncInfo(fn(Float) -> Float, FuncType);
|
|||||||
pub struct BinaryFuncInfo(fn(Float, Float) -> Float, FuncType);
|
pub struct BinaryFuncInfo(fn(Float, Float) -> Float, FuncType);
|
||||||
|
|
||||||
impl UnaryFuncInfo {
|
impl UnaryFuncInfo {
|
||||||
fn call(&self, x: Float, angle_unit: &Unit) -> Float {
|
fn call(&self, context: &mut interpreter::Context, x: Float, angle_unit: &str) -> Float {
|
||||||
let func = self.0;
|
let func = self.0;
|
||||||
match self.1 {
|
match self.1 {
|
||||||
FuncType::Trig => func(from_angle_unit(x, angle_unit)),
|
FuncType::Trig => func(from_angle_unit(context, x, angle_unit)),
|
||||||
FuncType::InverseTrig => to_angle_unit(func(x), angle_unit),
|
FuncType::InverseTrig => to_angle_unit(context, func(x), angle_unit),
|
||||||
FuncType::Other => func(x),
|
FuncType::Other => func(x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BinaryFuncInfo {
|
impl BinaryFuncInfo {
|
||||||
fn call(&self, x: Float, y: Float, angle_unit: &Unit) -> Float {
|
fn call(
|
||||||
|
&self,
|
||||||
|
context: &mut interpreter::Context,
|
||||||
|
x: Float,
|
||||||
|
y: Float,
|
||||||
|
angle_unit: &str,
|
||||||
|
) -> Float {
|
||||||
let func = self.0;
|
let func = self.0;
|
||||||
match self.1 {
|
match self.1 {
|
||||||
FuncType::Trig => func(
|
FuncType::Trig => func(
|
||||||
from_angle_unit(x, angle_unit),
|
from_angle_unit(context, x, angle_unit),
|
||||||
from_angle_unit(y, angle_unit),
|
from_angle_unit(context, y, angle_unit),
|
||||||
),
|
),
|
||||||
FuncType::InverseTrig => to_angle_unit(func(x, y), angle_unit),
|
FuncType::InverseTrig => to_angle_unit(context, func(x, y), angle_unit),
|
||||||
FuncType::Other => func(x, y),
|
FuncType::Other => func(x, y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_unary_func(name: &str, x: Float, angle_unit: &Unit) -> Option<Float> {
|
pub fn call_unary_func(
|
||||||
|
context: &mut interpreter::Context,
|
||||||
|
name: &str,
|
||||||
|
x: Float,
|
||||||
|
angle_unit: &str,
|
||||||
|
) -> Option<Float> {
|
||||||
if let Some(func_info) = UNARY_FUNCS.get(name) {
|
if let Some(func_info) = UNARY_FUNCS.get(name) {
|
||||||
Some(func_info.call(x, &angle_unit))
|
Some(func_info.call(context, x, &angle_unit))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_binary_func(name: &str, x: Float, y: Float, angle_unit: &Unit) -> Option<Float> {
|
pub fn call_binary_func(
|
||||||
|
context: &mut interpreter::Context,
|
||||||
|
name: &str,
|
||||||
|
x: Float,
|
||||||
|
y: Float,
|
||||||
|
angle_unit: &str,
|
||||||
|
) -> Option<Float> {
|
||||||
if let Some(func_info) = BINARY_FUNCS.get(name) {
|
if let Some(func_info) = BINARY_FUNCS.get(name) {
|
||||||
Some(func_info.call(x, y, angle_unit))
|
Some(func_info.call(context, x, y, angle_unit))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_angle_unit(x: Float, angle_unit: &Unit) -> Float {
|
fn to_angle_unit(context: &mut interpreter::Context, x: Float, angle_unit: &str) -> Float {
|
||||||
match angle_unit {
|
match angle_unit {
|
||||||
Unit::Radians => x,
|
"rad" => x,
|
||||||
Unit::Degrees => special_funcs::to_degrees(x),
|
_ => interpreter::convert_unit(context, &Expr::Literal(x.to_string()), "rad", angle_unit)
|
||||||
|
.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_angle_unit(x: Float, angle_unit: &Unit) -> Float {
|
fn from_angle_unit(context: &mut interpreter::Context, x: Float, angle_unit: &str) -> Float {
|
||||||
match angle_unit {
|
match angle_unit {
|
||||||
Unit::Radians => x,
|
"rad" => x,
|
||||||
Unit::Degrees => special_funcs::to_radians(x),
|
_ => interpreter::convert_unit(context, &Expr::Literal(x.to_string()), angle_unit, "rad")
|
||||||
|
.unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,14 +157,6 @@ pub mod special_funcs {
|
|||||||
pub fn factorial(x: Float) -> Float {
|
pub fn factorial(x: Float) -> Float {
|
||||||
((x + 1) as Float).gamma()
|
((x + 1) as Float).gamma()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_degrees(x: Float) -> Float {
|
|
||||||
Float::with_val(53, x.to_f64().to_degrees())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_radians(x: Float) -> Float {
|
|
||||||
Float::with_val(53, x.to_f64().to_radians())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod funcs {
|
mod funcs {
|
||||||
|
@ -36,6 +36,10 @@ pub fn group(expr: Box<Expr>) -> Box<Expr> {
|
|||||||
Box::new(Expr::Group(expr))
|
Box::new(Expr::Group(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unit(identifier: &str, expr: Box<Expr>) -> Box<Expr> {
|
||||||
|
Box::new(Expr::Unit(identifier.into(), expr))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn var_decl(identifier: &str, value: Box<Expr>) -> Stmt {
|
pub fn var_decl(identifier: &str, value: Box<Expr>) -> Stmt {
|
||||||
Stmt::VarDecl(identifier.into(), value)
|
Stmt::VarDecl(identifier.into(), value)
|
||||||
}
|
}
|
||||||
@ -43,3 +47,7 @@ pub fn var_decl(identifier: &str, value: Box<Expr>) -> Stmt {
|
|||||||
pub fn fn_decl(identifier: &str, parameters: Vec<String>, value: Box<Expr>) -> Stmt {
|
pub fn fn_decl(identifier: &str, parameters: Vec<String>, value: Box<Expr>) -> Stmt {
|
||||||
Stmt::FnDecl(identifier.into(), parameters, value)
|
Stmt::FnDecl(identifier.into(), parameters, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unit_decl(unit: &str, base_unit: &str, expr: Box<Expr>) -> Stmt {
|
||||||
|
Stmt::UnitDecl(unit.into(), base_unit.into(), expr)
|
||||||
|
}
|
||||||
|
@ -2,13 +2,12 @@ mod output;
|
|||||||
mod repl;
|
mod repl;
|
||||||
|
|
||||||
use kalk::parser;
|
use kalk::parser;
|
||||||
use kalk::parser::Unit;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut parser_context = parser::Context::new().set_angle_unit(get_angle_unit());
|
let mut parser_context = parser::Context::new().set_angle_unit(&get_angle_unit());
|
||||||
|
|
||||||
// Command line argument input, execute it and exit.
|
// Command line argument input, execute it and exit.
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
@ -64,16 +63,10 @@ kalk [OPTIONS] [INPUT]
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_angle_unit() -> Unit {
|
fn get_angle_unit() -> String {
|
||||||
if let Ok(angle_unit_var) = env::var("ANGLE_UNIT") {
|
if let Ok(angle_unit_var) = env::var("ANGLE_UNIT") {
|
||||||
match angle_unit_var.as_ref() {
|
angle_unit_var
|
||||||
"radians" => Unit::Radians,
|
|
||||||
"degrees" => Unit::Degrees,
|
|
||||||
_ => {
|
|
||||||
panic!("Unexpected angle unit: {}.", angle_unit_var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Unit::Radians
|
String::from("rad")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user