Skip to content

Commit

Permalink
fix: Support delayed type definition for function defns.
Browse files Browse the repository at this point in the history
This happens when a function is passed as callback to another function
which has already seen a different function be passed as callback. We
need to unify them against each other (for now, without polymorphism).
  • Loading branch information
iphydf committed Jan 26, 2024
1 parent 9411df3 commit 51bd91a
Showing 1 changed file with 15 additions and 12 deletions.
27 changes: 15 additions & 12 deletions src/Tokstyle/Linter/TypeCheck.hs
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ instance Pretty Env where
mapM (\(n, ty) -> (n,) <$> unify ty ty) tys


typeError :: (HasCallStack, Show a) => [a] -> State Env b
typeError x = do
typeError :: (HasCallStack, Show a) => String -> [a] -> State Env b
typeError msg x = do
env <- State.get
error $ show $ vcat $ map (text . show) x ++ [pretty env]
error $ msg <> ": " <> (show $ vcat $ map (text . show) x ++ [pretty env])

empty :: Env
empty = Env{..}
Expand Down Expand Up @@ -187,7 +187,7 @@ unifyRecursive :: HasCallStack => [(Type, Type)] -> Type -> Type -> State Env Ty
unifyRecursive stack ty1 ty2 = do
res <- go False ty1 ty2
case res of -- trace ("unify: " <> show (l, r)) $
T_Bot -> typeError $ (ty1, ty2):stack
T_Bot -> typeError "bottom" $ (ty1, ty2):stack
ok -> return ok
where
-- Equal types unify trivially.
Expand Down Expand Up @@ -254,7 +254,7 @@ unifyRecursive stack ty1 ty2 = do
go _ T_Bot _ = return T_Bot

go False a b = go True b a
go True a b = typeError [(a, b)]
go True a b = typeError "unification" [(a, b)]

unifyRec = unifyRecursive ((ty1, ty2):stack)

Expand Down Expand Up @@ -311,7 +311,7 @@ inferTypes = \case
TyFunc (L _ _ name) -> return $ T_Name name
TyStd (L _ _ name) ->
case Map.lookup name stdTypes of
Nothing -> return $ T_Name name -- typeError [name]
Nothing -> return $ T_Name name -- typeError "standard type" [name]
Just ty -> return ty
TyUserDefined (L _ _ name) -> return $ T_Name name
TyPointer ty -> return $ T_Ptr ty
Expand Down Expand Up @@ -373,12 +373,15 @@ inferTypes = \case
funTy <- unify (T_Func retTy args) callee
case funTy of
T_Func result _ -> return result
_ -> typeError [funTy]
FunctionDefn _ (T_Func r _) body -> do
_ -> typeError "function type" [funTy]
FunctionDefn _ defnTy body -> do
dropLocals
-- trace (show r) $ return ()
-- trace (show body) $ return ()
unify r body
retTy <- newTyVar
-- Ignore parameter types, unify will zip [] with the params, resulting in [].
funTy <- unify (T_Func retTy []) defnTy
case funTy of
T_Func r _ -> unify r body
_ -> typeError "function defn" [funTy]

ExprStmt{} -> return T_Void
Break -> return T_Void
Expand Down Expand Up @@ -422,7 +425,7 @@ inferTypes = \case
void $ unify e (T_Ptr (T_Struct (Map.singleton mem ty)))
return ty

x -> typeError [x]
x -> typeError "unhandled" [x]

linter :: AstActions (State Env) Text
linter = astActions
Expand Down

0 comments on commit 51bd91a

Please sign in to comment.