diff --git a/Cargo.lock b/Cargo.lock
index b2d22085299ae1eb46b4268a8febb6e50fbac4a2..7b7eec74c0cfb478cbcc3c39be9c1a4d0f683128 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5,6 +5,7 @@ dependencies = [
  "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "calculate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -63,6 +64,11 @@ dependencies = [
  "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "calculate"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "cfg-if"
 version = "0.1.2"
@@ -359,6 +365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum bytes 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24f16593f445422331a5eed46b72f7f171f910fead4f2ea8f17e727e9c5c14"
+"checksum calculate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b593017444d7b7d0d1cacfea9dd28a507e42cfd30c5366130d14e1e16eb33e0"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
 "checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a"
diff --git a/Cargo.toml b/Cargo.toml
index 225d8c619096755517c5bf7e16dc7ead1d5afefd..50db0d8c8c56b6b43d019fbde8caedd44893548a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ permutate = "0.3"
 unicode-segmentation = "1.2"
 smallvec = "0.4"
 smallstring = "0.1"
-
+calculate = "0.1.*"
 [target.'cfg(target_os = "redox")'.dependencies]
 redox_syscall = "0.1"
 
diff --git a/src/builtins/calc.rs b/src/builtins/calc.rs
index 49eb612461b488254753f272c31526b4648b32be..373ebb60e1dbf268e6cf4fd919abf1f099bfab77 100644
--- a/src/builtins/calc.rs
+++ b/src/builtins/calc.rs
@@ -1,481 +1,7 @@
-use std::io::{self, Write};
-use std::error::Error;
-use std::iter::Peekable;
-use self::CalcError::*;
-
-#[derive(Debug, Clone)]
-pub enum Token {
-    Plus,
-    Minus,
-    Divide,
-    Multiply,
-    Exponent,
-    Square,
-    Cube,
-    BitWiseAnd,
-    BitWiseOr,
-    BitWiseXor,
-    BitWiseNot,
-    BitWiseRShift,
-    BitWiseLShift,
-    Modulo,
-    OpenParen,
-    CloseParen,
-    // TODO: Don't pass around a string when we can pass around a number
-    Number(String),
-}
-
-impl Token {
-    pub fn to_str(&self) -> &'static str {
-        match *self {
-            Token::Plus       => "Plus",
-            Token::Minus      => "Minus",
-            Token::Divide     => "Divide",
-            Token::Multiply   => "Multiply",
-            Token::Exponent   => "Exponent",
-            Token::Square     => "Square",
-            Token::Cube       => "Cube",
-            Token::BitWiseAnd => "And",
-            Token::BitWiseOr  => "Or",
-            Token::BitWiseXor => "Xor",
-            Token::BitWiseNot => "Not",
-            Token::BitWiseRShift => "RShift",
-            Token::BitWiseLShift => "LShift",
-            Token::Modulo => "Modulo",
-            Token::OpenParen  => "OpenParen",
-            Token::CloseParen => "CloseParen",
-            Token::Number(_)  => "Number",
-        }
-    }
-
-    pub fn to_string(&self) -> String {
-        self.to_str().to_owned()
-    }
-}
-
-#[derive(Debug)]
-pub enum CalcError {
-    DivideByZero,
-    InvalidNumber(String),
-    InvalidOperator(char),
-    UnrecognizedToken(String),
-    UnexpectedToken(String, &'static str),
-    UnexpectedEndOfInput,
-    UnmatchedParenthesis,
-    IO(io::Error),
-}
-
-impl From<CalcError> for String {
-    fn from(data: CalcError) -> String {
-        match data {
-            DivideByZero                 => String::from("calc: attempted to divide by zero"),
-            InvalidNumber(number)        => ["calc: invalid number: ", &number].concat(),
-            InvalidOperator(character)   => format!("calc: invalid operator: {}", character),
-            IO(error)                    => error.description().to_owned(),
-            UnrecognizedToken(token)     => ["calc: unrecognized token: ", &token].concat(),
-            UnexpectedToken(token, kind) => ["calc: unexpected ", kind, " token: ", &token].concat(),
-            UnexpectedEndOfInput         => String::from("calc: unexpected end of input"),
-            UnmatchedParenthesis         => String::from("calc: unmatched parenthesis")
-        }
-    }
-}
-
-#[derive(Clone,Debug)]
-pub struct IntermediateResult {
-    value: f64,
-    tokens_read: usize,
-}
-
-impl IntermediateResult {
-    fn new(value: f64, tokens_read: usize) -> Self {
-        IntermediateResult {
-            value: value,
-            tokens_read: tokens_read,
-        }
-    }
-}
-
-enum OperatorState {
-    PotentiallyIncomplete,
-    Complete,
-    NotAnOperator
-}
-
-trait IsOperator {
-    fn is_operator(self) -> bool;
-}
-
-impl IsOperator for char {
-    fn is_operator(self) -> bool {
-        match self {
-            '+' | '-' | '/' | '^' | '²' | '³' |
-            '&' | '|' | '~' | '>' | '%' | '(' |
-            ')' | '*' | '<' => true,
-            _ => false
-        }
-    }
-}
-
-trait CheckOperator {
-    fn check_operator(self) -> OperatorState;
-}
-
-impl CheckOperator for char {
-    fn check_operator(self) -> OperatorState {
-        match self {
-            '+' | '-' | '/' |
-            '^' | '²' | '³' |
-            '&' | '|' | '~' |
-            '%' | '(' | ')' => OperatorState::Complete,
-            '*' | '<' | '>' => OperatorState::PotentiallyIncomplete,
-            _ => OperatorState::NotAnOperator
-        }
-    }
-}
-
-pub trait OperatorMatch {
-    fn operator_type(self) -> Option<Token>;
-}
-
-impl OperatorMatch for [char; 2] {
-    fn operator_type(self) -> Option<Token> {
-        if self == ['*', '*'] {
-            Some(Token::Exponent)
-        } else if self == ['<', '<'] {
-            Some(Token::BitWiseLShift)
-        } else if self == ['>', '>'] {
-            Some(Token::BitWiseRShift)
-        } else {
-            None
-        }
-    }
-}
-
-impl OperatorMatch for char {
-    fn operator_type(self) -> Option<Token> {
-        match self {
-            '+' => Some(Token::Plus),
-            '-' => Some(Token::Minus),
-            '/' => Some(Token::Divide),
-            '*' => Some(Token::Multiply),
-            '^' => Some(Token::BitWiseXor),
-            '²' => Some(Token::Square),
-            '³' => Some(Token::Cube),
-            '&' => Some(Token::BitWiseAnd),
-            '|' => Some(Token::BitWiseOr),
-            '~' => Some(Token::BitWiseNot),
-            '%' => Some(Token::Modulo),
-            '(' => Some(Token::OpenParen),
-            ')' => Some(Token::CloseParen),
-            _   => None
-        }
-    }
-}
-
-pub fn tokenize(input: &str) -> Result<Vec<Token>, CalcError> {
-    let mut tokens = Vec::with_capacity(input.len());
-    let mut chars = input.chars().peekable();
-
-    while let Some(&c) = chars.peek() {
-        if c.is_digit(10) || c == '.' {
-            let token_string = consume_number(&mut chars);
-            tokens.push(Token::Number(token_string));
-        } else {
-            match c.check_operator() {
-                OperatorState::Complete => {
-                    tokens.push(c.operator_type().ok_or_else(|| InvalidOperator(c))?);
-                    chars.next();
-                },
-                OperatorState::PotentiallyIncomplete => {
-                    chars.next();
-                    match chars.peek() {
-                        Some(&next_char) if next_char.is_operator() => {
-                            tokens.push([c, next_char].operator_type().ok_or_else(|| InvalidOperator(c))?);
-                            chars.next();
-                        }
-                        _ => {
-                            tokens.push(c.operator_type().ok_or_else(|| InvalidOperator(c))?);
-                        }
-                    }
-                },
-                OperatorState::NotAnOperator => {
-                    if c.is_whitespace() {
-                        chars.next();
-                    } else {
-                        let token_string = consume_until_new_token(&mut chars);
-                        return Err(CalcError::UnrecognizedToken(token_string));
-                    }
-                }
-            }
-        }
-    }
-    Ok(tokens)
-}
+extern crate calc;
 
-fn consume_number<I: Iterator<Item = char>>(input: &mut Peekable<I>) -> String {
-    let mut number = String::new();
-    let mut has_decimal_point = false;
-    while let Some(&c) = input.peek() {
-        if c == '.' {
-            if has_decimal_point {
-                break;
-            } else {
-                number.push(c);
-                has_decimal_point = true;
-            }
-        } else if c.is_digit(10) {
-            number.push(c);
-        } else {
-            break;
-        }
-        input.next();
-    }
-    number
-}
-
-fn consume_until_new_token<I: Iterator<Item = char>>(input: &mut I) -> String {
-    input.take_while(|c| !(c.is_whitespace() || c.is_operator() || c.is_digit(10)))
-         .collect()
-}
-
-pub fn d_expr(token_list: &[Token]) -> Result<IntermediateResult, CalcError> {
-    let mut e1 = try!(e_expr(token_list));
-    let mut index = e1.tokens_read;
-
-    while index < token_list.len() {
-        match token_list[index] {
-            Token::BitWiseAnd => {
-                let e2 = try!(e_expr(&token_list[index+1..]));
-                if e1.value == e1.value.floor() && e2.value == e2.value.floor(){
-                    let mut int_f = e1.value.floor() as i64;
-                    let int_s = e2.value.floor() as i64;
-                    int_f &= int_s;
-                    e1.value = int_f as f64;
-                    e1.tokens_read += e2.tokens_read + 1;
-                }
-                else {
-                    //Obviously to lowercase isn't really what I want, but I don't really know how to get the string from the number, will check later -mgmoens
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::BitWiseOr => {
-                let e2 = try!(e_expr(&token_list[index+1..]));
-                if e1.value == e1.value.floor() && e2.value == e2.value.floor(){
-                    let mut int_f = e1.value.floor() as i64;
-                    let int_s = e2.value.floor() as i64;
-                    int_f |= int_s;
-                    e1.value = int_f as f64;
-                    e1.tokens_read += e2.tokens_read + 1;
-                }
-                else {
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::BitWiseNot => {
-                if e1.value == e1.value.floor() {
-                    let mut int_f = e1.value.floor() as i64;
-                    //magic number: bigest integer representable by f64 is 2^53, which is 0b1<<54 according to https://stackoverflow.com/questions/1848700/biggest-integer-that-can-be-stored-in-a-double
-                    // make a mask by shifting 11... between the sign bit and the number to effectively get a 55 bit signed number
-                    //let mask = 0b111111111 << 54;
-                    int_f = !(int_f);
-                    e1.value = int_f as f64;
-                    e1.tokens_read += 1;
-                }
-                else {
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::BitWiseXor => {
-                let e2 = try!(e_expr(&token_list[index+1..]));
-                if e1.value == e1.value.floor() && e2.value == e2.value.floor(){
-                    let mut int_f = e1.value.floor() as i64;
-                    let int_s = e2.value.floor() as i64;
-                    int_f ^= int_s;
-                    e1.value = int_f as f64;
-                    e1.tokens_read += e2.tokens_read + 1;
-                }
-                else {
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::BitWiseLShift => {
-                let e2 = try!(e_expr(&token_list[index+1..]));
-                if e1.value == e1.value.floor() && e2.value == e2.value.floor(){
-                    let mut int_f = e1.value.floor() as i64;
-                    let int_s = e2.value.floor() as i64;
-                    int_f <<= int_s;
-                    e1.value = int_f as f64;
-                    e1.tokens_read += e2.tokens_read + 1;
-                }
-                else {
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::BitWiseRShift => {
-                let e2 = try!(e_expr(&token_list[index+1..]));
-                if e1.value == e1.value.floor() && e2.value == e2.value.floor(){
-                    let mut int_f = e1.value.floor() as i64;
-                    let int_s = e2.value.floor() as i64;
-                    int_f >>= int_s;
-                    e1.value = int_f as f64;
-                    e1.tokens_read += e2.tokens_read + 1;
-                }
-                else {
-                    return Err(CalcError::UnexpectedToken("Not a integer number!".to_lowercase(),"Not a integer number!"));
-                }
-            },
-            Token::Number(ref n) => return Err(CalcError::UnexpectedToken(n.clone(),"operator")),
-            _ => break,
-        };
-        index = e1.tokens_read;
-    }
-    Ok(e1)
-}
-// Addition and subtraction
-pub fn e_expr(token_list: &[Token]) -> Result<IntermediateResult, CalcError> {
-    let mut t1 = try!(t_expr(token_list));
-    let mut index = t1.tokens_read;
-
-    while index < token_list.len() {
-        match token_list[index] {
-            Token::Plus => {
-                let t2 = try!(t_expr(&token_list[index+1..]));
-                t1.value += t2.value;
-                t1.tokens_read += t2.tokens_read + 1;
-            }
-            Token::Minus => {
-                let t2 = try!(t_expr(&token_list[index+1..]));
-                t1.value -= t2.value;
-                t1.tokens_read += t2.tokens_read + 1;
-            }
-            Token::Number(ref n) => return Err(CalcError::UnexpectedToken(n.clone(),"operator")),
-            _ => break,
-        };
-        index = t1.tokens_read;
-    }
-    Ok(t1)
-}
-
-// Multiplication and division
-pub fn t_expr(token_list: &[Token]) -> Result<IntermediateResult, CalcError> {
-    let mut f1 = try!(f_expr(token_list));
-    let mut index = f1.tokens_read;
-
-    while index < token_list.len() {
-        match token_list[index] {
-            Token::Multiply => {
-                let f2 = try!(f_expr(&token_list[index+1..]));
-                f1.value *= f2.value;
-                f1.tokens_read += f2.tokens_read + 1;
-            }
-            Token::Divide => {
-                let f2 = try!(f_expr(&token_list[index+1..]));
-                if f2.value == 0.0 {
-                    return Err(CalcError::DivideByZero);
-                } else {
-                    f1.value /= f2.value;
-                    f1.tokens_read += f2.tokens_read + 1;
-                }
-            }
-            Token::Modulo => {
-                let f2 = try!(f_expr(&token_list[index+1..]));
-                if f2.value == 0.0{
-                    return Err(CalcError::DivideByZero);
-                } else {
-                    f1.value %= f2.value;
-                    f1.tokens_read += f2.tokens_read + 1;
-                }
-            }
-            Token::Number(ref n) => return Err(CalcError::UnexpectedToken(n.clone(),"operator")),
-            _ => break,
-        }
-        index = f1.tokens_read;
-    }
-    Ok(f1)
-}
-
-// Exponentiation
-pub fn f_expr(token_list: &[Token]) -> Result<IntermediateResult, CalcError> {
-    let mut g1 = try!(g_expr(token_list)); //was g1
-    let mut index = g1.tokens_read;
-    let token_len = token_list.len();
-    while index < token_len {
-        match token_list[index] {
-            Token::Exponent => {
-                let f = try!(f_expr(&token_list[index+1..]));
-                g1.value = g1.value.powf(f.value);
-                g1.tokens_read += f.tokens_read + 1;
-            },
-            Token::Square => {
-                g1.value = g1.value*g1.value;
-                g1.tokens_read += 1;
-            },
-            Token::Cube => {
-                g1.value = g1.value*g1.value*g1.value;
-                g1.tokens_read += 1;
-            },
-            Token::Number(ref n) => return Err(CalcError::UnexpectedToken(n.clone(),"operator")),
-            _ => break,
-        }
-        index = g1.tokens_read;
-    }
-    Ok(g1)
-}
-
-// Numbers and parenthesized expressions
-pub fn g_expr(token_list: &[Token]) -> Result<IntermediateResult, CalcError> {
-    if !token_list.is_empty() {
-        match token_list[0] {
-            Token::Number(ref n) => {
-                n.parse::<f64>()
-                 .map_err(|_| CalcError::InvalidNumber(n.clone()))
-                 .and_then(|num| Ok(IntermediateResult::new(num, 1)))
-            }
-            Token::Minus => {
-                if token_list.len() > 1 {
-                    if let Token::Number(ref n) = token_list[1] {
-                        n.parse::<f64>()
-                         .map_err(|_| CalcError::InvalidNumber(n.clone()))
-                         .and_then(|num| Ok(IntermediateResult::new(-1.0 * num, 2)))
-                    } else {
-                        Err(CalcError::UnexpectedToken(token_list[1].to_string(), "number"))
-                    }
-                } else {
-                    Err(CalcError::UnexpectedEndOfInput)
-                }
-            }
-            Token::OpenParen => {
-                let expr = d_expr(&token_list[1..]);
-                match expr {
-                    Ok(ir) => {
-                        let close_paren = ir.tokens_read + 1;
-                        if close_paren < token_list.len() {
-                            match token_list[close_paren] {
-                                Token::CloseParen => Ok(IntermediateResult::new(ir.value, close_paren+1)),
-                                _ => Err(CalcError::UnexpectedToken(token_list[close_paren].to_string(), ")")),
-                            }
-                        } else {
-                            Err(CalcError::UnmatchedParenthesis)
-                        }
-                    }
-                    Err(e) => Err(e),
-                }
-            }
-            _ => Err(CalcError::UnexpectedToken(token_list[0].to_string(), "number"))
-        }
-    } else {
-        Err(CalcError::UnexpectedEndOfInput)
-    }
-}
-
-
-pub fn parse(tokens: &[Token]) -> Result<String, CalcError> {
-    d_expr(tokens).map(|answer| answer.value.to_string())
-}
-
-pub fn eval(input: &str) -> Result<String, CalcError> {
-    tokenize(input).and_then(|x| parse(&x))
-}
+use std::io::{self, Write};
+use calc::{eval, CalcError};
 
 pub fn calc(args: &[&str]) -> Result<(), String> {
     let stdout = io::stdout();
diff --git a/src/main.rs b/src/main.rs
index cec152a1a1dc72e74a0c88bb839a078bbe5f259d..7bf6860a8e58d66b04c9c1b0f7e6ad3c36cb4f6b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,7 +13,7 @@ extern crate glob;
 extern crate liner;
 extern crate smallvec;
 extern crate smallstring;
-
+extern crate calc;
 #[cfg(all(unix, not(target_os = "redox")))] extern crate futures;
 #[cfg(all(unix, not(target_os = "redox")))] extern crate libc;
 #[cfg(all(unix, not(target_os = "redox")))] extern crate nix;
diff --git a/src/parser/shell_expand/mod.rs b/src/parser/shell_expand/mod.rs
index 687ac725360b7906265f854af3f34f97b7b7e06c..c168c4878d7e24ae1c0210b15bc94d2de25fa637 100644
--- a/src/parser/shell_expand/mod.rs
+++ b/src/parser/shell_expand/mod.rs
@@ -1,6 +1,7 @@
 // TODO: Handle Runtime Errors
 extern crate permutate;
 extern crate unicode_segmentation;
+extern crate calc;
 use self::unicode_segmentation::UnicodeSegmentation;
 
 use types::Array;
@@ -14,8 +15,6 @@ use self::ranges::parse_range;
 pub use self::words::{WordIterator, WordToken, Select, Index, Range};
 use shell::variables::Variables;
 
-use ::builtins::calc;
-
 use std::io::{self, Write};
 use types::*;
 
@@ -492,7 +491,7 @@ fn expand_arithmetic(output : &mut String , input : &str, expander : &ExpanderFu
     }
     flush(&mut varbuf, &mut intermediate);
     match calc::eval(&intermediate) {
-        Ok(s) => output.push_str(&s),
+        Ok(s) => output.push_str(&(s.to_string())),
         Err(e) => {
             let err_string : String = e.into();
             output.push_str(&err_string);