aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Eval.hs11
-rw-r--r--src/Helper.hs23
2 files changed, 32 insertions, 2 deletions
diff --git a/src/Eval.hs b/src/Eval.hs
index 2f1bb7e..fe8dbe8 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -8,6 +8,7 @@ import Control.Monad.State
import qualified Control.Monad.State.Strict as StrictState
import qualified Data.BitString as Bit
import qualified Data.ByteString as Byte
+import Data.Function ( on )
import Data.List
import qualified Data.Map as M
import Data.Maybe
@@ -67,9 +68,17 @@ evalFun fun (Environment sub) = state $ \env@(Environment e) ->
let lookup' name env' = case M.lookup fun env' of
Nothing -> Left $ UndefinedIdentifier name
Just (EnvDef { _exp = x }) -> Right x
+ matching n
+ | length e == 0 = "<no idea>"
+ | otherwise = snd $ minimumBy (compare `on` fst) $ map
+ (\f -> (levenshtein (functionName f) n, show f))
+ (M.keys e)
+ suggest (Left u@(UndefinedIdentifier n)) =
+ Left $ SuggestSolution u (matching $ functionName n)
+ suggest x = x
in case lookup' fun sub of -- search in sub env
s@(Right _) -> (s, env)
- _ -> (lookup' fun e, env) -- search in global env
+ _ -> (suggest $ lookup' fun e, env) -- search in global env
evalAbs :: Expression -> Environment -> EvalState (Failable Expression)
evalAbs e sub = evalExp e sub >>= pure . fmap Abstraction
diff --git a/src/Helper.hs b/src/Helper.hs
index 5433dd0..0c2b576 100644
--- a/src/Helper.hs
+++ b/src/Helper.hs
@@ -6,6 +6,7 @@
module Helper where
import qualified Control.Monad.State as S
+import Data.Array
import qualified Data.BitString as Bit
import qualified Data.ByteString as Byte
import qualified Data.ByteString.Char8 as C
@@ -35,9 +36,10 @@ printContext (Context inp path) = p $ lines inp
errPrefix :: String
errPrefix = "\ESC[41mERROR\ESC[0m "
-data Error = SyntaxError String | UndefinedIdentifier Identifier | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | ImportError String
+data Error = SyntaxError String | UndefinedIdentifier Identifier | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | SuggestSolution Error String | ImportError String
instance Show Error where
show (ContextualError err ctx) = show err <> "\n" <> (printContext ctx)
+ show (SuggestSolution err sol) = show err <> "\nPerhaps you meant: " <> sol
show (SyntaxError err) =
errPrefix <> "invalid syntax\n\ESC[45mnear\ESC[0m " <> err
show (UndefinedIdentifier ident) =
@@ -211,6 +213,25 @@ decodeStdout e = do
---
+-- from reddit u/cgibbard
+levenshtein :: (Eq a) => [a] -> [a] -> Int
+levenshtein xs ys = levMemo ! (n, m)
+ where
+ levMemo =
+ array ((0, 0), (n, m)) [ ((i, j), lev i j) | i <- [0 .. n], j <- [0 .. m] ]
+ n = length xs
+ m = length ys
+ xa = listArray (1, n) xs
+ ya = listArray (1, m) ys
+ lev 0 v = v
+ lev u 0 = u
+ lev u v
+ | xa ! u == ya ! v = levMemo ! (u - 1, v - 1)
+ | otherwise = 1 + minimum
+ [levMemo ! (u, v - 1), levMemo ! (u - 1, v), levMemo ! (u - 1, v - 1)]
+
+---
+
-- TODO: Performanize
matchingFunctions :: Expression -> Environment -> String
matchingFunctions e (Environment env) =