diff --git a/calculator.cabal b/calculator.cabal
--- a/calculator.cabal
+++ b/calculator.cabal
@@ -1,5 +1,5 @@
 name:                calculator
-version:             0.1.2.3
+version:             0.1.3.0
 synopsis:            A calculator that operates on string inputs
 description:         A calculator repl that processes mathematical expressions.
                      Does basic arithmetic, and provides pre-defined basic mathematical functions.
@@ -17,12 +17,22 @@
 
 executable calculator
   main-is:             Main.hs
-  other-modules:       Calculator.Evaluator
-                     , Calculator.Parser
+  other-modules:       Calculator.Evaluator.Base
+                     , Calculator.Evaluator.Cmd
+                     , Calculator.Evaluator.Expr
+                     , Calculator.Evaluator.Statement
+                     , Calculator.Parser.Cmd
+                     , Calculator.Parser.Expr
+                     , Calculator.Parser.Statement
+                     , Calculator.Prim.Base
+                     , Calculator.Prim.Cmd
+                     , Calculator.Prim.Expr
+                     , Calculator.Prim.Statement
   -- other-extensions:    
   build-depends:       QuickCheck >= 2.7.6 && <2.7.7
                      , base >=4.7 && <4.8
                      , haskeline >=0.7.1.0 && <0.7.2.0
+                     , mtl >= 2.2.1
                      , parsec >=3.1.7 && <3.2
   hs-source-dirs:      src/
   ghc-options:         -Wall
@@ -31,13 +41,21 @@
 test-suite model-test-arithmetic
   type:                exitcode-stdio-1.0
   main-is:             Arithmetic.hs
-  other-modules:       Calculator.Evaluator
-                     , Calculator.Parser
-                     , Calculator.Primitives
+  other-modules:       Calculator.Evaluator.Cmd
+                     , Calculator.Evaluator.Expr
+                     , Calculator.Evaluator.Statement
+                     , Calculator.Parser.Cmd
+                     , Calculator.Parser.Expr
+                     , Calculator.Parser.Statement
+                     , Calculator.Prim.Base
+                     , Calculator.Prim.Cmd
+                     , Calculator.Prim.Expr
+                     , Calculator.Prim.Statement
                      , Model.Arithmetic
   hs-source-dirs:      tests/ src/
   build-depends:       QuickCheck >= 2.7.6 && <2.7.7
                      , base >=4.7 && <4.8
+                     , mtl >= 2.2.1
                      , parsec >=3.1.7 && <3.2
   ghc-options:         -Wall
   default-language:    Haskell2010
