Skip to content

Commit

Permalink
Implemented #15 missing definition checks (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-lewandowski authored Oct 2, 2020
1 parent 5048e91 commit 72ae089
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/Harper/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ invTypes
-> HarperOutput a
iterCurrNoElem :: HarperOutput a
localWOutType :: (Print p, Position p) => Ident -> p -> HarperOutput a
missingDeclaration :: (Print p, Position p) => Ident -> p -> HarperOutput a
mixingYieldAndReturn :: (Print p, Position p) => p -> HarperOutput a
noRet :: (Position p) => Statement p -> HarperOutput a
nonExhPatMatch :: (Print p, Position p) => p -> HarperOutput a
Expand Down Expand Up @@ -444,6 +445,10 @@ localWOutType i ctx = do
ctx
typeErr

missingDeclaration i ctx = do
outputErr (("type hint for function `" ++) . showsPrt i . ("` has no associated definition." ++)) ctx
typeErr

mixingYieldAndReturn ctx = do
outputErr
("a `return` statement cannot be used in an iterator function." ++)
Expand Down Expand Up @@ -616,4 +621,4 @@ varNotDefAss i ctx = do
. ("` is not definitely assigned at point of use." ++)
)
ctx
typeErr
typeErr
18 changes: 17 additions & 1 deletion src/Harper/TypeChecker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,19 @@ typeCheck p@(Prog a ds) = do
let env = Env $ Map.union userEnv globalEnv
fs' <- mapM (local (const env) . (\f -> clearBlkSt >> annotate f)) fs
tds' <- mapM (local (const env) . annotateTypeMembers) tds
ctors <- gets tCtors
matchDeclarations fts fs
return (toProg tds' fts' fs')
where
matchDeclarations :: (Position a) => [TypeHint a] -> [FunDecl b] -> TypeChecker ()
matchDeclarations hs ds = mapM_ (findMatchingIn dsIdent) hs
where
dsIdent = Set.fromList $ map getDIdent ds
getDIdent (FDecl _ id _ _) = id
findMatchingIn :: (Position a) => Set.Set Ident -> TypeHint a -> TypeChecker ()
findMatchingIn decls hint = unless (hintId `Set.member` decls) (raise $ Error.missingDeclaration hintId hint)
where
hintId = getHIdent hint
getHIdent (THint _ id _) = id
toProg tds fts fs =
let tds' = [ TopLvlTDecl (annWith unitT $ pos td) td | td <- tds ]
fts' = [ TopLvlTHint (annWith (typ th) a) th | th <- fts ]
Expand All @@ -67,9 +77,15 @@ typeCheck p@(Prog a ds) = do
return $ RefTDecl (annWith unitT a') (annWith unitT <$> sig) body'
annotateTypeBody tName (TBody a membs) = do
membs' <- mapM (annotateMemb tName) membs
let hints = [ hint | TMemTHint _ hint <- membs ]
decls = [ decl | TMemFDecl _ decl <- membs ]
matchDeclarations hints decls
return $ TBody (annWith unitT a) membs'
annotateTypeBody tName (DataTBody a flds membs) = do
membs' <- mapM (annotateMemb tName) membs
let hints = [ hint | TMemTHint _ hint <- membs ]
decls = [ decl | TMemFDecl _ decl <- membs ]
matchDeclarations hints decls
return $ DataTBody (annWith unitT a)
(map (annWith unitT <$>) flds)
membs'
Expand Down
6 changes: 6 additions & 0 deletions test/Harper/Tests/Bad/DataMethodTypeHintWithoutDefinition.har
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
value HelloWorld = {
data = {
name :: String;
}
sayHello :: String;
};
7 changes: 7 additions & 0 deletions test/Harper/Tests/Bad/DataMethodTypeHintWithoutDefinition.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Error: type hint for function `sayHello` has no associated definition.
During evaluation of:
sayHello :: String

Located at line 5 column 5

Execution terminated with an error: type error.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main :: Integer;
7 changes: 7 additions & 0 deletions test/Harper/Tests/Bad/FunctionTypeHintWithoutDefinition.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Error: type hint for function `main` has no associated definition.
During evaluation of:
main :: Integer

Located at line 1 column 1

Execution terminated with an error: type error.
3 changes: 3 additions & 0 deletions test/Harper/Tests/Bad/MethodTypeHintWithoutDefinition.har
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
value HelloWorld = {
sayHello :: String;
};
7 changes: 7 additions & 0 deletions test/Harper/Tests/Bad/MethodTypeHintWithoutDefinition.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Error: type hint for function `sayHello` has no associated definition.
During evaluation of:
sayHello :: String

Located at line 2 column 5

Execution terminated with an error: type error.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
value HelloWorld = {
variant Hi = {
sayHello :: String;
sayHello = "Hi, World!";
};

variant Hello = {
data = {
name :: String;
}
sayHello :: String;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Error: type hint for function `sayHello` has no associated definition.
During evaluation of:
sayHello :: String

Located at line 11 column 7

Execution terminated with an error: type error.
10 changes: 10 additions & 0 deletions test/Harper/Tests/Bad/VariantMethodTypeHintWithoutDefinition.har
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
value HelloWorld = {
variant Hi = {
sayHello :: String;
sayHello = "Hi, World!";
};

variant Hello = {
sayHello :: String;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Error: type hint for function `sayHello` has no associated definition.
During evaluation of:
sayHello :: String

Located at line 8 column 7

Execution terminated with an error: type error.

0 comments on commit 72ae089

Please sign in to comment.