aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Evaluator.hs13
-rw-r--r--src/Parser.hs2
-rw-r--r--test/Spec.hs16
-rw-r--r--test/TestUtils.hs19
4 files changed, 33 insertions, 17 deletions
diff --git a/src/Evaluator.hs b/src/Evaluator.hs
index 2797fcd..4de5565 100644
--- a/src/Evaluator.hs
+++ b/src/Evaluator.hs
@@ -102,9 +102,16 @@ evaluateFunctionDef env asts = do
| length args' < 2 ->
throwL (astPos defAst) $ "\\ called with " ++ show (length args) ++ " arguments"
| otherwise -> return $ (head args', tail args')
+
AST { astNode = ASTVector params' } <- assertIsASTVector params''
params <- mapM assertIsASTSymbol params'
+ let shadowingParamM = L.find (astNode .> (\(ASTSymbol sym) -> sym) .> isParamNameShadowing) params
+ case shadowingParamM of
+ Just shadowingParam -> throwL (astPos shadowingParam)
+ $ "parameter is shadowing already defined symbol " ++ show (astNode shadowingParam)
+ Nothing -> return ()
+
let letExprs = take (length exprs - 1) exprs
let nonLetExprM = L.find (not . isLetAST) letExprs
case nonLetExprM of
@@ -117,6 +124,7 @@ evaluateFunctionDef env asts = do
where
isLetAST AST { astNode = ASTFunctionCall (AST { astNode = ASTSymbol "let" }:_) } = True
isLetAST _ = False
+ isParamNameShadowing name = M.member name env
evaluateMatch :: Env -> [AST] -> LContext (Env, AST)
evaluateMatch env asts = do
@@ -137,8 +145,9 @@ evaluateMatch env asts = do
return (env, matchAst { astNode = astNode ret })
where
matchPairs :: (AST, AST) -> [(AST, AST)] -> LContext AST
- matchPairs (actualExpr, evaledActual) [] = throwL (astPos actualExpr) $ "matching case not found when matching on expression: " ++ show actualExpr
- ++ " (actual value: " ++ show evaledActual ++ ")"
+ matchPairs (actualExpr, evaledActual) [] = throwL (astPos actualExpr)
+ $ "matching case not found when matching on expression: " ++ show actualExpr
+ ++ " (actual value: " ++ show evaledActual ++ ")"
matchPairs (actualExpr, evaledActual) ((matcher, branch):restPairs) = do
(_, evaledMatcher) <- evaluate env matcher
if evaledActual == evaledMatcher
diff --git a/src/Parser.hs b/src/Parser.hs
index 5089cb4..20a1454 100644
--- a/src/Parser.hs
+++ b/src/Parser.hs
@@ -41,7 +41,7 @@ parseToken (Token token tr tc tf)
removeQuotes s = drop 1 s $> take (length s - 2)
isBoolean t = t `elem` ["true", "false"]
asBoolean t = t == "true"
- ast astNode = AST { astNode = astNode, astRow = tr, astColumn = tc, astFileName = tf }
+ ast node = AST { astNode = node, astRow = tr, astColumn = tc, astFileName = tf }
_parse :: [AST] -> [Token] -> LContext [AST]
_parse acc' [] = do
diff --git a/test/Spec.hs b/test/Spec.hs
index 6e9104e..3d1ad3a 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -18,10 +18,8 @@ tokenizeTests = testGroup "tokenize" [
parseTests = testGroup "parse" [
do got <- expectSuccessL $ parse (map makeNonsenseToken ["(", "+", "1", "2", ")"])
- let expected = [wrapAST $ ASTFunctionCall
- [ wrapAST $ ASTSymbol "+",
- wrapAST $ ASTInteger 1,
- wrapAST $ ASTInteger 2 ]]
+ let expected = [astFunctionCall
+ [ astSymbol "+", astInteger 1, astInteger 2 ]]
assertEqual "" got expected
, do got <- expectErrorL $ parse (map makeNonsenseToken ["(", "+", "1", "2"])
@@ -31,11 +29,9 @@ parseTests = testGroup "parse" [
evaluateTests = testGroup "evaluate" [
do let env = M.fromList [builtinAdd2] :: Env
- (gotEnv, gotAST) <- expectSuccessL $ evaluate env (wrapAST $ ASTFunctionCall
- [wrapAST $ ASTSymbol "+",
- wrapAST $ ASTInteger 1,
- wrapAST $ ASTInteger 2])
- let expectedAST = wrapAST $ ASTInteger 3
+ (gotEnv, gotAST) <- expectSuccessL $ evaluate env (astFunctionCall
+ [astSymbol "+", astInteger 1, astInteger 2])
+ let expectedAST = astInteger 3
assertEqual "" gotAST expectedAST
assertEqual "" (M.keys gotEnv) (M.keys env)
]
@@ -46,7 +42,7 @@ e2eTests = testGroup "e2e" [
(gotEnv, gotASTs) <- expectSuccessL $ runInlineScript "<test>" env script1
let expectedEnvKeys = ["-", "sub2"]
assertEqual "" (M.keys gotEnv) expectedEnvKeys
- assertEqual "" (last gotASTs) (wrapAST $ ASTInteger 1)
+ assertEqual "" (last gotASTs) (astInteger 1)
]
testGroup label xs = TestLabel label $ TestList $ map TestCase xs
diff --git a/test/TestUtils.hs b/test/TestUtils.hs
index 5206d27..e497ece 100644
--- a/test/TestUtils.hs
+++ b/test/TestUtils.hs
@@ -19,15 +19,26 @@ expectSuccessL :: LContext a -> IO a
expectSuccessL lc =
do res <- testRunL lc
case res of
- Left (LException err) -> error $ "unexpected error: " ++ err
+ Left (LException _ err) -> error $ "unexpected error: " ++ err
Right val -> return val
expectErrorL :: Show a => LContext a -> IO String
expectErrorL lc =
do res <- testRunL lc
case res of
- Left (LException err) -> return err
+ Left (LException _ err) -> return err
Right val -> error $ "unexpected success: " ++ show val
-wrapAST :: ASTNode -> AST
-wrapAST node = AST { astNode = node }
+ast :: ASTNode -> AST
+ast node = AST { astNode = node }
+
+astInteger a = ast $ ASTInteger a
+astDouble a = ast $ ASTDouble a
+astSymbol a = ast $ ASTSymbol a
+astBoolean a = ast $ ASTBoolean a
+astString a = ast $ ASTString a
+astVector a = ast $ ASTVector a
+astFunctionCall a = ast $ ASTFunctionCall a
+astHashMap a = ast $ ASTHashMap a
+astUnit = ast $ ASTUnit
+astHole = ast $ ASTHole