diff --git a/src/Calculator/Evaluator.hs b/src/Calculator/Evaluator.hs
deleted file mode 100644
--- a/src/Calculator/Evaluator.hs
+++ /dev/null
@@ -1,40 +0,0 @@
-module Calculator.Evaluator (eval) where
-
-import           Calculator.Parser             (parseExpr)
-import           Calculator.Primitives
-
-import           Control.Applicative           ((<$>), (<*))
-import           Data.Function                 (on)
-import           Text.ParserCombinators.Parsec (ParseError, eof, parse)
-
-evaluate :: Expr -> Expr
-evaluate e@(Constant _)     = e
-evaluate e@(InvalidError _) = e
-evaluate (UnOp (UnaryOp op) e) = Constant . op . fromConst $ evaluate e
-evaluate (BinOp (expr, rest))  = process expr rest
-evaluate (Function "" e) = evaluate e
-evaluate (Function f e) =
-  let func = lookup f dispatch :: Maybe (Number -> Number)
-      val  = fromConst $ evaluate e
-  in case func of
-      Nothing -> InvalidError $ "Unknown function " ++ show f
-      Just g  -> Constant $ g val
-evaluate _ = InvalidError evalFaliure
-
-process :: Expr -> [(Operator, Expr)] -> Expr
-process expr rest = evaluate $ foldl evalPart expr rest
-
-evalPart :: Expr -> (Operator, Expr) -> Expr
-evalPart e1 ((BinaryOp op), e2) =
-  let val1 = evaluate e1
-      val2 = evaluate e2
-  in if isConst val1 && isConst val2
-     then Constant $ (op `on` fromConst) val1 val2
-     else case (val1, val2) of
-           (e@(InvalidError _), _) -> e
-           (_, e@(InvalidError _)) -> e
-           (_, _)                  -> InvalidError evalFaliure
-evalPart _ _ = InvalidError evalFaliure
-
-eval :: String -> Either ParseError Expr
-eval s = evaluate <$> parse (parseExpr <* eof) s s
diff --git a/src/Calculator/Evaluator/Base.hs b/src/Calculator/Evaluator/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Evaluator/Base.hs
@@ -0,0 +1,34 @@
+module Calculator.Evaluator.Base (evaluate) where
+
+--------------------------------------------------------------------------------
+
+import Calculator.Prim.Expr (Bindings, Expr(..))
+import Calculator.Parser.Statement (parseStat)
+import Calculator.Evaluator.Statement (evalStat)
+
+--------------------------------------------------------------------------------
+
+import Text.ParserCombinators.Parsec (parse, eof)
+import Control.Applicative ((<*))
+
+--------------------------------------------------------------------------------
+
+eval :: Bindings -> String -> Either Expr Bindings
+eval b inp = case parse (parseStat <* eof) "Statement" inp of
+              Left e  -> Left $ InvalidError $ show e
+              Right s -> evalStat b s
+
+--------------------------------------------------------------------------------
+
+result :: Either Expr Bindings -> Either String Bindings
+result e = case e of
+            Left (Constant c)     -> Left $ show c
+            Left (InvalidError x) -> Left x
+            Right b               -> Right b
+
+--------------------------------------------------------------------------------
+
+evaluate :: Bindings -> String -> Either String Bindings
+evaluate b s = result $ eval b s
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Evaluator/Cmd.hs b/src/Calculator/Evaluator/Cmd.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Evaluator/Cmd.hs
@@ -0,0 +1,15 @@
+module Calculator.Evaluator.Cmd (evalCmd) where
+
+--------------------------------------------------------------------------------
+
+import Calculator.Prim.Expr (Bindings, def_vars, fromConst)
+import Calculator.Prim.Cmd (Cmd(..))
+import Calculator.Evaluator.Expr (evalExpr)
+
+--------------------------------------------------------------------------------
+
+evalCmd :: Bindings -> Cmd -> Bindings
+evalCmd _ (Reset)      = def_vars
+evalCmd b (Assign s e) = (s, fromConst $ evalExpr b e) : b
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Evaluator/Expr.hs b/src/Calculator/Evaluator/Expr.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Evaluator/Expr.hs
@@ -0,0 +1,55 @@
+module Calculator.Evaluator.Expr (evalExpr) where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Base (Number)
+import           Calculator.Prim.Expr (Bindings, Expr (..), Operator (..),
+                                       dispatch, fromConst, isConst)
+
+--------------------------------------------------------------------------------
+
+import           Data.Function        (on)
+
+--------------------------------------------------------------------------------
+
+evalExpr :: Bindings -> Expr -> Expr
+evalExpr _ e@(Constant _)     = e
+evalExpr _ e@(InvalidError _) = e
+-- evalExpr b (UnOp (UnaryOp op) e) = Constant . op . fromConst $ evalExpr b e
+evalExpr b (BinOp (expr, rest))  = process b expr rest
+evalExpr b (Variable s) =
+  let val = lookup s b
+  in case val of
+      Nothing -> InvalidError $ "Unknown variable " ++ show s
+      Just v  -> Constant v
+evalExpr b (Function "" e) = evalExpr b e
+evalExpr b (Function f e)  =
+  let func = lookup f dispatch :: Maybe (Number -> Number)
+  in case evalExpr b e of
+      Constant x -> case func of
+                     Nothing -> InvalidError $ "Unknown function " ++ show f
+                     Just g  -> Constant $ g x
+      e@(InvalidError _) -> e
+      _ -> InvalidError "Recieved Impossible result from evalExpr"
+evalExpr _ _ = InvalidError "Could not find suitable pattern for evalExpr"
+
+--------------------------------------------------------------------------------
+
+process :: Bindings -> Expr -> [(Operator, Expr)] -> Expr
+process bind expr rest = evalExpr bind $ foldl (evalPart bind) expr rest
+
+--------------------------------------------------------------------------------
+
+evalPart :: Bindings -> Expr -> (Operator, Expr) -> Expr
+evalPart b e1 ((BinaryOp op), e2) =
+  let val1 = evalExpr b e1
+      val2 = evalExpr b e2
+  in if ((&&) `on` isConst) val1 val2
+     then Constant $ (op `on` fromConst) val1 val2
+     else case (val1, val2) of
+           (e@(InvalidError _), _) -> e
+           (_, e@(InvalidError _)) -> e
+           _ -> InvalidError "Could not find matching pairs for evalPart"
+evalPart _ _ _ = InvalidError "Could not find suitable pattern for evalPart"
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Evaluator/Statement.hs b/src/Calculator/Evaluator/Statement.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Evaluator/Statement.hs
@@ -0,0 +1,17 @@
+module Calculator.Evaluator.Statement (evalStat) where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Evaluator.Cmd  (evalCmd)
+import           Calculator.Evaluator.Expr (evalExpr)
+import           Calculator.Prim.Expr      (Bindings, Expr)
+import           Calculator.Prim.Statement (Statement (..))
+
+--------------------------------------------------------------------------------
+
+evalStat :: Bindings -> Statement -> Either Expr Bindings
+evalStat b stat = case stat of
+                   Expression e -> Left $ evalExpr b e
+                   Command c    -> Right $ evalCmd b c
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Parser.hs b/src/Calculator/Parser.hs
deleted file mode 100644
--- a/src/Calculator/Parser.hs
+++ /dev/null
@@ -1,85 +0,0 @@
-module Calculator.Parser (parseExpr) where
-
-import           Calculator.Primitives
-
-import           Control.Applicative           ((<$>))
-import           Control.Monad                 (liftM2)
-import           Text.ParserCombinators.Parsec
-
--- expr -> term ( "+-" term )*
-
-parseExpr :: Parser Expr
-parseExpr = do
-  term <- parseTerm
-  rest <- parseRestExpr
-  if null rest
-    then return term
-    else return $ BinOp (term, rest)
-
-parseRestExpr :: Parser [(Operator, Expr)]
-parseRestExpr = many $ do
-  oper <- oneOf "+-"
-  let (Just op) = lookup oper binaryOps
-  expr <- parseTerm
-  return (op, expr)
-
--- term -> fact ( "*/" fact )*
-
-parseTerm :: Parser Expr
-parseTerm = do
-  fact <- parseFact
-  rest <- parseRestTerm
-  if null rest
-    then return fact
-    else return $ BinOp (fact, rest)
-
-parseRestTerm :: Parser [(Operator, Expr)]
-parseRestTerm = many $ do
-  oper <- oneOf "*/"
-  let (Just op) = lookup oper binaryOps
-  expr <- parseFact
-  return (op, expr)
-
--- fact -> val ( "^" fact )?
--- Right recursion for right associativity
-
-constEq :: Expr -> Expr -> Bool
-constEq (Constant x) (Constant y) = x == y
-constEq _ _ = False
-
-parseFact :: Parser Expr
-parseFact = do
-  val <- parseVal
-  pow <- parsePower
-  if constEq (Constant 1) (snd pow)
-    then return val
-    else return $ BinOp (val, [pow])
-
-parsePower :: Parser (Operator, Expr)
-parsePower = let (Just op) = lookup '^' binaryOps
-             in option (op, Constant 1) $ do
-               _ <- char '^'
-               fact <- parseFact
-               return (op, fact)
-
--- val -> func? ( expr ) | number
--- Parentheses can be seen as function calls
-
-parseVal :: Parser Expr
-parseVal = parseFunction <|> parseNumber
-
-parseFunction :: Parser Expr
-parseFunction = do
-  fname <- option "" (many letter)
-  _ <- char '('
-  e <- parseExpr
-  _ <- char ')'
-  return $ Function fname e
-
-parseNumber :: Parser Expr
-parseNumber = Constant . read <$> do
-  dec <- many1 digit
-  flt <- option "" (liftM2 (:) (char '.') (many1 digit))
-  if null flt
-    then return dec
-    else return $ dec ++ flt
diff --git a/src/Calculator/Parser/Cmd.hs b/src/Calculator/Parser/Cmd.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Parser/Cmd.hs
@@ -0,0 +1,42 @@
+module Calculator.Parser.Cmd (parseCmd) where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Base          (parseId)
+import           Calculator.Prim.Cmd           (Cmd (..))
+import           Calculator.Parser.Expr        (parseExpr)
+
+--------------------------------------------------------------------------------
+
+import           Text.ParserCombinators.Parsec
+
+--------------------------------------------------------------------------------
+-- cmd -> ':' cmd'
+
+parseCmd :: Parser Cmd
+parseCmd = char ':' >> parseCmd'
+
+--------------------------------------------------------------------------------
+-- cmd' -> reset | assign
+
+parseCmd' :: Parser Cmd
+parseCmd' = parseReset <|> parseAssign
+
+--------------------------------------------------------------------------------
+-- reset -> "reset"
+
+parseReset :: Parser Cmd
+parseReset = string "reset" >> return Reset
+
+--------------------------------------------------------------------------------
+-- assign -> "let" var "=" expr
+
+parseAssign :: Parser Cmd
+parseAssign = do
+  _   <- string "var "
+  str <- parseId
+  _   <- char '='
+  ex  <- parseExpr
+  return $ Assign str ex
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Parser/Expr.hs b/src/Calculator/Parser/Expr.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Parser/Expr.hs
@@ -0,0 +1,89 @@
+module Calculator.Parser.Expr (parseExpr) where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Base          (parseId, parseNumber)
+import           Calculator.Prim.Expr          (Expr (..), Operator, binaryOps,
+                                                constEq)
+
+--------------------------------------------------------------------------------
+
+import           Control.Applicative           ((<$>), (<*))
+import           Text.ParserCombinators.Parsec
+
+--------------------------------------------------------------------------------
+-- expr -> term ( "+-" term )*
+
+parseExpr :: Parser Expr
+parseExpr = do
+  term <- parseTerm
+  rest <- parseRestExpr
+  if null rest
+    then return term
+    else return $ BinOp (term, rest)
+
+parseRestExpr :: Parser [(Operator, Expr)]
+parseRestExpr = many $ do
+  oper <- oneOf "+-"
+  let (Just op) = lookup oper binaryOps
+  expr <- parseTerm
+  return (op, expr)
+
+--------------------------------------------------------------------------------
+-- term -> fact ( "*/" fact )*
+
+parseTerm :: Parser Expr
+parseTerm = do
+  fact <- parseFact
+  rest <- parseRestTerm
+  if null rest
+    then return fact
+    else return $ BinOp (fact, rest)
+
+parseRestTerm :: Parser [(Operator, Expr)]
+parseRestTerm = many $ do
+  oper <- oneOf "*/"
+  let (Just op) = lookup oper binaryOps
+  expr <- parseFact
+  return (op, expr)
+
+--------------------------------------------------------------------------------
+-- fact -> val ( "^" fact )?
+-- Right recursion for right associativity
+
+parseFact :: Parser Expr
+parseFact = do
+  val <- parseVal
+  pow <- parsePower
+  if constEq (Constant 1) (snd pow)
+    then return val
+    else return $ BinOp (val, [pow])
+
+parsePower :: Parser (Operator, Expr)
+parsePower = let (Just op) = lookup '^' binaryOps
+             in option (op, Constant 1) $ do
+               _ <- char '^'
+               fact <- parseFact
+               return (op, fact)
+
+--------------------------------------------------------------------------------
+-- val -> func? ( expr ) | number
+-- Parentheses can be parsed as function calls with no function
+
+parseVal :: Parser Expr
+parseVal = parseFunction <|> parseVariable <|> parseConstant
+
+parseVariable :: Parser Expr
+parseVariable = Variable <$> parseId
+
+parseConstant :: Parser Expr
+parseConstant = Constant <$> parseNumber
+
+parseFunction :: Parser Expr
+parseFunction = do
+  ident <- try (parseId <* char '(')
+  expr  <- parseExpr
+  _     <- char ')'
+  return $ Function ident expr
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Parser/Statement.hs b/src/Calculator/Parser/Statement.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Parser/Statement.hs
@@ -0,0 +1,19 @@
+module Calculator.Parser.Statement (parseStat) where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Parser.Cmd         (parseCmd)
+import           Calculator.Parser.Expr        (parseExpr)
+import           Calculator.Prim.Statement     (Statement (..))
+
+--------------------------------------------------------------------------------
+
+import           Control.Applicative           ((<$>))
+import           Text.ParserCombinators.Parsec
+
+--------------------------------------------------------------------------------
+
+parseStat :: Parser Statement
+parseStat = (Expression <$> parseExpr) <|> (Command <$> parseCmd)
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Prim/Base.hs b/src/Calculator/Prim/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Prim/Base.hs
@@ -0,0 +1,31 @@
+module Calculator.Prim.Base where
+
+--------------------------------------------------------------------------------
+
+import           Text.ParserCombinators.Parsec
+
+--------------------------------------------------------------------------------
+
+import           Control.Applicative           ((<$>))
+import           Control.Monad                 (liftM2)
+
+--------------------------------------------------------------------------------
+
+type Number = Double
+
+--------------------------------------------------------------------------------
+
+parseNumber :: Parser Number
+parseNumber = read <$> do
+  dec <- many1 digit
+  flt <- option "" (liftM2 (:) (char '.') (many1 digit))
+  if null flt
+    then return dec
+    else return $ dec ++ flt
+
+--------------------------------------------------------------------------------
+
+parseId :: Parser String
+parseId = (liftM2 (:) letter (many (letter <|> digit)))
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Prim/Cmd.hs b/src/Calculator/Prim/Cmd.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Prim/Cmd.hs
@@ -0,0 +1,17 @@
+module Calculator.Prim.Cmd where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Base (Number)
+import           Calculator.Prim.Expr (Expr)
+
+--------------------------------------------------------------------------------
+
+type Bindings = [(String, Number)]
+
+--------------------------------------------------------------------------------
+
+data Cmd = Assign String Expr
+         | Reset
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Prim/Expr.hs b/src/Calculator/Prim/Expr.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Prim/Expr.hs
@@ -0,0 +1,77 @@
+module Calculator.Prim.Expr where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Base (Number)
+
+--------------------------------------------------------------------------------
+
+type Bindings = [(String, Number)]
+
+data Expr = Function String Expr
+          | Constant Number
+          | UnOp Operator Expr
+          | BinOp (Expr, [(Operator, Expr)])
+          | Variable String
+          | InvalidError String
+
+data Operator = UnaryOp  (Number -> Number)
+              | BinaryOp (Number -> Number -> Number)
+
+--------------------------------------------------------------------------------
+
+binaryOps :: [(Char, Operator)]
+binaryOps = [ ('+', BinaryOp (+))
+            , ('-', BinaryOp (-))
+            , ('*', BinaryOp (*))
+            , ('/', BinaryOp (/))
+            , ('^', BinaryOp (**))
+            ]
+
+dispatch :: (RealFrac a, Floating a) => [(String, a -> a)]
+dispatch = [ ("sin", sin)
+           , ("cos", cos)
+           , ("tan", tan)
+           , ("asin", asin)
+           , ("acos", acos)
+           , ("atan", atan)
+           , ("sinh", sinh)
+           , ("cosh", cosh)
+           , ("tanh", tanh)
+           , ("exp", exp)
+           , ("log", log)
+           , ("log10", logBase 10)
+           , ("sqrt", sqrt)
+           , ("ceil", fromInteger . ceiling)
+           , ("floor", fromInteger . floor)
+           , ("abs", abs)
+           ]
+
+--------------------------------------------------------------------------------
+
+constEq :: Expr -> Expr -> Bool
+constEq (Constant x) (Constant y) = x == y
+constEq _ _ = False
+
+--------------------------------------------------------------------------------
+
+def_vars :: Bindings
+def_vars = [ ("pi", pi) ]
+
+--------------------------------------------------------------------------------
+
+fromConst :: Expr -> Number
+fromConst (Constant v)     = v
+fromConst (Function _ _)   = error "fromConst Function"
+fromConst (UnOp _ _)       = error "fromConst UnOp"
+fromConst (BinOp _)        = error "fromConst BinOp"
+fromConst (Variable _)     = error "fromConst Variable"
+fromConst (InvalidError _) = error "fromConst InvalidError"
+
+--------------------------------------------------------------------------------
+
+isConst :: Expr -> Bool
+isConst (Constant _) = True
+isConst _            = False
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Prim/Statement.hs b/src/Calculator/Prim/Statement.hs
new file mode 100644
--- /dev/null
+++ b/src/Calculator/Prim/Statement.hs
@@ -0,0 +1,14 @@
+module Calculator.Prim.Statement where
+
+--------------------------------------------------------------------------------
+
+import           Calculator.Prim.Cmd           (Cmd)
+import           Calculator.Prim.Expr          (Expr)
+
+--------------------------------------------------------------------------------
+-- stmt -> cmd | expr
+
+data Statement = Expression Expr
+               | Command Cmd
+
+--------------------------------------------------------------------------------
diff --git a/src/Calculator/Primitives.hs b/src/Calculator/Primitives.hs
deleted file mode 100644
--- a/src/Calculator/Primitives.hs
+++ /dev/null
@@ -1,58 +0,0 @@
-module Calculator.Primitives where
-
-import Text.ParserCombinators.Parsec.Error (ParseError)
-
-type Number = Double
-
-data Expr = Function String Expr
-          | Constant Number
-          | UnOp Operator Expr
-          | BinOp (Expr, [(Operator, Expr)])
-          | InvalidError String
-
-data Operator = UnaryOp  (Number -> Number)
-              | BinaryOp (Number -> Number -> Number)
-
-evalFaliure :: String
-evalFaliure = "Evaluation Failed"
-
-fromConst :: Expr -> Number
-fromConst (Constant c) = c
-fromConst _ = error "Error: Making number from expr"
-
-isConst :: Expr -> Bool
-isConst (Constant _) = True
-isConst _ = False
-
-result :: Either ParseError Expr -> String
-result (Right (Constant c)) = " == " ++ show c
-result (Right (InvalidError e)) = " !! " ++ e
-result (Left e) = show e
-result _ = evalFaliure
-
-binaryOps :: [(Char, Operator)]
-binaryOps = [ ('+', BinaryOp (+))
-            , ('-', BinaryOp (-))
-            , ('*', BinaryOp (*))
-            , ('/', BinaryOp (/))
-            , ('^', BinaryOp (**))
-            ]
-
-dispatch :: (RealFrac a, Floating a) => [(String, a -> a)]
-dispatch = [ ("sin", sin)
-           , ("cos", cos)
-           , ("tan", tan)
-           , ("asin", asin)
-           , ("acos", acos)
-           , ("atan", atan)
-           , ("sinh", sinh)
-           , ("cosh", cosh)
-           , ("tanh", tanh)
-           , ("exp", exp)
-           , ("log", log)
-           , ("log10", logBase 10)
-           , ("sqrt", sqrt)
-           , ("ceil", fromInteger . ceiling)
-           , ("floor", fromInteger . floor)
-           , ("abs", abs)
-           ]
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,21 +1,33 @@
 module Main where
 
-import           Calculator.Evaluator                (eval)
-import           Calculator.Primitives               (result)
+--------------------------------------------------------------------------------
 
+import           Calculator.Evaluator.Base     (evaluate)
+import           Calculator.Prim.Expr          (Bindings, def_vars)
+
+--------------------------------------------------------------------------------
+
 import           System.Console.Haskeline
 
+--------------------------------------------------------------------------------
+
 type Repl a = InputT IO a
 
-process :: String -> Repl ()
-process input = outputStrLn $ result $ eval input
+--------------------------------------------------------------------------------
 
-repl :: Repl ()
-repl = do
+repl :: Bindings -> Repl ()
+repl b = do
   input <- getInputLine "calc> "
   case input of
    Nothing  -> return ()
-   Just inp -> process inp >> repl
+   Just inp -> let result = evaluate b inp
+               in case result of
+                   Left s   -> outputStrLn s >> repl b
+                   Right b' -> repl b'
 
+--------------------------------------------------------------------------------
+
 main :: IO ()
-main = runInputT defaultSettings repl
+main = runInputT defaultSettings (repl def_vars)
+
+--------------------------------------------------------------------------------
