packages feed

mathexpr (empty) → 0.1.0.0

raw patch · 4 files changed

+236/−0 lines, 4 filesdep +basedep +data-default-classsetup-changed

Dependencies added: base, data-default-class

Files

+ LICENSE view
@@ -0,0 +1,101 @@+                    GNU GENERAL PUBLIC LICENSE+                       Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++                            Preamble++  The GNU General Public License is a free, copyleft license for+software and other kinds of works.++  The licenses for most software and other practical works are designed+to take away your freedom to share and change the works.  By contrast,+the GNU General Public License is intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users.  We, the Free Software Foundation, use the+GNU General Public License for most of our software; it applies also to+any other work released this way by its authors.  You can apply it to+your programs, too.++  When we speak of free software, we are referring to freedom, not+price.  Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++  To protect your rights, we need to prevent others from denying you+these rights or asking you to surrender the rights.  Therefore, you have+certain responsibilities if you distribute copies of the software, or if+you modify it: responsibilities to respect the freedom of others.++  For example, if you distribute copies of such a program, whether+gratis or for a fee, you must pass on to the recipients the same+freedoms that you received.  You must make sure that they, too, receive+or can get the source code.  And you must show them these terms so they+know their rights.++  Developers that use the GNU GPL protect your rights with two steps:+(1) assert copyright on the software, and (2) offer you this License+giving you legal permission to copy, distribute and/or modify it.++  For the developers' and authors' protection, the GPL clearly explains+that there is no warranty for this free software.  For both users' and+authors' sake, the GPL requires that modified versions be marked as+changed, so that their problems will not be attributed erroneously to+authors of previous versions.++  Some devices are designed to deny users access to install or run+modified versions of the software inside them, although the manufacturer+can do so.  This is fundamentally incompatible with the aim of+protecting users' freedom to change the software.  The systematic+pattern of such abuse occurs in the area of products for individuals to+use, which is precisely where it is most unacceptable.  Therefore, we+have designed this version of the GPL to prohibit the practice for those+products.  If such problems arise substantially in other domains, we+stand ready to extend this provision to those domains in future versions+of the GPL, as needed to protect the freedom of users.++  Finally, every program is threatened constantly by software patents.+States should not allow patents to restrict development and use of+software on general-purpose computers, but in those that do, we wish to+avoid the special danger that patents applied to a free program could+make it effectively proprietary.  To prevent this, the GPL assures that+patents cannot be used to render the program non-free.++  The precise terms and conditions for copying, distribution and+modification follow.++                       TERMS AND CONDITIONS++  0. Definitions.++  "This License" refers to version 3 of the GNU General Public License.++  "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++  "The Program" refers to any copyrightable work licensed under this+License.  Each licensee is addressed as "you".  "Licensees" and+"recipients" may be individuals or organizations.++  To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy.  The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++  A "covered work" means either the unmodified Program or a work based+on the Program.++  To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy.  Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++  To "convey" a work means any kind of propagation that enables other+parties to make or receive copies.  Mere interaction with a user through+a computer network, with no transfer of a copy, 
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ mathexpr.cabal view
@@ -0,0 +1,25 @@+name:                mathexpr+version:             0.1.0.0+synopsis:            Parse and evaluate math expressions with variables and functions+description:         A simple tool to evaluate math expressions as strings with support for custom functions and operators+homepage:            https://github.com/mdibaiee/mathexpr+license:             GPL-3+license-file:        LICENSE+author:              Mahdi Dibaiee+maintainer:          mdibaiee@aol.com+copyright:           2016 Mahdi Dibaiee+category:            Math+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Data.MathExpr+  build-depends:       base >= 4.7 && < 5,+                       data-default-class+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/mdibaiee/mathexpr
+ src/Data/MathExpr.hs view
@@ -0,0 +1,108 @@+module Data.MathExpr+    ( evaluate+    , Settings (..)+    , defaultFunctions+    , defaultOperators+    ) where+      import Data.Default.Class+      import Data.Maybe (isJust, fromJust)+      import Debug.Trace+      import Data.List (find)++      data Settings = Settings { operators :: [(Char, Int, Double -> Double -> Double)]+                               , functions :: [(String, Double -> Double)]+                               }++      defaultOperators = [+          ('+', 0, (+)), ('-', 0, (-)),+          ('*', 1, (*)), ('/', 1, (/)),+          ('^', 2, (**))+        ]+      defaultFunctions = [("ln", log), ("sin", sin), ("cos", cos)]++      instance Default Settings where+        def = Settings { operators = defaultOperators+                       , functions = defaultFunctions+                       }+      toPostfix :: Settings -> String -> String+      toPostfix settings s = helper (tokenize s) [] []+        where+          ops = operators settings+          fns = functions settings++          helper :: [String] -> [String] -> String -> String+          helper [] os out = out ++ concat os+          helper (c:cs) os out+            | head c == '(' = helper cs (c:os) out+            | head c == ')' && head os == "(" = helper cs (tail os) out+            | head c == ')' = helper (c:cs) (tail os) (out ++ pad (head os))+            | isOperator c && (null os || precedence c > precedence (head os)) = helper cs (c:os) out+            | isOperator c = helper (c:cs) (tail os) (out ++ pad (head os))+            | otherwise = helper cs os (out ++ pad c)++          isOperator cs = isOp cs || isFunction cs+          isOp cs = isJust $ (head cs) `triLookup` ops+          isFunction cs = isJust $ cs `lookup` fns+          precedence cs+            | isFunction cs = Just 999+            | otherwise = (head cs) `triLookup` ops++      tokenize :: String -> [String]+      tokenize str = words $ helper str+        where+          helper :: String -> String+          helper [] = []+          helper (c:cs)+            | isAlphanumeric c = c : helper cs+            | isSymbol c = pad [c] ++ helper cs++      replaceVariables :: String -> [(String, Double)] -> String+      replaceVariables str [] = str+      replaceVariables str vars = concatMap replace (tokenize str)+        where+          replace c+            | isVariable c = pad $ show $ fromJust $ c `lookup` vars+            | otherwise = c++          isVariable c = isJust $ c `lookup` vars++      -- | Evaluate an expression+      -- Example: `evaluate def "x + y ^ 2" [("x", 1), ("y", 2)]+      evaluate :: Settings -> String -> [(String, Double)] -> Double+      evaluate settings expr vars =+        let postfix = toPostfix settings expr+            replaced = replaceVariables postfix vars+        in helper (tokenize replaced) []+        where+          ops = operators settings+          fns = functions settings++          helper :: [String] -> [String] -> Double+          helper [] [o] = read o+          helper (c:cs) os+            | isOperator c =+                let result = (operatorFunction c) (read . head . tail $ os) (read . head $ os) +                in helper cs $ (show result) : drop 2 os+            | isFunction c =+                let result = (function c) (read . head $ os)+                in helper cs $ (show result) : tail os+            | otherwise = helper cs (c:os)++          isOperator cs = isJust $ (head cs) `triLookup` ops+          isFunction cs = isJust $ cs `lookup` fns++          function cs = fromJust $ cs `lookup` fns+          operatorFunction cs = case find (\(a, _, _) -> a == head cs) ops of+                                  Just (_, _, c) -> c+                                  Nothing -> const (const 0)+          isParen cs = head cs `elem` ['(', ')']++      alphanumeric = '.' : ['a'..'z'] ++ ['0'..'9']+      isAlphanumeric = (`elem` alphanumeric)+      isSymbol = not . (`elem` alphanumeric)  ++      triLookup :: (Eq a) => a -> [(a, b, c)] -> Maybe b+      triLookup a x = lookup a $ map (\(a, b, _) -> (a, b)) x++      pad :: String -> String+      pad x = ' ' : x ++ [' ']