Frank-0.1: Check.lhs
> {-# OPTIONS_GHC -F -pgmF she #-}
> {-# LANGUAGE TypeOperators, KindSignatures, GADTs, TypeSynonymInstances,
> FlexibleInstances, GeneralizedNewtypeDeriving, TupleSections,
> MultiParamTypeClasses #-}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> module Check where
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> import Prelude hiding (elem, all)
> import Data.Char
> import Data.List hiding (elem, all)
> import Data.Monoid
> import Data.Foldable
> import Data.Traversable
> import Control.Applicative
> import Control.Monad
> import Control.Newtype
> import Data.Void
> import Gubbins
> import Types
> import Pa
> import Syntax
> import Template
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% TError %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> data TError
> = TMissing UpId
> | SMissing UpId
> | TArity UpId Int [VT]
> | SArity UpId Int [VT]
> | BadTemplate
> | Cockup String
> | AmbiguousPats [Pat]
> | AmbiguousRaws [Raw]
> | BadPat VT Pat
> | NoConstructor VT Template
> | AppliedPVar String
> | RepeatedPVar Template
> | PatArityError Template
> | RawArityError Template
> | BadLhs [Pat]
> | UnifyVFail VT VT
> | UnifyCFail CT CT
> | UnifySFail Sig Sig
> | BadBunk
> | Useless VT
> | CheckR VT Raw
> | CantDo Sig [Sig]
> | AmbiguousOp Template [Sig]
> | ThunkMismatch CT ([Pat], Raw)
> | BadMessPat [Pat]
> | GuessThunk [([Pat], Raw)]
> | BadHandlerType VT
> | SynCon
> | Line ([Pat], Raw) TError
> | Raw VT Raw TError
> | Dunno Template [Sig] [Template]
> deriving Show
> type Moan = TError :>>: Void
> type Moaning = Free Moan
> moan :: TError -> Moaning x
> moan e = com (e :? absurd)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% checking top level data, signature and function declarations %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> data TypeInfo = TypeInfo
> { dataDecls :: [(UpId, (Int, [(Template, [VT])]))]
> , sigDecls :: [(UpId, (Int, [(Template, ([VT], VT))]))]
> , funDecls :: [(Template, (Int, [VT], [Sig], VT))]
> , templateT :: TemplateTable
> } deriving Show
> typeInfo :: Source -> Moaning TypeInfo
> typeInfo src = do
> let dt (n, (xs, cs)) =
> (| ~n, (| ~(length xs), traverse (conTemplate src xs) cs|)|)
> sg (n, (xs, os)) = (| ~n, (| ~(length xs), traverse oper os|)|) where
> oper (vs, v) = (|rass (conTemplate src xs vs) (tScope src xs v)|)
> rass (a, b) c = (a, (b, c))
> fn stuf@(vs, (ss, v)) = do
> let xs = ftvs src stuf
> (t, vs') <- conTemplate src xs vs
> ss' <- tScope src xs ss
> v' <- tScope src xs v
> return (t, (length xs, vs', ss', v'))
> ds <- (| ~ primitiveTypes ++ traverse dt (sourceData src) |)
> ss <- (| ~ primitiveSigs ++ traverse sg (sourceSigs src) |)
> fs <- (| ~primitiveFunDecls ++ traverse fn (sourceDecl src) |)
> let ts = (| fst (|(snd . snd) ds @ |)
> | fst (|(snd . snd) ss @ |)
> | fst fs
> |)
> return $ TypeInfo ds ss fs (TemplateTable ts [] [])
> ftvs :: TMang t => Source -> t -> [UpId]
> ftvs src = ala' UnionList (ala' Const tMang) (var chk mempty mempty)
> where chk u = maybe (maybe [u] (const []) (lookup u primitiveTypes))
> (const []) (lookup u (sourceData src))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% generating a template and domains from a declaration %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> conTemplate :: Source -> [UpId] -> [Lump] -> Moaning (Template, [VT])
> conTemplate src xs vs = do
> (bs, us) <- go vs
> (|tmp bs, ~us|)
> where
> go [] = return ([], [])
> go (LTy v : vs) = do
> u <- tScope src xs v
> (bs, us) <- go vs
> return (Place : bs, u : us)
> go (LNm n : vs) = do
> (bs, us) <- go vs
> return (Mark n : bs, us)
> tmp [] = moan $ BadTemplate
> tmp (Mark n : bs) | all place bs = (|[Mark n]|)
> tmp bs = (|id (post bs)|)
> post [] = (|[]|)
> post (Place : Place : bs) = moan $ BadTemplate
> post (b : bs) = (| ~b : post bs|)
> place Place = True
> place _ = False
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% type scope and arity checking %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> class TScope x where
> tScope :: Source -> [UpId] -> x -> Moaning x
> instance TScope x => TScope [x] where
> tScope src xs = traverse (tScope src xs)
> instance TScope VT where
> tScope src xs (D x []) | Just i <- findIndex (==x) xs = return (X i)
> tScope src xs (D x vs) = do
> a <- maybe
> (maybe (moan $ TMissing x) (return . fst) (lookup x primitiveTypes))
> (return . length . fst) $
> lookup x (sourceData src)
> if a == length vs
> then (|(D x) (tScope src xs vs)|)
> else moan $ TArity x a vs
> tScope src xs (M os ss v) =
> (|M (tScope src xs os) (tScope src xs ss) (tScope src xs v)|)
> tScope src xs Un = return Un
> tScope src xs Ze = return Ze
> tScope src xs (U c) = (|U (tScope src xs c)|)
> tScope src xs (X _) = moan $ Cockup "X already?"
> tScope src xs (Q _) = moan $ Cockup "Q already?"
> instance TScope CT where
> tScope src xs (v :-> c) = (|tScope src xs v :-> tScope src xs c|)
> tScope src xs (F ss v) = (|F (tScope src xs ss) (tScope src xs v)|)
> instance TScope Sig where
> tScope src xs (s :$ vs) = do
> a <- maybe (maybe (moan $ SMissing s)
> (pure . fst) (lookup s primitiveSigs))
> (pure . length . fst) $
> lookup s (sourceSigs src)
> if a == length vs
> then (| ~s :$ tScope src xs vs|)
> else moan $ SArity s a vs
> tScope src xs Pure = (|Pure|)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% prmimitives %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> primitiveTypes :: [(UpId, (Int, [(Template, [VT])]))]
> primitiveTypes =
> [ (Up "Char", (0, []))
> , (Up "Bool", (0, [([Mark "tt"], []), ([Mark "ff"], [])]))
> ]
> char :: VT
> char = D (Up "Char") []
> bool :: VT
> bool = D (Up "Bool") []
> primitiveFunDecls :: [(Template, (Int, [VT], [Sig], VT))]
> primitiveFunDecls =
> [ ([Place, Mark "=Char=", Place], (0, [char, char], [], bool))
> ]
> primitiveSigs :: [(UpId, (Int, [(Template, ([VT], VT))]))]
> primitiveSigs =
> [ (Up "Console", (0,
> [ ([Mark "inch"], ([], char))
> , ([Mark "ouch"], ([char], Un))
> ]))
> ]